Cocos2D-X shader(三) Shader and Program编程基本概念

前端之家收集整理的这篇文章主要介绍了Cocos2D-X shader(三) Shader and Program编程基本概念前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

@H_404_2@一、本文关注的问题:

• Shader and program 对象介绍
•创建并编译一个Shader对象
• 创建并链接一个Program对象
获取并设置uniforms
获取并设置attributes

在OpenGL ES中,每个program对象有且仅有一个Vertex Shader对象和一个Fragment Shader对象连接到它。

Shader:类似于C编译器

Program:类似于C链接

glLinkProgram操作产生最后的可执行程序,它包含最后可以在硬件上执行的硬件指令。

@H_404_2@二、Shader和Program编程概述

@H_404_2@1. 创建Shader
1)编写Vertex Shader和Fragment Shader源码。

2)创建两个shader 实例:GLuint glCreateShader(GLenum type);

3)给Shader实例指定源码。 glShaderSource

4)在线编译shaer源码 void glCompileShader(GLuint shader)

@H_404_2@2. 创建Program

1)创建program GLuint glCreateProgram(void)

2)绑定shader到program 。 void glAttachShader(GLuint program,GLuint shader)。每个program必须绑定一个Vertex Shader 和一个Fragment Shader。

3)链接program 。 void glLinkProgram(GLuint program)

4)使用porgram 。 void glUseProgram(GLuint program)

对于使用独立shader编译器编译的二进制shader代码,可使用glShaderBinary来加载到一个shader实例中。

@H_404_2@三、Shading Language中的数据类型与变量
1. Uniforms and Attributes

Uniforms 是一个program 中统一分配的,vertext 和fragment中同名的Uniform必须同类型。对应于不经常变化的变量(用于存储只读常量值的变量)。

Attributes 变化率高的变量。主要用来定义输入的每个点属性

Uniforms and Attributes 在shader中通过location 和 name 来对应的。

@H_404_2@2. 数据类型

1)@H_404_2@三类基本数据类型:float,int,boolean

2)@H_404_2@复合类型:浮点、整型、布尔向量 vec2,vec3,vec4。vector访问方式有以下两种:

(1).操作:数学{x,y,z,w},颜色{r,g,b,a}或 纹理坐标{s,t,r,q},但不能混用,举例如下:

vec3 myVec3 = vec3(0.0,1.0,2.0); // myVec3 = {0.0,2.0}
vec3 temp;
temp = myVec3.xyz; // temp = {0.0,2.0}
temp = myVec3.xxx; // temp = {0.0,0.0,0.0}
temp = myVec3.zyx; // temp = {2.0,0.0}

(2)[ ]操作:[0]对应x,[1]对应y,[2]对应z,[3]对应w。[ ]中只能为常量或uniform变量,不能为整数量变量(如:i,j,k)。

3)@H_404_2@矩阵:mat2,mat3,mat4 (按顺序存储)

mat3 myMat3 = mat3(1.0,// 第一列
0.0,// 第二列
0.5,1.0); // 第三列

可用[ ]或.操作符来访问:

mat4 myMat4 = mat4(1.0);// Initialize diagonal to 1.0 (identity)
vec4 col0 = myMat4[0];// Get col0 vector out of the matrix
float m1_1 = myMat4[1][1];// Get element at [1][1] in matrix
float m2_2 = myMat4[2].z; // Get element at [2][2] in matrix

4)@H_404_2@常量

const float zero = 0.0;
const float pi = 3.14159;
const vec4 red = vec4(1.0,1.0);
const mat4 identity = mat4(1.0);

5)@H_404_2@结构体: 用基本类型和复合类型构建结构体。

struct fogStruct
{
vec4 color;
float start;
float end;
} fogVar;
fogVar = fogStruct(vec4(0.0,0.0),// color
0.5,// start
2.0); // end
vec4 color = fogVar.color;
float start = fogVar.start;
float end = fogVar.end;

6)@H_404_2@数组:类似于C语言,索引从0开始。在创建时不能被初始化,索引只能为常量或uniform变量。

