GLProgram Added Light Shader

GLProgram Added Normal Matrix
This commit is contained in:
songchengjiang 2014-08-15 19:15:14 +08:00
parent 1e9c02dfa3
commit 2b1efc59cb
7 changed files with 269 additions and 141 deletions

View File

@ -203,12 +203,12 @@ void Scene::onProjectionChanged(EventCustom* event)
void Scene::setAmbientColor( const Color4F &color ) void Scene::setAmbientColor( const Color4F &color )
{ {
_ambientColor = color; _ambientColor = color;
} }
const Color4F& Scene::getAmbientColor() const const Color4F& Scene::getAmbientColor() const
{ {
return _ambientColor; return _ambientColor;
} }
#endif #endif

View File

@ -35,7 +35,7 @@ THE SOFTWARE.
NS_CC_BEGIN NS_CC_BEGIN
class Camera; class Camera;
class Light; class Light3D;
/** /**
* @addtogroup scene * @addtogroup scene
* @{ * @{
@ -69,21 +69,21 @@ public:
/** get all cameras */ /** get all cameras */
const std::vector<Camera*>& getCameras() const { return _cameras; } const std::vector<Camera*>& getCameras() const { return _cameras; }
const std::vector<Light*>& getLights() const { return _lights; } const std::vector<Light3D*>& getLights() const { return _lights; }
/** /**
* Sets the ambient color of scene. * Sets the ambient color of scene.
* *
* @param color The ambient color of scene. * @param color The ambient color of scene.
*/ */
void setAmbientColor(const Color4F &color); void setAmbientColor(const Color4F &color);
/** /**
* Returns the ambient color of scene. * Returns the ambient color of scene.
* *
* @return The ambient color of scene. * @return The ambient color of scene.
*/ */
const Color4F& getAmbientColor() const; const Color4F& getAmbientColor() const;
CC_CONSTRUCTOR_ACCESS: CC_CONSTRUCTOR_ACCESS:
Scene(); Scene();
@ -100,14 +100,14 @@ protected:
friend class SpriteBatchNode; friend class SpriteBatchNode;
friend class Camera; friend class Camera;
friend class Director; friend class Director;
friend class Light; friend class Light3D;
std::vector<Camera*> _cameras; //weak ref to Camera std::vector<Camera*> _cameras; //weak ref to Camera
Camera* _defaultCamera; //weak ref, default camera created by scene, _cameras[0], Caution that the default camera can not be added to _cameras before onEnter is called Camera* _defaultCamera; //weak ref, default camera created by scene, _cameras[0], Caution that the default camera can not be added to _cameras before onEnter is called
EventListenerCustom* _event; EventListenerCustom* _event;
std::vector<Light *> _lights; std::vector<Light3D *> _lights;
Color4F _ambientColor; Color4F _ambientColor;
private: private:
CC_DISALLOW_COPY_AND_ASSIGN(Scene); CC_DISALLOW_COPY_AND_ASSIGN(Scene);

View File

