openGl API说明

来源:互联网 发布:沈阳电明数据恢复 编辑:程序博客网 时间:2024/06/07 00:36


glVertexPointer .

 

指定数组顶点用glVertexPointer,指定完了就可以用glDrawArray()来把指定的数组中的顶点绘制出来了

About glVertexPointer(int size,int type,int stride,Buffer pointer)

parameters:

size:

  每个顶点有几个数指描述。必须是2,3  ,4 之一,初始值是4.也就是维数,指定3 即:有x,y,z 三维

type:
 数组中每个顶点的坐标类型。取值:GL_BYTE, GL_SHORT , GL_FIXED , GL_FLOAT,   初始值 GL_FLOAT

stride:

数组中每个顶点间的间隔,步长(字节位移)。取值若为0,表示数组是连续的   初始值为0

pointer

It's your array ,存储着每个顶点的坐标值。初始值为0

 

Attention: type 中高速opgl你的数组类型。分别对应byte[],short[],int[],float[],一般用GL_FIXED

描述的时候,大家的点坐标单位是0X10000,

比如一个点事(60,120),用GL_FIXED的时候,需要设置为(60*0X10000,120*10000),所以经常看到

int one = 0X10000的编程语句。

再来看glDrawArrays(int mode,int first ,int count)

参数:mode 指定你要绘制何种图元, opengl 中的图元就这几个: GL_POINTS, GL_LINE_STRIP,

GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES.

 first 在已制定的数组中的开始位置(索引位置)

count 点的绘制次数, 比如我们绘制一个三角形,就是绘制三个顶点,即此参数为 3。

快速渲染函数glDrawElements使用说明 .


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]);

 

 // 启用阴影平滑,glShadeModel 用于启用阴影平滑度。阴影平滑通过多边形精细地混合色彩,并对外

部光进行平滑。

        gl.glShadeModel(GL10.GL_SMOOTH);
       
        // 黑色背景,glClearColor 设置清除屏幕时所用的颜色,色彩值的范围从 0.0f~1.0f 大小从

暗到这的过程。

        gl.glClearColor(0, 0, 0, 0);
       
        // 设置深度缓存
        gl.glClearDepthf(1.0f);
                          
        // 启用深度测试
        gl.glEnable(GL10.GL_DEPTH_TEST);
                      
        // 所作深度测试的类型, 为将深度缓存设想为屏幕后面的层,它不断地对物体进入屏幕内部的

深度进行跟踪。

        gl.glDepthFunc(GL10.GL_LEQUAL);                           
       
        // 告诉系统对透视进行修正,这会轻微地影响性能,但会使得透视图更好看
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

//设置OpenGL场景的大小
gl.glViewport(0, 0, width, height);

//设置投影矩阵,指明接下来的代码将影响 projection matrix (投影矩阵),投影矩阵负责为场景增

加透视度。

        gl.glMatrixMode(GL10.GL_PROJECTION);
        //重置投影矩阵
gl.glLoadIdentity(); 此方法相当于我们手机的重置功能,它将所选择的矩阵状态恢复成原始状态,调

用  glLoadIdentity(); 之后为场景设置透视图。

        gl.glLoadIdentity();

        // 设置视口的大小,此方法,前面4个参数用于确定窗口的大小,而后面两个参数分别是在场景

中所能绘制深度的起点和终点。

        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

        // 选择模型观察矩阵,指明任何新的变换将会影响 modelview matrix (模型观察矩阵)。
        gl.glMatrixMode(GL10.GL_MODELVIEW);   
        // 重置模型观察矩阵
        gl.glLoadIdentity();   

 

// 清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 重置当前的模型观察矩阵
gl.glLoadIdentity();
 
// 左移 1.5 单位,并移入屏幕 6.0
        gl.glTranslatef(-1.5f, 0.0f, -6.0f);
         //设置旋转
        gl.glRotatef(rotateTri, 0.0f, 1.0f, 0.0f);

//设置定点数组
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        //设置颜色数组
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
 
      
        gl.glColorPointer(4, GL10.GL_FIXED, 0, colorBuffer);
        // 设置三角形顶点
 // 设置三角形顶点
        gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer);


        //绘制三角形
        gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
        //取消顶点数组

        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);

OpenGL中,典型的方式是为坐标定义一个浮点类型的顶点数组。为了最高效,你应把这些坐标都写进一个

ByteBuffer,它会被传到OpenGLES图形管线以进行处理。

 static float triangleCoords[] = { // 按逆时针方向顺序:
         0.0f,  0.622008459f, 0.0f,   // top
        -0.5f, -0.311004243f, 0.0f,   // bottom left
         0.5f, -0.311004243f, 0.0f    // bottom right
    };
private FloatBuffer vertexBuffer;

ByteBuffer bb = ByteBuffer.allocateDirect(
                // (坐标数 * 4)float占四字节
                triangleCoords.length * 4);
        // 设用设备的本点字节序
        bb.order(ByteOrder.nativeOrder());

        // 从ByteBuffer创建一个浮点缓冲
        vertexBuffer = bb.asFloatBuffer();
        // 把坐标们加入FloatBuffer中
        vertexBuffer.put(triangleCoords);
vertexBuffer.position(0);


缺省情况下,OpenGLES 假定[0,0,0](X,Y,Z) 是GLSurfaceView 帧的中心,[1,1,0]是右上角,[-1,-1,0]

是左下角。

注意此形状的坐标是按逆时针方向定义的。绘制顺序很重要

 

 


 

0 0
原创粉丝点击