float floatArray[4];
vec4 vecArray[2];

7)@H_404_2@操作

支持的操作有:*,/,+,-,++,--,=,+=,-=,*=,/=,==,!=,<,>,<=,>=,&&,^^,||

@H_404_2@[cpp] view plain copy
  1. floatmyFloat;
  2. vec4myVec4;
  3. mat4myMat4;
  4. myVec4=myVec4*myFloat;//MultiplieseachcomponentofmyVec4
  5. //byascalarmyFloat
  6. myVec4=myVec4*myVec4;//together(e.g.,myVec4^2)
  7. myVec4=myMat4*myVec4;//Doesamatrix*vectormultiplyof
  8. //myMat4*myVec4
  9. myMat4=myMat4*myMat4;//Doesamatrix*matrixmultiplyof
  10. //myMat4*myMat4
  11. myMat4=myMat4*myFloat;//Multiplieseachmatrixcomponentby
  12. //thescalarmyFloat

@H_404_2@前面矩阵的行数就是结果矩阵的行数,后面矩阵的列数就是结果矩阵的列数。

8)@H_404_2@自定义函数

copy
    vec4myFunc(inoutfloatmyFloat,//inoutparameter
  1. outvec4myVec4,//outparameter
  2. mat4myMat4);//inparameter(default)

函数不能递归调用,因为GPU不一定有Stack和流控。

9)@H_404_2@Shading Language内嵌函数

主要有以下几类函数

(1)角度和三角函数

(2)指数函数

(3)通用函数(绝对值、取整、取余、取小数部分等)

(4)几何函数

(5)矩阵函数

(6)向量比较函数

(7)纹理查找函数

(8)Derivative函数

10)@H_404_2@控制流

copy
    if(color.a<0.25)
  1. {
  2. color*=color.a;
  3. }
  4. else
  5. @H_301_458@ color=vec4(0.0); @H_301_458@
  6. //For循环。只支持常数循环次数
  7. //无论下标,还是循环变量,都只能使用编译时可确定的常数。
  8. for(inti=0;i<3;i++)
  9. {
  10. sum+=i;
  11. }

以下不允许(因为下标为变量或loop次数为变量):

copy
    floatmyArr[4];
  1. sum+=myArr[i];//NOTALLOWEDINOPENGLES,CANNOTDO
  2. //INDEXINGWITHNONCONSTANTEXPRESSION
  3. @H_301_458@ ...
  4. uniformintloopIter;
  5. inti=0;i<loopIter;i++)

  6. @H_404_2@11)Uniforms(前辍修改
    Uniform前辍修饰的变量初始值由外部程序赋值。在program中具有统一访问空间,存储空间有限。在Shader中是只读的,只能由外部主机程序传入值。

    它用于存储shader需要的各种数据,如:变换矩阵、光照参数和颜色。基本上,对于Shader是一个常量,但在编译时其值未知,则应当作为一个uniform变量。

    Uniform变量在Vertex Shader和Fragment Shader之间共享。当使用glUniform***设置了一个uniform变量的值之后,Vertex Shader和Fragment Shader中具有相同的值。

    Uniform变量被存储在GPU中的“常量存储区”,其空间大小是固定的,可通过API<glGetIntegerv>查询(GL_MAX_VERTEX_UNIFORM_VECTORS或 GL_MAX_FRAGMENT_UNIFORM_VECTORS)。

    @H_404_2@12)Attributes(前辍修改

    Attribute类型的变量只有Vertex Shader才有。Attribute前辍修饰的变量定义的是每个Vertex的属性变量,包括位置,颜色,法线和纹理坐标

    Attribute类型的变量在Vertex Shader中是只读的,只能由外部主机程序传入值。

    Attribute类型的变量:是为每个被正在画的顶点所指定的数据。在画图前,每个顶点的属性由应用程序输入。

    与Uniform变量一样,其存储数量也是有限制的。可用glGetIntegerv(GL_MAX_VERTEX_ATTRIBS)进行查询。GPU至少支持8个属性,所以Vertex Shader源码中不要超过8个attributes。

    @H_404_2@13)Varyings

    Varying变量用于存储Vertex Shader的输出和Fragment Shader的输入。在Vertex Shader和Fragment Shader中必须申明同一个Varying变量。

    与Uniform和Attribute一样,其存储数量也是有限制的,可用glGetIntegerv(GL_MAX_VARYING_VECTORS)进行查询。GPU至少支持8个Varying vector,所以Vertex Shader源码中不要超过8个Varying vector。

    GLint maxVertexAttribs; // n will be >= 8
    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS,&maxVertexAttribs);

    @H_404_2@

    @H_404_2@14)预处理

    @H_404_2@

    copy
    #define
  1. #undef
  2. #if
  3. #ifdef
  4. #ifndef
  5. #else
  6. #elif
  7. #endif
  8. __LINE__//Replacedwiththecurrentlinenumberinashader
  9. __FILE__//Always0inOpenGLES2.0
  10. __VERSION__//TheOpenGLESshadinglanguageversion(e.g.,100)
  11. GL_ES//ThiswillbedefinedforESshaderstoavalueof1


