OpenGL几种绘制方式 |
您所在的位置:网站首页 › 直线工具有几种绘制方式 › OpenGL几种绘制方式 |
OpenGL几种绘制方式
OpenGL 绘制 本文介绍了OpenGL的几种绘制方式及各自特点。绘制方式如下: 立即模式 显示列表 顶点数组 VBO 1、立即模式最直接的方式,传统的使用glBegin...glEnd绘制的方式,如下所示: glBegin( GL_TRIANGLES ); glVertex3f(-1.0f, -0.5f, -4.0f); glVertex3f( 1.0f, -0.5f, -4.0f); glVertex3f( 0.0f, 0.5f, -4.0f); glEnd();这种方式效率较低。原因是 glVertex函数每次调用只把一个顶点从客户端(CPU或内存)传输到服务端(GPU),而这个传输的过程相对于GPU处理数据的过程是很慢的。 glVertex函数的调用次数过多 2、显示列表将图形绘制进行预编译,把绘制好的图形放到GPU,使用的时候直接调用。 初始化函数 displayList = glGenLists( 1 ); //请求显示列表名称 glNewList( displayList, GL_COMPILE ); //创建显示列表 glBegin( GL_TRIANGLES ); glVertex3f(-1.0f, -0.5f, -4.0f); glVertex3f( 1.0f, -0.5f, -4.0f); glVertex3f( 0.0f, 0.5f, -4.0f); glEnd(); glEndList();渲染函数 glCallList( displayList );显示列表的优化策略是将图形绘制命令集(数据块)存储在GPU中,无须CPU到GPU间的数据传递,节省了时间。 然而显示列表虽然提升了绘制速度,但是它一旦创建了就是不可修改的,如果要修改,只能销毁并重新创建显示列表,所以它适用于那些静态的图形。 3、顶点数组将数据保存在数组中,当执行绘制(glDrawArrays或glDrawElements)的时候一次性将数据从CPU传递到GPU中。 //初始化顶点数组 GLfloat vertices[ 3 ][3] = {0}; vertices[0][0] = -1.0f; vertices[0][1] = -0.5f; vertices[0][2] = -4.0f; vertices[1][0] = 1.0f; vertices[1][1] = -0.5f; vertices[1][2] = -4.0f; vertices[2][0] = 0.0f; vertices[2][1] = 0.5f; vertices[2][2] = -4.0f; glEnableClientState( GL_VERTEX_ARRAY ); //启用顶点数组 glVertexPointer( 3, GL_FLOAT, 0, vertices ); //指定数据 glDrawArrays( GL_TRIANGLES, 0, 3); //进行绘图 glDisableClientState( GL_VERTEX_ARRAY );顶点数据的优化策略是减少数据从CPU到GPU的传递次数,从而节省了时间。但是它仍然有数据的传递,所以绘制效率不如显示列表高。相比于显示列表它的优点是数据可以动态修改。 4、VBOVBO将顶点数据存储在GPU缓存中,无须CPU到GPU的数据传递,并且可以动态修改。 初始化函数 //初始化顶点数组 GLfloat vertices[ 3 ][3] = {0}; vertices[0][0] = -1.0f; vertices[0][1] = -0.5f; vertices[0][2] = -4.0f; vertices[1][0] = 1.0f; vertices[1][1] = -0.5f; vertices[1][2] = -4.0f; vertices[2][0] = 0.0f; vertices[2][1] = 0.5f; vertices[2][2] = -4.0f; glewInit(); glGenBuffers( 1, buffer ); //创建缓冲区 //指定缓冲区数据 glBindBuffer( GL_ARRAY_BUFFER, buffer ); glBufferData( GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 3, vertices, GL_DYNAMIC_DRAW );渲染函数 glBindBuffer( GL_ARRAY_BUFFER, buffer ); //绑定缓冲区 glEnableClientState( GL_VERTEX_ARRAY ); //使用VBO必须开启顶点数组 glVertexPointer( 3, GL_FLOAT, 0, 0 ); glDrawArrays( GL_TRIANGLES, 0, 3 ); //绘制 glDisableClientState( GL_VERTEX_ARRAY ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); //取消绑定缓冲区关于VBO的动态修改,可以将数据映射到客户端(内存)中,然后再进行修改。以下是一种刷新所有顶点数据的方法。 //初始化新数组 GLfloat newvertices[3][3] = {0}; newvertices[0][0] = 0.0f; newvertices[0][1] = 0.0f; newvertices[0][2] = 50.0f; ... //映射缓冲区 glBindBuffer( GL_ARRAY_BUFFER, buffer] ); glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * 3* 3, NULL, GL_STREAM_DRAW ); GLvoid* PositionBuffer = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); //刷新数据 memcpy( PositionBuffer, newvertices, sizeof( GLfloat ) * 1002 * 3 ); //刷新到VBO glBindBuffer( GL_ARRAY_BUFFER, buffer ); glUnmapBuffer( GL_ARRAY_BUFFER ); glVertexPointer( 3, GL_FLOAT, 0, 0 );VBO结合了显示列表与顶点数组的优点,既在GPU保存数据避免数据传输,提高了绘制效率,又可以动态修改。 [参考] OpenGL超级宝典(第四版) OpenGL Vertex Buffer Object (VBO) 学一学,VBO—OpenGL技术-ZwqXin |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |