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

@ -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,7 +69,7 @@ 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.
@ -100,13 +100,13 @@ 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:

View File

@ -3,72 +3,90 @@
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()
{
return _lightType;
}
void Light3D::setEnabled( bool isEnabled )
{
_isEnabled = isEnabled;
}
bool Light3D::getEnabled()
{
return _isEnabled;
}
void Light3D::setRange( float range )
{ {
_range = range; _range = range;
} }
float Light::getRange() float Light3D::getRange()
{ {
return _range; return _range;
} }
void Light::setDirection( const Vec3 &dir ) void Light3D::setDirection( const Vec3 &dir )
{ {
_dir = dir; _dir = dir;
} }
const Vec3& Light::getDirection() const const Vec3& Light3D::getDirection() const
{ {
return _dir; return _dir;
} }
void Light::setInnerAngle( float angle ) void Light3D::setInnerAngle( float angle )
{ {
_innerAngle = angle; _innerAngle = angle;
} }
float Light::getInnerAngle() float Light3D::getInnerAngle()
{ {
return _innerAngle; return _innerAngle;
} }
void Light::setOuterAngle( float angle ) void Light3D::setOuterAngle( float angle )
{ {
_outerAngle = angle; _outerAngle = angle;
} }
float Light::getOuterAngle() float Light3D::getOuterAngle()
{ {
return _outerAngle; return _outerAngle;
} }
void Light::onEnter() void Light3D::onEnter()
{ {
auto scene = getScene(); auto scene = getScene();
if (scene) if (scene)
@ -80,7 +98,7 @@ void Light::onEnter()
} }
} }
void Light::onExit() void Light3D::onExit()
{ {
auto scene = getScene(); auto scene = getScene();
if (scene) if (scene)

View File

@ -29,21 +29,21 @@
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;
@ -59,6 +59,16 @@ public:
*/ */
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.
* *
@ -117,12 +127,13 @@ public:
CC_CONSTRUCTOR_ACCESS: CC_CONSTRUCTOR_ACCESS:
Light(); Light3D();
virtual ~Light(); virtual ~Light3D();
protected: protected:
LightType _lightType; LightType _lightType;
bool _isEnabled;
Vec3 _dir; Vec3 _dir;
float _range; float _range;
float _innerAngle; float _innerAngle;

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";
@ -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;
@ -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);
@ -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);
} }