@H_404_2@15) Uniform Attribute Varying存储空间最小值

@H_404_2@变量类型

@H_404_2@GPU必须支持的最小个数

Vertex Uniform Vectors

128

Fragment Uniform Vectors

16

Vertex Attributes

8

Varying Vectors

8


@H_404_2@16) 精度限定(Precision Qualifiers)

关键词:lowp highp mediump

(1)指定变量精度(放在数据类型之前):

copy
    highpvec4position;
  1. varyinglowpvec4color;
  2. mediumpfloatspecularExp;

(2)指定默认精度(放在Vertex和Fragment shader源码的开始处):

copy
    precisionhighpfloat;
  1. precisionmediumpint;

在Vertex Shader中,如果没有默认的精度,则float和int精度都为highp;在Fragment Shader中,float没有默认的精度,所以必须在Fragment Shader中为float指定一个默认精度或为每个float变量指定精度

@H_404_2@17)结果一致性

invariant可被应用于任何Vertex ShaderVarying输出变量,其目前是保证相同的操作和相同的输入,其结果一样。因为由于Shader精度不一样,其结果有可能不一样。

copy
    uniformmat4u_viewProjMatrix;
  1. attributevec4a_vertex;
  2. invariantgl_Position;
  3. voidmain
  4. //…
  5. gl_Position=u_viewProjMatrix*a_vertex;//Willbethesame
  6. //valueinall
  7. //shaderswiththe
  8. //sameviewProjMatrix
  9. //andvertex
  10. }

也可指定所有的输出变量都为:invariant

copy
    #pragmaSTDGLinvariant(all)

@H_404_2@四、获取和设置Uniforms

通过GLint glGetUniformLocation(GLuint program,const char* name).根据一个Uniform的名称获取其location.

通过 glUniform***系列函数可以给一个location 设置一个Uniform的值。

copy
    voidglUniform1f(GLintlocation,GLfloatx)
  1. voidglUniform1fv(GLintlocation,GLsizeicount,constGLfloat*v)
  2. voidglUniform1i(GLintlocation,GLintx)
  3. voidglUniform1iv(GLintlocation,153); background-color:inherit; font-weight:bold">constGLint*v)
  4. voidglUniform2f(GLintlocation,GLfloatx,GLfloaty)
  5. voidglUniform2fv(GLintlocation,153); background-color:inherit; font-weight:bold">voidglUniform2i(GLintlocation,GLintx,GLinty)
  6. voidglUniform2iv(GLintlocation,153); background-color:inherit; font-weight:bold">voidglUniform3f(GLintlocation,GLfloaty,GLfloatz)
  7. voidglUniform3fv(GLintlocation,153); background-color:inherit; font-weight:bold">voidglUniform3i(GLintlocation,GLinty,GLintz)
  8. voidglUniform3iv(GLintlocation,153); background-color:inherit; font-weight:bold">voidglUniform4f(GLintlocation,GLfloatz,GLfloatw);
  9. voidglUniform4fv(GLintlocation,153); background-color:inherit; font-weight:bold">voidglUniform4i(GLintlocation,GLintz,GLintw)
  10. voidglUniform4iv(GLintlocation,153); background-color:inherit; font-weight:bold">voidglUniformMatrix2fv(GLintlocation,
  11. GLbooleantranspose,constGLfloat*value)
  12. voidglUniformMatrix3fv(GLintlocation,153); background-color:inherit; font-weight:bold">voidglUniformMatrix4fv(GLintlocation,153); background-color:inherit; font-weight:bold">constGLfloat*value)

