cocos2d-x之OpenGL概述

来源:互联网 发布:qq for linux 编辑:程序博客网 时间:2024/06/05 12:02

概述

cocos2d-x底层实现依赖OpenGL,这是一个图形库,可以操作显卡,因此,在处理比较复杂的游戏,消耗较大的游戏时,处理的效率会很高。而像android自带的canvas工具,就不能提供这种效率,因为它不是直接操作显卡的。当然,android自带的一些画图工具,可以做一些简单的游戏开发,如下棋,贪食蛇,连连看等。

OpenGL1.0是固定管线的,内置functions设置所有渲染状态:灯光,顶点,颜色,摄像机。

OpenGL2.0是针对可编程管线的,需要手动设置着色器(shader)。shader包括vertexShader和textureShader,可以处理顶点和纹理的数值,这样,在显卡将要显示前,就可以对对象的坐标和颜色进行修改,轻易地实现很多特效:如波纹。可以通过shader对灯光、阴影的细节进行处理,而1.0是无法对这些细节进行处理的。


cocos2d-x使用的OpenGL技术,大概就如下面所述,因为是2d图形引擎,所以,比较少用到3D的OpenGL API,因此,本文算是粗略涵盖了cocos2d-x涉及到OpenGL的内容。

cocos2d-x也使用了DirectX库,其实和OpenGL的渲染流程,原理是一样的,只是API的命名方式不同。因此,可以从OpenGL中借鉴设计原理。

使用流程

1.准备view,如android中的MySurfaceView

2.创建OpenGl context

3.创建render buffer

是OpenGL对象,用于存放渲染过的图像。屏幕区域这么大的尺寸作为约束。

4.创建frame buffer

是OpenGL对象,存放帧,它包含了render buffer . depth buffer , stencil buffer 和 accumulation buffer

深度缓冲区depth buffer:3D渲染时候,受到Z轴影响,会有遮挡现象,需要保存深度信息进行深度比较,以保证遮挡关系正确。

渲染流程

注意渲染流程的一个特点:先传入指针,再传入值。所以,我们会看到多次对顶点,或者对某个变量进行操作。我所指的指针,可能是glxxxHandle,glxxxLocation,glxxxPointer。然后把先前准备好的数值:glBufferData,glUniform4fv。这些变量的意思会在下面看到。

编写着色器——shader程序

包括顶点着色器vertex.sh和片元着色器frag.sh。直接由显卡GPU执行,而不是由CPU执行。GPU的图形处理能力高于CPU的,因此openg2.0 比 1.0效率高好多。shader程序可以保存在任意文档格式中,甚至可以保存在字符串里,因为我们只需要获取程序内容,而不管它是什么格式。

顶点着色器中
1.使用了4个变量存放顶点位置,这是因为在进行矩阵运算时候,比x,y,z多一个变量w“方便矩阵运算”。
2.使用了varing对颜色进行声明,该关键字的功能是可以实现“渐变色”,即我们虽然只指定了4个顶点的颜色,但是顶点间的区域是按照顶点间的色差进行渐变的。

片元着色器中
varing lowp vec4 DestinationColor;   //表示低精度运算的向量,把lowp改为highp关键字,则表示高精度运算..一般手机进行低精度运算即可。

这两个着色器,是在运行的时候才编译,而且是通过OpenGL库来编译的。因为OpenGL是跨平台的,进行运行时编译,比较适合,这样可以把编译出来的代码兼容到不同的平台。


OpenGL系统函数

glCreateShader
glShaderSource //获取shader源码
glCompileShader  //编译shader
glGetShaderiv/glGetShaderInfoLog  //检测编译是否成功,得到错误信息
glCreateProgram    //创建program
glAttachShader  //绑定两个shader到program
glLinkProgram   //将两个shader链接成一个完成的program
glGetProgramiv,glGetProgramInfoLog   //检测是否链接成功
glUseProgram    //让OpenGl执行Program
glGetAttribLocation  //获取shader中的传入变量,后期将传递值到shader中计算
glEnableVertexAttribArray  //启用数据,不启用的话,glGetAttribLocation的数据就不会被传入program

顶点数据(准备阶段)
glGenBuffers   //创建顶点缓冲对象
glBindBuffer    //绑定缓冲区,告诉OpenGL这是指GL_ARRAY_BUFFER数组缓冲区
glBufferData  //绑定数据到缓冲区

渲染图形(着色阶段)
glVertexAttribPointer   // 向shader提供输入参数值(上面的只是准备了顶点数据,还没输入到着色器)
glDrawElement   // 绘制图形,每个顶点都会调用vertex shader , 每个“像素”都会调用frag shader

这样就完成渲染了。

投影矩阵

uniform mat4 Projection;      //mat4是4个变量的矩阵变量,uniform关键字会影响所有的顶点的位置变量。
gl_Position = Projection * Position;
glGetUniformLocation ;  //获取vertex shader中的Projection的指针(下面的函数会为这个指针传入值)
glUniformMatrix4fv   //为shader传入变量的值

模型视图矩阵

unifrom mat4 ModelView;
gl_Position = Projection* ModelView*Position;
每个物体都有一个模型视图矩阵,用来控制模型的旋转/平移/缩放。

纹理数据

attribute vec2 TexCoordIn;
varying vec2 TexCoordOut;
TexCoordOut = TexCoordIn;

varying lowp vec2 TexCoordOut;
unifrom sampler2D Texture ;  // 读取一张图片
gl_FragColor =  DesitinationColor *  texture2D(Texture, TexCoordOut);   //调用系统函数texture2D,根据纹理坐标TexCoordOut,显示Texuture图片(二维数组)。//DestinationColor是原来的颜色,乘不乘都可以,只是一个混合运算。

glGenTexutures ;   //创建纹理(指针)
glBindTexture ;    //绑定纹理后,下面的代码都使用该纹理,直至重新调用一次该绑定glBindTexture
glTexParameteri;  //设置纹理过滤(纹理比对象小或者大时候的处理方式,min map 等)
glTexImage2D;  // 设置纹理数据 (读取一个二位数组,即图形的数据)
glActiveTexture;  //激活纹理数据(绘制)

glBindTexture; //再次绑定纹理
glUnifrom1i ;  //向frag shader 传递纹理“数据”
至此,图片就能被成功贴到对象上

OpenGL的文本显示

一般是通过每个平台下的drawString把文字绘制到图片上,然后把这个图片纹理贴到四方形上。android调用的是canvas,windows上是调用GDI绘制,cocos2d调用xx二维API绘制。