22
OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System Suntae Kim 2015.01.27 2015 LINE CORPORATION

OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

Embed Size (px)

Citation preview

Page 1: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  Programming����������� ������������������  and����������� ������������������  

Cocos2d-x����������� ������������������  v3.3����������� ������������������  Rendering����������� ������������������  System����������� ������������������  

Suntae Kim

2015.01.27

ⓒ 2015����������� ������������������  LINE����������� ������������������  CORPORATION

Page 2: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

2����������� ������������������  

•  EGL����������� ������������������  

•  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  Pipeline����������� ������������������  

•  Vertex����������� ������������������  shader����������� ������������������  

•  Fragment����������� ������������������  shader����������� ������������������  

•  The����������� ������������������  simple����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  codes����������� ������������������  

����������� ������������������  ����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  programming����������� ������������������  

Page 3: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

3����������� ������������������  

•  EGL����������� ������������������  is����������� ������������������  an����������� ������������������  interface����������� ������������������  between����������� ������������������  rendering����������� ������������������  APIs����������� ������������������  such����������� ������������������  as����������� ������������������  OpenCL,����������� ������������������  OpenGL,����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  or����������� ������������������  OpenVG����������� ������������������  (referred����������� ������������������  to����������� ������������������  collectively����������� ������������������  as����������� ������������������  client����������� ������������������  APIs)����������� ������������������  

•  EGL����������� ������������������  provides����������� ������������������  mechanisms����������� ������������������  for����������� ������������������  creating����������� ������������������  rendering����������� ������������������  surfaces����������� ������������������  onto����������� ������������������  which����������� ������������������  client����������� ������������������  APIs����������� ������������������  can����������� ������������������  draw,����������� ������������������  creating����������� ������������������  graphics����������� ������������������  contexts����������� ������������������  for����������� ������������������  client����������� ������������������  APIs,����������� ������������������  and����������� ������������������  synchronizing����������� ������������������  drawing����������� ������������������  by����������� ������������������  client����������� ������������������  APIs����������� ������������������  as����������� ������������������  well����������� ������������������  as����������� ������������������  platform����������� ������������������  rendering����������� ������������������  APIs.����������� ������������������  

•  EGL����������� ������������������  is����������� ������������������  intended����������� ������������������  to����������� ������������������  be����������� ������������������  implementable����������� ������������������  on����������� ������������������  multiple����������� ������������������  operating����������� ������������������  systems����������� ������������������  (such����������� ������������������  as����������� ������������������  Android,����������� ������������������  Unix,����������� ������������������  and����������� ������������������  Windows)����������� ������������������  and����������� ������������������  platforms1����������� ������������������  (including����������� ������������������  window����������� ������������������  systems����������� ������������������  such����������� ������������������  as����������� ������������������  X11����������� ������������������  and����������� ������������������  Microsoft����������� ������������������  Windows,����������� ������������������  and����������� ������������������  platforms����������� ������������������  supporting����������� ������������������  rendering����������� ������������������  without����������� ������������������  a����������� ������������������  display,����������� ������������������  such����������� ������������������  as����������� ������������������  GBM)����������� ������������������  

����������� ������������������  ����������� ������������������  ����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  programming����������� ������������������  >����������� ������������������  EGL����������� ������������������  

Page 4: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

4����������� ������������������  

static const EGLint s_configAttribs[] = !{ ! EGL_RED_SIZE, 5, ! EGL_GREEN_SIZE, 6, ! EGL_BLUE_SIZE, 5, ! EGL_ALPHA_SIZE, 0, ! EGL_LUMINANCE_SIZE, ! EGL_DONT_CARE, ! EGL_SURFACE_TYPE, ! EGL_VG_COLORSPACE_LINEAR_BIT, ! EGL_SAMPLES, 0, ! EGL_NONE !}; !