为矩阵uniform变量设置值的函数中的transpose必须为GL_FALSE,它目的为兼容性,但在 OpenGL ES 2.0中并没有工作。

一旦你设置了一个Program中unifrom变量的值之后,即使你激活了另外一个Program,此uniform的值不变。即uniform变量是Program的局部变量。

@H_404_2@五、VertexAttributes

@H_404_2@ Vertex属性即顶点数据,它指定了每个顶点的数据。在OpenGL ES1.1中,顶点属性有四个预定义的名字:position(位置),normal(法线),color(颜色),和 texture coordinates(纹理坐标)。在OpenGL ES2.0中,用户必须定义“顶点属性的名字”

@H_404_2@1. 常量顶点属性(Constant Vertex Attribute)

常量顶点属性对所有顶点都是一样的。因此只需要指定一个值就可以应用于所有顶点。一般很少使用。其设置函数有:

copy
    voidglVertexAttrib1f(GLuintindex,GLfloatx);
  1. voidglVertexAttrib2f(GLuintindex,GLfloaty);
  2. voidglVertexAttrib3f(GLuintindex,GLfloatz);
  3. voidglVertexAttrib4f(GLuintindex,GLfloatw);
  4. voidglVertexAttrib1fv(GLuintindex,153); background-color:inherit; font-weight:bold">constGLfloat*values);
  5. voidglVertexAttrib2fv(GLuintindex,153); background-color:inherit; font-weight:bold">constGLfloat*values);
  6. voidglVertexAttrib3fv(GLuintindex,153); background-color:inherit; font-weight:bold">voidglVertexAttrib4fv(GLuintindex,153); background-color:inherit; font-weight:bold">constGLfloat*values);

@H_404_2@2.如何装载顶点数据?(Vertex Arrays)

Vertex Array(顶点数组):是一个存储在应用程序空间(Client)中的内存buffer,它存储了每个顶点的属性数据。

如何把顶点数据组的数据传递给GPU呢?

void glVertexAttribPointer(GLuint index,

GLint size,//每个属性元素个数有效值1-4(x,w)
GLenum type,//数组中每个元素的数据类型
GLboolean normalized,
GLsizei stride,//如果数据连续存放,则为0或

//size*sizeof(type)
const void *ptr) //顶点数组指针

举例如下:

copy

    GLfloatvVertices[]={0.0f,0.5f,0.0f,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> -0.5f,-0.5f,
  1. 0.5f,0.0f};
  2. //Settheviewport
  3. glViewport(0,esContext->width,esContext->height);
  4. //Clearthecolorbuffer
  5. glClear(GL_COLOR_BUFFER_BIT);
  6. //Usetheprogramobject
  7. glUseProgram(programObject);
  8. //Loadthevertexdata
  9. glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,vVertices);


@H_404_2@2.1一个顶点的所有属性存储在一起(Array of Structures)

如下图所示,顶点的位置(x,z)、法线(x,z)和两个纹理坐标(s,t)存储在一起,如下图所示:

例子代码如下(当然,此代码cpu上运动):

