Qt OpenGLWindow不渲染三角形

时间:2019-02-27 11:04:44

标签: qt opengl qt5

使用Qt5(5.12)和OpenGL 4.3,下面的代码不会绘制我想要的矩形。

编译正常,但仅显示黑色背景(更改值时颜色会发生变化,因此至少可以正常工作),但不显示任何三角形

该示例来自OpenGL蓝皮书的早期章节。既然那是我拥有的并且可以轻松使用的唯一资源,我想直接使用opengl函数进行编码,并尽可能避免在此时使用Qt的类。

 > 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

请注意,窗口已使用OpenGL,CoreProfile,4.3格式初始化

 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();
  }

1 个答案:

答案 0 :(得分:1)

这很难看。

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",
 };

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",
 };

的类型不是const char*,而是const char*[]vertex_shader有11个元素,而fragment_shader_source有8个元素。

glShaderSource的第二个参数必须是数组中元素的数量。
因此必须是:

glShaderSource(vertex_shader, 11, vertex_shader_source, NULL);

分别

glShaderSource(fragment_shader, 8, fragment_shader_source, NULL);

我建议使用Raw string literal而不是数组:

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);

进一步,检查着色器的编译是否成功:

例如

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;
}

,如果成功链接程序:

例如

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;
}