Amir
Amir

Reputation: 31

Qt OpenGLWindow not rendering triangle

Using Qt5 (5.12) and OpenGL 4.3, code below won't draw the rectangle I want.

compiles fine, but just shows the black background (color changes when I change the value, so at least something working) but doesn't show any the triangle

The example is from early chapters of the OpenGL blue book. Since thats the only resource I have and can comfortably follow, would like to code directly with opengl functions and avoid using Qt's class's at this point if possible.

 > glxinfo
   OpenGL core profile version string: 4.6.0 NVIDIA 390.77
   OpenGL core profile shading language version string: 4.60 NVIDIA
   OpenGL core profile context flags: (none)
   OpenGL core profile profile mask: core profile
   OpenGL core profile extensions:
   OpenGL version string: 4.6.0 NVIDIA 390.77
   OpenGL shading language version string: 4.60 NVIDIA

please note Window is initialized with OpenGL, CoreProfile, 4.3 format

 class Window : public QOpenGLWindow, protected QOpenGLFunctions_4_3_Core
 {
    Q_OBJECT
    ...

    // QOpenGLWindow interface
    protected:
    void initializeGL() override;
    void resizeGL(int w, int h) override;
    void paintGL() override;

     GLuint rendering_program;
     GLuint vertex_array_object;
  }



initializeGL() ----------------
{
    /**** COMPILE SHADERS ****/

    GLuint vertex_shader, fragment_shader, program;

    static const GLchar *vertex_shader_source[] = {
    "#version 430 core                              \n",
    "                                               \n",
    "void main(void)                                \n",
    "{                                              \n",
    "   const vec4 vertices[3] = vec4[3](           \n",
    "       vec4( 0.25, -0.25, 0.5, 1.0),           \n",
    "       vec4(-0.25, -0.25, 0.5, 1.0),           \n",
    "       vec4( 0.25,  0.25, 0.5, 1.0));          \n",
    "                                               \n",
    "   gl_Position = vertices[gl_VertexID];        \n",
    "}                                              \n",
    };


     static const GLchar *fragment_shader_source[] = {
        "#version 430 core                              \n",
        "                                               \n",
        "out vec4 color;                                \n",
        "                                               \n",
        "void main(void)                                \n",
       "{                                              \n",
        "   color = vec4(0.0, 0.8, 1.0, 1.0);            \n",
        "}                                              \n",
      };


      // create and compile vertex shader
      vertex_shader = glCreateShader(GL_VERTEX_SHADER);
      glShaderSource(vertex_shader, 1, vertex_shader_source, NULL);
      glCompileShader(vertex_shader);

      // create and compile fragment shader
     fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
     glShaderSource(fragment_shader, 1, fragment_shader_source, NULL);
     glCompileShader(fragment_shader);

     // crate a program, attach shaders to it
     program = glCreateProgram();
     glAttachShader(program, vertex_shader);
     glAttachShader(program, fragment_shader);
     glLinkProgram(program);

     glDeleteShader(vertex_shader);
     glDeleteShader(fragment_shader);

     rendering_program = program;

      glGenVertexArrays(1, &vertex_array_object);
      glBindVertexArray(vertex_array_object);
  }


 paintGL() --------------------------
 {
     const GLfloat color[] = { 0.0f, 0.0f, 0.0f, 1.0f };
     glClearBufferfv(GL_COLOR, 0, color);

     glUseProgram(rendering_program);
     glBindVertexArray(vertex_array_object);



     glDrawArrays(GL_TRIANGLES, 0, 3);
     glFlush();
  }

Upvotes: 2

Views: 307

Answers (1)

Rabbid76
Rabbid76

Reputation: 210909

This was hard to see.

The declaration of vertex_shader_source

 static const GLchar *vertex_shader_source[] = {
     "#version 430 core                              \n",
     "                                               \n",
     "void main(void)                                \n",
     "{                                              \n",
     "   const vec4 vertices[3] = vec4[3](           \n",
     "       vec4( 0.25, -0.25, 0.5, 1.0),           \n",
     "       vec4(-0.25, -0.25, 0.5, 1.0),           \n",
     "       vec4( 0.25,  0.25, 0.5, 1.0));          \n",
     "                                               \n",
     "   gl_Position = vertices[gl_VertexID];        \n",
     "}                                              \n",
 };

and fragment_shader_source

 static const GLchar *fragment_shader_source[] = {
     "#version 430 core                              \n",
     "                                               \n",
     "out vec4 color;                                \n",
     "                                               \n",
     "void main(void)                                \n",
     "{                                              \n",
     "   color = vec4(0.0, 0.8, 1.0, 1.0);            \n",
     "}                                              \n",
 };

are not of type const char*, but of const char*[]. vertex_shader has 11 elements, and fragment_shader_source has 8 elements.

The 2nd paramter of glShaderSource has to be the number of elements in the array.
So it has to be:

glShaderSource(vertex_shader, 11, vertex_shader_source, NULL);

respectively

glShaderSource(fragment_shader, 8, fragment_shader_source, NULL);

I recommend to use Raw string literal instead of arrays:

const char *vertex_shader_source = R"(
#version 430 core                      

void main(void)                        
{                                      
const vec4 vertices[3] = vec4[3](   
    vec4( 0.25, -0.25, 0.5, 1.0),   
    vec4(-0.25, -0.25, 0.5, 1.0),   
    vec4( 0.25,  0.25, 0.5, 1.0));  

gl_Position = vertices[gl_VertexID];                                     
}
)";


const char *fragment_shader_source = R"(
#version 430 core                   

out vec4 color;                     

void main(void)                     
{                                   
color = vec4(0.0, 0.8, 1.0, 1.0);
}                                   
)";
glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);

Further, check if the compilation of the shaders succeeded:

e.g.

GLint status;

glCompileShader(vertex_shader);
glGetShaderiv( vertex_shader, GL_COMPILE_STATUS, &status );
if ( status == GL_FALSE )
{
    GLint logLen;
    glGetShaderiv( vertex_shader, GL_INFO_LOG_LENGTH, &logLen );
    std::vector< char >log( logLen );
    GLsizei written;
    glGetShaderInfoLog( vertex_shader, logLen, &written, log.data() );
    std::cout << "compile error:" << std::endl << log.data() << std::endl;
}

and if linking the program succeeded:

e.g.

glLinkProgram(program);
glGetProgramiv( program, GL_LINK_STATUS, &status );
if ( status == GL_FALSE )
{
    GLint logLen;
    glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logLen );
    std::vector< char >log( logLen );
    GLsizei written;
    glGetProgramInfoLog( program, logLen, &written, log.data() );
    std::cout  << "link error:" << std::endl << log.data() << std::endl;
}

Upvotes: 1

Related Questions