随笔 - 367, 文章 - 2, 评论 - 75, 阅读 - 114万

导航

< 2025年1月 >
29 30 31 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 1
2 3 4 5 6 7 8

OPENGL顶点数组

Posted on   网名还没想好  阅读(2066)  评论(0编辑  收藏  举报

         当我们人为的绘制形状时,首先想到是是坐标点,而不是api,如要绘制一条直线,首先将两个点的坐标存在一起,则更加容易理解,OpenGL的顶点数组就是这样的作用.

首先来回顾下之前画直线的函数

示例1

void drawOneLine(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)
{
   glBegin(GL_LINES);
   glVertex2f ((x1),(y1)); 
   glVertex2f ((x2),(y2));
   glEnd();
}

需要调用两次glVertex2f ,并且输入两个顶点,现在我们来看另一种做法

将坐标存在一个数组中

示例2

void drawLineWithArray()
{
    GLint vertices[]={25,25,
                      100,100};
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2,GL_INT,0,vertices);
    glBegin(GL_LINES);
    glArrayElement(0);
    glArrayElement(1);
    glEnd();

}

vertices记录了两个坐标(x1,y1)=(25,25),(x2,y2)=(100,100)
但是其索引值却是0,1,2,3.为了识别一个坐标点,需要一个函数将数组进行切分.
glVertexPointer则用于这个功能,可以称这种数组为混合数组,参数指定了顶点数组的配对点(如坐标定位为2个,颜色则为3个),数据类型及数组
注意:在使用顶点数组时,必须先调用glEnableClientState开启顶点数组功能,在不用的时候调用glDisableClientState来禁用

glArrayElement则根据顶点数组来调用相应的函数,每次只调用1个顶点

示例2和示例1的效果是相同,初看好像并没有变简单,反而变复杂了.

启用多个顶点数组

除了指定顶点的坐标数组外,还可以启动颜色,表面法线等其他顶点数组

下面以不同颜色画两条直线
示例3

void drawTwoLineWithArray()
{
    GLint vertices[]={25,25,
                      100,100,
                      120,120,
                      200,200};
    GLfloat colors[]={1.0, 0.0, 0.0,
                      1.0, 0.0, 0.0,
                      0.0, 1.0, 0.0,
                      0.0, 1.0, 0.0};
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(2,GL_INT,0,vertices);
    glColorPointer(3,GL_FLOAT,0,colors);
    glBegin(GL_LINES);
    glArrayElement(0);
    glArrayElement(1);
    glArrayElement(2);
    glArrayElement(3);
    glEnd();
}

注意:每开启一种顶点数组都必须调用glEnableClientState来激活

效果如下

image

跨距

如上示例3,有一个坐标数组和颜色数组,如果将两个数组合并在一起,那么坐标和颜色的数据就在一个数组了,现在代码修改如下

示例4

GLfloat data[]=  {1.0, 0.0, 0.0,25.0,25.0,
                  1.0, 0.0, 0.0,100.0,100.0,
                  0.0, 1.0, 0.0,120.0,120.0,
                  0.0, 1.0, 0.0,200.0,200.0};

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3,GL_FLOAT,5*sizeof(GLfloat),&data[0]);
glVertexPointer(2,GL_FLOAT,5*sizeof(GLfloat),&data[3]);

第3个参数指定跨距,如颜色,从数组的每组数据的第1个开始取数据,然后跨5个,坐标顶点则从数据每组数据的第4个开始取数据并跨5个
注意:由于跨距需要计算数据类型,所以数组的数据类型需要相同

以上代码效果是相同的

解引用顶点数组列表

1.其提供了一个glDrawElements函数用于循环调用glArrayElement,但需要定义一个索引的数组

示例5

void drawTwoLineWithArray2()
{
    GLfloat data[]=  {1.0, 0.0, 0.0,25.0,25.0,
                      1.0, 0.0, 0.0,100.0,100.0,
                      0.0, 1.0, 0.0,120.0,120.0,
                      0.0, 1.0, 0.0,200.0,200.0};
    GLubyte index[]= {0,1,2,3} ;
    

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glColorPointer(3,GL_FLOAT,5*sizeof(GLfloat),&data[0]);
    glVertexPointer(2,GL_FLOAT,5*sizeof(GLfloat),&data[3]);
    
    glDrawElements(GL_LINES,4,GL_UNSIGNED_BYTE,index);
    
}

2.从索引项开始

glDrawArrays(GL_LINES,0,4);

这个函数更加简单,直接从第0个开始访问4个元素

在顶点比较多的情况下,顶点数组应该是很有用的一个功能

混合数组

以下是最简化的操作

glInterleavedArrays函数将会根据参数,激活各种顶点数组,并存储顶点,如下

void drawTwoLineWithArray3()
{
    GLfloat data[]=  {1.0, 0.0, 0.0,25.0,25.0,0.0,
                      1.0, 0.0, 0.0,100.0,100.0,0.0,
                      0.0, 1.0, 0.0,120.0,120.0,0.0,
                      0.0, 1.0, 0.0,200.0,200.0,0.0};
    
    
    glInterleavedArrays(GL_C3F_V3F,0,data);
    glDrawArrays(GL_LINES,0,4);
    
}

效果是相同的
现在去掉颜色的数组的话,代码如下

GLfloat data[]=  {25.0,25.0,
                  100.0,100.0,
                  120.0,120.0,
                  200.0,200.0};
glInterleavedArrays(GL_V2F,0,data);
glDrawArrays(GL_LINES,0,4);

上述代码可看性就比较高了

转自:http://www.cnblogs.com/Clingingboy/archive/2010/10/16/1853304.html

编辑推荐:
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· 程序员常用高效实用工具推荐,办公效率提升利器!
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
点击右上角即可分享
微信分享提示