@H_404_2@[cpp] view plain copy
    #defineVERTEX_POS_SIZE3//x,yandz
  1. #defineVERTEX_NORMAL_SIZE3//x,yandz
  2. #defineVERTEX_TEXCOORD0_SIZE2//sandt
  3. #defineVERTEX_TEXCOORD1_SIZE2//sandt
  4. #defineVERTEX_POS_INDX0
  5. #defineVERTEX_NORMAL_INDX1
  6. #defineVERTEX_TEXCOORD0_INDX2
  7. #defineVERTEX_TEXCOORD1_INDX3
  8. //thefollowing4definesareusedtodeterminelocationofvarIoUs
  9. //attributesifvertexdataisarestoredasanarrayofstructures
  10. #defineVERTEX_POS_OFFSET0
  11. #defineVERTEX_NORMAL_OFFSET3
  12. #defineVERTEX_TEXCOORD0_OFFSET6
  13. #defineVERTEX_TEXCOORD1_OFFSET8
  14. #defineVERTEX_ATTRIB_SIZEVERTEX_POS_SIZE+\
  15. VERTEX_NORMAL_SIZE+\
  16. VERTEX_TEXCOORD0_SIZE+\
  17. VERTEX_TEXCOORD1_SIZE
  18. float*p=malloc(numVertices*VERTEX_ATTRIB_SIZE
  19. *sizeof(float));
  20. //positionisvertexattribute0
  21. glVertexAttribPointer(VERTEX_POS_INDX,VERTEX_POS_SIZE,
  22. GL_FLOAT,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> VERTEX_ATTRIB_SIZE*float),248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> p+VERTEX_POS_OFFSET);
  23. //normalisvertexattribute1
  24. glVertexAttribPointer(VERTEX_NORMAL_INDX,VERTEX_NORMAL_SIZE,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> (p+VERTEX_NORMAL_OFFSET));
  25. //texturecoordinate0isvertexattribute2
  26. glVertexAttribPointer(VERTEX_TEXCOORD0_INDX,VERTEX_TEXCOORD0_SIZE,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> (p+VERTEX_TEXCOORD0_OFFSET));
  27. //texturecoordinate1isvertexattribute3
  28. glVertexAttribPointer(VERTEX_TEXCOORD1_INDX,VERTEX_TEXCOORD1_SIZE,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> (p+VERTEX_TEXCOORD1_OFFSET));

@H_404_2@2.2 顶点的每个属性单独存储(Structure of Arrays)

@H_404_2@

例子代码如下(当然,此代码cpu上运动):

#define VERTEX_POS_SIZE         3 // x,y and z
#define VERTEX_NORMAL_SIZE      3 // x,y and z
#define VERTEX_TEXCOORD0_SIZE   2 // s and t
#define VERTEX_TEXCOORD1_SIZE   2 // s and t

#define VERTEX_POS_INDX         0
#define VERTEX_NORMAL_INDX      1
#define VERTEX_TEXCOORD0_INDX   2
#define VERTEX_TEXCOORD1_INDX   3


#define VERTEX_ATTRIB_SIZE  VERTEX_POS_SIZE + \
                            VERTEX_NORMAL_SIZE + \
                            VERTEX_TEXCOORD0_SIZE + \
                            VERTEX_TEXCOORD1_SIZE
                            
float *position  = malloc(numVertices * VERTEX_POS_SIZE *
                          sizeof(float));
float *normal    = malloc(numVertices * VERTEX_NORMAL_SIZE *
                          sizeof(float));
float *texcoord0 = malloc(numVertices * VERTEX_TEXCOORD0_SIZE *
                          sizeof(float));
float *texcoord1 = malloc(numVertices * VERTEX_TEXCOORD1_SIZE *
                          sizeof(float));

// position is vertex attribute 0
glVertexAttribPointer(VERTEX_POS_INDX,VERTEX_POS_SIZE * sizeof(float),position);

// normal is vertex attribute 1
glVertexAttribPointer(VERTEX_NORMAL_INDX,VERTEX_NORMAL_SIZE * sizeof(float),normal);

// texture coordinate 0 is vertex attribute 2
glVertexAttribPointer(VERTEX_TEXCOORD0_INDX,VERTEX_TEXCOORD0_SIZE *
                      sizeof(float),texcoord0);

// texture coordinate 1 is vertex attribute 3
glVertexAttribPointer(VERTEX_TEXCOORD1_INDX,VERTEX_TEXCOORD1_SIZE * sizeof(float),//也可为0,因为数据是紧接着存放的
                      texcoord1);

