2015-10-01 1 views
0

J'essaie de créer un wrapper de shader Objective-C OpenGL de haut niveau qui me permet d'exécuter divers shaders GL sans beaucoup de code GL qui encombre la logique de l'application.GLSL 3.2 shader arguments de shader

donc quelque chose comme ça pour un shader avec deux « dans » arguments pour créer un quad avec une couleur différente dans tous les coins:

OpenGLShader* theShader = [OpenGLShaderManager shaderWithName:@"MyShader"]; 
glUseProgram(theShader.program); 

float colorsForQuad[4] = {{1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 1.0 ....}} 
theShader.arguments[@"inColor"] setValue:colorsForQuad forNumberOfVertices:4]; 

float positionsForQuad[4] = {{-1.0f, -1.0f, 0.0f, 1.0f}, {-1.0f, 1.0f, ....}} 
theShader.arguments[@"inPosition"] setValue:positionsForQuad forNumberOfVertices:4]; 

glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 

La fonction setValue:forNumberOfVertices: ressemble à ceci:

int bytesForGLType = numBytesForGLType(self.openGLValueType); 
glBindVertexArray(self.vertexArrayObject); 
GetError(); 

glBindBuffer(GL_ARRAY_BUFFER, self.vertexBufferObject); 
GetError(); 

glBufferData(GL_ARRAY_BUFFER, bytesForGLType * numVertices, value, GL_STATIC_DRAW); 
GetError(); 

glEnableVertexAttribArray((GLuint)self.boundLocation); 
GetError(); 

glVertexAttribPointer((GLuint)self.boundLocation, numVertices, 
           GL_FLOAT, GL_FALSE, 0, 0); 

Je pense que le problème est que chaque argument a ses propres VAO et VBO mais le shader a besoin des données de tous les arguments quand il est exécuté. Je ne peux évidemment que lier un tampon à la fois. Les exemples que j'ai vus jusqu'ici utilisent seulement un VAO et un VBO et créent une structure C contenant toutes les données nécessaires. Cela rendrait toutefois mon approche modulaire actuelle beaucoup plus difficile.

Existe-t-il une option permettant à OpenGL de copier les données de sorte qu'il n'a pas besoin d'être disponible et lié lors de l'appel de glDraw ...?

Modifier

J'ai découvert que l'utilisation d'un objet Array Vertex partagé est suffisant pour résoudre le problème. Cependant, j'apprécierais un peu plus de perspicacité sur quand les choses sont réellement copiées au GPU.

Répondre

0

La fonction glVertexAttribPointer prend ces paramètres:

glVertexAttribPointer void ( indice de GLuint, la taille de l'éclat, de type GLenum, GLboolean normalisée, GLsizei foulée, pointeur const GLvoid *);

Je pense que le problème est que vous insérez le nombre de sommets dans le paramètre "taille". Ce n'est pas ce à quoi cela est destiné. Il contrôle le nombre de composants que l'attribut aura. Lorsque l'attribut vertex est censé être vec "taille" doit être réglé sur , en utilisant des flottants, il devrait être 1 et ainsi de suite.

EDIT: Comme Reto Koradi l'a souligné, utiliser 0 comme "foulée" est bien dans ce cas.

+0

La définition de la foulée à 0 signifie que les valeurs d'attribut sont compactées. Donc, cette partie est bien. –

+0

Je ne savais pas ça, merci! – Kvaleya

+0

Ok, vous pourriez avoir raison avec ça. Je pensais que cela détermine combien d'éléments il y a dans le tampon. Comment puis-je dire à GL combien d'éléments y a-t-il? Est-ce déterminé par le paramètre glBufferData qui lit "bytesForGLType * numVertices" dans ce cas? – guitarflow