What is the modern OpenGL equivalent to glBegin/glEnd
我正在为OpenGL构建图形API,该API基于基本的调用绘图图形样式。 基本上,不是将数据存储到GPU中,而是使用它的句柄调用它,而是提供信息以绘制应该在每次更新时绘制的内容。 我知道它很慢,但它很简单,适用于对性能要求不高的应用程序。 无论如何,是否有与glBegin / glEnd等效的现代方法? 它不必为每个顶点调用,而是一种可以在不将顶点存储在gpu中的情况下每次发送数据的方式吗?
您几乎回答了自己的问题。
is there any modern equivalent to glBegin/glEnd? It doesn't have to a call for every vertex, but a way where I can send the data each update, without storing the vertices in the gpu?
基本上没有,现代的方法是将VAO与VBO(和IBO)一起使用。
如果要更改VBO中的数据,请记住,可以更改glBufferData中的
-
GL_STREAM_DRAW-数据存储的内容将被修改一次,最多使用几次。
-
GL_STATIC_DRAW-数据存储内容将被修改一次并使用多次。
-
GL_DYNAMIC_DRAW-数据存储内容将被重复修改并使用多次。
然后,与使用
您可以在OpenGL Wiki上了解有关不同缓冲区的更多信息。
查找您要实现的VAO / VBO用法。
在C / C ++代码中,波纹管是一个简单的示例。
输入变量模式为
这也是GLSL和核心配置文件传递属性的唯一选项(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | //------------------------------------------------------------------------------ //--- 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[]= { // x y z 0.75f, 0.75f, 0.0f, 0.75f,-0.75f, 0.0f, -0.75f,-0.75f, 0.0f, }; const float vao_col[]= { // r g b 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); glEnableVertexAttribArray(0); glVertexAttribPointer(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); glEnableVertexAttribArray(1); glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(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]); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glDrawArrays(mode,0,3); glBindVertexArray(0); } //------------------------------------------------------------------------------ #endif //------------------------------------------------------------------------------ //--- end. --------------------------------------------------------------------- //------------------------------------------------------------------------------ |
如果您不想使用GLSL,则必须将代码稍微更改为如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | //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。我建议不要在我使用的所有卡上使用通常比索引慢得多的索引,但是当然会占用更多内存。同样,在驱动程序上实现索引不是很好,有时会出现错误(即使在nVidia上,当然也可以在ATI上,如果满足正确的情况)
如果还需要着色器,请参阅我的:
- 完整的GL + GLSL + VAO / VBO C ++示例