@ -3,93 +3,111 @@
NS_CC_BEGIN NS_CC_BEGIN
Light::Light() Light3D::Light3D()
: _range(0.0f) : _isEnabled(false)
, _range(0.0f)
, _innerAngle(0.0f) , _innerAngle(0.0f)
, _outerAngle(0.0f) , _outerAngle(0.0f)
{ {
} }
Light::~Light() Light3D::~Light3D()
{ {
} }
Light* Light::Create( LightType lightType ) Light3D* Light3D::Create( LightType lightType )
{ {
Light *light = new Light; Light3D *light = new Light3D;
light->setLightType(lightType); light->setLightType(lightType);
light->autorelease(); light->autorelease();
return light; return light;
} }
void Light::setLightType( LightType lightType ) void Light3D::setLightType( LightType lightType )
{ {
_lightType = lightType; _lightType = lightType;
} }
void Light::setRange( float range )
Light3D::LightType Light3D::getLightType()
{ {
_range = range; return _lightType;
} }
float Light::getRange() void Light3D::setEnabled( bool isEnabled )
{ {
return _range; _isEnabled = isEnabled;
} }
void Light::setDirection( const Vec3 &dir ) bool Light3D::getEnabled()
{ {
_dir = dir; return _isEnabled;
} }
const Vec3& Light::getDirection() const
void Light3D::setRange( float range )
{ {
return _dir; _range = range;
} }
void Light::setInnerAngle( float angle ) float Light3D::getRange()
{ {
_innerAngle = angle; return _range;
} }
float Light::getInnerAngle() void Light3D::setDirection( const Vec3 &dir )
{ {
return _innerAngle; _dir = dir;
} }
void Light::setOuterAngle( float angle ) const Vec3& Light3D::getDirection() const
{ {
_outerAngle = angle; return _dir;
} }
float Light::getOuterAngle() void Light3D::setInnerAngle( float angle )
{ {
return _outerAngle; _innerAngle = angle;
} }
void Light::onEnter() float Light3D::getInnerAngle()
{ {
auto scene = getScene(); return _innerAngle;
if (scene)
{
auto lights = scene->_lights;
auto iter = std::find(lights.begin(), lights.end(), this);
if (iter == lights.end())
lights.push_back(this);
}
} }
void Light::onExit() void Light3D::setOuterAngle( float angle )
{ {
auto scene = getScene(); _outerAngle = angle;
if (scene) }
{
auto lights = scene->_lights; float Light3D::getOuterAngle()
auto iter = std::find(lights.begin(), lights.end(), this); {
if (iter != lights.end()) return _outerAngle;
lights.erase(iter); }
}
void Light3D::onEnter()
{
auto scene = getScene();
if (scene)
{
auto lights = scene->_lights;
auto iter = std::find(lights.begin(), lights.end(), this);
if (iter == lights.end())
lights.push_back(this);
}
}
void Light3D::onExit()
{
auto scene = getScene();
if (scene)
{
auto lights = scene->_lights;
auto iter = std::find(lights.begin(), lights.end(), this);
if (iter != lights.end())
lights.erase(iter);
}
} }
NS_CC_END NS_CC_END

View File