•  The����������� ������������������  eglMakeCurrent����������� ������������������  function����������� ������������������  binds����������� ������������������  ctx����������� ������������������  to����������� ������������������  the����������� ������������������  current����������� ������������������  rendering����������� ������������������  thread����������� ������������������  and����������� ������������������  to����������� ������������������  the����������� ������������������  draw����������� ������������������  and����������� ������������������  read����������� ������������������  surfaces.����������� ������������������  ����������� ������������������  

•  The����������� ������������������  same����������� ������������������  EGLSurface����������� ������������������  may����������� ������������������  be����������� ������������������  specified����������� ������������������  for����������� ������������������  both����������� ������������������  draw����������� ������������������  and����������� ������������������  read.����������� ������������������  ����������� ������������������  

• When����������� ������������������  the����������� ������������������  client����������� ������������������  is����������� ������������������  finished����������� ������������������  drawing����������� ������������������  a����������� ������������������  frame,����������� ������������������  the����������� ������������������  back����������� ������������������  buffer����������� ������������������  may����������� ������������������  be����������� ������������������  copied����������� ������������������  ����������� ������������������  to����������� ������������������  a����������� ������������������  visible����������� ������������������  window����������� ������������������  using����������� ������������������  eglSwapBuffers.����������� ������������������  

!EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib list, ! EGLConfig *configs, EGLint config_size, EGLint *num config); !!!EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, ! NativeWindowType win, const EGLint *attrib_list); !!!EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, ! EGLContext share context, onst EGLint *attrib_list); !!!EGLBoolean eglMakeCurrent(EGLDisplay dpy,EGLSurface draw, ! EGLSurface read, EGLContext ctx); !!!EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface); !

����������� ������������������  ����������� ������������������  ����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  programming����������� ������������������  >����������� ������������������  EGL����������� ������������������  

Page 5: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

5����������� ������������������  

// Draw the Scene!void Director::drawScene() !{ ! // calculate "global" dt! calculateDeltaTime(); ! ! //tick before glClear: issue #533! if (! _paused) ! { ! _scheduler->update(_deltaTime); ! _eventDispatcher->dispatchEvent(_eventAfterUpdate); ! } !! glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); !! /* to avoid flickr, nextScene MUST be here: after tick and before draw. ! * FIXME: Which bug is this one. It seems that it can't be reproduced with v0.9 ! */! if (_nextScene) ! { ! setNextScene(); ! } !! pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); ! ! if (_runningScene) ! { ! //clear draw stats! _renderer->clearDrawStats(); ! ! //render the scene! _runningScene->render(_renderer); ! ! _eventDispatcher->dispatchEvent(_eventAfterVisit); ! } !! _renderer->render(); !! _eventDispatcher->dispatchEvent(_eventAfterDraw); !! popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); !! // swap buffers! if (_openGLView) ! { ! _openGLView->swapBuffers(); ! } !} !

void GLViewImpl::swapBuffers() !{ ! CCEAGLView *eaglview = (CCEAGLView*) _eaglview; ! [eaglview swapBuffers]; !} !

����������� ������������������  ����������� ������������������  ����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  programming����������� ������������������  >����������� ������������������  EGL����������� ������������������  swapBuffers����������� ������������������  of����������� ������������������  Cocos2d-x����������� ������������������  

Page 6: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

6����������� ������������������  

•  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  combines����������� ������������������  a����������� ������������������  version����������� ������������������  of����������� ������������������  the����������� ������������������  OpenGL����������� ������������������  Shading����������� ������������������  Language����������� ������������������  for����������� ������������������  programming����������� ������������������  vertex����������� ������������������  and����������� ������������������  fragment����������� ������������������  shaders����������� ������������������  that����������� ������������������  have����������� ������������������  been����������� ������������������  adapted����������� ������������������  for����������� ������������������  embedded����������� ������������������  platforms.����������� ������������������  ����������� ������������������  

