OPENGL顶点数组, glDrawArrays,glDrawElements

2024-09-08 08:38

本文主要是介绍OPENGL顶点数组, glDrawArrays,glDrawElements,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

顶点数组, glDrawArrays,glDrawElements 
前两天接触OpenGL ES的时候发现里面没有了熟悉的glBegin(), glEnd(),glVertex3f()函数,取而代之的是glDrawArrays()。有问题问google,终于找到答案:因为OpenGL ES是针对嵌入式设备这些对性能要求比较高的平台,因此把很多影响性能的函数都去掉了,上述的几个函数都被移除了。接下来看看这些函数是如何使用的。

1.glEnableClientState(GL_VERTEX_ARRAY); 使能顶点数组功能。

2.将准备好的数组告知程序,使用glVertexPointer(),原型如下:

void glVertexPointer(

GLint size, //每个顶点占用的数组元素数量

GLenum type, //数组元素的数据类型

GLsizei stride, //元素之间的间隔,一般系统为0

const GLvoid *pointer //指向数组的指针

);

3.进行绘图:glDrawArrays()或者 glDrawElements(),glDrawElements()主要用于索引数组。函数原型如下:

void glDrawArrays(

GLenum mode, //绘图方式 GL_POINTS、GL_QUADS etc

GLint first, //第一个元素的下标

GLsizei count //绘制元素的数量

);

void glDrawElements(
GLenum mode, //绘图方式 GL_POINTS、GL_QUADS etc

GLsizei count, //顶点数组当中元素的个数

GLenum type, //索引数组当中元素数据类型

const GLvoid *indices //指向索引数组的指针

);

对应于顶点数组,OpenGL当中还提供了法向量数组、纹理坐标数组等等的支持,这些数组与顶点数组的使用方式相同,只是在相关参数和函数名称上将Vertex改为对应的名字即可。

glEnableClientState(GL_COLOR_ARRAY);

glColorPointer();



glDrawArrays 和 glDrawElements 的作用都是从一个数据数组中提取数据渲染基本图元。( render primitives from array data )
注!如果要 glDrawArrays 和 glDrawElements 正确进行绘制的话,必须在之前 调用带有相应参数的 glEnableClientState 方法。 比如:


glEnableClientState( GL_VERTEX_ARRAY );

glEnableClientState( GL_TEXTURE_COORD_ARRAY );


 
这两个方法的第一个形参都是代表 绘制模式(GLenum mode)。绘图模式有如下几种:
GL_POINTS
GL_LINES
GL_LINE_LOOP
GL_LINE_STRIP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN
我们还没有讨论点或线,所以我只介绍最后的三个 。
在我开始之前,我要提醒你,顶点数组可能包含不止一个三角形,以便当您只看到一个物体顶点数组,你要知道,不仅限于这一点。
假设我们有如下的顶点数据:

const GLfloat squareVertices[] = {
    -1.0,  1.0, -6.0, 
// Top left
    -1.0, -1.0, -6.0, 
// Bottom left
    1.0,  -1.0, -6.0, 
// Bottom right
    1.0,   1.0, -6. 
// Top right
};

GL_POINTS - 单独的将顶点画出来。
GL_LINES - 单独地将直线画出来。行为和 GL_TRIANGLES 类似。

