support ambient light without normal & optimaze code

This commit is contained in:
yangxiao 2014-09-25 18:32:33 +08:00
parent 8f3f37c2bb
commit ca9eb3d203
3 changed files with 58 additions and 25 deletions

View File

@ -2800,6 +2800,9 @@
B3AF019F1842FBA400A98B85 /* b2MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MotorJoint.h; sourceTree = "<group>"; };
B60C5BD219AC68B10056FBDE /* CCBillBoard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCBillBoard.cpp; sourceTree = "<group>"; };
B60C5BD319AC68B10056FBDE /* CCBillBoard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCBillBoard.h; sourceTree = "<group>"; };
B67C624319D4186F00F11FC6 /* ccShader_3D_ColorNormal.frag */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = ccShader_3D_ColorNormal.frag; sourceTree = "<group>"; };
B67C624419D4186F00F11FC6 /* ccShader_3D_ColorNormalTex.frag */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = ccShader_3D_ColorNormalTex.frag; sourceTree = "<group>"; };
B67C624519D4186F00F11FC6 /* ccShader_3D_PositionNormalTex.vert */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = ccShader_3D_PositionNormalTex.vert; sourceTree = "<group>"; };
B6C039DB19C95E03007207DC /* CCLight3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCLight3D.cpp; sourceTree = "<group>"; };
B6C039DC19C95E03007207DC /* CCLight3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLight3D.h; sourceTree = "<group>"; };
ED9C6A9218599AD8000A5232 /* CCNodeGrid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = CCNodeGrid.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
@ -4484,6 +4487,9 @@
5034CA5D191D591900CE6051 /* shaders */ = {
isa = PBXGroup;
children = (
B67C624319D4186F00F11FC6 /* ccShader_3D_ColorNormal.frag */,
B67C624419D4186F00F11FC6 /* ccShader_3D_ColorNormalTex.frag */,
B67C624519D4186F00F11FC6 /* ccShader_3D_PositionNormalTex.vert */,
B29594AF1926D5D9003EEF37 /* ccShader_3D_Color.frag */,
B29594B01926D5D9003EEF37 /* ccShader_3D_ColorTex.frag */,
B29594B11926D5D9003EEF37 /* ccShader_3D_PositionTex.vert */,

View File

@ -526,10 +526,12 @@ void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
//check light and determine the shader used
const auto& lights = Director::getInstance()->getRunningScene()->getLights();
bool usingLight = false;
Color4F ambient(0.f, 0.f, 0.f, 1.f);
for (const auto light : lights) {
usingLight = ((unsigned short)light->getLightFlag() & _lightMask) > 0;
if (usingLight)
break;
if (((unsigned short)light->getLightFlag() & _lightMask) > 0)
{
usingLight = true;
}
}
if (usingLight != _shaderUsingLight)
genGLProgramState();

View File

@ -252,7 +252,8 @@ void MeshCommand::batchDraw()
}
setLightUniforms();
if (Director::getInstance()->getRunningScene()->getLights().size() > 0)
setLightUniforms();
_glProgramState->applyGLProgram(_mv);
_glProgramState->applyUniforms();
@ -294,7 +295,8 @@ void MeshCommand::execute()
}
setLightUniforms();
if (Director::getInstance()->getRunningScene()->getLights().size() > 0)
setLightUniforms();
_glProgramState->apply(_mv);
@ -351,24 +353,22 @@ void MeshCommand::setLightUniforms()
int maxDirLight = conf->getMaxSupportDirLightInShader();
int maxPointLight = conf->getMaxSupportPointLightInShader();
int maxSpotLight = conf->getMaxSupportSpotLightInShader();
if (scene)
auto &lights = scene->getLights();
if (_glProgramState->getVertexAttribsFlags() & GLProgram::VERTEX_ATTRIB_NORMAL)
{
auto &lights = scene->getLights();
GLint enabledDirLightNum = 0;
GLint enabledPointLightNum = 0;
GLint enabledSpotLightNum = 0;
Vec3 ambientColor;
for (unsigned int i = 0; i < lights.size(); ++i)
for (const auto& light : lights)
{
BaseLight3D *light = lights[i];
bool useLight = light->isEnabled();
useLight = useLight && ((unsigned short)light->getLightFlag() & _lightMask);
bool useLight = light->isEnabled() && ((unsigned short)light->getLightFlag() & _lightMask);
if (useLight)
{
float intensity = light->getIntensity();
switch (light->getLightType())
{
case LightType::DIRECTIONAL:
case LightType::DIRECTIONAL:
{
CCASSERT(enabledDirLightNum < maxDirLight, "");
DirectionLight3D *dirLight = static_cast<DirectionLight3D *>(light);
@ -379,8 +379,8 @@ void MeshCommand::setLightUniforms()
_glProgramState->setUniformVec3(s_dirLightUniformNames[enabledDirLightNum].dir, dir);
++enabledDirLightNum;
}
break;
case LightType::POINT:
break;
case LightType::POINT:
{
CCASSERT(enabledPointLightNum < maxPointLight, "");
PointLight3D *pointLight = static_cast<PointLight3D *>(light);
@ -391,8 +391,8 @@ void MeshCommand::setLightUniforms()
_glProgramState->setUniformFloat(s_pointLightUniformNames[enabledPointLightNum].rangeInverse, 1.0f / pointLight->getRange());
++enabledPointLightNum;
}
break;
case LightType::SPOT:
break;
case LightType::SPOT:
{
CCASSERT(enabledSpotLightNum < maxSpotLight, "");
SpotLight3D *spotLight = static_cast<SpotLight3D *>(light);
@ -408,33 +408,33 @@ void MeshCommand::setLightUniforms()
_glProgramState->setUniformFloat(s_spotLightUniformNames[enabledSpotLightNum].rangeInverse, 1.0f / spotLight->getRange());
++enabledSpotLightNum;
}
break;
case LightType::AMBIENT:
break;
case LightType::AMBIENT:
{
AmbientLight3D *ambLight = static_cast<AmbientLight3D *>(light);
const Color3B &col = ambLight->getDisplayedColor();
ambientColor += Vec3(col.r / 255.0f * intensity, col.g / 255.0f * intensity, col.b / 255.0f * intensity);
}
break;
default:
break;
break;
default:
break;
}
}
}
for (unsigned short i = enabledDirLightNum; i < maxDirLight; ++i)
{
_glProgramState->setUniformVec3(s_dirLightUniformNames[i].color, Vec3::ZERO);
_glProgramState->setUniformVec3(s_dirLightUniformNames[i].dir, Vec3::ZERO);
}
for (unsigned short i = enabledPointLightNum; i < maxPointLight; ++i)
{
_glProgramState->setUniformVec3(s_pointLightUniformNames[i].color, Vec3::ZERO);
_glProgramState->setUniformVec3(s_pointLightUniformNames[i].position, Vec3::ZERO);
_glProgramState->setUniformFloat(s_pointLightUniformNames[i].rangeInverse, 0.0f);
}
for (unsigned short i = enabledSpotLightNum; i < maxSpotLight; ++i)
{
_glProgramState->setUniformVec3(s_spotLightUniformNames[i].color, Vec3::ZERO);
@ -444,9 +444,34 @@ void MeshCommand::setLightUniforms()
_glProgramState->setUniformFloat(s_spotLightUniformNames[i].outerAngleCos, 0.0f);
_glProgramState->setUniformFloat(s_spotLightUniformNames[i].rangeInverse, 0.0f);
}
_glProgramState->setUniformVec3("u_AmbientLightSourceColor", ambientColor);
}
else // normal does not exist
{
Vec3 ambient(0.0f, 0.0f, 0.0f);
bool hasAmbient;
for (const auto& light : lights)
{
if (light->getLightType() == LightType::AMBIENT)
{
bool useLight = light->isEnabled() && ((unsigned short)light->getLightFlag() & _lightMask);
if (useLight)
{
hasAmbient = true;
const Color3B &col = light->getDisplayedColor();
ambient.x += col.r * light->getIntensity();
ambient.y += col.g * light->getIntensity();
ambient.z += col.b * light->getIntensity();
}
}
}
if (hasAmbient)
{
ambient.x /= 255.f; ambient.y /= 255.f; ambient.z /= 255.f;
}
_glProgramState->setUniformVec4("u_color", Vec4(_displayColor.x * ambient.x, _displayColor.y * ambient.y, _displayColor.z * ambient.z, _displayColor.w));
}
}
void MeshCommand::setLightUniformNames()