•  The����������� ������������������  streamlined����������� ������������������  API����������� ������������������  from����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  1.1����������� ������������������  has����������� ������������������  removed����������� ������������������  any����������� ������������������  fixed����������� ������������������  functionality����������� ������������������  that����������� ������������������  can����������� ������������������  be����������� ������������������  easily����������� ������������������  replaced����������� ������������������  by����������� ������������������  shader����������� ������������������  programs,����������� ������������������  to����������� ������������������  minimize����������� ������������������  the����������� ������������������  cost����������� ������������������  and����������� ������������������  power����������� ������������������  consumption����������� ������������������  of����������� ������������������  advanced����������� ������������������  programmable����������� ������������������  graphics����������� ������������������  subsystems.����������� ������������������  

����������� ������������������  ����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  programming����������� ������������������  >����������� ������������������  Rendering����������� ������������������  pipeline����������� ������������������  

Page 7: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

7����������� ������������������  

CPU����������� ������������������  ->����������� ������������������  GPU(����������� ������������������  Vertex����������� ������������������  shader����������� ������������������  ->����������� ������������������  Fragment����������� ������������������  shader����������� ������������������  )����������� ������������������  

����������� ������������������  ����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  programming����������� ������������������  >����������� ������������������  Shader����������� ������������������  processing����������� ������������������  view����������� ������������������  

Page 8: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

8����������� ������������������  

#include <EGL/egl.h>!#include <GLES2/GL2.h>!#include <GLES2/gl2ext.h>!!const char* g_strVSProgram = !"attribute vec4 g_vVertex; \n"!"attribute vec4 g_vColor; \n"!"varying vec4 g_vVSColor; \n"!"void main() \n"!"{ \n"!" gl_Position = vec4( g_vVertex.x, g_vVertex.y, g_vVertex.z, g_vVertex.w ); \n"!" g_vVSColor = g_vColor; \n"!"} \n"; !!const char* g_strFSProgram = !"precision mediump float; \n"!"varying vec4 g_vVSColor; \n"!"void main() \n"!"{ \n"!"gl_FragColor = g_vVSColor; \n"!"} \n"; !!GLuint g_hShaderProgram = 0; !GLuint g_VertexLoc = 0; !GLuint g_ColorLoc = 1; !!GLuint hVertexShader = glCreateShader( GL_VERTEX_SHADER ); !glShaderSource( hVertexShader, 1, &g_strVSProgram, NULL ); !glCompileShader( hVertexShader ); !!GLuint hFragmentShader = glCreateShader( GL_FRAGMENT_SHADER ); !glShaderSource( hFragmentShader, 1, &g_strFSProgram, NULL ); !glCompileShader( hFragmentShader ); !!g_hShaderProgram = glCreateProgram(); !glAttachShader( g_hShaderProgram, hVertexShader ); !glAttachShader( g_hShaderProgram, hFragmentShader ); !

