Shader preparation for Cocos2dx engine 11-OpenGLES Rendering

Source: Internet
Author: User

Shader preparation for Cocos2dx engine 11-OpenGLES Rendering

The underlying Graphics of Cocos2dx are drawn using OpenGL ES protocol. What is OpenGL ES?

OpenGL ES (OpenGl for Embedded System) is a subset of OpenGL 3D graphics APIs. It is designed for Embedded devices such as mobile phones, PDAs, and game hosts. this API is defined and promoted by Khronos group. Khronos is a graphic software and hardware industry association, which focuses on open standards in graphics and multimedia.

OpenGL ES is tailored or customized from OpenGL, except for complex elements such as glBegin/glEnd, quadrilateral (GL_QUADS), and polygon. after years of development, there are now two major versions: OpenGLES1.x for fixed pipeline hardware and OpenGL ES2.x for programmable pipeline hardware. openGL ES1.0 is based on OpenGL1.3 specifications, and OpenGL ES1.1 is based on OpenGL1.5. They support both common and commonlite profiles. openGL ES2.0 is defined according to OpenGL2.0 specifications.

Starting from Cocos2dx 2.x, the underlying graphics rendering of Cocos2dx uses the OpenGL ES2.x new programmable coloring tool (Shader). The following describes how to use the Shader.

Xxxxx... // Shader Program

1. Create a shader object

GlCreateShader

2. Associate the colorant object with the colorant code.

GlShaderSource

3. Compile the source code of the shader into the target code.

GlCompileShader

4. verify whether the colorant has passed the mutation.

GlGetShaderiv glGetShaderInfoLog

5. Create a coloring Program

GlCreatePragram

6. link the colorant to the colorant program.

GlAttachShader

7. Link coloring Program

GlLinkProgram

8. verify whether the coloring er program is linked successfully.

GlGetProgramiv glGetProgramInfoLog

9. Use the coloring tool to process fixed points or fragments.

GlUseProgram

The GLProgramCache class plays an important role in the Cocos2dx engine, initializing and saving the Shader program, and providing the Shader program for the elements to be rendered;

ClassCC_DLL GLProgramCache: public Ref {public:/*** @ constructor */GLProgramCache ();/*** @ destructor */~ GLProgramCache ();/** Singleton Method */static GLProgramCache * getInstance ();/** clear Singleton */static void destroyInstance (); /** load the Shader Program */void loaddefaglglprograms (); CC_DEPRECATED_ATTRIBUTE void loaddefashadshaders () {loaddefaglglprograms ();}/** reload the Shader Program */void Merge (); CC_DEPRECATED_ATTRIBUTE void reloaddefashadshaders () {reloaddefaglprograms ();}/** use the Key to get the Shader Program */GLProgram * getGLProgram (const std: string & key ); CC_DEPRECATED_ATTRIBUTE GLProgram * getProgram (conststd: string & key) {return getGLProgram (key);} CC_DEPRECATED_ATTRIBUTE GLProgram * programForKey (conststd: string & key) {return getGLProgram (key );} /** Add the Shader program to the GLProgramCache Singleton */void addGLProgram (GLProgram * program, conststd: string & key); CC_DEPRECATED_ATTRIBUTE void addProgram (GLProgram * program, const std :: string & key) {addGLProgram (program, key);} private: bool init (); void loaddefaglglprogram (GLProgram * program, int type ); // use the dictionary programs to save all Shader programs std: unordered_map
 
  
_ Programs ;};
 

The following is the singleton method getInstance:

staticGLProgramCache *_sharedGLProgramCache = 0;GLProgramCache*GLProgramCache::getInstance(){    if (!_sharedGLProgramCache) {        _sharedGLProgramCache = new GLProgramCache();        if (!_sharedGLProgramCache->init())        {            CC_SAFE_DELETE(_sharedGLProgramCache);        }    }    return _sharedGLProgramCache;}

1. When the GLProgramCache: getInstance () method is called for the first time, a new GLProgramCache instance method will be created.

2. initialize a GLProgramCache instance

3. Method single_sharedglprogramcache

The following is the init method of GLProgramCache:

boolGLProgramCache::init(){       loadDefaultGLPrograms();    return true;}voidGLProgramCache::loadDefaultGLPrograms(){    GLProgram *p = new GLProgram();loadDefaultGLProgram(p, kShaderType_PositionTextureColor);_programs.insert( std::make_pair( GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR,p ) );……}

1. In GLProgramCache: init, the load Shader method loadDefaultGLPrograms will be called.

2. In the loaddefaglglprograms method, a GLProgram object is created first.

3. Load the Shader of the corresponding name to the GLProgram object.

4. Insert the GLProgram object to the dictionary _ programs.

In the loaddefaglglprogram method:

