cocos2d opengl- Shader

来源:互联网 发布:中国流浪汉数据 编辑:程序博客网 时间:2024/05/21 17:00

第三周总结:

 

 

1. 熟悉cocos2d-x的画图函数

(1)绘制一条线,参1为起点,参2为终点,ccp为生成CCPoint的宏  

     ccDrawLine( ccp(0, 0), ccp(s.width, s.height) );

 

(2)设置点大小,参数就是需要设定的大小值

ccPointSize(10);在OpenGL 中通常是采用glPointSize设定

(3)设置后面要进行绘制时所用的色彩  

ccDrawColor4B(255,0,0,255);在OpenGL中通常采用glColor来进行设定

  

(4) 设定线宽

glLineWidth(5.0f);

   

(5)绘制一个点 ,参数即为点位置 

     ccDrawPoint( ccp(s.width / 2, s.height / 2) );  

 

(6)绘制多个点

CCPoint points[] = { ccp(60,60), ccp(70,70), ccp(60,70), ccp(70,60) };  

ccDrawPoints( points, 4);

(7)绘制圆函数,参1是中心点,参2为半径,参3为圆的逆时针旋转角度,参4为圆的平均切分段数,最后一个参 数是指定是否从圆分段起止点位置向圆中心连线,这里不进行连线  

        ccDrawCircle( ccp(s.width/2,  s.height/2), 100, 0, 10, false);

(8)绘制多边形线框函数,使用上面的顶点数组做为多边形线框的顶点位置,第二个参数为顶点数量,第三个参 数指定是否首尾自动连接形成封闭线框。

CCPoint vertices[] = { ccp(0,0), ccp(50,50), ccp(100,50), ccp(100,100), ccp(50,100) };

ccDrawPoly( vertices, 5, false);

(9)这里绘制内部填充指定色彩的多边形

CCPoint filledVertices[] = { ccp(0,120), ccp(50,120), ccp(50,170), ccp(25,200), ccp(0,170) };    

     ccDrawSolidPoly(filledVertices, 5, ccc4f(0.5f, 0.5f, 1, 1 ) );

 

(10)就是cocos2d-x2.0绘制二次贝塞尔曲线函数,三个参数分别如图中P0,P1,P2,不过在咱们

   这个例子中,正好与之上下镜像。最后一个是曲线构成所用的线段数,当然,线段数越多

曲线越平滑。 

 

ccDrawQuadBezier(ccp(0,height/2), ccp(width/2, height), ccp(width,height/2), 50);

(11)   前四个参数应该对应的是P0,P1,P3,P4,图上的P2可以省去。最后一个是曲线构成所用的线段

数。  

     ccDrawCubicBezier(ccp(s.width/2, s.height/2), ccp(s.width/2+30,s.height/2+50), ccp(s.width/

2+60,s.height/2-50),ccp(s.width, s.height/2),100);  

 

 

 

2. 熟悉opengl shader

固定管线的渲染方式

 

 

 

 

可编程管线的渲染方式

 

 

 

OpenGL shaker的编写流程(右侧的两个文件就是vertex和fragment文件)

 

 

 

3. 使用opengl shader编写一个示例

//vertex.h中的内容

"                                               \n\

attribute vec4 a_position;                       \n\

attribute vec2 a_texCoord;                      \n\

//uniform mat4 CC_MVPMatrix;              \n\

#ifdef GL_ES                                         \n\

varying lowp vec2 v_texCoord;                \n\

#else                                                           \n\

varying vec2 v_texCoord;                        \n\

#endif                                                         \n\

void main()                                               \n\

{                                                                 \n\

    gl_Position = CC_MVPMatrix * a_position;    \n\

    v_texCoord = a_texCoord;                    \n\

}";

 

//fragment.h中的内容

"                                                  \n\

#ifdef GL_ES                                    \n\

precision lowp float;                           \n\

#endif                                          \n\

                                                    \n\

varying vec2 v_texCoord;                        \n\

uniform sampler2D CC_TEXTURE1;                  \n\

void main()                                     \n\

{                                               \n\

    gl_FragColor = texture2D(CC_TEXTURE1, v_texCoord);  \n\

                                                    \n\

    //gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0);  \n\

}";

 

 

//关于上面两个文件的注意点描述,上面两个文件内容加载到程序中均为字符串的形式进行加载,这就是为什么

    在前后要加上双引号,并且在字符串赋值后就相当于是一个赋值语句,这就是为什么在最后要加上分号,当然     程序在读取文件内容的方式一:通过#include“文件”方式把里面的东西赋值给一个字符指针(这种方式在

    window下不行),方式二:通过读取文件的方式进行读取, 方式三:直接把文件中的内容赋值到程序中赋值     给字符指针。

//对于里面的一些书写格式和变量类型可以参考OpenGL Shader相关知识

 

 

//CocoaLigature0 此CocoaLigature1 函数中的两个参数就是vertex文件和fragment文件中的内容

void UserShaderMgr::createProgramAndSave(const char* vShader, const char* fShader)

