Problem: I have a VBO containing an array of structs (MyStruct), which contain a boolean attribute. I want to pass this boolean to my vertex shader, but GL_BOOL
is not allowed according to the documentation of glVertexAttribPointer(...);
.
Specifies the data type of each component in the array. The symbolic constants GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, and GL_UNSIGNED_INT are accepted by glVertexAttribPointer and glVertexAttribIPointer. Additionally GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED, GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV and GL_UNSIGNED_INT_10F_11F_11F_REV are accepted by glVertexAttribPointer. GL_DOUBLE is also accepted by glVertexAttribLPointer and is the only token accepted by the type parameter for that function. The initial value is GL_FLOAT. Source: https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml
What did I try: As shown in the moc-up i tried to use in int myBoolean;
instead but the boolean values of the struct (which are set properly, I've checked) are not correctly mapped to the ints in the vertex shader (this might be something on my end though?).
Moc-up code of the problem:
MyStruct
struct MyStruct{
...
bool myBoolean;
...
}
Vertex Shader
#version 400 compatibility // Can be set higher if needed
in vec3 position;
//in bool myBoolean;
//in int myBoolean; -> doesn't work either
out vec4 color;
void main( void )
{
//if (myBoolean){ // (myBool == 1) for the int
// color = vec4(1,0,0,1);
//} else {
color = vec4(position, 1);
//}
...
};
How I set up the buffers:
// Build OpenGL VBO
glGenBuffers( 1, &m_glVBO );
glBindBuffer( GL_ARRAY_BUFFER, m_glVBO );
glBufferData( GL_ARRAY_BUFFER, numOfMyStructs*sizeof(MyStruct), myStructs, GL_DYNAMIC_DRAW );
// Build OpenGL VAO
glGenVertexArrays( 1, &m_glVAO );
glBindVertexArray( m_glVAO );
// Position attribute
glEnableVertexAttribArray( 0 );
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof(myStruct), (GLvoid*)offsetof(MyStruct, position) );
// Does not work, all booleans in the vertex buffer are false
// and GL_BOOL is not allowed.
//glEnableVertexAttribArray( 1 );
//glVertexAttribPointer( 1, 1, GL_INT, GL_FALSE, sizeof(MyStruct), (GLvoid*)offsetof(MyStruct, myBoolean) );
glBindVertexArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
Binding the shader:
myShader = new QGLShaderProgram( QGLContext::currentContext() );
...
myShader->bindAttributeLocation( "position", 0 );
//myShader->bindAttributeLocation( "myBoolean", 1);
glBindFragDataLocation( myShader->programId(), 0, "color" );
...
Rendering: (I want to use instance rendering (a sphere) in the future but that doesn't matter)
...
glEnable( GL_POINT_SMOOTH );
glHint( GL_POINT_SMOOTH_HINT, GL_NICEST );
glBindVertexArray( m_glVAO );
glDrawArrays( GL_POINTS, 0, numMyStructs );
glBindVertexArray( 0 );
...
Additional information: I work with QtCreator (3.6.1), C++11, OpenGL (4.5), GLM (0.9.7.4), GLEW(1.13), Nvidia card (364.16 driver + CUDA 7.5), Linux 64bit. I'm an OpenGL novice. I would prefer to use no additional libraries if possible. It works fine without the myBoolean (so with the commented sections as set in the moc-up code). The moc-up code is quickly typed for stackoverflow, my apologies for possible syntax errors feel free to point them out (the real world code does work without the myBoolean). I can provide additional information if required.
Thanks in advance.