Comment faire de l'instanciation de la bonne façon en OpenGL.
Je suis en train d'utiliser les VBO et l'Instanciation mécanisme le plus efficace. J'ai un monde basé sur les voxels et je tiens à les dessiner en utilisant le moins possible nombre de tirage-des appels. Le code ci-dessous prépare VBO avec un quad:
void VoxelView::initVBOs() {
/*--------------------- Main OpenGL Program ---------------------*/
/* Vertices of a triangle (counter-clockwise winding) */
float data[6][3] = {
//Left bottom triangle
{ -0.5f, 0.5f, 0.0f },
{ -0.5f, -0.5f, 0.0f },
{ 0.5f, -0.5f, 0.0f },
//Right top triangle
{ 0.5f, -0.5f, 0.0f },
{ 0.5f, 0.5f, 0.0f },
{ -0.5f, 0.5f, 0.0f }
};
/*---------------------- Initialise VBO - (Note: do only once, at start of program) ---------------------*/
/* Create a new VBO and use the variable "triangleVBO" to store the VBO id */
glGenBuffers(1, &triangleVBO);
/* Make the new VBO active */
glBindBuffer(GL_ARRAY_BUFFER, triangleVBO);
/* Upload vertex data to the video device */
glBufferData(GL_ARRAY_BUFFER, 6 * 3 * sizeof(float), data, GL_STATIC_DRAW);
/* Specify that our coordinate data is going into attribute index 0(shaderAttribute), and contains three floats per vertex */
glVertexAttribPointer(shaderAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);
/* Enable attribute index 0(shaderAttribute) as being used */
glEnableVertexAttribArray(shaderAttribute);
/* Make the new VBO active. */
glBindBuffer(GL_ARRAY_BUFFER, triangleVBO);
/*-------------------------------------------------------------------------------------------------------*/
/*--------------------- Load Vertex and Fragment shaders from files and compile them --------------------*/
/* Read our shaders into the appropriate buffers */
vertexSource = filetobuf("Shaders/exampleVertexShader1.vert");
fragmentSource = filetobuf("Shaders/exampleFragmentShader1.frag");
/* Assign our handles a "name" to new shader objects */
vertexShader = glCreateShader(GL_VERTEX_SHADER);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
/* Associate the source code buffers with each handle */
glShaderSource(vertexShader, 1, (const GLchar**)&vertexSource, 0);
glShaderSource(fragmentShader, 1, (const GLchar**)&fragmentSource, 0);
/* Free the temporary allocated memory */
free(vertexSource);
free(fragmentSource);
/* Compile our shader objects */
glCompileShader(vertexShader);
glCompileShader(fragmentShader);
/*-------------------------------------------------------------------------------------------------------*/
/*-------------------- Create shader program, attach shaders to it and then link it ---------------------*/
/* Assign our program handle a "name" */
shaderProgram = glCreateProgram();
/* Attach our shaders to our program */
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
/* Bind attribute index 0 (shaderAttribute) to in_Position*/
/* "in_Position" will represent "data" array's contents in the vertex shader */
glBindAttribLocation(shaderProgram, shaderAttribute, "in_Position");
/* Link shader program*/
glLinkProgram(shaderProgram);
Je me suis rendu du quad, de la manière suivante:
void VoxelView::renderVBO()
{
/* Set shader program as being actively used */
glUseProgram(shaderProgram);
/* Set background colour to BLACK */
glClearColor(0.0, 0.0, 0.0, 1.0);
/* Clear background with BLACK colour */
glClear(GL_COLOR_BUFFER_BIT);
/* Actually draw the triangle, giving the number of vertices provided by invoke glDrawArrays
while telling that our data is a triangle and we want to draw 0-3 vertexes
*/
glDrawArrays(GL_TRIANGLES, 0, 6);
}
Je voudrais attirer ce quad (qui utilise le VBO) plusieurs fois à l'aide de l'instanciation mechanizm. Je voudrais qu'elle fe assez simple que je veux le mettre en œuvre des outils plus sophistiqués code. Je sais que je devrais utiliser glDrawElementsInstanced de la méthode à utiliser l'instanciation mais je ne sais pas comment le faire. Quelqu'un sait comment faire?
OriginalL'auteur Paweł Jastrzębski | 2014-02-03
Vous devez vous connecter pour publier un commentaire.
Lors de l'utilisation de glDrawElementsInstanced vous avez besoin pour faire de votre shaders utilisation gl_InstanceiD
glDrawElementsInstanced
utilisation gl_InstanceID variable comme si elle était une statique entier sommet de l'attribut. Lors de la première copie des sommets est envoyé à OpenGL,gl_InstanceID
sera de zéro. Il sera alors augmenté une fois pour chaque copie de la géométrie et finira par atteindre instanceCount - 1.Il se comporte comme cela
Sauf que ce qui se passe en interne, et vous avez seulement besoin d'appeler
glDrawArraysInstanced()
une fois. Afin d'utiliser différents transforme pour chaque instance, vous pouvez passer un tableau de l'uniforme des matrices et l'index de l'aide degl_InstanceID
ou vous pouvez utiliser la texture de la mémoire tampon des objets et de les stocker transforme.De sorte que votre code doit devenir comme cela, mais notez que vous devez toujours passer uniforme des matrices pour chaque intsance dans un tableau ou de passer un tampon texture de l'objet, une fois pour toutes.
et votre vertex shader doit devenir
la seule méthode de dessin moderne openGL est à l'aide des Organisations sises à vienne. glDrawArrays réellement besoin d'un VBO à lier, et vous avez besoin de le répéter à plusieurs reprises afin d'en tirer les mêmes géométrie à plusieurs reprises. Vous pouvez
glDrawElementsInstanced
ouglDrawArraysInstanced
comme elles ne sont qu'une alternaitve méthode pour dessiner des Organisations sises à vienne. Comme je l'ai dit dans la réponse au lieu d'utiliser glDrawElement/Tableaux en boucle vous utilisez glDrawArraysInstanced ou glDrawElementsInstanced une seule fois. J'espère que c'est clairoui
C'est vraiment de la mauvaise habitude d'utiliser des fonctionnalités obsolètes, comme
gl_Vertex
dans les réponses... on peut définir les débutants sur le mauvais chemin dans leur objectif d'apprentissage moderne OpenGL. Aussi, vous devez les utiliser plus tard, les caractéristiques commeARB_instanced_arrays
(OpenGL 3.3) -- les uniformes, par le biais degl_InstanceID
est à la fois plus lent que d'utiliser les vertex attributs / des Organisations sises à vienne et est également limitée parMAX_VERTEX_UNIFORM_COMPONENTS
, la taille maximale d'uniformes par shader programme (généralement 512-1024 flotteurs, ce qui est tout à fait insuffisant quand vous considérez que l'instanciation compte peut facilement atteindre des dizaines de milliers).merci pour le commentaire. Je pense que vous avez raison, je vais mettre à jour ma réponse.
OriginalL'auteur concept3d