Reputation: 31
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
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