diff --git a/cocos/renderer/CCGLProgram.cpp b/cocos/renderer/CCGLProgram.cpp index 69f4ebbcd2..00322b2d26 100644 --- a/cocos/renderer/CCGLProgram.cpp +++ b/cocos/renderer/CCGLProgram.cpp @@ -414,20 +414,20 @@ bool GLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* source } GLchar lightStruct[] = { - "#define MAX_LIGHT 6 \n" + "#define CC_MAX_LIGHT 6 \n" "struct LightSource \n" "{ \n" " vec4 color; \n" " vec3 position; \n" " vec3 direction; \n" " float range; \n" + " float range2; \n" " float innerAngle; \n" " float outerAngle; \n" " float type; \n" " float use; \n" - " float none; \n" "}; \n" - "uniform LightSource CC_LightSource[MAX_LIGHT];\n" + "uniform LightSource CC_LightSource[CC_MAX_LIGHT];\n" }; const GLchar *sources[] = { @@ -905,8 +905,8 @@ void GLProgram::setUniformsForBuiltins(const Mat4 &matrixMV) mvInverse.transpose(); GLfloat normalMat[9]; normalMat[0] = mvInverse.m[0];normalMat[1] = mvInverse.m[1];normalMat[2] = mvInverse.m[2]; - normalMat[3] = mvInverse.m[3];normalMat[4] = mvInverse.m[4];normalMat[5] = mvInverse.m[5]; - normalMat[6] = mvInverse.m[6];normalMat[7] = mvInverse.m[7];normalMat[8] = mvInverse.m[8]; + normalMat[3] = mvInverse.m[4];normalMat[4] = mvInverse.m[5];normalMat[5] = mvInverse.m[6]; + normalMat[6] = mvInverse.m[8];normalMat[7] = mvInverse.m[9];normalMat[8] = mvInverse.m[10]; setUniformLocationWithMatrix3fv(_builtInUniforms[UNIFORM_NORMAL_MATRIX], normalMat, 1); } @@ -947,11 +947,11 @@ void GLProgram::setUniformsForBuiltins(const Mat4 &matrixMV) lightSources[4 + idx] = pos.x;lightSources[5 + idx] = pos.y;lightSources[6 + idx] = pos.z; lightSources[7 + idx] = dir.x;lightSources[8 + idx] = dir.y;lightSources[9 + idx] = dir.z; lightSources[10 + idx] = iter->getRange(); - lightSources[11 + idx] = iter->getInnerAngle(); - lightSources[12 + idx] = iter->getOuterAngle(); - lightSources[13 + idx] = static_cast(iter->getLightType()); - lightSources[14 + idx] = static_cast(iter->getEnabled()); - lightSources[15 + idx] = -1; + lightSources[11 + idx] = iter->getRange() * iter->getRange(); + lightSources[12 + idx] = iter->getInnerAngle(); + lightSources[13 + idx] = iter->getOuterAngle(); + lightSources[14 + idx] = static_cast(iter->getLightType()); + lightSources[15 + idx] = static_cast(iter->getEnabled()); idx += 16; } diff --git a/cocos/renderer/ccShader_3D_Color.frag b/cocos/renderer/ccShader_3D_Color.frag index d5f5913f97..f286667fdd 100644 --- a/cocos/renderer/ccShader_3D_Color.frag +++ b/cocos/renderer/ccShader_3D_Color.frag @@ -10,6 +10,6 @@ uniform vec4 u_color; void main(void) { - gl_FragColor = u_color; + gl_FragColor = u_color; } ); diff --git a/cocos/renderer/ccShader_3D_ColorTex.frag b/cocos/renderer/ccShader_3D_ColorTex.frag index d7465c9013..1819bea738 100644 --- a/cocos/renderer/ccShader_3D_ColorTex.frag +++ b/cocos/renderer/ccShader_3D_ColorTex.frag @@ -3,13 +3,18 @@ const char* cc3D_ColorTex_frag = STRINGIFY( \n#ifdef GL_ES\n varying mediump vec2 TextureCoordOut; +varying mediump vec4 LightIntensityOut; \n#else\n varying vec2 TextureCoordOut; +varying vec4 LightIntensityOut; \n#endif\n uniform vec4 u_color; void main(void) -{ - gl_FragColor = texture2D(CC_Texture0, TextureCoordOut) * u_color; +{ + if (LightIntensityOut.w == 0.0) + gl_FragColor = texture2D(CC_Texture0, TextureCoordOut) * u_color; + else + gl_FragColor = texture2D(CC_Texture0, TextureCoordOut) * u_color * LightIntensityOut; } ); diff --git a/cocos/renderer/ccShader_3D_PositionTex.vert b/cocos/renderer/ccShader_3D_PositionTex.vert index 92a359922b..536541f53e 100644 --- a/cocos/renderer/ccShader_3D_PositionTex.vert +++ b/cocos/renderer/ccShader_3D_PositionTex.vert @@ -3,14 +3,39 @@ const char* cc3D_PositionTex_vert = STRINGIFY( attribute vec4 a_position; attribute vec2 a_texCoord; - +attribute vec3 a_normal; varying vec2 TextureCoordOut; +varying vec4 LightIntensityOut; + +vec4 PointLight(int n, vec4 ePosition, vec3 eNormal) +{ + vec4 intensity = vec4(0.0); + if (0.0 < CC_LightSource[n].use) + { + vec4 p = vec4(CC_LightSource[n].position, 1.0) * CC_MVMatrix; + p -= ePosition; + intensity.xyz = CC_LightSource[n].color * max(0.0, dot(normalize(p.xyz), eNormal)); + intensity.w = 1.0; + } + + return intensity; +} void main(void) { - gl_Position = CC_MVPMatrix * a_position; + vec4 ePosition = CC_MVMatrix * a_position; + vec3 eNormal = CC_NormalMatrix * a_normal; + + vec4 intensity = vec4(0.0); + for (int i = 0; i < CC_MAX_LIGHT; ++i) + { + intensity += PointLight(i, ePosition, eNormal); + } + LightIntensityOut = intensity; + TextureCoordOut = a_texCoord; TextureCoordOut.y = 1.0 - TextureCoordOut.y; + gl_Position = CC_PMatrix * ePosition; } ); @@ -22,14 +47,31 @@ attribute vec4 a_blendIndex; attribute vec2 a_texCoord; +attribute vec3 a_normal; + const int SKINNING_JOINT_COUNT = 60; // Uniforms uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3]; // Varyings varying vec2 TextureCoordOut; +varying vec4 LightIntensityOut; -vec4 getPosition() +vec4 PointLight(int n, vec4 ePosition, vec3 eNormal) +{ + vec4 intensity = vec4(0.0); + if (0.0 < CC_LightSource[n].use) + { + vec4 p = vec4(CC_LightSource[n].position, 1.0) * CC_MVMatrix; + p -= ePosition; + intensity.xyz = CC_LightSource[n].color * max(0.0, dot(normalize(p.xyz), eNormal)); + intensity.w = 1.0; + } + + return intensity; +} + +void getPositionAndNormal(out vec4 position, out vec3 normal) { float blendWeight = a_blendWeight[0]; @@ -69,23 +111,36 @@ vec4 getPosition() } - vec4 _skinnedPosition; - vec4 postion = vec4(a_position, 1.0); - _skinnedPosition.x = dot(postion, matrixPalette1); - _skinnedPosition.y = dot(postion, matrixPalette2); - _skinnedPosition.z = dot(postion, matrixPalette3); - _skinnedPosition.w = postion.w; - - return _skinnedPosition; + vec4 p = vec4(a_position, 1.0); + position.x = dot(p, matrixPalette1); + position.y = dot(p, matrixPalette2); + position.z = dot(p, matrixPalette3); + position.w = p.w; + + vec4 n = vec4(a_normal, 0.0); + normal.x = dot(n, matrixPalette1); + normal.y = dot(n, matrixPalette2); + normal.z = dot(n, matrixPalette3); } void main() { - vec4 position = getPosition(); - gl_Position = CC_MVPMatrix * position; - + vec4 position; + vec3 normal; + getPositionAndNormal(position, normal); + + vec4 ePosition = CC_MVMatrix * position; + vec3 eNormal = CC_NormalMatrix * normal; + vec4 intensity = vec4(0.0); + for (int i = 0; i < CC_MAX_LIGHT; ++i) + { + intensity += PointLight(i, ePosition, eNormal); + } + LightIntensityOut = intensity; + TextureCoordOut = a_texCoord; TextureCoordOut.y = 1.0 - TextureCoordOut.y; + gl_Position = CC_PMatrix * ePosition; } ); \ No newline at end of file diff --git a/tests/cpp-tests/Classes/LightTest/LightTestDemo.cpp b/tests/cpp-tests/Classes/LightTest/LightTestDemo.cpp new file mode 100644 index 0000000000..124bce0825 --- /dev/null +++ b/tests/cpp-tests/Classes/LightTest/LightTestDemo.cpp @@ -0,0 +1,134 @@ +#include "LightTestDemo.h" +#include "3d/CCLight.h" + +static int sceneIdx = -1; + + +static std::function createFunctions[] = +{ + CL(LightTestDemo) +}; + +#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) + +static Layer* nextSpriteTestAction() +{ + sceneIdx++; + sceneIdx = sceneIdx % MAX_LAYER; + + auto layer = (createFunctions[sceneIdx])(); + return layer; +} + +static Layer* backSpriteTestAction() +{ + sceneIdx--; + int total = MAX_LAYER; + if( sceneIdx < 0 ) + sceneIdx += total; + + auto layer = (createFunctions[sceneIdx])(); + return layer; +} + +static Layer* restartSpriteTestAction() +{ + auto layer = (createFunctions[sceneIdx])(); + return layer; +} + +LightTestDemo::LightTestDemo() +{ + addSprite(); + addLights(); +} + + +LightTestDemo::~LightTestDemo() +{ +} + +std::string LightTestDemo::title() const +{ + return "Point Light"; +} + +std::string LightTestDemo::subtitle() const +{ + return ""; +} + +void LightTestDemo::restartCallback( Ref* sender ) +{ + auto s = new LightTestScene(); + s->addChild(restartSpriteTestAction()); + Director::getInstance()->replaceScene(s); + s->release(); +} + +void LightTestDemo::nextCallback( Ref* sender ) +{ + auto s = new LightTestScene(); + s->addChild( nextSpriteTestAction() ); + Director::getInstance()->replaceScene(s); + s->release(); +} + +void LightTestDemo::backCallback( Ref* sender ) +{ + auto s = new LightTestScene(); + s->addChild( backSpriteTestAction() ); + Director::getInstance()->replaceScene(s); + s->release(); +} + +void LightTestDemo::addSprite() +{ + auto s = Director::getInstance()->getWinSize(); + std::string fileName = "Sprite3DTest/orc.c3b"; + auto sprite = Sprite3D::create(fileName); + sprite->setScale(5.0f); + sprite->setRotation3D(Vec3(0,180,0)); + sprite->setPosition(Vec2(s.width/2, s.height/2)); + addChild(sprite); + + auto sp = Sprite3D::create("Sprite3DTest/axe.c3b"); + sprite->getAttachNode("Bip001 R Hand")->addChild(sp); + + auto animation = Animation3D::create(fileName); + if (animation) + { + auto animate = Animate3D::create(animation); + + sprite->runAction(RepeatForever::create(animate)); + } +} + +void LightTestDemo::onEnter() +{ + BaseTest::onEnter(); +} + +void LightTestDemo::onExit() +{ + BaseTest::onExit(); +} + +void LightTestDemo::addLights() +{ + auto s = Director::getInstance()->getWinSize(); + auto light1 = Light3D::Create(Light3D::POINT); + light1->setEnabled(true); + light1->setPosition(Vec2(s.width/2, s.height)); + light1->setColor(Color3B(255, 255, 255)); + + addChild(light1); +} + +void LightTestScene::runThisTest() +{ + auto layer = nextSpriteTestAction(); + addChild(layer); + + Director::getInstance()->replaceScene(this); +} diff --git a/tests/cpp-tests/Classes/LightTest/LightTestDemo.h b/tests/cpp-tests/Classes/LightTest/LightTestDemo.h new file mode 100644 index 0000000000..f98ea4dee4 --- /dev/null +++ b/tests/cpp-tests/Classes/LightTest/LightTestDemo.h @@ -0,0 +1,62 @@ +/**************************************************************************** + Copyright (c) 2013 cocos2d-x.org + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +#ifndef _LIGHT_TEST_H_ +#define _LIGHT_TEST_H_ + +#include "../testBasic.h" +#include "../BaseTest.h" + +class LightTestDemo : public BaseTest +{ +public: + CREATE_FUNC(LightTestDemo); + LightTestDemo(); + virtual ~LightTestDemo(); + + virtual std::string title() const; + virtual std::string subtitle() const; + + virtual void restartCallback(Ref* sender); + virtual void nextCallback(Ref* sender); + virtual void backCallback(Ref* sender); + + virtual void onEnter() override; + virtual void onExit() override; + +private: + + void addSprite(); + void addLights(); +}; + + +class LightTestScene : public TestScene +{ +public: + virtual void runThisTest(); +}; + +#endif + diff --git a/tests/cpp-tests/Classes/controller.cpp b/tests/cpp-tests/Classes/controller.cpp index 5d7c834f06..2c95ff271b 100644 --- a/tests/cpp-tests/Classes/controller.cpp +++ b/tests/cpp-tests/Classes/controller.cpp @@ -77,6 +77,7 @@ Controller g_aTestNames[] = { { "Node: Sprite", [](){return new SpriteTestScene(); } }, { "Node: Sprite3D", [](){ return new Sprite3DTestScene(); }}, { "Node: Camera 3D Test", [](){ return new Camera3DTestScene(); }}, + { "Node: Light Test", [](){ return new LightTestScene(); }}, { "Node: TileMap", [](){return new TileMapTestScene(); } }, #if CC_TARGET_PLATFORM != CC_PLATFORM_WP8 { "Node: FastTileMap", [](){return new TileMapTestSceneNew(); } }, diff --git a/tests/cpp-tests/Classes/tests.h b/tests/cpp-tests/Classes/tests.h index 5f0f139b23..029af6944a 100644 --- a/tests/cpp-tests/Classes/tests.h +++ b/tests/cpp-tests/Classes/tests.h @@ -70,5 +70,6 @@ #include "Sprite3DTest/Sprite3DTest.h" #include "Camera3DTest/Camera3DTest.h" +#include "LightTest/LightTestDemo.h" #endif diff --git a/tests/cpp-tests/proj.win32/cpp-tests.vcxproj b/tests/cpp-tests/proj.win32/cpp-tests.vcxproj index 394aa71ab2..6603e301b4 100644 --- a/tests/cpp-tests/proj.win32/cpp-tests.vcxproj +++ b/tests/cpp-tests/proj.win32/cpp-tests.vcxproj @@ -171,6 +171,7 @@ + @@ -358,6 +359,7 @@ + diff --git a/tests/cpp-tests/proj.win32/cpp-tests.vcxproj.filters b/tests/cpp-tests/proj.win32/cpp-tests.vcxproj.filters index eee082ff8a..f3b0da20d6 100644 --- a/tests/cpp-tests/proj.win32/cpp-tests.vcxproj.filters +++ b/tests/cpp-tests/proj.win32/cpp-tests.vcxproj.filters @@ -331,6 +331,9 @@ {7f85be1c-98c5-4412-afc5-6f39ae1452a7} + + {7cfec1ae-5766-4913-8f3c-3b4ad4745ce4} + @@ -864,6 +867,9 @@ Classes\Camera3DTest + + Classes\LightTest + @@ -1595,5 +1601,8 @@ Classes\Camera3DTest + + Classes\LightTest + \ No newline at end of file