glBindAttribLocation(g_hShaderProgram, g_VertexLoc, "g_vVertex"); !glBindAttribLocation(g_hShaderProgram, g_ColorLoc, "g_vColor"); !glLinkProgram( g_hShaderProgram ); !!glDeleteShader( hVertexShader ); !glDeleteShader( hFragmentShader ); !!float fSize = 0.5f; !float vertexPositionArr[] = !{ ! 0.0f, fSize, 0.0f, 1.0f, ! -fSize, -fSize, 0.0f, 1.0f, ! fSize, -fSize, 0.0f, 1.0f, !}; ! !float vertexColorArr[] = !{ ! 1.0f, 0.0f, 0.0f, 1.0f, ! 0.0f, 1.0f, 0.0f, 1.0f, ! 0.0f, 0.0f, 1.0f, 1.0f !}; !!!void Render() !{ !! // Clear the backbuffer and depth-buffer! glClearColor( 0.0f, 0.0f, 0.5f, 1.0f ); ! glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); ! ! // Set the shader program! glUseProgram( g_hShaderProgram ); ! ! // Draw the colored triangle! glVertexAttribPointer( g_VertexLoc, 4, GL_FLOAT, 0, 0, vertexPositionArr ); ! glEnableVertexAttribArray( g_VertexLoc ); ! glVertexAttribPointer( g_ColorLoc, 4, GL_FLOAT, 0, 0, vertexColorArr); ! glEnableVertexAttribArray( g_ColorLoc ); !! glDrawArrays( GL_TRIANGLE_STRIP, 0, 3 ); !! glDisableVertexAttribArray( g_VertexLoc ); ! glDisableVertexAttribArray( g_ColorLoc ); !} !!!

����������� ������������������  ����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  programming����������� ������������������  >����������� ������������������  The����������� ������������������  simple����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  codes����������� ������������������  

Page 9: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

9����������� ������������������  

File : CCGLProgram.cpp !!const char* GLProgram::ATTRIBUTE_NAME_COLOR = "a_color"; !const char* GLProgram::ATTRIBUTE_NAME_POSITION = "a_position"; !const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD = "a_texCoord"; !const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD1 = "a_texCoord1"; !const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD2 = "a_texCoord2"; !const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD3 = "a_texCoord3"; !const char* GLProgram::ATTRIBUTE_NAME_NORMAL = "a_normal"; !const char* GLProgram::ATTRIBUTE_NAME_BLEND_WEIGHT = "a_blendWeight"; !const char* GLProgram::ATTRIBUTE_NAME_BLEND_INDEX = “a_blendIndex"; !!void GLProgram::bindPredefinedVertexAttribs() !{ ! static const struct { ! const char *attributeName; ! int location; ! } attribute_locations[] = ! { ! {GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION}, ! {GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR}, ! {GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORD}, ! {GLProgram::ATTRIBUTE_NAME_TEX_COORD1, GLProgram::VERTEX_ATTRIB_TEX_COORD1}, ! {GLProgram::ATTRIBUTE_NAME_TEX_COORD2, GLProgram::VERTEX_ATTRIB_TEX_COORD2}, ! {GLProgram::ATTRIBUTE_NAME_TEX_COORD3, GLProgram::VERTEX_ATTRIB_TEX_COORD3}, ! {GLProgram::ATTRIBUTE_NAME_NORMAL, GLProgram::VERTEX_ATTRIB_NORMAL}, ! }; !! const int size = sizeof(attribute_locations) / sizeof(attribute_locations[0]); !! for(int i=0; i<size;i++) { ! glBindAttribLocation(_program, attribute_locations[i].location, attribute_locations[i].attributeName); ! } !} !!bool GLProgram::link() !{ ! bindPredefinedVertexAttribs(); !! glLinkProgram(_program); !! parseVertexAttribs(); ! parseUniforms(); !} !

����������� ������������������  ����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  programming����������� ������������������  >����������� ������������������  bindPredefinedVertexAttribs()����������� ������������������  of����������� ������������������  Cocos2d-x����������� ������������������  

Page 10: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

10����������� ������������������  

bool GLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* source) !{ ! GLint status; ! ! if (!source) ! { ! return false; ! } ! ! const GLchar *sources[] = { !#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT ! (type == GL_VERTEX_SHADER ? "precision mediump float;\n precision mediump int;\n" : "precision mediump float;\n precision mediump int;\n"), !#elif (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 && CC_TARGET_PLATFORM != CC_PLATFORM_LINUX && CC_TARGET_PLATFORM != CC_PLATFORM_MAC) ! (type == GL_VERTEX_SHADER ? "precision highp float;\n precision highp int;\n" : "precision mediump float;\n precision mediump int;\n"), !#endif ! "uniform mat4 CC_PMatrix;\n"! "uniform mat4 CC_MVMatrix;\n"! "uniform mat4 CC_MVPMatrix;\n"! "uniform mat3 CC_NormalMatrix;\n"! "uniform vec4 CC_Time;\n"! "uniform vec4 CC_SinTime;\n"! "uniform vec4 CC_CosTime;\n"! "uniform vec4 CC_Random01;\n"! "uniform sampler2D CC_Texture0;\n"! "uniform sampler2D CC_Texture1;\n"! "uniform sampler2D CC_Texture2;\n"! "uniform sampler2D CC_Texture3;\n"! "//CC INCLUDES END\n\n", ! source, ! }; !! *shader = glCreateShader(type); ! glShaderSource(*shader, sizeof(sources)/sizeof(*sources), sources, nullptr); ! glCompileShader(*shader); !! glGetShaderiv(*shader, GL_COMPILE_STATUS, &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 to compile 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); !} !

����������� ������������������  ����������� ������������������  OpenGL����������� ������������������  ES����������� ������������������  2.0����������� ������������������  programming����������� ������������������  >����������� ������������������  compileShader()����������� ������������������  of����������� ������������������  Cocos2d-x����������� ������������������  

Page 11: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

11����������� ������������������  

•  Version����������� ������������������  :����������� ������������������  v3.3����������� ������������������  

•  Document����������� ������������������  :����������� ������������������  http://cocos2d-x.org/wiki/Cocos2d_v30_renderer_pipeline_roadmap����������� ������������������  

•  Pseudo����������� ������������������  code����������� ������������������  :����������� ������������������  

https://gist.github.com/ricardoquesada/7049216����������� ������������������  

����������� ������������������  ����������� ������������������  Cocos2d-x����������� ������������������  v3.3����������� ������������������  Rendering����������� ������������������  pipeline����������� ������������������  

Page 12: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

12����������� ������������������  

•  Decouple����������� ������������������  the����������� ������������������  scene����������� ������������������  graph����������� ������������������  from����������� ������������������  the����������� ������������������  renderer����������� ������������������  

•  Viewing����������� ������������������  frustum����������� ������������������  Geometry����������� ������������������  culling����������� ������������������  

•  Rendering����������� ������������������  on����������� ������������������  a����������� ������������������  separate����������� ������������������  thread����������� ������������������  (Not����������� ������������������  yet)����������� ������������������  

•  Automatic����������� ������������������  batching����������� ������������������  

•  (Node����������� ������������������  based)����������� ������������������  Customizable����������� ������������������  rendering����������� ������������������  

•  Optimized����������� ������������������  for����������� ������������������  2D,����������� ������������������  but����������� ������������������  suitable����������� ������������������  for����������� ������������������  3D����������� ������������������  as����������� ������������������  well����������� ������������������  

����������� ������������������  ����������� ������������������  ����������� ������������������  Cocos2d-x����������� ������������������  v3.3����������� ������������������  Rendering����������� ������������������  pipeline����������� ������������������  >����������� ������������������  The����������� ������������������  Goal����������� ������������������  of����������� ������������������  Cocos2d-x����������� ������������������  New����������� ������������������  Renderer����������� ������������������  

Page 13: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

13����������� ������������������  

1.����������� ������������������  Add����������� ������������������  commands����������� ������������������  

2.����������� ������������������  Grouping����������� ������������������  commands����������� ������������������  

3.����������� ������������������  Sorting����������� ������������������  and����������� ������������������  rearrangement����������� ������������������  

4.����������� ������������������  Execute����������� ������������������  commands����������� ������������������  

����������� ������������������  ����������� ������������������  ����������� ������������������  Cocos2d-x����������� ������������������  v3.3����������� ������������������  Rendering����������� ������������������  pipeline����������� ������������������  >����������� ������������������  RenderQueue����������� ������������������  

Page 14: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

14����������� ������������������  

void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) !{ ! // Don't do calculate the culling if the transform was not updated! _insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds; !! if(_insideBounds) ! { ! _quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform); !! renderer->addCommand(&_quadCommand); ! } !} !!void Renderer::addCommand(RenderCommand* command) !{ ! int renderQueue =_commandGroupStack.top(); ! addCommand(command, renderQueue); !} !!void Renderer::addCommand(RenderCommand* command, int renderQueue) !{ ! if (command->isTransparent()) ! _transparentRenderGroups.push_back(command); ! else! _renderGroups[renderQueue].push_back(command); !} !

����������� ������������������  ����������� ������������������  ����������� ������������������  Cocos2d-x����������� ������������������  v3.3����������� ������������������  Rendering����������� ������������������  pipeline����������� ������������������  >����������� ������������������  AddCommand����������� ������������������  

Page 15: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

15����������� ������������������  

File : CCRenderer.cpp !!void Renderer::render() !{ ! //Uncomment this once everything is rendered by new renderer! //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);!! //TODO: setup camera or MVP! _isRendering = true; ! ! if (_glViewAssigned) ! { ! //Process render commands! //1. Sort render commands based on ID! for (auto &renderqueue : _renderGroups) ! { ! renderqueue.sort(); ! } !! visitRenderQueue(_renderGroups[0]); ! flush(); ! ! //Process render commands! //draw transparent objects here, do not batch for transparent objects! if (0 < _transparentRenderGroups.size()) ! { ! _transparentRenderGroups.sort(); ! glEnable(GL_DEPTH_TEST); ! visitTransparentRenderQueue(_transparentRenderGroups); ! glDisable(GL_DEPTH_TEST); ! } ! } ! clean(); ! _isRendering = false; !} !

����������� ������������������  ����������� ������������������  ����������� ������������������  Cocos2d-x����������� ������������������  v3.3����������� ������������������  Rendering����������� ������������������  pipeline����������� ������������������  >����������� ������������������  Sorting����������� ������������������  and����������� ������������������  Rearrangement����������� ������������������  

Page 16: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

16����������� ������������������  

File : CCRenderer.cpp !!static bool compareRenderCommand(RenderCommand* a, RenderCommand* b) !{ ! return a->getGlobalOrder() < b->getGlobalOrder(); !} !!void RenderQueue::push_back(RenderCommand* command) !{ ! float z = command->getGlobalOrder(); ! if(z < 0) ! _queueNegZ.push_back(command); ! else if(z > 0) ! _queuePosZ.push_back(command); ! else! _queue0.push_back(command); !} !!void RenderQueue::sort() !{ ! // Don't sort _queue0, it already comes sorted! std::sort(std::begin(_queueNegZ), std::end(_queueNegZ), compareRenderCommand); ! std::sort(std::begin(_queuePosZ), std::end(_queuePosZ), compareRenderCommand); !} !!static bool compareTransparentRenderCommand(RenderCommand* a, RenderCommand* b) !{ ! return a->getGlobalOrder() > b->getGlobalOrder(); !} !!void TransparentRenderQueue::sort() !{ ! std::sort(std::begin(_queueCmd), std::end(_queueCmd), compareTransparentRenderCommand); !} !

����������� ������������������  ����������� ������������������  ����������� ������������������  Cocos2d-x����������� ������������������  v3.3����������� ������������������  Rendering����������� ������������������  pipeline����������� ������������������  >����������� ������������������  Sorting����������� ������������������  and����������� ������������������  Rearrangement����������� ������������������  

Page 17: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

17����������� ������������������  

•  Reducing����������� ������������������  the����������� ������������������  number����������� ������������������  of����������� ������������������  draw����������� ������������������  calls����������� ������������������  and����������� ������������������  render����������� ������������������  device����������� ������������������  state����������� ������������������  changes����������� ������������������  will����������� ������������������  improve����������� ������������������  drastically����������� ������������������  rendering����������� ������������������  speed.����������� ������������������  

•  if����������� ������������������  all����������� ������������������  the����������� ������������������  Quads����������� ������������������  share����������� ������������������  the����������� ������������������  same����������� ������������������  material,����������� ������������������  then����������� ������������������  only����������� ������������������  one����������� ������������������  draw����������� ������������������  call����������� ������������������  will����������� ������������������  be����������� ������������������  used����������� ������������������  (automatic����������� ������������������  batching)����������� ������������������  

����������� ������������������  ����������� ������������������  ����������� ������������������  Cocos2d-x����������� ������������������  v3.3����������� ������������������  Rendering����������� ������������������  pipeline����������� ������������������  >����������� ������������������  Auto����������� ������������������  Batching����������� ������������������  

Page 18: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

18����������� ������������������  

visitRenderQueue����������� ������������������  and����������� ������������������  flush����������� ������������������  

File : CCRenderer.cpp !!RenderCommand* RenderQueue::operator[](ssize_t index) const!{ ! if(index < static_cast<ssize_t>(_queueNegZ.size())) ! return _queueNegZ[index]; !! index -= _queueNegZ.size(); !! if(index < static_cast<ssize_t>(_queue0.size())) ! return _queue0[index]; !! index -= _queue0.size(); !! if(index < static_cast<ssize_t>(_queuePosZ.size())) ! return _queuePosZ[index]; !! CCASSERT(false, "invalid index"); ! return nullptr; !} !!void Renderer::render() !{ ! if (_glViewAssigned) ! { ! //Process render commands! //1. Sort render commands based on ID! for (auto &renderqueue : _renderGroups) ! { ! renderqueue.sort(); ! } !! visitRenderQueue(_renderGroups[0]); ! flush(); ! } ! clean(); ! _isRendering = false; !} !!void Renderer::flush() !{ ! flush2D(); ! flush3D(); !} !!void Renderer::flush2D() !{ ! drawBatchedQuads(); ! _lastMaterialID = 0; ! drawBatchedTriangles(); ! _lastMaterialID = 0; !} !

File : CCRenderer.cpp !!!void Renderer::visitRenderQueue(const RenderQueue& queue) !{ ! ssize_t size = queue.size(); ! ! for (ssize_t index = 0; index < size; ++index) ! { ! auto command = queue[index]; ! auto commandType = command->getType(); !

" if( RenderCommand::Type::TRIANGLES_COMMAND == commandType) ! { ! //Batch Triangles" "!

"" } ! else if ( RenderCommand::Type::QUAD_COMMAND == commandType ) ! { ! flush3D(); ! if(_filledIndex > 0) ! { ! drawBatchedTriangles(); ! _lastMaterialID = 0; ! } ! auto cmd = static_cast<QuadCommand*>(command); ! //Batch quads! if( (_numberQuads + cmd->getQuadCount()) * 4 > VBO_SIZE ) ! { ! //Draw batched quads if VBO is full! drawBatchedQuads(); ! } ! ! _batchQuadCommands.push_back(cmd);! ! fillQuads(cmd); ! } ! } !} !!!!!!!!!

����������� ������������������  ����������� ������������������  ����������� ������������������  Cocos2d-x����������� ������������������  v3.3����������� ������������������  Rendering����������� ������������������  pipeline����������� ������������������  >����������� ������������������  Auto����������� ������������������  Batching����������� ������������������  

Page 19: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

19����������� ������������������  

“if����������� ������������������  all����������� ������������������  the����������� ������������������  Quads����������� ������������������  share����������� ������������������  the����������� ������������������  same����������� ������������������  material,����������� ������������������  ����������� ������������������  then����������� ������������������  only����������� ������������������  one����������� ������������������  draw����������� ������������������  call����������� ������������������  will����������� ������������������  be����������� ������������������  used����������� ������������������  (automatic����������� ������������������  batching)”����������� ������������������  

File : CCRenderer.cpp !!void Renderer::drawBatchedQuads() !{ ! glBindBuffer(GL_ARRAY_BUFFER, _quadbuffersVBO[0]); ! glBufferData(GL_ARRAY_BUFFER, sizeof(_quadVerts[0]) * _numberQuads * 4, nullptr, GL_DYNAMIC_DRAW); ! void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); ! memcpy(buf, _quadVerts, sizeof(_quadVerts[0])* _numberQuads * 4); ! glUnmapBuffer(GL_ARRAY_BUFFER);! glBindBuffer(GL_ARRAY_BUFFER, 0);! glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _quadbuffersVBO[1]); !!

"//Start drawing verties in batch! for(const auto& cmd : _batchQuadCommands) ! { ! auto newMaterialID = cmd->getMaterialID(); ! if(_lastMaterialID != newMaterialID || newMaterialID == MATERIAL_ID_DO_NOT_BATCH) ! { ! //Draw quads! if(indexToDraw > 0) ! { ! glDrawElements(GL_TRIANGLES, (GLsizei) indexToDraw, GL_UNSIGNED_SHORT, (GLvoid*) (startIndex*sizeof(_indices[0])) ); ! _drawnBatches++; ! _drawnVertices += indexToDraw; ! ! startIndex += indexToDraw; ! indexToDraw = 0; ! } ! ! //Use new material! cmd->useMaterial();! _lastMaterialID = newMaterialID; ! } ! ! indexToDraw += cmd->getQuadCount() * 6; ! } !} !

Renderer::flush(); !

����������� ������������������  ����������� ������������������  ����������� ������������������  Cocos2d-x����������� ������������������  v3.3����������� ������������������  Rendering����������� ������������������  pipeline����������� ������������������  >����������� ������������������  Auto����������� ������������������  Batching����������� ������������������  

Page 20: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

20����������� ������������������  

If����������� ������������������  the����������� ������������������  AABB����������� ������������������  of����������� ������������������  the����������� ������������������  node����������� ������������������  is����������� ������������������  outside����������� ������������������  the����������� ������������������  frustum,����������� ������������������  ����������� ������������������  then����������� ������������������  no����������� ������������������  Commands����������� ������������������  will����������� ������������������  be����������� ������������������  submitted����������� ������������������  to����������� ������������������  the����������� ������������������  RenderQueue.����������� ������������������  

bool Renderer::checkVisibility(const Mat4 &transform, const Size &size) !{ ! auto scene = Director::getInstance()->getRunningScene(); ! // only cull the default camera. The culling algorithm is valid for default camera.! if (scene && scene->_defaultCamera != Camera::getVisitingCamera()) ! return true; ! ! // half size of the screen! Size screen_half = Director::getInstance()->getWinSize(); ! screen_half.width /= 2; ! screen_half.height /= 2; !! float hSizeX = size.width/2; ! float hSizeY = size.height/2; !! Vec4 v4world, v4local; ! v4local.set(hSizeX, hSizeY, 0, 1); ! transform.transformVector(v4local, &v4world); !! // center of screen is (0,0)! v4world.x -= screen_half.width; ! v4world.y -= screen_half.height; !! // convert content size to world coordinates! float wshw = std::max(fabsf(hSizeX * transform.m[0] + hSizeY * transform.m[4]), fabsf(hSizeX * transform.m[0] - hSizeY * transform.m[4])); ! float wshh = std::max(fabsf(hSizeX * transform.m[1] + hSizeY * transform.m[5]), fabsf(hSizeX * transform.m[1] - hSizeY * transform.m[5])); !! // compare if it in the positive quadrant of the screen! float tmpx = (fabsf(v4world.x)-wshw); ! float tmpy = (fabsf(v4world.y)-wshh); ! bool ret = (tmpx < screen_half.width && tmpy < screen_half.height); !! return ret; !} !

����������� ������������������  ����������� ������������������  ����������� ������������������  Cocos2d-x����������� ������������������  v3.3����������� ������������������  Rendering����������� ������������������  pipeline����������� ������������������  >����������� ������������������  Auto����������� ������������������  Culling����������� ������������������  

Page 21: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

21����������� ������������������  

•  http://cocos2d-x.org����������� ������������������  

•  http://cocos2d-x.org/wiki/Cocos2d_v30_renderer_pipeline_roadmap����������� ������������������  

•  http://cache.freescale.com/files/dsp/doc/app_note/AN3994.pdf����������� ������������������  

•  https://www.khronos.org/egl����������� ������������������  

•  https://www.khronos.org/opengles����������� ������������������  

•  https://www.khronos.org/registry/egl/specs/eglspec.1.5.pdf����������� ������������������  

•  https://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf����������� ������������������  

����������� ������������������  ����������� ������������������  ����������� ������������������  Cocos2d-x����������� ������������������  v3.3����������� ������������������  Rendering����������� ������������������  pipeline����������� ������������������  >����������� ������������������  References����������� ������������������  

Page 22: OpenGL ES 2.0 Programming and Cocos2d-x v3.3 Rendering System

Thank����������� ������������������  you!!����������� ������������������  

Q&A����������� ������������������