@ -29,104 +29,115 @@
NS_CC_BEGIN NS_CC_BEGIN
class CC_DLL Light : public Node class CC_DLL Light3D : public Node
{ {
public: public:
enum class LightType enum LightType
{ {
DIRECTIONAL, DIRECTIONAL = 0,
POINT, POINT = 1,
SPOT SPOT = 2
}; };
/** /**
* Create light according to type. * Create light according to type.
*/ */
static Light* Create(LightType lightType); static Light3D* Create(LightType lightType);
//override //override
virtual void onEnter() override; virtual void onEnter() override;
virtual void onExit() override; virtual void onExit() override;
/** /**
* Sets light type. * Sets light type.
*/ */
void setLightType(LightType lightType); void setLightType(LightType lightType);
/** /**
* Gets light type. * Gets light type.
*/ */
LightType getLightType(); LightType getLightType();
/** /**
* Sets light enabled.
*/
void setEnabled(bool isEnabled);
/**
* Gets light enabled.
*/
bool getEnabled();
/**
* Sets the range of point or spot light. * Sets the range of point or spot light.
* *
* @param range The range of point or spot light. * @param range The range of point or spot light.
*/ */
void setRange(float range); void setRange(float range);
/** /**
* Returns the range of point or spot light. * Returns the range of point or spot light.
* *
* @return The range of the point or spot light. * @return The range of the point or spot light.
*/ */
float getRange(); float getRange();
/** /**
* Sets the Direction of Directional light. * Sets the Direction of Directional light.
* *
* @param dir The Direction of the Directional light. * @param dir The Direction of the Directional light.
*/ */
void setDirection(const Vec3 &dir); void setDirection(const Vec3 &dir);
/** /**
* Returns the Direction of Directional light. * Returns the Direction of Directional light.
* *
* @return dir Direction of the Directional light. * @return dir Direction of the Directional light.
*/ */
const Vec3& getDirection() const; const Vec3& getDirection() const;
/** /**
* Sets the inner angle of a spot light (in radians). * Sets the inner angle of a spot light (in radians).
* *
* @param angle The angle of spot light (in radians). * @param angle The angle of spot light (in radians).
*/ */
void setInnerAngle(float angle); void setInnerAngle(float angle);
/** /**
* Returns the inner angle the spot light (in radians). * Returns the inner angle the spot light (in radians).
* *
* @return The inner angle of the spot light (in radians). * @return The inner angle of the spot light (in radians).
*/ */
float getInnerAngle(); float getInnerAngle();
/** /**
* Sets the outer angle of a spot light (in radians). * Sets the outer angle of a spot light (in radians).
* *
* @param outerAngle The angle of spot light (in radians). * @param outerAngle The angle of spot light (in radians).
*/ */
void setOuterAngle(float angle); void setOuterAngle(float angle);
/** /**
* Returns the outer angle of the spot light (in radians). * Returns the outer angle of the spot light (in radians).
* *
* @return The outer angle of the spot light (in radians). * @return The outer angle of the spot light (in radians).
*/ */
float getOuterAngle(); float getOuterAngle();
CC_CONSTRUCTOR_ACCESS: CC_CONSTRUCTOR_ACCESS:
Light(); Light3D();
virtual ~Light(); virtual ~Light3D();
protected: protected:
LightType _lightType; LightType _lightType;
Vec3 _dir; bool _isEnabled;
float _range; Vec3 _dir;
float _innerAngle; float _range;
float _outerAngle; float _innerAngle;
float _outerAngle;
}; };
NS_CC_END NS_CC_END

View File

