Upload
oasiskim
View
770
Download
13
Embed Size (px)
Citation preview
OpenGL����������� ������������������ ES����������� ������������������ 2.0����������� ������������������ Programming����������� ������������������ and����������� ������������������
Cocos2d-x����������� ������������������ v3.3����������� ������������������ Rendering����������� ������������������ System����������� ������������������
Suntae Kim
2015.01.27
ⓒ 2015����������� ������������������ LINE����������� ������������������ CORPORATION
2����������� ������������������
• EGL����������� ������������������
• OpenGL����������� ������������������ ES����������� ������������������ 2.0����������� ������������������ Pipeline����������� ������������������
• Vertex����������� ������������������ shader����������� ������������������
• Fragment����������� ������������������ shader����������� ������������������
• The����������� ������������������ simple����������� ������������������ OpenGL����������� ������������������ ES����������� ������������������ 2.0����������� ������������������ codes����������� ������������������
����������� ������������������ ����������� ������������������ OpenGL����������� ������������������ ES����������� ������������������ 2.0����������� ������������������ programming����������� ������������������
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����������� ������������������
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����������� ������������������
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����������� ������������������
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����������� ������������������
7����������� ������������������
CPU����������� ������������������ ->����������� ������������������ GPU(����������� ������������������ Vertex����������� ������������������ shader����������� ������������������ ->����������� ������������������ Fragment����������� ������������������ shader����������� ������������������ )����������� ������������������
����������� ������������������ ����������� ������������������ OpenGL����������� ������������������ ES����������� ������������������ 2.0����������� ������������������ programming����������� ������������������ >����������� ������������������ Shader����������� ������������������ processing����������� ������������������ view����������� ������������������
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����������� ������������������
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����������� ������������������
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����������� ������������������
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����������� ������������������
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����������� ������������������
13����������� ������������������
1.����������� ������������������ Add����������� ������������������ commands����������� ������������������
2.����������� ������������������ Grouping����������� ������������������ commands����������� ������������������
3.����������� ������������������ Sorting����������� ������������������ and����������� ������������������ rearrangement����������� ������������������
4.����������� ������������������ Execute����������� ������������������ commands����������� ������������������
����������� ������������������ ����������� ������������������ ����������� ������������������ Cocos2d-x����������� ������������������ v3.3����������� ������������������ Rendering����������� ������������������ pipeline����������� ������������������ >����������� ������������������ RenderQueue����������� ������������������
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����������� ������������������
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����������� ������������������
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����������� ������������������
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����������� ������������������
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����������� ������������������
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����������� ������������������
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����������� ������������������
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����������� ������������������
Thank����������� ������������������ you!!����������� ������������������
Q&A����������� ������������������