使用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();
}
这很难看到。
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);
我建议使用原始字符串文字而不是数组:
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;
}