[转]OpenGL快速渲染函数glDrawElements使用说明

来源:互联网 发布:linux 关闭wlan0 指令 编辑:程序博客网 时间:2024/06/05 15:15

OpenGL基本的绘图函数例如glVertex、glNormal等在调试模式下运行时,如果模型的顶点数或者三角面数过大(比如超过一万时),则程序运行速度会非常慢,根本就无法进行正常的调试。为此查阅了相关资料,找到glArrayElement、glDrawElements这两个个函数。这两个函数都能通过少数几条语句的调用实现大量数据的绘制,从而节省了函数调用的资源占用。

 
glArrayElement函数用法简单直接,只要把所有的顶点、法向量等数据,按照三角形的顺序准备好,就可以直接渲染,但缺点是不支持顶点索引,所以内存占用比较大。举例来说,如果一个网格有100个顶点,一般大约会有200个三角面,如果使用glArrayElement就需要存储200×3=600个顶点的数据,相比原有的数据多了5倍。如果是已经条带化的数据,这种冗余数据多的可能就不只5倍了。权衡之下还是决定使用glDrawElements函数。
 
glDrawElements函数支持顶点数据列表,更为方便的是它还支持顶点索引,所以就成为了快速渲染的首选。可是我在具体使用过程中,却总是没有任何顶点数据被绘制出来,查了相关资料,既不是数据错误,也不是硬件不支持,只好暂时搁置一边了。一个偶然的机会,我看到某段示例代码,发现glDrawElements中索引数据类型的参数是GL_UNSIGNED_INT,而我之前用的参数都是GL_INT(因为算法的需要,有时需要存储负数索引,以表示正反方向的不同)。抱着试试看的想法,我把参数改成了GL_UNSIGNED_INT,结果竟然绘制出图像来了。赶紧查阅了MSDN,对glDrawElements的说明如下:
void glDrawElements(
  GLenum
mode,
  GLsizei count,
  GLenum type,
  const GLvoid *indices
);

Parameters

mode
The kind of primitives to render. It can assume one of the following symbolic values: GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP, GL_QUADS, and GL_POLYGON.
count
The number of elements to be rendered.
type
The type of the values in indices. Must be one of GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT.
indices
A pointer to the location where the indices are stored.
注意其中对type参数的说明,索引数据的类型必须是GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT、GL_UNSIGNED_INT之一。这一来就解释了为什么glDrawElements没有绘制出任何元素的问题所在了。可气的是OpenGL竟然没有对这个问题给出任何的提示,不知到是不是微软有意如此淡化OpenGL的作用,如果改天有机会可以用linux系统下的编译器作作测试。
 
最后,附上我在渲染时调用的部分代码。
 
//顶点
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, (float*)m_vDataCoord[0]);
 
// 法向量
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, (float*)m_vDataNormal[0]);
 
//顶点颜色
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, 0, (float*)m_vDataColor[0]);
 
//纹理坐标
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, (float*)m_vDataUv[0]);
glDrawElements(GL_TRIANGLES, (GLsizei)m_vIndexCoord.size()*3, GL_UNSIGNED_INT, (GLvoid*)m_vIndexCoord[0]);
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 战地4延迟高怎么办 红米手机打不开怎么办 台式电脑网页打不开怎么办 电脑网页很多都打不开怎么办 qq发送不了位置怎么办 qq无法找到入口怎么办 玩游戏总是掉怎么办 ipad所有按键失灵怎么办 手机启动器停止运行怎么办 安卓版泰拉瑞亚联机失去连接怎么办 吃鸡安装不了怎么办 obb文件丢失了怎么办 dnf登录闪退怎么办 泰拉瑞亚地图找不到备份怎么办 服务器没远程管理卡怎么办 tplink上不了网怎么办 键盘端口坏了怎么办 小米路由dns错误怎么办 电脑内存性能低怎么办 nas硬盘坏了怎么办 360安装环境异常怎么办 连接不上服务器怎么办 路由器被绑定mac怎么办 mac地址绑定失败怎么办 触摸屏忘了密码怎么办? 小区高层水压低怎么办 高层楼房水压不够怎么办 热水器温度太高怎么办 热水器出热水小怎么办 天然气热水器水压不够怎么办 热水器水变小了怎么办 液压齿轮泵没力怎么办 gps总是浮点解怎么办 电源要做到稳压怎么办 变压器输出电压低怎么办 变压器输出电压高怎么办 家里空调带不动怎么办 小天才定位不准怎么办 伐木锯链条不出油怎么办 角磨机切割片卸不下来怎么办 油泵电机声音大怎么办