@ -32,6 +32,7 @@ THE SOFTWARE.
#include <alloca.h> #include <alloca.h>
#endif #endif
#include "3d/CCLight.h"
#include "base/CCDirector.h" #include "base/CCDirector.h"
#include "base/ccMacros.h" #include "base/ccMacros.h"
#include "base/uthash.h" #include "base/uthash.h"
@ -45,6 +46,8 @@ THE SOFTWARE.
#include "CCPrecompiledShaders.h" #include "CCPrecompiledShaders.h"
#endif #endif
#define CC_MAX_LIGHT_NUM 6
NS_CC_BEGIN NS_CC_BEGIN
typedef struct _hashUniformEntry typedef struct _hashUniformEntry
@ -77,9 +80,11 @@ const char* GLProgram::SHADER_3D_SKINPOSITION_TEXTURE = "Shader3DSkinPositionTex
// uniform names // uniform names
const char* GLProgram::UNIFORM_NAME_LIGHT_SOURCE = "CC_LightSource";
const char* GLProgram::UNIFORM_NAME_P_MATRIX = "CC_PMatrix"; const char* GLProgram::UNIFORM_NAME_P_MATRIX = "CC_PMatrix";
const char* GLProgram::UNIFORM_NAME_MV_MATRIX = "CC_MVMatrix"; const char* GLProgram::UNIFORM_NAME_MV_MATRIX = "CC_MVMatrix";
const char* GLProgram::UNIFORM_NAME_MVP_MATRIX = "CC_MVPMatrix"; const char* GLProgram::UNIFORM_NAME_MVP_MATRIX = "CC_MVPMatrix";
const char* GLProgram::UNIFORM_NAME_NORMAL_MATRIX = "CC_NormalMatrix";
const char* GLProgram::UNIFORM_NAME_TIME = "CC_Time"; const char* GLProgram::UNIFORM_NAME_TIME = "CC_Time";
const char* GLProgram::UNIFORM_NAME_SIN_TIME = "CC_SinTime"; const char* GLProgram::UNIFORM_NAME_SIN_TIME = "CC_SinTime";
const char* GLProgram::UNIFORM_NAME_COS_TIME = "CC_CosTime"; const char* GLProgram::UNIFORM_NAME_COS_TIME = "CC_CosTime";
@ -295,56 +300,56 @@ void GLProgram::parseVertexAttribs()
{ {
_vertexAttribs.clear(); _vertexAttribs.clear();
// Query and store vertex attribute meta-data from the program. // Query and store vertex attribute meta-data from the program.
GLint activeAttributes; GLint activeAttributes;
GLint length; GLint length;
glGetProgramiv(_program, GL_ACTIVE_ATTRIBUTES, &activeAttributes); glGetProgramiv(_program, GL_ACTIVE_ATTRIBUTES, &activeAttributes);
if(activeAttributes > 0) if(activeAttributes > 0)
{ {
VertexAttrib attribute; VertexAttrib attribute;
glGetProgramiv(_program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &length); glGetProgramiv(_program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &length);
if(length > 0) if(length > 0)
{ {
GLchar* attribName = (GLchar*) alloca(length + 1); GLchar* attribName = (GLchar*) alloca(length + 1);
for(int i = 0; i < activeAttributes; ++i) for(int i = 0; i < activeAttributes; ++i)
{ {
// Query attribute info. // Query attribute info.
glGetActiveAttrib(_program, i, length, nullptr, &attribute.size, &attribute.type, attribName); glGetActiveAttrib(_program, i, length, nullptr, &attribute.size, &attribute.type, attribName);
attribName[length] = '\0'; attribName[length] = '\0';
attribute.name = std::string(attribName); attribute.name = std::string(attribName);
// Query the pre-assigned attribute location // Query the pre-assigned attribute location
attribute.index = glGetAttribLocation(_program, attribName); attribute.index = glGetAttribLocation(_program, attribName);
_vertexAttribs[attribute.name] = attribute; _vertexAttribs[attribute.name] = attribute;
} }
} }
} }
} }
void GLProgram::parseUniforms() void GLProgram::parseUniforms()
{ {
_userUniforms.clear(); _userUniforms.clear();
// Query and store uniforms from the program. // Query and store uniforms from the program.
GLint activeUniforms; GLint activeUniforms;
glGetProgramiv(_program, GL_ACTIVE_UNIFORMS, &activeUniforms); glGetProgramiv(_program, GL_ACTIVE_UNIFORMS, &activeUniforms);
if(activeUniforms > 0) if(activeUniforms > 0)
{ {
GLint length; GLint length;
glGetProgramiv(_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &length); glGetProgramiv(_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &length);
if(length > 0) if(length > 0)
{ {
Uniform uniform; Uniform uniform;
GLchar* uniformName = (GLchar*)alloca(length + 1); GLchar* uniformName = (GLchar*)alloca(length + 1);
for(int i = 0; i < activeUniforms; ++i) for(int i = 0; i < activeUniforms; ++i)
{ {
// Query uniform info. // Query uniform info.
glGetActiveUniform(_program, i, length, nullptr, &uniform.size, &uniform.type, uniformName); glGetActiveUniform(_program, i, length, nullptr, &uniform.size, &uniform.type, uniformName);
uniformName[length] = '\0'; uniformName[length] = '\0';
// Only add uniforms that are not built-in. // Only add uniforms that are not built-in.
// The ones that start with 'CC_' are built-ins // The ones that start with 'CC_' are built-ins
@ -370,9 +375,9 @@ void GLProgram::parseUniforms()
_userUniforms[uniform.name] = uniform; _userUniforms[uniform.name] = uniform;
} }
} }
} }
} }
} }
Uniform* GLProgram::getUniform(const std::string &name) Uniform* GLProgram::getUniform(const std::string &name)
@ -408,13 +413,32 @@ bool GLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* source
return false; return false;
} }
GLchar lightStruct[] = {
"#define MAX_LIGHT 6 \n"
"struct LightSource \n"
"{ \n"
" vec4 color; \n"
" vec3 position; \n"
" vec3 direction; \n"
" float range; \n"
" float innerAngle; \n"
" float outerAngle; \n"
" float type; \n"
" float use; \n"
" float none; \n"
"}; \n"
"uniform LightSource CC_LightSource[MAX_LIGHT];\n"
};
const GLchar *sources[] = { const GLchar *sources[] = {
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 && CC_TARGET_PLATFORM != CC_PLATFORM_LINUX && CC_TARGET_PLATFORM != CC_PLATFORM_MAC) #if (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 mediump float;\n"), (type == GL_VERTEX_SHADER ? "precision highp float;\n" : "precision mediump float;\n"),
#endif #endif
lightStruct,
"uniform mat4 CC_PMatrix;\n" "uniform mat4 CC_PMatrix;\n"
"uniform mat4 CC_MVMatrix;\n" "uniform mat4 CC_MVMatrix;\n"
"uniform mat4 CC_MVPMatrix;\n" "uniform mat4 CC_MVPMatrix;\n"
"uniform mat3 CC_NormalMatrix;\n"
"uniform vec4 CC_Time;\n" "uniform vec4 CC_Time;\n"
"uniform vec4 CC_SinTime;\n" "uniform vec4 CC_SinTime;\n"
"uniform vec4 CC_CosTime;\n" "uniform vec4 CC_CosTime;\n"
@ -474,9 +498,11 @@ void GLProgram::bindAttribLocation(const std::string &attributeName, GLuint inde
void GLProgram::updateUniforms() void GLProgram::updateUniforms()
{ {
_builtInUniforms[UNIFORM_LIGHT_SOURCE] = glGetUniformLocation(_program, UNIFORM_NAME_LIGHT_SOURCE);
_builtInUniforms[UNIFORM_P_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_P_MATRIX); _builtInUniforms[UNIFORM_P_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_P_MATRIX);
_builtInUniforms[UNIFORM_MV_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MV_MATRIX); _builtInUniforms[UNIFORM_MV_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MV_MATRIX);
_builtInUniforms[UNIFORM_MVP_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MVP_MATRIX); _builtInUniforms[UNIFORM_MVP_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MVP_MATRIX);
_builtInUniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_NORMAL_MATRIX);
_builtInUniforms[UNIFORM_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_TIME); _builtInUniforms[UNIFORM_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_TIME);
_builtInUniforms[UNIFORM_SIN_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_SIN_TIME); _builtInUniforms[UNIFORM_SIN_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_SIN_TIME);
@ -489,9 +515,11 @@ void GLProgram::updateUniforms()
_builtInUniforms[UNIFORM_SAMPLER2] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER2); _builtInUniforms[UNIFORM_SAMPLER2] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER2);
_builtInUniforms[UNIFORM_SAMPLER3] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER3); _builtInUniforms[UNIFORM_SAMPLER3] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER3);
_flags.usesLights = _builtInUniforms[UNIFORM_LIGHT_SOURCE] != -1;
_flags.usesP = _builtInUniforms[UNIFORM_P_MATRIX] != -1; _flags.usesP = _builtInUniforms[UNIFORM_P_MATRIX] != -1;
_flags.usesMV = _builtInUniforms[UNIFORM_MV_MATRIX] != -1; _flags.usesMV = _builtInUniforms[UNIFORM_MV_MATRIX] != -1;
_flags.usesMVP = _builtInUniforms[UNIFORM_MVP_MATRIX] != -1; _flags.usesMVP = _builtInUniforms[UNIFORM_MVP_MATRIX] != -1;
_flags.usesNormal = _builtInUniforms[UNIFORM_NORMAL_MATRIX] != -1;
_flags.usesTime = ( _flags.usesTime = (
_builtInUniforms[UNIFORM_TIME] != -1 || _builtInUniforms[UNIFORM_TIME] != -1 ||
_builtInUniforms[UNIFORM_SIN_TIME] != -1 || _builtInUniforms[UNIFORM_SIN_TIME] != -1 ||
@ -773,6 +801,17 @@ void GLProgram::setUniformLocationWith4f(GLint location, GLfloat f1, GLfloat f2,
} }
} }
void GLProgram::setUniformLocationWith1fv( GLint location, const GLfloat* floats, unsigned int numberOfArrays )
{
bool updated = updateUniformLocation(location, floats, sizeof(float)*numberOfArrays);
if( updated )
{
glUniform1fv( (GLint)location, (GLsizei)numberOfArrays, floats );
}
}
void GLProgram::setUniformLocationWith2fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays) void GLProgram::setUniformLocationWith2fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays)
{ {
bool updated = updateUniformLocation(location, floats, sizeof(float)*2*numberOfArrays); bool updated = updateUniformLocation(location, floats, sizeof(float)*2*numberOfArrays);
@ -858,6 +897,19 @@ void GLProgram::setUniformsForBuiltins(const Mat4 &matrixMV)
setUniformLocationWithMatrix4fv(_builtInUniforms[UNIFORM_MVP_MATRIX], matrixMVP.m, 1); setUniformLocationWithMatrix4fv(_builtInUniforms[UNIFORM_MVP_MATRIX], matrixMVP.m, 1);
} }
if (_flags.usesNormal)
{
Mat4 mvInverse = matrixMV;
mvInverse.m[12] = mvInverse.m[13] = mvInverse.m[14] = 0.0f;
mvInverse.inverse();
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];
setUniformLocationWithMatrix3fv(_builtInUniforms[UNIFORM_NORMAL_MATRIX], normalMat, 1);
}
if(_flags.usesTime) { if(_flags.usesTime) {
Director *director = Director::getInstance(); Director *director = Director::getInstance();
// This doesn't give the most accurate global time value. // This doesn't give the most accurate global time value.
@ -872,6 +924,44 @@ void GLProgram::setUniformsForBuiltins(const Mat4 &matrixMV)
if(_flags.usesRandom) if(_flags.usesRandom)
setUniformLocationWith4f(_builtInUniforms[GLProgram::UNIFORM_RANDOM01], CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1()); setUniformLocationWith4f(_builtInUniforms[GLProgram::UNIFORM_RANDOM01], CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1());
if (_flags.usesLights)
{
Director *director = Director::getInstance();
auto scene = director->getRunningScene();
if (scene)
{
auto lights = scene->getLights();
CCASSERT(lights.size() < CC_MAX_LIGHT_NUM, "");
GLfloat lightSources[16 * CC_MAX_LIGHT_NUM];
unsigned int sz = sizeof(lightSources);
memset(lightSources, 0, sizeof(lightSources));
unsigned int idx = 0;
for (auto iter : lights)
{
const Color3B &col = iter->getColor();
const Vec3 &pos = iter->getPosition3D();
const Vec3 &dir = iter->getDirection();
float range = iter->getRange();
float innerAngle = iter->getInnerAngle();
float outerAngle = iter->getOuterAngle();
float type =
lightSources[0 + idx] = col.r / 255.0f;lightSources[1 + idx] = col.g / 255.0f;lightSources[2 + idx] = col.b / 255.0f;lightSources[3 + idx] = 1.0f;
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<float>(iter->getLightType());
lightSources[14 + idx] = static_cast<float>(iter->getEnabled());
lightSources[15 + idx] = -1;
idx += 16;
}
setUniformLocationWith1fv(_builtInUniforms[GLProgram::UNIFORM_LIGHT_SOURCE], lightSources, 16 * CC_MAX_LIGHT_NUM);
}
}
} }
void GLProgram::reset() void GLProgram::reset()