@H_404_2@2.3. 哪种顶点属性数据存储方式在GPU上性能更好?

@H_404_2@ 答案是:把一个顶点的所有属性放在一起(array of structures)。其原因是每个顶点的属性数据以连续的方式读取,使内存访问效率更高。其缺点是,如果要修改其中部分属性数据,将导致整个属性buffer全部重新装载,解决此问题的方法是把这些需要动态修改属性数据放在单独的buffer中。

五、 顶点属性数据类型优化

顶点属性数据类型不会影响在GPU上每个顶点占用的内存,但在Render a Frame时,它影响cpu与GPU之间的内存带宽。推荐尽量使用GL_HALF_FLOAT_OES。

六、glVertexAttribPointer中的归一化参数

如果normalized为GL_FALSE:则直接把数据转换为GLfloat,因为Vertex Shader内部把顶点属性当作GLfloat(32位)来进行存储。

GL_BYTE,GL_SHORT or GL_FIXED被归一化为[-1,1];GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT被归一化为[0.0,1.0]。具体转换公式为:

3、选择常量或顶点数组Vertex Attribute

可通过以下函数来Enable或Disable顶点数组(Vertex Array)。

void glEnableVertexAttribArray(GLuint index);
void glDisableVertexAttribArray(GLuint index);

其关系如下图所示:

@H_404_2@4、申明attribute变量(在Vertex Shader中)

Attribute变量的数据类型只能为:float,vec2,vec4,mat2,and mat4;Attribute变量不能为数组或结构。如下面的申明是错误的:

    attributefoo_ta_A;//foo_tisastructure
  1. attributevec4a_B[10];

每个GPU支持GL_MAX_VERTEX_ATTRIBS vec4。float、vec2和vec3也被当作一个vec4来进行存储;mat2、mat3、mat4被分别当作2、3、和4个vec4来进行存储。

@H_404_2@5、把“顶点属性索引”绑定到“顶点属性名”

把“顶点属性索引”绑定到“顶点属性名”有以下两个方法

1)@H_404_2@OpenGL ES 2.0把“顶点属性索引”绑定到“顶点属性名”,当link program时,OpengGL ES 2.0执行此绑定。然后应用程序通过glGetAttribLocation(失败时返回-1)获取“顶点属性索引”。

@H_404_2@[html]
    GLintglGetAttribLocation(GLuintprogram,constGLchar*name)

2)@H_404_2@应用程序通过glBindAttribLocation把“顶点属性索引”绑定到“顶点属性名”,glBindAttribLocation在program被link之前执行。

    voidglBindAttribLocation(GLuintprogram,GLuintindex,153); background-color:inherit; font-weight:bold">constGLchar*name)

在link program时,OpenGL ES 2.0对每个顶点属性执行如下操作:

(1)首先检查属性变量是否被通过glBindAttribLocation绑定了属性索引,如果是,则使用此绑定的属性索引;否则,为之分配一个属性索引

在应用程序中,一般使用函数glBindAttribLocation来绑定每个attribute变量的位置,然后用函数glVertexAttribPointer为每个attribute变量赋值。

6、顶点buffer对象(Vertex Buffer Objects)

顶点数组(Vertex Array)被保存在客户端内存,当执行glDrawArrays或 glDrawElements时,才把它们从客户端内存copy到图形内存。这样占用了大量的内存带宽,Vertex Buffer Objects允许OpengGL ES2.0应用在高性能的图形内存中分配并cache顶点数据,然后从此图形内存中执行render,这样避免了每次画一个原语都要重发送数据。

Vertex Buffer Objects有以下两种类型:

(1)array buffer objects:通过GL_ARRAY_BUFFER标记创建,并存储vertex data。

(2)element array buffer objects:通过GL_ELEMENT_ARRAY_BUFFER标记创建,并存储indices of a primitive。

