mirror of https://github.com/axmolengine/axmol.git
GLProgram Added Light Shader
GLProgram Added Normal Matrix
This commit is contained in:
parent
1e9c02dfa3
commit
2b1efc59cb
|
@ -203,12 +203,12 @@ void Scene::onProjectionChanged(EventCustom* event)
|
|||
|
||||
void Scene::setAmbientColor( const Color4F &color )
|
||||
{
|
||||
_ambientColor = color;
|
||||
_ambientColor = color;
|
||||
}
|
||||
|
||||
const Color4F& Scene::getAmbientColor() const
|
||||
{
|
||||
return _ambientColor;
|
||||
return _ambientColor;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,7 +35,7 @@ THE SOFTWARE.
|
|||
NS_CC_BEGIN
|
||||
|
||||
class Camera;
|
||||
class Light;
|
||||
class Light3D;
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
|
@ -69,21 +69,21 @@ public:
|
|||
/** get all 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.
|
||||
*
|
||||
* @param color The ambient color of scene.
|
||||
*/
|
||||
void setAmbientColor(const Color4F &color);
|
||||
void setAmbientColor(const Color4F &color);
|
||||
|
||||
/**
|
||||
* Returns the ambient color of scene.
|
||||
*
|
||||
* @return The ambient color of scene.
|
||||
*/
|
||||
const Color4F& getAmbientColor() const;
|
||||
const Color4F& getAmbientColor() const;
|
||||
|
||||
CC_CONSTRUCTOR_ACCESS:
|
||||
Scene();
|
||||
|
@ -100,14 +100,14 @@ protected:
|
|||
friend class SpriteBatchNode;
|
||||
friend class Camera;
|
||||
friend class Director;
|
||||
friend class Light;
|
||||
friend class Light3D;
|
||||
|
||||
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
|
||||
EventListenerCustom* _event;
|
||||
|
||||
std::vector<Light *> _lights;
|
||||
Color4F _ambientColor;
|
||||
std::vector<Light3D *> _lights;
|
||||
Color4F _ambientColor;
|
||||
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(Scene);
|
||||
|
|
|
@ -3,93 +3,111 @@
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
Light::Light()
|
||||
: _range(0.0f)
|
||||
Light3D::Light3D()
|
||||
: _isEnabled(false)
|
||||
, _range(0.0f)
|
||||
, _innerAngle(0.0f)
|
||||
, _outerAngle(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Light::~Light()
|
||||
Light3D::~Light3D()
|
||||
{
|
||||
}
|
||||
|
||||
Light* Light::Create( LightType lightType )
|
||||
Light3D* Light3D::Create( LightType lightType )
|
||||
{
|
||||
Light *light = new Light;
|
||||
light->setLightType(lightType);
|
||||
light->autorelease();
|
||||
return light;
|
||||
Light3D *light = new Light3D;
|
||||
light->setLightType(lightType);
|
||||
light->autorelease();
|
||||
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();
|
||||
if (scene)
|
||||
{
|
||||
auto lights = scene->_lights;
|
||||
auto iter = std::find(lights.begin(), lights.end(), this);
|
||||
if (iter == lights.end())
|
||||
lights.push_back(this);
|
||||
}
|
||||
return _innerAngle;
|
||||
}
|
||||
|
||||
void Light::onExit()
|
||||
void Light3D::setOuterAngle( float angle )
|
||||
{
|
||||
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);
|
||||
}
|
||||
_outerAngle = angle;
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
float Light3D::getOuterAngle()
|
||||
{
|
||||
return _outerAngle;
|
||||
}
|
||||
|
||||
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
|
|
@ -29,104 +29,115 @@
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
class CC_DLL Light : public Node
|
||||
class CC_DLL Light3D : public Node
|
||||
{
|
||||
public:
|
||||
|
||||
enum class LightType
|
||||
{
|
||||
DIRECTIONAL,
|
||||
POINT,
|
||||
SPOT
|
||||
};
|
||||
enum LightType
|
||||
{
|
||||
DIRECTIONAL = 0,
|
||||
POINT = 1,
|
||||
SPOT = 2
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Create light according to type.
|
||||
*/
|
||||
static Light* Create(LightType lightType);
|
||||
static Light3D* Create(LightType lightType);
|
||||
|
||||
//override
|
||||
virtual void onEnter() override;
|
||||
virtual void onExit() override;
|
||||
//override
|
||||
virtual void onEnter() override;
|
||||
virtual void onExit() override;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Sets light type.
|
||||
*/
|
||||
void setLightType(LightType lightType);
|
||||
void setLightType(LightType lightType);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @return The range of the point or spot light.
|
||||
*/
|
||||
float getRange();
|
||||
float getRange();
|
||||
|
||||
/**
|
||||
* Sets the Direction of 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.
|
||||
*
|
||||
* @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).
|
||||
*
|
||||
* @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).
|
||||
*
|
||||
* @return The inner angle of the spot light (in radians).
|
||||
*/
|
||||
float getInnerAngle();
|
||||
float getInnerAngle();
|
||||
|
||||
/**
|
||||
* Sets the outer angle of a 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).
|
||||
*
|
||||
* @return The outer angle of the spot light (in radians).
|
||||
*/
|
||||
float getOuterAngle();
|
||||
float getOuterAngle();
|
||||
|
||||
CC_CONSTRUCTOR_ACCESS:
|
||||
|
||||
Light();
|
||||
virtual ~Light();
|
||||
Light3D();
|
||||
virtual ~Light3D();
|
||||
|
||||
protected:
|
||||
|
||||
LightType _lightType;
|
||||
Vec3 _dir;
|
||||
float _range;
|
||||
float _innerAngle;
|
||||
float _outerAngle;
|
||||
LightType _lightType;
|
||||
bool _isEnabled;
|
||||
Vec3 _dir;
|
||||
float _range;
|
||||
float _innerAngle;
|
||||
float _outerAngle;
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -32,6 +32,7 @@ THE SOFTWARE.
|
|||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include "3d/CCLight.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "base/ccMacros.h"
|
||||
#include "base/uthash.h"
|
||||
|
@ -45,6 +46,8 @@ THE SOFTWARE.
|
|||
#include "CCPrecompiledShaders.h"
|
||||
#endif
|
||||
|
||||
#define CC_MAX_LIGHT_NUM 6
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
typedef struct _hashUniformEntry
|
||||
|
@ -77,9 +80,11 @@ const char* GLProgram::SHADER_3D_SKINPOSITION_TEXTURE = "Shader3DSkinPositionTex
|
|||
|
||||
|
||||
// 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_MV_MATRIX = "CC_MVMatrix";
|
||||
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_SIN_TIME = "CC_SinTime";
|
||||
const char* GLProgram::UNIFORM_NAME_COS_TIME = "CC_CosTime";
|
||||
|
@ -295,56 +300,56 @@ void GLProgram::parseVertexAttribs()
|
|||
{
|
||||
_vertexAttribs.clear();
|
||||
|
||||
// Query and store vertex attribute meta-data from the program.
|
||||
GLint activeAttributes;
|
||||
GLint length;
|
||||
glGetProgramiv(_program, GL_ACTIVE_ATTRIBUTES, &activeAttributes);
|
||||
if(activeAttributes > 0)
|
||||
{
|
||||
// Query and store vertex attribute meta-data from the program.
|
||||
GLint activeAttributes;
|
||||
GLint length;
|
||||
glGetProgramiv(_program, GL_ACTIVE_ATTRIBUTES, &activeAttributes);
|
||||
if(activeAttributes > 0)
|
||||
{
|
||||
VertexAttrib attribute;
|
||||
|
||||
glGetProgramiv(_program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &length);
|
||||
if(length > 0)
|
||||
{
|
||||
GLchar* attribName = (GLchar*) alloca(length + 1);
|
||||
glGetProgramiv(_program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &length);
|
||||
if(length > 0)
|
||||
{
|
||||
GLchar* attribName = (GLchar*) alloca(length + 1);
|
||||
|
||||
for(int i = 0; i < activeAttributes; ++i)
|
||||
{
|
||||
// Query attribute info.
|
||||
glGetActiveAttrib(_program, i, length, nullptr, &attribute.size, &attribute.type, attribName);
|
||||
attribName[length] = '\0';
|
||||
for(int i = 0; i < activeAttributes; ++i)
|
||||
{
|
||||
// Query attribute info.
|
||||
glGetActiveAttrib(_program, i, length, nullptr, &attribute.size, &attribute.type, attribName);
|
||||
attribName[length] = '\0';
|
||||
attribute.name = std::string(attribName);
|
||||
|
||||
// Query the pre-assigned attribute location
|
||||
attribute.index = glGetAttribLocation(_program, attribName);
|
||||
// Query the pre-assigned attribute location
|
||||
attribute.index = glGetAttribLocation(_program, attribName);
|
||||
_vertexAttribs[attribute.name] = attribute;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLProgram::parseUniforms()
|
||||
{
|
||||
_userUniforms.clear();
|
||||
|
||||
// Query and store uniforms from the program.
|
||||
GLint activeUniforms;
|
||||
glGetProgramiv(_program, GL_ACTIVE_UNIFORMS, &activeUniforms);
|
||||
if(activeUniforms > 0)
|
||||
{
|
||||
// Query and store uniforms from the program.
|
||||
GLint activeUniforms;
|
||||
glGetProgramiv(_program, GL_ACTIVE_UNIFORMS, &activeUniforms);
|
||||
if(activeUniforms > 0)
|
||||
{
|
||||
GLint length;
|
||||
glGetProgramiv(_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &length);
|
||||
if(length > 0)
|
||||
{
|
||||
glGetProgramiv(_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &length);
|
||||
if(length > 0)
|
||||
{
|
||||
Uniform uniform;
|
||||
|
||||
GLchar* uniformName = (GLchar*)alloca(length + 1);
|
||||
GLchar* uniformName = (GLchar*)alloca(length + 1);
|
||||
|
||||
for(int i = 0; i < activeUniforms; ++i)
|
||||
{
|
||||
// Query uniform info.
|
||||
glGetActiveUniform(_program, i, length, nullptr, &uniform.size, &uniform.type, uniformName);
|
||||
uniformName[length] = '\0';
|
||||
for(int i = 0; i < activeUniforms; ++i)
|
||||
{
|
||||
// Query uniform info.
|
||||
glGetActiveUniform(_program, i, length, nullptr, &uniform.size, &uniform.type, uniformName);
|
||||
uniformName[length] = '\0';
|
||||
|
||||
// Only add uniforms that are not built-in.
|
||||
// The ones that start with 'CC_' are built-ins
|
||||
|
@ -370,9 +375,9 @@ void GLProgram::parseUniforms()
|
|||
|
||||
_userUniforms[uniform.name] = uniform;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Uniform* GLProgram::getUniform(const std::string &name)
|
||||
|
@ -407,14 +412,33 @@ bool GLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* source
|
|||
{
|
||||
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[] = {
|
||||
#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"),
|
||||
#endif
|
||||
lightStruct,
|
||||
"uniform mat4 CC_PMatrix;\n"
|
||||
"uniform mat4 CC_MVMatrix;\n"
|
||||
"uniform mat4 CC_MVPMatrix;\n"
|
||||
"uniform mat3 CC_NormalMatrix;\n"
|
||||
"uniform vec4 CC_Time;\n"
|
||||
"uniform vec4 CC_SinTime;\n"
|
||||
"uniform vec4 CC_CosTime;\n"
|
||||
|
@ -474,9 +498,11 @@ void GLProgram::bindAttribLocation(const std::string &attributeName, GLuint inde
|
|||
|
||||
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_MV_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MV_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_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_SAMPLER3] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER3);
|
||||
|
||||
_flags.usesLights = _builtInUniforms[UNIFORM_LIGHT_SOURCE] != -1;
|
||||
_flags.usesP = _builtInUniforms[UNIFORM_P_MATRIX] != -1;
|
||||
_flags.usesMV = _builtInUniforms[UNIFORM_MV_MATRIX] != -1;
|
||||
_flags.usesMVP = _builtInUniforms[UNIFORM_MVP_MATRIX] != -1;
|
||||
_flags.usesNormal = _builtInUniforms[UNIFORM_NORMAL_MATRIX] != -1;
|
||||
_flags.usesTime = (
|
||||
_builtInUniforms[UNIFORM_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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
Director *director = Director::getInstance();
|
||||
// This doesn't give the most accurate global time value.
|
||||
|
@ -872,6 +924,44 @@ void GLProgram::setUniformsForBuiltins(const Mat4 &matrixMV)
|
|||
|
||||
if(_flags.usesRandom)
|
||||
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()
|
||||
|
|
|
@ -96,9 +96,11 @@ public:
|
|||
|
||||
enum
|
||||
{
|
||||
UNIFORM_LIGHT_SOURCE,
|
||||
UNIFORM_P_MATRIX,
|
||||
UNIFORM_MV_MATRIX,
|
||||
UNIFORM_MVP_MATRIX,
|
||||
UNIFORM_NORMAL_MATRIX,
|
||||
UNIFORM_TIME,
|
||||
UNIFORM_SIN_TIME,
|
||||
UNIFORM_COS_TIME,
|
||||
|
@ -135,9 +137,11 @@ public:
|
|||
static const char* SHADER_3D_SKINPOSITION_TEXTURE;
|
||||
|
||||
// uniform names
|
||||
static const char* UNIFORM_NAME_LIGHT_SOURCE;
|
||||
static const char* UNIFORM_NAME_P_MATRIX;
|
||||
static const char* UNIFORM_NAME_MV_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_SIN_TIME;
|
||||
static const char* UNIFORM_NAME_COS_TIME;
|
||||
|
@ -183,8 +187,8 @@ public:
|
|||
static GLProgram* createWithFilenames(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);
|
||||
Uniform* getUniform(const std::string& name);
|
||||
//void bindUniform(std::string uniformName, int value);
|
||||
Uniform* getUniform(const std::string& name);
|
||||
VertexAttrib* getVertexAttrib(const std::string& name);
|
||||
|
||||
/** 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);
|
||||
|
||||
/** 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. */
|
||||
void setUniformLocationWith2fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays);
|
||||
|
||||
|
@ -326,7 +333,7 @@ protected:
|
|||
GLuint _fragShader;
|
||||
GLint _builtInUniforms[UNIFORM_MAX];
|
||||
struct _hashUniformEntry* _hashForUniforms;
|
||||
bool _hasShaderCompiler;
|
||||
bool _hasShaderCompiler;
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
|
||||
std::string _shaderId;
|
||||
|
@ -334,10 +341,12 @@ protected:
|
|||
|
||||
struct flag_struct {
|
||||
unsigned int usesTime:1;
|
||||
unsigned int usesNormal:1;
|
||||
unsigned int usesMVP:1;
|
||||
unsigned int usesMV:1;
|
||||
unsigned int usesP:1;
|
||||
unsigned int usesRandom:1;
|
||||
unsigned int usesRandom:1;
|
||||
unsigned int usesLights:1;
|
||||
|
||||
// handy way to initialize the bitfield
|
||||
flag_struct() { memset(this, 0, sizeof(*this)); }
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
|
||||
USING_NS_CC;
|
||||
|
||||
class LightTexture : public Sprite
|
||||
class Light : public Sprite
|
||||
{
|
||||
public:
|
||||
LightTexture();
|
||||
~LightTexture();
|
||||
Light();
|
||||
~Light();
|
||||
|
||||
static LightTexture* lightWithFile(const char* name);
|
||||
static Light* lightWithFile(const char* name);
|
||||
|
||||
void setIsConnectToSwitch(bool bConnectToSwitch);
|
||||
void switchStateChanged(Ref* obj);
|
||||
|
@ -25,31 +25,31 @@ private:
|
|||
static bool s_bSwitchOn;
|
||||
};
|
||||
|
||||
bool LightTexture::s_bSwitchOn = false;
|
||||
bool Light::s_bSwitchOn = false;
|
||||
|
||||
LightTexture::LightTexture()
|
||||
Light::Light()
|
||||
: _connected(false)
|
||||
{}
|
||||
|
||||
LightTexture::~LightTexture()
|
||||
Light::~Light()
|
||||
{
|
||||
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->autorelease();
|
||||
return pLight;
|
||||
}
|
||||
|
||||
void LightTexture::setIsConnectToSwitch(bool bConnectToSwitch)
|
||||
void Light::setIsConnectToSwitch(bool bConnectToSwitch)
|
||||
{
|
||||
_connected = bConnectToSwitch;
|
||||
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
|
||||
{
|
||||
|
@ -58,13 +58,13 @@ void LightTexture::setIsConnectToSwitch(bool bConnectToSwitch)
|
|||
updateLightState();
|
||||
}
|
||||
|
||||
void LightTexture::switchStateChanged(Ref* obj)
|
||||
void Light::switchStateChanged(Ref* obj)
|
||||
{
|
||||
s_bSwitchOn = obj == 0x00 ? false : true;
|
||||
updateLightState();
|
||||
}
|
||||
|
||||
void LightTexture::updateLightState()
|
||||
void Light::updateLightState()
|
||||
{
|
||||
if (s_bSwitchOn && _connected)
|
||||
{
|
||||
|
@ -104,7 +104,7 @@ NotificationCenterTest::NotificationCenterTest()
|
|||
|
||||
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->setPosition(Vec2(100, s.height/4*i));
|
||||
addChild(light);
|
||||
|
@ -155,7 +155,7 @@ void NotificationCenterTest::connectToSwitch(Ref *sender)
|
|||
{
|
||||
auto item = (MenuItemToggle*)sender;
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue