使用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();
}
答案 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;
}