From fb574697aa21ce30033dfc3445bef83679a2db35 Mon Sep 17 00:00:00 2001 From: Dale Stammen Date: Sat, 22 Mar 2014 05:58:07 -0700 Subject: [PATCH] added support for precompiled shaders in wp8 --- cocos/2d/CCGLProgram.cpp | 65 ++++++++++++++++++++++++++++++++++++++-- cocos/2d/CCGLProgram.h | 15 ++++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/cocos/2d/CCGLProgram.cpp b/cocos/2d/CCGLProgram.cpp index ee6b53cb42..6f3bce0f3b 100644 --- a/cocos/2d/CCGLProgram.cpp +++ b/cocos/2d/CCGLProgram.cpp @@ -37,6 +37,10 @@ THE SOFTWARE. #include "kazmath/GL/matrix.h" #include "kazmath/kazmath.h" +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +#include "CCPrecompiledShaders.h" +#endif + NS_CC_BEGIN typedef struct _hashUniformEntry @@ -116,6 +120,18 @@ GLProgram::~GLProgram() bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray) { + +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) + GLboolean hasCompiler = false; + glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler); + _hasShaderCompiler = (hasCompiler == GL_TRUE); + + if(!_hasShaderCompiler) + { + return initWithPrecompiledProgramByteArray(vShaderByteArray,fShaderByteArray); + } +#endif + _program = glCreateProgram(); CHECK_GL_ERROR_DEBUG(); @@ -126,7 +142,8 @@ bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* if (!compileShader(&_vertShader, GL_VERTEX_SHADER, vShaderByteArray)) { CCLOG("cocos2d: ERROR: Failed to compile vertex shader"); - } + return false; + } } // Create and compile fragment shader @@ -135,6 +152,7 @@ bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* if (!compileShader(&_fragShader, GL_FRAGMENT_SHADER, fShaderByteArray)) { CCLOG("cocos2d: ERROR: Failed to compile fragment shader"); + return false; } } @@ -152,9 +170,34 @@ bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* CHECK_GL_ERROR_DEBUG(); +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) + _shaderId = CCPrecompiledShaders::getInstance()->addShaders(vShaderByteArray, fShaderByteArray); +#endif + return true; } +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +bool GLProgram::initWithPrecompiledProgramByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray) +{ + bool haveProgram = false; + + _program = glCreateProgram(); + CHECK_GL_ERROR_DEBUG(); + + _vertShader = _fragShader = 0; + + haveProgram = CCPrecompiledShaders::getInstance()->loadProgram(_program, vShaderByteArray, fShaderByteArray); + + CHECK_GL_ERROR_DEBUG(); + _hashForUniforms = NULL; + + CHECK_GL_ERROR_DEBUG(); + + return haveProgram; +} +#endif + bool GLProgram::initWithFilenames(const std::string &vShaderFilename, const std::string &fShaderFilename) { auto fileUtils = FileUtils::getInstance(); @@ -275,6 +318,15 @@ bool GLProgram::link() { CCASSERT(_program != 0, "Cannot link invalid program"); + +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) + if(!_hasShaderCompiler) + { + // precompiled shader program is already linked + return true; + } +#endif + GLint status = GL_TRUE; glLinkProgram(_program); @@ -291,7 +343,7 @@ bool GLProgram::link() _vertShader = _fragShader = 0; -#if COCOS2D_DEBUG +#if DEBUG || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) glGetProgramiv(_program, GL_LINK_STATUS, &status); if (status == GL_FALSE) @@ -301,7 +353,14 @@ bool GLProgram::link() _program = 0; } #endif - + +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) + if (status == GL_TRUE) + { + CCPrecompiledShaders::getInstance()->addProgram(_program, _shaderId); + } +#endif + return (status == GL_TRUE); } diff --git a/cocos/2d/CCGLProgram.h b/cocos/2d/CCGLProgram.h index c111c0c724..19c9865f7d 100644 --- a/cocos/2d/CCGLProgram.h +++ b/cocos/2d/CCGLProgram.h @@ -126,7 +126,18 @@ public: * @js initWithString * @lua initWithString */ + +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) + /** Initializes the CCGLProgram with precompiled shader program */ + bool initWithPrecompiledProgramByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray); +#endif + + /** Initializes the GLProgram with a vertex and fragment with bytes array + * @js initWithString + * @lua initWithString + */ bool initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray); + /** Initializes the GLProgram with a vertex and fragment with contents of filenames * @js init * @lua init @@ -266,6 +277,10 @@ private: GLuint _fragShader; GLint _uniforms[UNIFORM_MAX]; struct _hashUniformEntry* _hashForUniforms; + bool _hasShaderCompiler; +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) + std::string _shaderId; +#endif struct flag_struct { unsigned int usesTime:1;