创建和绑定Vertex Buffer Objects例子代码如下:

    voidinitVertexBufferObjects(vertex_t*vertexBuffer,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> GLushort*indices,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> GLuintnumVertices,GLuintnumIndices
  1. GLuint*vboIds)
  2. glGenBuffers(2,vboIds);
  3. glBindBuffer(GL_ARRAY_BUFFER,vboIds[0]);
  4. glBufferData(GL_ARRAY_BUFFER,numVertices*sizeof(vertex_t),108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> vertexBuffer,GL_STATIC_DRAW);//savevertexattributedata
  5. //bindbufferobjectforelementindices
  6. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vboIds[1]);
  7. glBufferData(GL_ELEMENT_ARRAY_BUFFER,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> numIndices*sizeof(GLushort),indices,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> GL_STATIC_DRAW);//saveelementindicesthatmakeuptheprimitive
  8. @H_404_2@有无Vertex Buffer Object画图例子:

      #defineVERTEX_POS_SIZE3//x,yandz
    1. #defineVERTEX_NORMAL_SIZE3//x,yandz
    2. #defineVERTEX_TEXCOORD0_SIZE2//sandt
    3. #defineVERTEX_POS_INDX0
    4. #defineVERTEX_NORMAL_INDX1
    5. #defineVERTEX_TEXCOORD0_INDX2
    6. //
    7. //vertices–pointertoabufferthatcontainsvertexattribute
    8. data
    9. //vtxStride–strideofattributedata/vertexinbytes
    10. //numIndices–numberofindicesthatmakeupprimitive
    11. //drawnastriangles
    12. //indices-pointertoelementindexbuffer.
    13. //
    14. voiddrawPrimitiveWithoutVBOs(GLfloat*vertices,GLintvtxStride,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> GLintnumIndices,GLushort*indices)
    15. GLfloat*vtxBuf=vertices;
    16. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
    17. glEnableVertexAttribArray(VERTEX_POS_INDX);
    18. glEnableVertexAttribArray(VERTEX_NORMAL_INDX);
    19. glEnableVertexAttribArray{VERTEX_TEXCOORD0_INDX);
    20. glVertexAttribPointer(VERTEX_POS_INDX,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> GL_FLOAT,vtxStride,vtxBuf);
    21. vtxBuf+=VERTEX_POS_SIZE;
    22. vtxBuf+=VERTEX_NORMAL_SIZE;
    23. glVertexAttribPointer(VERTEX_TEXCOORD0_INDX,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> VERTEX_TEXCOORD0_SIZE,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> GL_FALSE,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> glBindAttribLocation(program,VERTEX_POS_INDX,"v_position");
    24. glBindAttribLocation(program,VERTEX_NORMAL_INDX,"v_normal");
    25. glDrawElements(GL_TRIANGLES,numIndices,GL_UNSIGNED_SHORT,indices);

      1. voiddrawPrimitiveWithVBOs(GLintnumVertices,GLfloat*vtxBuf,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> GLintvtxStride,GLintnumIndices,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> GLushort*indices) @H_301_458@ GLuintoffset=0;
      2. GLuintvboIds[2];
      3. //vboIds[0]–usedtostorevertexattributedata
      4. //vboIds[1]–usedtostoreelementindices
      5. glGenBuffers(2,vboIds);
      6. glBindBuffer(GL_ARRAY_BUFFER,vboIds[0]);
      7. glBufferData(GL_ARRAY_BUFFER,vtxStride*numVertices,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> vtxBuf,GL_STATIC_DRAW);
      8. sizeof(GLushort)*numIndices,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> indices,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> (constvoid*)offset);
      9. offset+=VERTEX_POS_SIZE*sizeof(GLfloat);
      10. glVertexAttribPointer(VERTEX_NORMAL_INDX,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> offset+=VERTEX_NORMAL_SIZE*sizeof(GLfloat);
      11. @H_301_458@ (constvoid*)offset);
      12. glDrawElements(GL_TRIANGLES,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> glDeleteBuffers(2,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> }
      原文链接:https://www.f2er.com/cocos2dx/340588.html

      猜你在找的Cocos2d-x相关文章