GL_LINE_STRIP - 连贯地将直线画出来。行为和 GL_TRIANGLE_STRIP 类似。
GL_LINE_LOOP - 连贯地将直线画出来。行为和 GL_LINE_STRIP 类似,但是会自动将最后一个顶点和第一个顶点通过直线连接起来。
GL_TRIANGLES - 这个参数意味着OpenGL使用三个顶点来组成图形。所以,在开始的三个顶点,将用顶点1,顶点2,顶点3来组成一个三角形。完成后,在用下一组的三个顶点(顶点4,5,6)来组成三角形,直到数组结束。

 
GL_TRIANGLE_STRIP - OpenGL的使用将最开始的两个顶点出发,然后遍历每个顶点,这些顶点将使用前2个顶点一起组成一个三角形。
所以 squareVertices[6~8]{1.0, -1.0, 6.0} 将与 squareVerticies[0~2]{-1.0, 1.0, -6.0} 和 squareVerticies[3~5]{-1.0, -1.0, -6.0} 生成一个三角形。
squareVertices[9~11]{1.0, 1,0, -6.0} 将与  squareVertices[3~5]{-1.0, -1.0, -6.0} 和squareVertices[6~8]{1.0, -1.0, 6.0} 生成三角形。
也就是说,P0,P1,P2这三个点组成一个三角形,P1,P2,P3这三个点也组成一个三角形。
注意的是, squareVerticies[0~2]表示的意思是:
squareVerticies[0] x坐标
squareVerticies[1] y坐标
squareVerticies[2] z坐标
GL_TRIANGLE_FAN - 在跳过开始的2个顶点,然后遍历每个顶点,让OpenGL将这些顶点于它们前一个,以及数组的第一个顶点一起组成一个三角形。 squareVertices[6~8]{1.0, -1.0, 6.0} 将与 squareVerticies[3~5]{-1.0, -1.0, -6.0} (前一个)和 squareVerticies[0~2]{-1.0, 1.0, -6.0}(第一个).生成一个三角形。
也就是说,同样是P0,P1,P2,P3 这4个顶点。
1) 在 GL_TRIANGLE_STRIP 状态下是: P2、P1、P0 ; P3、P2、P1 这2个三角形。
2) 在 GL_TRIANGLE_FAN   状态下是: P2、P1、P0 ; P3、P2、P0 这2个三角形。
1.1 glDrawArrays 方法介绍
Description

glDrawArrays specifies multiple geometric primitives with very few subroutine calls. You can prespecify separate arrays of vertices, normals, colors, and texture coordinates and use them to construct a sequence of primitives with a single call to glDrawArrays.
When glDrawArrays is called, it uses count sequential elements from each enabled array to construct a sequence of geometric primitives, beginning with element first. mode specifies what kind of primitives are constructed, and how the array elements construct those primitives. If GL_VERTEX_ARRAY is not enabled, no geometric primitives are generated.
Vertex attributes that are modified by glDrawArrays have an unspecified value after glDrawArrays returns. For example, if GL_COLOR_ARRAY is enabled, the value of the current color is undefined after glDrawArrays executes. Attributes that aren't modified remain well defined.


示例代码:

glEnableClientState(GL_VERTEX_ARRAY);
    
const GLfixed vers[] = {
        F2X(0.25), F2X(0.25), F2X(0.0), 
        F2X(0.75), F2X(0.25), F2X(0.0), 
        F2X(0.25), F2X(0.75), F2X(0.0), 
        F2X(0.75), F2X(0.75), F2X(0.0), 
}
;

glVertexPointer(3, GL_FIXED, 0, vers);
    
glDrawArrays(GL_LINE_STRIP, 0, 4);
    
eglSwapBuffers(iGlDisp, iGlSurface);



结果:
【OpenGL】glDrawArrays, <wbr>glDrawElements
1.2 glDrawElements 是一个OPENGL的图元绘制函数,从数组中获得数据并渲染图元。
函数原型为:
void glDrawElements( 
        GLenum mode, 
        GLsizei count,
        GLenum type, 
        const GLvoid *indices
        );
其中:
    mode 指定绘制图元的类型,但是如果GL_VERTEX_ARRAY 没有被激活的话,不能生成任何图元。它应该是下列值之一:
        GL_POINTS, GL_LINE_STRIP, 
        GL_LINE_LOOP, GL_LINES, 
        GL_TRIANGLE_STRIP, 
        GL_TRIANGLE_FAN, 
        GL_TRIANGLES, 
        GL_QUAD_STRIP, 
        GL_QUADS, 
        GL_POLYGON

         
    count 为绘制图元的数量。
    type 为索引数组(indices)中元素的类型,只能是下列值之一: 
        GL_UNSIGNED_BYTE, 
        GL_UNSIGNED_SHORT, 
        GL_UNSIGNED_INT

        
    indices:指向索引数组的指针。