voidGLProgramCache::loadDefaultGLProgram(GLProgram *p, int type){    switch (type) {        case kShaderType_PositionTextureColor:            p->initWithByteArrays(ccPositionTextureColor_vert,ccPositionTextureColor_frag);            break;        ………        default:            CCLOG("cocos2d: %s:%d, errorshader type", __FUNCTION__, __LINE__);            return;    }       p->link();    p->updateUniforms();       CHECK_GL_ERROR_DEBUG();}

1. Use the corresponding shader program to initialize GLProgram according to the GLProgram type. In initWithByteArrays, 1-6 of the above Shader use process will not be executed

2. Link to Program

3. Obtain some Uniform variables in the Program and use them later.

The following describes how to save the Shader program in Cocos2dx:

In cocos2d \ cocos \ renderer \ ccShaders. cpp:

#include"ccShader_Position_uColor.frag"#include"ccShader_Position_uColor.vert"……

CcShader_Position_uColor.vert file:

constchar* ccPosition_uColor_vert = STRINGIFY( attributevec4 a_position;uniformvec4 u_color;uniformfloat u_pointSize; \n#ifdefGL_ES\nvaryinglowp vec4 v_fragmentColor;\n#else\nvaryingvec4 v_fragmentColor;\n#endif\n voidmain(){    gl_Position = CC_MVPMatrix * a_position;    gl_PointSize = u_pointSize;    v_fragmentColor = u_color;});

The ccPosition_uColor_vert variable is defined here. The function room of this Vertex coloring tool uses a matrix to calculate the vertex position in OpenGL;

CcShader_Position_uColor.frag file:

constchar* ccPosition_uColor_frag = STRINGIFY( \n#ifdefGL_ES\nprecisionlowp float;\n#endif\n varyingvec4 v_fragmentColor; voidmain(){    gl_FragColor = v_fragmentColor;});

The ccPosition_uColor_frag variable is defined here. The Shader function of this segment is to set the vertex color;

The Shader program in the above two sections will pass in the initWithByteArrays method as a string. The following is the initWithByteArrays method:

BoolGLProgram: initWithByteArrays (const GLchar * vShaderByteArray, const GLchar * fShaderByteArray ){...... // SET _ program = glCreateProgram (); CHECK_GL_ERROR_DEBUG (); _ vertShader = _ fragShader = 0; if (vShaderByteArray) {if (! CompileShader (& _ vertShader, GL_VERTEX_SHADER, vShaderByteArray) {CCLOG ("cocos2d: ERROR: Failedto compile vertex shader"); return false ;}} // Create and compile fragment shader if (fShaderByteArray) {if (! CompileShader (& _ fragShader, GL_FRAGMENT_SHADER, fShaderByteArray) {CCLOG ("cocos2d: ERROR: Failedto compile fragment shader"); return false ;}} if (_ vertShader) {glAttachShader (_ program, _ vertShader);} else (); if (_ fragShader) {glAttachShader (_ program, _ fragShader);} _ hashForUniforms = nullptr; else (); ...... // Set return true on Windows ;}

1. If the vertex Shader is not empty, compile the vertex Shader.

2. If the segment Shader is not empty, compile the segment Shader

3. Bind the program and vertex Shader

4. Bind the program and fragment Shader

In the compileShader method:

BoolGLProgram: compileShader (GLuint * shader, GLenum type, const GLchar * source) {GLint status; if (! Source) return false; const GLchar * sources [] = {...... // The Uniform variable "uniform mat4 CC_PMatrix; \ n" "uniform mat4 CC_MVMatrix; \ n" "uniform mat4CC_MVPMatrix; \ n" "uniform vec4 CC_Time; \ n "" uniform vec4 CC_SinTime; \ n "" uniform vec4 CC_CosTime; \ n "" uniform vec4 CC_Random01; \ n "" uniform success; \ n "" uniform success; \ n "" uniform sampler2DCC_Texture2; \ n "" uniform sampler2DCC_Texture3; \ n "" // CC between des END \ n ", source,}; * shader = GlCreateShader (type); glShaderSource (* shader, sizeof (sources)/sizeof (* sources), sources, nullptr); glCompileShader (* shader); glGetShaderiv (* shader, reporter, & status); if (! Status) {GLsizei length; glGetShaderiv (* shader, GL_SHADER_SOURCE_LENGTH, & length); GLchar * src = (GLchar *) malloc (sizeof (GLchar) * length); glGetShaderSource (* shader, length, nullptr, src); CCLOG ("cocos2d: ERROR: Failed tocompile shader: \ n % s", src); if (type = GL_VERTEX_SHADER) CCLOG ("cocos2d: % s ", getVertexShaderLog (). c_str (); else CCLOG ("cocos2d: % s", getFragmentShaderLog (). c_str (); free (src); return false;} return (status = GL_TRUE );}

1. Add the Uniform variable that may be required for Shader execution before the Shader program string to form a new string

2. Execute steps 1-3 in the above Shader usage process

3. verify whether the Shader has been compiled successfully.

At this time, the Shader program to be used in Cocos2dx is ready, and how to use it will be further discussed in the following blog; for OpenGL Shader (GLSL) if you are not familiar with this information, you can query the information.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.