Je construis une API graphique pour OpenGL, qui est basée sur le style graphique de base appelant à dessiner. Fondamentalement, au lieu de stocker les données dans le GPU et de les appeler à l’aide de son handle, donnez-leur l’information pour dessiner ce qu’elle devrait dessiner chaque mise à jour. Je sais que c’est lent, mais c’est simple et c’est pour les applications critiques non performantes. Quoi qu’il en soit, existe-t-il un équivalent moderne de glBegin / glEnd? Il ne faut pas un appel pour chaque sumt, mais un moyen d’envoyer les données à chaque mise à jour, sans stocker les sumts dans le gpu?
Vous avez à peu près répondu à votre propre question.
Existe-t-il un équivalent moderne de glBegin / glEnd? Il ne faut pas un appel pour chaque sumt, mais un moyen d’envoyer les données à chaque mise à jour, sans stocker les sumts dans le gpu?
Fondamentalement non, la méthode moderne consiste à utiliser des VAO avec des VBO (et des IBO).
Si vous envisagez de modifier les données dans le VBO, rappelez-vous que vous pouvez modifier le paramètre mode
dans glBufferData .
GL_STREAM_DRAW – Le contenu du magasin de données sera modifié une fois et utilisé au plus quelques fois.
GL_STATIC_DRAW – Le contenu du magasin de données sera modifié une fois et utilisé plusieurs fois.
GL_DYNAMIC_DRAW – Le contenu du magasin de données sera modifié à plusieurs resockets et utilisé plusieurs fois.
Ensuite, au lieu d’utiliser GL_STATIC_DRAW
, puis d’utiliser GL_DYNAMIC_DRAW
, le FPS augmentera beaucoup par rapport à l’utilisation de GL_STATIC_DRAW
, bien que cela dépende de la quantité de données et de la fréquence à laquelle vous les modifiez. Mais essayez de le limiter autant que vous le pouvez, par exemple, ne mettez pas à jour les données dans les mémoires tampons si vous n’en avez pas réellement besoin.
Vous pouvez en savoir plus sur les différents tampons sur le Wiki d’OpenGL, cliquez ici .
Recherchez l’utilisation de VAO / VBO correspondant à ce que vous souhaitez implémenter.
En C / C ++, le code ci-dessous est un exemple simple.
Le mode variable d’entrée est GL_POINYS / TRIANGLES / QUADS / …. (comme dans glBegin ())
C’est aussi la seule option avec GLSL et le profil principal de passer des atsortingbuts (glVertex / glNormal / … est inconnue dans le kernel depuis quelque temps déjà)
//------------------------------------------------------------------------------ //--- Open GL VAO example (GLSL) ----------------------------------------------- //------------------------------------------------------------------------------ #ifndef _OpenGL_VAO_example_h #define _OpenGL_VAO_example_h //------------------------------------------------------------------------------ GLuint vbo[4]={-1,-1,-1,-1}; GLuint vao[4]={-1,-1,-1,-1}; const float vao_pos[]= { // xyz 0.75f, 0.75f, 0.0f, 0.75f,-0.75f, 0.0f, -0.75f,-0.75f, 0.0f, }; const float vao_col[]= { // rgb 1.0f,0.0f,0.0f, 0.0f,1.0f,0.0f, 0.0f,0.0f,1.0f, }; //--------------------------------------------------------------------------- void vao_init() { glGenVertexArrays(4,vao); glGenBuffers(4,vbo); glBindVertexArray(vao[0]); glBindBuffer(GL_ARRAY_BUFFER,vbo[0]); glBufferData(GL_ARRAY_BUFFER,sizeof(vao_pos),vao_pos,GL_STATIC_DRAW); glEnableVertexAtsortingbArray(0); glVertexAtsortingbPointer(0,3,GL_FLOAT,GL_FALSE,0,0); glBindBuffer(GL_ARRAY_BUFFER,vbo[1]); glBufferData(GL_ARRAY_BUFFER,sizeof(vao_col),vao_col,GL_STATIC_DRAW); glEnableVertexAtsortingbArray(1); glVertexAtsortingbPointer(1,3,GL_FLOAT,GL_FALSE,0,0); glDisableVertexAtsortingbArray(0); glDisableVertexAtsortingbArray(1); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER,0); } //--------------------------------------------------------------------------- void vao_exit() { glDeleteVertexArrays(4,vao); glDeleteBuffers(4,vbo); } //--------------------------------------------------------------------------- void vao_draw(GLuint mode) { void *p=NULL; glBindVertexArray(vao[0]); glEnableVertexAtsortingbArray(0); glEnableVertexAtsortingbArray(1); glDrawArrays(mode,0,3); glBindVertexArray(0); } //------------------------------------------------------------------------------ #endif //------------------------------------------------------------------------------ //--- end. --------------------------------------------------------------------- //------------------------------------------------------------------------------
Si vous ne voulez pas utiliser GLSL, vous devez changer le code en quelque chose comme ceci:
//tetraeder #define V_SIZ 12 #define I_SIZ 6 GLfloat tet_verts[V_SIZ] = { \ -0.5f, -1.0f, -0.86f, \ -0.5f, -1.0f, 0.86f, \ 1.0f, -1.0f, 0.0f, \ 0.0f, 1.0f, 0.0f}; GLushort tet_index = {3, 0, 1, 2, 3, 0}; void init_buffers() { glGenBuffersARB(1, &vertex_buf); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buf); glBufferDataARB(GL_ARRAY_BUFFER_ARB, V_SIZ*sizeof(GLfloat), tet_verts, GL_STATIC_DRAW_ARB); //upload data glGenBuffersARB(1, &index_buf); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, index_buf); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, I_SIZ*sizeof(GLushort), tet_index, GL_STATIC_DRAW_ARB); //upload data return; } void draw_buffers() { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buf); glVertexPointer(3, GL_FLOAT, 0, 0); //3 is xyz, last 0 ("pointer") is offset in vertex-array glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, index_buf); glEnableClientState(GL_VERTEX_ARRAY); //use indexing glDrawElements(GL_TRIANGLE_STRIP, I_SIZ, GL_UNSIGNED_SHORT, 0); //last 0 is offset in element-array return; } void deinit_buffers() { glDeleteBuffersARB(1, &vertex_buf); glDeleteBuffersARB(1, &index_buf); return; }
PS Je recommande de ne pas utiliser l’indexation qui est généralement beaucoup plus lente sur toutes les cartes que j’utilise mais bien sûr, cela prend plus de mémoire. De plus, l’indexation n’est pas très bonne et implémenté sur les pilotes parfois devient bogué (même sur nVidia et bien sûr sur ATI aussi si les circonstances sont réunies)