1

I have working application done using QtCreator. My render class is

GLRendWindow::GLRendWindow(QWidget *parent): QOpenGLWidget(parent)

Now I would like to draw objects using arrays with coordinates of vertices.
I found some tutorial that draws triangle on this page: OpenGL Window Example

I tried to reused it to draw simple line

void GLRendWindow::drawLine()
{
    GLfloat line[] =
    {
        0.5f, 1.0f,
        0.5f, -1.0f
    };
    GLfloat line_colors[] =
    {
        1.0f, 0.0f, 0.0f, // red
        0.0f, 0.0f, 1.0f, // blue
    };
    shaderProgram->bind();
    glVertexAttribPointer(posAttr, 2, GL_FLOAT, GL_FALSE, 0, line);
    glVertexAttribPointer(colAttr, 3, GL_FLOAT, GL_FALSE, 0, line_colors);
    glEnableVertexAttribArray(colAttr);
    glEnableVertexAttribArray(posAttr);
    glDrawArrays(GL_LINE, 0, 2);
    glDisableVertexAttribArray(posAttr);
    glDisableVertexAttribArray(colAttr);
    shaderProgram->release();
}

Also my initialization method

void GLRendWindow::initializeGL()
{
    initializeOpenGLFunctions();
    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );

    shaderProgram = new QOpenGLShaderProgram(this);
    shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
    shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
    shaderProgram->link();
    posAttr = shaderProgram->attributeLocation("posAttr");
    colAttr = shaderProgram->attributeLocation("colAttr");
}

and drawing method

void GLRendWindow::paintGL()
{
    glClear( GL_COLOR_BUFFER_BIT );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    drawLine();

    if (isUpdated)
    {
       //some other stuff

        isUpdated = false;
    }
    glFlush();
}

and resize method

void GLRendWindow::resizeGL(int w, int h)
{
    glViewport( 0, 0, w, h );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    if ( w < h && w > 0 )
    {
        glFrustum( - 1.0, 1.0, - 1.0 * h / w, 1.0 * h / w, 1.0, 5.0 );
    }
    else
    {
        if ( w >= h && h > 0 )
        {
            glFrustum( - 0.3 * w / h, 0.3 * w / h, - 0.3, 0.3, 0.5, 5.0 );
        }
    }
}

But when I run app, nothing is drawed. No errors, no exceptions, nothing. In this tutorial I see

static const char *vertexShaderSource =
    "attribute highp vec4 posAttr;\n"
    "attribute lowp vec4 colAttr;\n"
    "varying lowp vec4 col;\n"
    "uniform highp mat4 matrix;\n"
    "void main() {\n"
    "   col = colAttr;\n"
    "   gl_Position = matrix * posAttr;\n"
    "}\n";

static const char *fragmentShaderSource =
    "varying lowp vec4 col;\n"
    "void main() {\n"
    "   gl_FragColor = col;\n"
    "}\n";

and it is possible solution is hidden here, but I completely don't understand what for it is and what is going on here. I am even not sure if this is necessary for drawing simple line.
What should I do to see stright line using array of coordinates?

rainbow
  • 1,161
  • 3
  • 14
  • 29

2 Answers2

1

Problem was also here

glDrawArrays(GL_LINE, 0, 2);

It should be

glDrawArrays(GL_LINES, 0, 2);

And I had to changed

static const char *vertexShaderSource =
    "attribute highp vec4 posAttr;\n"
    "attribute lowp vec4 colAttr;\n"
    "varying lowp vec4 col;\n"
    "uniform highp mat4 matrix;\n"
    "void main() {\n"
    "   col = colAttr;\n"
    "   gl_Position = matrix * posAttr;\n"
    "}\n";

to

static const char *vertexShaderSource =
    "attribute highp vec4 posAttr;\n"
    "attribute lowp vec4 colAttr;\n"
    "varying lowp vec4 col;\n"
    "void main() {\n"
    "   col = colAttr;\n"
    "   gl_Position = posAttr;\n"
    "}\n";
rainbow
  • 1,161
  • 3
  • 14
  • 29
  • Where is the explanation? – Rabbid76 Oct 18 '20 at 07:13
  • @Rabbid76 I suppose your advice about color was right. But for some reason when I wrote my solution answer your post was not visible and I tought you deleted it. glDrawArray is just simple notation mistake. I think it doesn't need any axplanation. In case of "matrix" I just removed it. I suppose it is needed for some transformations but in this case is not necessary. – rainbow Oct 21 '20 at 11:48
  • The point is that `glMatrixMode( GL_MODELVIEW );`, `glLoadIdentity();` etc. is useless when using a shader. If you want to set the transformation matrix, then you have to set the matrix uniform. See my answer. – Rabbid76 Oct 21 '20 at 11:51
  • @Rabbid76 You are righ. My code may be messy because on the very begining I started from basic functions and now I just use something more "modern" (if it is proper word). Additionally I am lost in all those possibilities. – rainbow Oct 21 '20 at 11:55
0

You missed to set specify the array of generic vertex attribute data for the color attribute (attribute lowp vec4 colAttr;). This is similar to specifying the vertex attributes.
For example, add the following code to GLRendWindow::drawLine:

GLfloat line_colors[] =
{
    1.0f, 0.0f, 0.0f, // red
    0.0f, 0.0f, 1.0f  // blue
};
glVertexAttribPointer(colAttr, 3, GL_FLOAT, GL_FALSE, 0, line_colors);
glEnableVertexAttribArray(colAttr);

You don't specify the color attribute array, so the value of colAttr is by default (0, 0, 0). Actually you draw a black line on a black background.


You are mixing different technologies. You have a shader program with a matrix Uniform:

uniform highp mat4 matrix;\n"
void main() {
   // [...]

   gl_Position = matrix * posAttr;
}

You don't set this uniform at all. Instead you try to set the legacy OpenGL fixed function matrix. The contents of the legacy current matrix do not magically appear in the unitary variable.

Use setUniformValue to set the value of the matrix uniform:

QMatrix4x4 matrix;
int matrix_location = shaderprogram->uniformLocation("matrix");

matrix.setToIdentity();
shaderprogram->setUniformValue(matrix_location, matrix);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • I've update code in my first post with your hints. Unfortunatelly result is the same - nothing. I also added my resize method. – rainbow Oct 17 '20 at 22:03
  • @rainbow You have 2 vertices, so you need 2 color attributes, too. Why did you delete the 2nd color attribute? – Rabbid76 Oct 17 '20 at 22:07
  • You are right. It was copy-paste mistake. Even with two colors it doesn't work. I wonder maybe I draw this line outside the view? – rainbow Oct 17 '20 at 22:09