View File

@ -96,9 +96,11 @@ public:
enum enum
{ {
UNIFORM_LIGHT_SOURCE,
UNIFORM_P_MATRIX, UNIFORM_P_MATRIX,
UNIFORM_MV_MATRIX, UNIFORM_MV_MATRIX,
UNIFORM_MVP_MATRIX, UNIFORM_MVP_MATRIX,
UNIFORM_NORMAL_MATRIX,
UNIFORM_TIME, UNIFORM_TIME,
UNIFORM_SIN_TIME, UNIFORM_SIN_TIME,
UNIFORM_COS_TIME, UNIFORM_COS_TIME,
@ -135,9 +137,11 @@ public:
static const char* SHADER_3D_SKINPOSITION_TEXTURE; static const char* SHADER_3D_SKINPOSITION_TEXTURE;
// uniform names // uniform names
static const char* UNIFORM_NAME_LIGHT_SOURCE;
static const char* UNIFORM_NAME_P_MATRIX; static const char* UNIFORM_NAME_P_MATRIX;
static const char* UNIFORM_NAME_MV_MATRIX; static const char* UNIFORM_NAME_MV_MATRIX;
static const char* UNIFORM_NAME_MVP_MATRIX; static const char* UNIFORM_NAME_MVP_MATRIX;
static const char* UNIFORM_NAME_NORMAL_MATRIX;
static const char* UNIFORM_NAME_TIME; static const char* UNIFORM_NAME_TIME;
static const char* UNIFORM_NAME_SIN_TIME; static const char* UNIFORM_NAME_SIN_TIME;
static const char* UNIFORM_NAME_COS_TIME; static const char* UNIFORM_NAME_COS_TIME;
@ -183,8 +187,8 @@ public:
static GLProgram* createWithFilenames(const std::string& vShaderFilename, const std::string& fShaderFilename); static GLProgram* createWithFilenames(const std::string& vShaderFilename, const std::string& fShaderFilename);
bool initWithFilenames(const std::string& vShaderFilename, const std::string& fShaderFilename); bool initWithFilenames(const std::string& vShaderFilename, const std::string& fShaderFilename);
//void bindUniform(std::string uniformName, int value); //void bindUniform(std::string uniformName, int value);
Uniform* getUniform(const std::string& name); Uniform* getUniform(const std::string& name);
VertexAttrib* getVertexAttrib(const std::string& name); VertexAttrib* getVertexAttrib(const std::string& name);
/** It will add a new attribute to the shader by calling glBindAttribLocation */ /** It will add a new attribute to the shader by calling glBindAttribLocation */
@ -263,6 +267,9 @@ public:
*/ */
void setUniformLocationWith4f(GLint location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4); void setUniformLocationWith4f(GLint location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4);
/** calls glUniformfv only if the values are different than the previous call for this same shader program. */
void setUniformLocationWith1fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays);
/** calls glUniform2fv only if the values are different than the previous call for this same shader program. */ /** calls glUniform2fv only if the values are different than the previous call for this same shader program. */
void setUniformLocationWith2fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays); void setUniformLocationWith2fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays);
@ -326,7 +333,7 @@ protected:
GLuint _fragShader; GLuint _fragShader;
GLint _builtInUniforms[UNIFORM_MAX]; GLint _builtInUniforms[UNIFORM_MAX];
struct _hashUniformEntry* _hashForUniforms; struct _hashUniformEntry* _hashForUniforms;
bool _hasShaderCompiler; bool _hasShaderCompiler;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
std::string _shaderId; std::string _shaderId;
@ -334,10 +341,12 @@ protected:
struct flag_struct { struct flag_struct {
unsigned int usesTime:1; unsigned int usesTime:1;
unsigned int usesNormal:1;
unsigned int usesMVP:1; unsigned int usesMVP:1;
unsigned int usesMV:1; unsigned int usesMV:1;
unsigned int usesP:1; unsigned int usesP:1;
unsigned int usesRandom:1; unsigned int usesRandom:1;
unsigned int usesLights:1;
// handy way to initialize the bitfield // handy way to initialize the bitfield
flag_struct() { memset(this, 0, sizeof(*this)); } flag_struct() { memset(this, 0, sizeof(*this)); }

View File

@ -8,13 +8,13 @@
USING_NS_CC; USING_NS_CC;
class LightTexture : public Sprite class Light : public Sprite
{ {
public: public:
LightTexture(); Light();
~LightTexture(); ~Light();
static LightTexture* lightWithFile(const char* name); static Light* lightWithFile(const char* name);
void setIsConnectToSwitch(bool bConnectToSwitch); void setIsConnectToSwitch(bool bConnectToSwitch);
void switchStateChanged(Ref* obj); void switchStateChanged(Ref* obj);
@ -25,31 +25,31 @@ private:
static bool s_bSwitchOn; static bool s_bSwitchOn;
}; };
bool LightTexture::s_bSwitchOn = false; bool Light::s_bSwitchOn = false;
LightTexture::LightTexture() Light::Light()
: _connected(false) : _connected(false)
{} {}
LightTexture::~LightTexture() Light::~Light()
{ {
NotificationCenter::getInstance()->removeObserver(this, MSG_SWITCH_STATE); NotificationCenter::getInstance()->removeObserver(this, MSG_SWITCH_STATE);
} }
LightTexture* LightTexture::lightWithFile(const char* name) Light* Light::lightWithFile(const char* name)
{ {
LightTexture* pLight = new LightTexture(); Light* pLight = new Light();
pLight->initWithFile(name); pLight->initWithFile(name);
pLight->autorelease(); pLight->autorelease();
return pLight; return pLight;
} }
void LightTexture::setIsConnectToSwitch(bool bConnectToSwitch) void Light::setIsConnectToSwitch(bool bConnectToSwitch)
{ {
_connected = bConnectToSwitch; _connected = bConnectToSwitch;
if (_connected) if (_connected)
{ {
NotificationCenter::getInstance()->addObserver(this, callfuncO_selector(LightTexture::switchStateChanged), MSG_SWITCH_STATE, nullptr); NotificationCenter::getInstance()->addObserver(this, callfuncO_selector(Light::switchStateChanged), MSG_SWITCH_STATE, nullptr);
} }
else else
{ {
@ -58,13 +58,13 @@ void LightTexture::setIsConnectToSwitch(bool bConnectToSwitch)
updateLightState(); updateLightState();
} }
void LightTexture::switchStateChanged(Ref* obj) void Light::switchStateChanged(Ref* obj)
{ {
s_bSwitchOn = obj == 0x00 ? false : true; s_bSwitchOn = obj == 0x00 ? false : true;
updateLightState(); updateLightState();
} }
void LightTexture::updateLightState() void Light::updateLightState()
{ {
if (s_bSwitchOn && _connected) if (s_bSwitchOn && _connected)
{ {
@ -104,7 +104,7 @@ NotificationCenterTest::NotificationCenterTest()
for (int i = 1; i <= 3; i++) for (int i = 1; i <= 3; i++)
{ {
LightTexture* light = LightTexture::lightWithFile("Images/Pea.png"); Light* light = Light::lightWithFile("Images/Pea.png");
light->setTag(kTagLight+i); light->setTag(kTagLight+i);
light->setPosition(Vec2(100, s.height/4*i)); light->setPosition(Vec2(100, s.height/4*i));
addChild(light); addChild(light);
@ -155,7 +155,7 @@ void NotificationCenterTest::connectToSwitch(Ref *sender)
{ {
auto item = (MenuItemToggle*)sender; auto item = (MenuItemToggle*)sender;
bool bConnected = item->getSelectedIndex() == 0 ? false : true; bool bConnected = item->getSelectedIndex() == 0 ? false : true;
LightTexture* pLight = (LightTexture*)this->getChildByTag(item->getTag()-kTagConnect+kTagLight); Light* pLight = (Light*)this->getChildByTag(item->getTag()-kTagConnect+kTagLight);
pLight->setIsConnectToSwitch(bConnected); pLight->setIsConnectToSwitch(bConnected);
} }