glDrawElements函数能够通过较少的函数调用绘制多个几何图元,而不是通过OPENGL函数调用来传递每一个顶点,法线,颜色信息。
你可以事先准备一系列分离的顶点、法线、颜色数组,并且调用一次glDrawElements把这些数组定义成一个图元序列。
当调用glDrawElements函数的时候,它将通过索引使用count个成序列的元素来创建一系列的几何图元。
glDrawElements修改的顶点属性在glDrawElements调用返回后的值具有不确定性。

例如,在 GL_COLOR_ARRAY 被激活后,当glDrawElements执行完成时,当前的颜色值是没有指定的。没有被修改的属性值保持不变。
可以在显示列表中包含 glDrawElements,当glDrawElements被包含进显示列表时,相应的顶点、法线、颜色数组数据也得进入显示列表的,因为那些数组指针是ClientSideState的变量,在显示列表创建的时候而不是在显示列表执行的时候,这些数组指针的值影响显示列表。
glDrawElements 只能用在 OPENGL1.1 或者更高的版本。

示例代码如下:

// The vertex array is enabled for writing and used during rendering.
glEnableClientState(GL_VERTEX_ARRAY); 

// 顶点坐标数组
const GLfixed vers[] = {
        F2X(0.25), F2X(0.25), F2X(0.0), 
// 第1个顶点坐标
        F2X(0.75), F2X(0.25), F2X(0.0), 
// 第2个顶点坐标
        F2X(0.25), F2X(0.75), F2X(0.0), 
// 第3个顶点坐标
        F2X(0.75), F2X(0.75), F2X(0.0)  
// 第4个顶点坐标
};


glVertexPointer(
        3,        
// 表示每一个顶点由3维坐标构成
        GL_FIXED, 
// 顶点坐标数组中的元素是 GL_FIXED 类型
        0,        
// 从顶点坐标数组的第0个元素开始读取数据
        vers      
// 指向顶点坐标数组的指针
        );

// 等效替换 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) ++


const GLubyte indices[] = {0, 1, 2, 3};

glDrawElements(
        GL_TRIANGLE_STRIP, 
// 绘图模式
        4,                 
// 依次从索引数组中读取4个顶点来进行绘制
        GL_UNSIGNED_BYTE,  
// 索引数组中存放的元素的类型
        indices            
// 指向索引数组的指针
        );

// 等效替换 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) --


eglSwapBuffers(iGlDisp, iGlSurface);

#SinaEditor_Temp_FontName







这篇关于OPENGL顶点数组, glDrawArrays,glDrawElements的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1147640

相关文章

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

POJ3041 最小顶点覆盖

N*N的矩阵,有些格子有物体,每次消除一行或一列,最少要几次消灭完。 行i - >列j 连边,表示(i,j)处有物体,即 边表示 物体。 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;impo

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

计算数组的斜率,偏移,R2

模拟Excel中的R2的计算。         public bool fnCheckRear_R2(List<double[]> lRear, int iMinRear, int iMaxRear, ref double dR2)         {             bool bResult = true;             int n = 0;             dou

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };

PHP7扩展开发之数组处理

前言 这次,我们将演示如何在PHP扩展中如何对数组进行处理。要实现的PHP代码如下: <?phpfunction array_concat ($arr, $prefix) {foreach($arr as $key => $val) {if (isset($prefix[$key]) && is_string($val) && is_string($prefix[$key])) {$arr[

Go 数组赋值问题

package mainimport "fmt"type Student struct {Name stringAge int}func main() {data := make(map[string]*Student)list := []Student{{Name:"a",Age:1},{Name:"b",Age:2},{Name:"c",Age:3},}// 错误 都指向了最后一个v// a

码蹄集部分题目(2024OJ赛9.4-9.8;线段树+树状数组)

1🐋🐋配对最小值(王者;树状数组) 时间限制:1秒 占用内存:64M 🐟题目思路 MT3065 配对最小值_哔哩哔哩_bilibili 🐟代码 #include<bits/stdc++.h> using namespace std;const int N=1e5+7;int a[N],b[N],c[N],n,q;struct QUERY{int l,r,id;}que