{

    GLuint VerSID = glCreateShader(GL_VERTEX_SHADER);

    GLuint FragID = glCreateShader(GL_FRAGMENT_SHADER);

    

    glShaderSource(VerSID, 1, &vShader, NULL);

    glShaderSource(FragID, 1, &fShader, NULL);

    

    glCompileShader(VerSID);

    glCompileShader(FragID);

    

    GLuint PID = glCreateProgram();

    glAttachShader(PID, VerSID);

    glAttachShader(PID, FragID);

    

    glLinkProgram(PID);

    

    GLint status = GL_TRUE;

    glGetProgramiv(PID, GL_LINK_STATUS, &status);

    if (status == GL_FALSE)

    {

        CCLOG("cocos2d: ERROR: Failed to link program: %i", PID);

        glDeleteProgram(PID);

        PID = 0;

    }

    

    glDeleteShader(VerSID);

    glDeleteShader(FragID);

    

    glUseProgram(PID);

}

 

在继承自CCNode的类中draw函数中加入以下代码:

glEnable(GL_BLEND);

    glBlendFunc(GL_ONE, GL_ZERO);

    //GLuint programID = UserShaderMgr::sharedMgr()->getProgramByIndex(0);

//programID就是上面glCreateProgram()获得的返回值

    glEnableVertexAttribArray(kCCVertexAttrib_Position);

    glEnableVertexAttribArray(kCCVertexAttrib_TexCoords);

//下面两句就是对Program中vertex文件中的两个变量绑定位置,并且这里有个注意点,就是在绑定过后一定需要对你的程序需要重新Link,否则无效;

    glBindAttribLocation(programID, kCCVertexAttrib_Position, "a_position");

    glBindAttribLocation(programID, kCCVertexAttrib_TexCoords, "a_texCoord");

    glLinkProgram(programID);

    

     

    glUseProgram(programID);

//下面的内容是对Fragment文件中的纹理赋值,这里注意对纹理赋值一定要在glUseProgram下面,否则无效

    glEnable(GL_TEXTURE_2D);

    glActiveTexture(GL_TEXTURE0);

    glBindTexture(GL_TEXTURE_2D, m_texture2D->getName());

    int uIT = glGetUniformLocation(programID, "CC_TEXTURE1");

    glUniform1f(uIT, 0);

    

    //下面的内容是获取cocos2dx环境下的当前的矩阵,得到该矩阵后把值赋给vertex文件中CC_MVPMatrix量,以便点的位置能够正确显示;

    int uPV = glGetUniformLocation(programID, "CC_MVPMatrix");

    kmMat4 matrixP;

kmMat4 matrixMV;

kmMat4 matrixMVP;

kmGLGetMatrix(KM_GL_PROJECTION, &matrixP);

kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV);

kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV);

    glUniformMatrix4fv(uPV, 1, GL_FALSE, matrixMVP.mat);

 

//如果是在其他的框架环境下,上述的大部分是不需要改变的,需要改变的地方只是变换矩阵获取方式,比如在 xcode中的GLKView中可以通过下面方式进行获取:

int MVPMatrix = glGetUniformLocation(m_uProgramID, "CC_MVPMatrix");

    glUniformMatrix4fv(MVPMatrix, 1, GL_FALSE, 

GLKMatrix4Multiply(self.baseEffect.transform.projectionMatrix, 

baseEffect.transform.modelviewMatrix).m);

 

 

4. 熟悉cocos2d-x shader机制

  (1)cocos2d-x shader机制就是基于OpenGl的,在cocos2d-x shader中对于OpenGL shader进行了封装, 在程序起来的时候,把几个预定义好的shader通过CCShaderCache加载完成,需要使用时只需要简单的调用就 行了。

 

5. 使用cocos2d-x shader实现4中示例

  (1)m_glProgram = CCShaderCache::sharedShaderCache()-

>programForKey(kCCShader_PositionTexture);

    setShaderProgram(m_glProgram);

//通过Key找到预定义好的Shader

//在draw函数中调用下述代码

getShaderProgram()->use();

    ccGLBindTexture2D(m_texture2D->getName());

//上述的m_texture2D就是需要加载的纹理对象

    m_glProgram->setUniformsForBuiltins();

 

6. 输出OpenGL 坐标与cocos2d-x坐标映射关系

  (1)OpenGL和coco2d-x的坐标系都是基于右手坐标系的,原点是在屏幕的左下角;

     (2)在OpenGL中的坐标系可以分为 世界坐标系, 局部坐标系, 视点坐标系等,在opengl中需要描述的对象经过 一系列的矩阵相乘,转换成对应位置点,最终经过投影,显示在屏幕上;

     (3)投影方式有三种,正投影, 平行投影,透视投影,可以查看相关资料进行详细了解。

 

 

7. 实践cocos2d-x中OpenGL 上下文设置,搞清楚设置作用

EAGLContex* context_ = [[EAGLContext alloc] 

initWithAPI:kEAGLRenderingAPIOpenGLES2];

上面创建之后,还要设置成当前的contex

[EAGLContext setCurrentContext: context_];

0 0
原创粉丝点击