diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index 50c9a718b6..1db15c51e1 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -3678,6 +3678,8 @@ B3AF019F1842FBA400A98B85 /* b2MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MotorJoint.h; sourceTree = ""; }; B603F1A61AC8EA0900A9579C /* CCTerrain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCTerrain.cpp; sourceTree = ""; }; B603F1A71AC8EA0900A9579C /* CCTerrain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTerrain.h; sourceTree = ""; }; + B603F1B11AC8F1FD00A9579C /* ccShader_3D_Terrain.frag */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = ccShader_3D_Terrain.frag; sourceTree = ""; }; + B603F1B21AC8F1FD00A9579C /* ccShader_3D_Terrain.vert */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = ccShader_3D_Terrain.vert; sourceTree = ""; }; B60C5BD219AC68B10056FBDE /* CCBillBoard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCBillBoard.cpp; sourceTree = ""; }; B60C5BD319AC68B10056FBDE /* CCBillBoard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCBillBoard.h; sourceTree = ""; }; B63990CA1A490AFE00B07923 /* CCAsyncTaskPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCAsyncTaskPool.cpp; path = ../base/CCAsyncTaskPool.cpp; sourceTree = ""; }; @@ -5879,6 +5881,8 @@ 5034CA5D191D591900CE6051 /* shaders */ = { isa = PBXGroup; children = ( + B603F1B11AC8F1FD00A9579C /* ccShader_3D_Terrain.frag */, + B603F1B21AC8F1FD00A9579C /* ccShader_3D_Terrain.vert */, B6D38B941AC3B45600043997 /* ccShader_3D_Particle.frag */, B6D38B951AC3B45600043997 /* ccShader_3D_Particle.vert */, B6D38B961AC3B45600043997 /* ccShader_3D_Skybox.frag */, diff --git a/build/cocos2d_tests.xcodeproj/project.pbxproj b/build/cocos2d_tests.xcodeproj/project.pbxproj index 50df5e85b7..bae53e5f60 100644 --- a/build/cocos2d_tests.xcodeproj/project.pbxproj +++ b/build/cocos2d_tests.xcodeproj/project.pbxproj @@ -816,6 +816,8 @@ B2507B6C192589AF00FA4972 /* Shaders3D in Resources */ = {isa = PBXBuildFile; fileRef = B2507B6A192589AF00FA4972 /* Shaders3D */; }; B603F1AF1AC8EA4E00A9579C /* TerrainTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B603F1AD1AC8EA4E00A9579C /* TerrainTest.cpp */; }; B603F1B01AC8EA4E00A9579C /* TerrainTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B603F1AD1AC8EA4E00A9579C /* TerrainTest.cpp */; }; + B603F1B41AC8FBFB00A9579C /* TerrainTest in Resources */ = {isa = PBXBuildFile; fileRef = B603F1B31AC8FBFB00A9579C /* TerrainTest */; }; + B603F1B51AC8FBFB00A9579C /* TerrainTest in Resources */ = {isa = PBXBuildFile; fileRef = B603F1B31AC8FBFB00A9579C /* TerrainTest */; }; B609E67319C18DAD003D0074 /* BillBoardTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B609E67119C18DAD003D0074 /* BillBoardTest.cpp */; }; B609E67419C18DAD003D0074 /* BillBoardTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B609E67119C18DAD003D0074 /* BillBoardTest.cpp */; }; B6337DF71ABA9B44005AEF24 /* PerformanceParticle3DTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6337DF51ABA9B44005AEF24 /* PerformanceParticle3DTest.cpp */; }; @@ -1756,6 +1758,7 @@ B2507B6A192589AF00FA4972 /* Shaders3D */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Shaders3D; path = "../tests/cpp-tests/Resources/Shaders3D"; sourceTree = ""; }; B603F1AD1AC8EA4E00A9579C /* TerrainTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TerrainTest.cpp; path = TerrainTest/TerrainTest.cpp; sourceTree = ""; }; B603F1AE1AC8EA4E00A9579C /* TerrainTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TerrainTest.h; path = TerrainTest/TerrainTest.h; sourceTree = ""; }; + B603F1B31AC8FBFB00A9579C /* TerrainTest */ = {isa = PBXFileReference; lastKnownFileType = folder; name = TerrainTest; path = "../tests/cpp-tests/Resources/TerrainTest"; sourceTree = ""; }; B609E67119C18DAD003D0074 /* BillBoardTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BillBoardTest.cpp; path = BillBoardTest/BillBoardTest.cpp; sourceTree = ""; }; B609E67219C18DAD003D0074 /* BillBoardTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BillBoardTest.h; path = BillBoardTest/BillBoardTest.h; sourceTree = ""; }; B6337DF51ABA9B44005AEF24 /* PerformanceParticle3DTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceParticle3DTest.cpp; sourceTree = ""; }; @@ -3221,6 +3224,7 @@ 1AC35CA818CED83500F37B72 /* Resources */ = { isa = PBXGroup; children = ( + B603F1B31AC8FBFB00A9579C /* TerrainTest */, B63993301A49359F00B07923 /* Particle3D */, 15B3709219EE5D1000ABE682 /* Manifests */, 3E2BDB0019C5E5D40055CDCD /* background.wav */, @@ -4507,6 +4511,7 @@ 3E92EA851921A7720094CD21 /* Sprite3DTest in Resources */, 1AC35CA318CECF1E00F37B72 /* InfoPlist.strings in Resources */, 1AC35CA418CECF1E00F37B72 /* MainMenu.xib in Resources */, + B603F1B41AC8FBFB00A9579C /* TerrainTest in Resources */, 1AC35CD418CED84500F37B72 /* ccb in Resources */, C08689C118D370C90093E810 /* background.caf in Resources */, 1AC35CE418CED84500F37B72 /* effect1.wav in Resources */, @@ -4552,6 +4557,7 @@ 1AC35C9618CECF1400F37B72 /* Icon-76.png in Resources */, 1AC35C8A18CECF1400F37B72 /* Default@2x.png in Resources */, 1AC35CE318CED84500F37B72 /* effect1.raw in Resources */, + B603F1B51AC8FBFB00A9579C /* TerrainTest in Resources */, 1A221C9D191771E400FD2BE4 /* ccs-res in Resources */, 1AC35C9018CECF1400F37B72 /* Icon-29.png in Resources */, 1AC35D0918CED84500F37B72 /* TileMaps in Resources */, diff --git a/cocos/3d/CCTerrain.cpp b/cocos/3d/CCTerrain.cpp index 729ac3ca72..cc73f526e0 100644 --- a/cocos/3d/CCTerrain.cpp +++ b/cocos/3d/CCTerrain.cpp @@ -3,62 +3,14 @@ USING_NS_CC; #include "renderer/CCGLProgram.h" +#include "renderer/CCGLProgramCache.h" #include "renderer/CCGLProgramState.h" #include "renderer/CCRenderer.h" #include "renderer/CCGLProgramStateCache.h" #include "renderer/ccGLStateCache.h" #include "2d/CCCamera.h" #include -static const char * vertex_shader = "\ - attribute vec4 a_position;\ - attribute vec2 a_texCoord;\ - attribute vec3 a_normal;\ - \n#ifdef GL_ES\n\ - varying mediump vec2 v_texCoord;\ - varying mediump vec3 v_normal;\ - \n#else\n\ - varying vec2 v_texCoord;\ - varying vec3 v_normal;\ - \n#endif\n\ - void main()\ - {\ - gl_Position = CC_MVPMatrix * a_position;\ - v_texCoord = a_texCoord;\ - v_normal = a_normal;\ - }\ - "; -static const char * fragment_shader_RGB_4_DETAIL ="\n#ifdef GL_ES\n\ - precision lowp float;\ - \n#endif\n\ - uniform vec3 u_color;\ - varying vec2 v_texCoord;\ - varying vec3 v_normal;\ - uniform int u_has_alpha;\ - uniform sampler2D u_alphaMap;\ - uniform sampler2D u_texture0;\ - uniform sampler2D u_texture1;\ - uniform sampler2D u_texture2;\ - uniform sampler2D u_texture3;\ - uniform float u_detailSize[4];\ - void main()\ - {\ - vec3 light_direction = vec3(-1,-1,0);\ - float lightFactor = dot(-light_direction,v_normal);\ - if(u_has_alpha<=0)\ - {\ - gl_FragColor = texture2D(u_texture0, v_texCoord)*lightFactor;\ - }else\ - {\ - vec4 blendFactor =texture2D(u_alphaMap,v_texCoord);\ - vec4 color = vec4(0,0,0,0);\ - color = texture2D(u_texture0, v_texCoord*u_detailSize[0])*blendFactor.r +\ - texture2D(u_texture1, v_texCoord*u_detailSize[1])*blendFactor.g + texture2D(u_texture2, v_texCoord*u_detailSize[2])*blendFactor.b;\n\ - float grayFactor =dot(blendFactor.rgb, vec3(1, 1, 1));\ - color +=texture2D(u_texture3, v_texCoord*u_detailSize[3])*(1.0-grayFactor);\ - gl_FragColor = color*lightFactor;\ - }\ - }"; NS_CC_BEGIN Terrain * Terrain::create(TerrainData ¶meter) { @@ -105,7 +57,7 @@ bool Terrain::init() _lodDistance[0]=64; _lodDistance[1]=128; _lodDistance[2]=196; - auto shader = GLProgram::createWithByteArrays(vertex_shader,fragment_shader_RGB_4_DETAIL); + auto shader = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_TERRAIN); auto state = GLProgramState::create(shader); setGLProgramState(state); diff --git a/cocos/renderer/CCGLProgram.cpp b/cocos/renderer/CCGLProgram.cpp index 838450c7bb..f7d3666391 100644 --- a/cocos/renderer/CCGLProgram.cpp +++ b/cocos/renderer/CCGLProgram.cpp @@ -73,6 +73,7 @@ const char* GLProgram::SHADER_3D_SKINPOSITION_NORMAL_TEXTURE = "Shader3DSkinPosi const char* GLProgram::SHADER_3D_PARTICLE_COLOR = "Shader3DParticleColor"; const char* GLProgram::SHADER_3D_PARTICLE_TEXTURE = "Shader3DParticleTexture"; const char* GLProgram::SHADER_3D_SKYBOX = "Shader3DSkybox"; +const char* GLProgram::SHADER_3D_TERRAIN = "Shader3DTerrain"; // uniform names diff --git a/cocos/renderer/CCGLProgram.h b/cocos/renderer/CCGLProgram.h index c95dca151c..58917b7f4c 100644 --- a/cocos/renderer/CCGLProgram.h +++ b/cocos/renderer/CCGLProgram.h @@ -223,6 +223,11 @@ public: */ static const char* SHADER_3D_SKYBOX; + /** + Built in shader for terrain + */ + static const char* SHADER_3D_TERRAIN; + /** end of built shader types. @} diff --git a/cocos/renderer/CCGLProgramCache.cpp b/cocos/renderer/CCGLProgramCache.cpp index 51d85ae171..08e7b336d0 100644 --- a/cocos/renderer/CCGLProgramCache.cpp +++ b/cocos/renderer/CCGLProgramCache.cpp @@ -64,6 +64,7 @@ enum { kShaderType_3DParticleTex, kShaderType_3DParticleColor, kShaderType_3DSkyBox, + kShaderType_3DTerrain, #if CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || defined(WP8_SHADER_COMPILER) kShaderType_PositionColor_noMVP_GrayScale, #endif @@ -250,6 +251,10 @@ void GLProgramCache::loadDefaultGLPrograms() p = new GLProgram(); loadDefaultGLProgram(p, kShaderType_3DSkyBox); _programs.insert(std::make_pair(GLProgram::SHADER_3D_SKYBOX, p)); + + p = new GLProgram(); + loadDefaultGLProgram(p, kShaderType_3DTerrain); + _programs.insert(std::make_pair(GLProgram::SHADER_3D_TERRAIN, p)); } void GLProgramCache::reloadDefaultGLPrograms() @@ -381,6 +386,10 @@ void GLProgramCache::reloadDefaultGLPrograms() p = getGLProgram(GLProgram::SHADER_3D_SKYBOX); p->reset(); loadDefaultGLProgram(p, kShaderType_3DSkyBox); + + p = getGLProgram(GLProgram::SHADER_3D_TERRAIN); + p->reset(); + loadDefaultGLProgram(p, kShaderType_3DTerrain); } void GLProgramCache::loadDefaultGLProgram(GLProgram *p, int type) @@ -475,6 +484,9 @@ void GLProgramCache::loadDefaultGLProgram(GLProgram *p, int type) case kShaderType_3DSkyBox: p->initWithByteArrays(cc3D_Skybox_vert, cc3D_Skybox_frag); break; + case kShaderType_3DTerrain: + p->initWithByteArrays(cc3D_Terrain_vert, cc3D_Terrain_frag); + break; #if CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || defined(WP8_SHADER_COMPILER) case kShaderType_PositionColor_noMVP_GrayScale: p->initWithByteArrays(ccPositionTextureColor_noMVP_vert, ccUIGrayScale_frag); diff --git a/cocos/renderer/ccShader_3D_Terrain.frag b/cocos/renderer/ccShader_3D_Terrain.frag new file mode 100644 index 0000000000..b853800f9f --- /dev/null +++ b/cocos/renderer/ccShader_3D_Terrain.frag @@ -0,0 +1,34 @@ + +const char* cc3D_Terrain_frag = STRINGIFY( +\n#ifdef GL_ES\n +precision lowp float; +\n#endif\n +uniform vec3 u_color; +varying vec2 v_texCoord; +varying vec3 v_normal; +uniform int u_has_alpha; +uniform sampler2D u_alphaMap; +uniform sampler2D u_texture0; +uniform sampler2D u_texture1; +uniform sampler2D u_texture2; +uniform sampler2D u_texture3; +uniform float u_detailSize[4]; +void main() +{ +vec3 light_direction = vec3(-1,-1,0); +float lightFactor = dot(-light_direction,v_normal); +if(u_has_alpha<=0) +{ + gl_FragColor = texture2D(u_texture0, v_texCoord)*lightFactor; +}else +{ + vec4 blendFactor =texture2D(u_alphaMap,v_texCoord); + vec4 color = vec4(0,0,0,0); + color = texture2D(u_texture0, v_texCoord*u_detailSize[0])*blendFactor.r + + texture2D(u_texture1, v_texCoord*u_detailSize[1])*blendFactor.g + texture2D(u_texture2, v_texCoord*u_detailSize[2])*blendFactor.b;\n + float grayFactor =dot(blendFactor.rgb, vec3(1, 1, 1)); + color +=texture2D(u_texture3, v_texCoord*u_detailSize[3])*(1.0-grayFactor); + gl_FragColor = color*lightFactor; +} +} +); diff --git a/cocos/renderer/ccShader_3D_Terrain.vert b/cocos/renderer/ccShader_3D_Terrain.vert new file mode 100644 index 0000000000..19a366b67c --- /dev/null +++ b/cocos/renderer/ccShader_3D_Terrain.vert @@ -0,0 +1,19 @@ + +const char* cc3D_Terrain_vert = STRINGIFY( +attribute vec4 a_position; +attribute vec2 a_texCoord; +attribute vec3 a_normal; +\n#ifdef GL_ES\n +varying mediump vec2 v_texCoord; +varying mediump vec3 v_normal; +\n#else\n +varying vec2 v_texCoord; +varying vec3 v_normal; +\n#endif\n +void main() +{ + gl_Position = CC_MVPMatrix * a_position; + v_texCoord = a_texCoord; + v_normal = a_normal; +} +); \ No newline at end of file diff --git a/cocos/renderer/ccShaders.cpp b/cocos/renderer/ccShaders.cpp index 70fb421ad4..93a775286b 100644 --- a/cocos/renderer/ccShaders.cpp +++ b/cocos/renderer/ccShaders.cpp @@ -84,5 +84,7 @@ NS_CC_BEGIN #include "ccShader_3D_Particle.frag" #include "ccShader_3D_Skybox.vert" #include "ccShader_3D_Skybox.frag" +#include "ccShader_3D_Terrain.vert" +#include "ccShader_3D_Terrain.frag" NS_CC_END diff --git a/cocos/renderer/ccShaders.h b/cocos/renderer/ccShaders.h index 3c7963a483..5b00b180fd 100644 --- a/cocos/renderer/ccShaders.h +++ b/cocos/renderer/ccShaders.h @@ -86,6 +86,8 @@ extern CC_DLL const GLchar * cc3D_Particle_tex_frag; extern CC_DLL const GLchar * cc3D_Particle_color_frag; extern CC_DLL const GLchar * cc3D_Skybox_vert; extern CC_DLL const GLchar * cc3D_Skybox_frag; +extern CC_DLL const GLchar * cc3D_Terrain_vert; +extern CC_DLL const GLchar * cc3D_Terrain_frag; NS_CC_END