2016-04-19 6 views
0

Problem: Ich habe eine VBO mit einem Array von Strukturen (MyStruct), die ein boolesches Attribut enthalten. Ich möchte diesen booleschen Wert an meinen Vertex-Shader übergeben, aber GL_BOOL ist laut der Dokumentation von glVertexAttribPointer(...); nicht erlaubt.OpenGL Vertex Shader Set boolesch pro Vertex (glVertexAttribPointer)

Gibt den Datentyp jeder Komponente im Array an. Die symbolischen Konstanten GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT und GL_UNSIGNED_INT werden von glVertexAttribPointer und glVertexAttribIPointer akzeptiert. Zusätzlich GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED, GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV und GL_UNSIGNED_INT_10F_11F_11F_REV sind von glVertexAttribPointer akzeptiert. GL_DOUBLE wird auch von glVertexAttribLPointer akzeptiert und ist das einzige Token, das vom Typ für diese Funktion akzeptiert wird. Der Anfangswert ist GL_FLOAT. Quelle: https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml

Was habe ich versucht: Wie in der moc-up gezeigt habe ich versucht in int myBoolean; stattdessen zu verwenden, aber die Boolesche Werte der Struktur (die richtig eingestellt sind, ich geprüft habe) nicht korrekt den Ints im Vertex-Shader zugeordnet (dies könnte aber etwas an meinem Ende sein?).

Moc-up-Code des Problems:

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); 
//} 
... 
}; 

Wie ich die Puffer ein:

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

Bindung des Shader:

myShader = new QGLShaderProgram(QGLContext::currentContext()); 
... 
myShader->bindAttributeLocation("position", 0); 
//myShader->bindAttributeLocation("myBoolean", 1); 
glBindFragDataLocation(myShader->programId(), 0, "color"); 
... 

Rendering: (Ich möchte Instanz verwenden Rendering (eine Kugel) in der Zukunft, aber das spielt keine Rolle)

... 
glEnable(GL_POINT_SMOOTH); 
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); 

glBindVertexArray(m_glVAO); 
glDrawArrays(GL_POINTS, 0, numMyStructs); 
glBindVertexArray(0); 
... 

Zusätzliche Informationen: mit denen ich arbeite QtCreator (3.6.1), C++ 11, OpenGL (4.5), GLM (0.9.7.4), GLEW (1.13), Nvidia-Karte (364.16-Treiber + CUDA 7.5), Linux 64bit. Ich bin ein OpenGL-Neuling. Ich würde es vorziehen, wenn möglich keine zusätzlichen Bibliotheken zu verwenden. Es funktioniert ohne die myBoolean (also mit den kommentierten Abschnitte wie in der Moc-up-Code festgelegt). Der Moc-up-Code wird schnell für stackoverflow getippt, ich entschuldige mich für mögliche Syntaxfehler und weise sie darauf hin (der reale Code funktioniert ohne myBoolean). Ich kann bei Bedarf zusätzliche Informationen bereitstellen.

Vielen Dank im Voraus.

Antwort

1

Sie wollen wahrscheinlich glVertexAttribIPointer (beachten Sie den Buchstaben "I" dort eingebettet) - das ist für die Weitergabe von Integralwerten in.Und da alles in einer Struktur zumindest Byte ausgerichtet sind, kann ein einzelner bool nicht kleiner als GL_UNSIGNED_BYTE

https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml

+1

„Die symbolische Konstanten GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT und GL_UNSIGNED_INT akzeptiert werden von glVertexAttribPointer und glVertexAttribIPointer. " verwirrte mich, ich dachte, glVertexAttribPointer (ohne I) könnte auch mit ganzen Zahlen umgehen. Aber dein Vorschlag ist in Ordnung und es funktioniert jetzt, danke! 10 Stunden meines Lebens werde ich nicht zurückkommen. – iami

+0

ohne das i, es konvertiert sie in floats .. ich denke. Das steuert das NORMALIZED-Flag in der Nicht-I-Version. Sie werden also akzeptiert, aber sie verhalten sich anders. Außerdem ist es nur dummes Glück, dass ich vor ungefähr einer Woche über diese genaue Situation gestolpert bin. – xaxxon

+0

Aah ich sehe, danke für die Erklärung. – iami