1、头文件
- //LightTest.h
- classLightTest:publicLayer
- {
- public:
- CREATE_FUNC(LightTest);
- LightTest();
- virtual~LightTest();
- virtualvoidupdate(floatdelta);
- voidSwitchLight(Ref*sender,LightTypelightType);//转换光源
- private:
- voidaddSprite();//添加精灵
- voidaddLights();//添加光源
- private:
- AmbientLight*_ambientLight;//环境光,想四周发射光线,模拟一个屋子的环境,光线来源方向不定。
- DirectionLight*_directionalLight;//方向光,表示一个非常远的光源,投射光线是平行的,用来模拟太阳光
- PointLight*_pointLight;//点光,从空间某点向四周均匀发射有限长的光线,用来模拟向四周发射状的光
- SpotLight*_spotLight;//聚光,从某点发射一个圆锥形状,用来模拟台灯
- Label*_ambientLightLabel;
- Label*_directionalLightLabel;
- Label*_pointLightLabel;
- Label*_spotLightLabel;
- };
2、Cpp文件
- #include"LightTest.h"
- //构造函数,初始化除环境光AmbientLight之外的三种光为nullptr
- LightTest::LightTest()
- :_directionalLight(nullptr)
- ,_pointLight(nullptr)
- ,_spotLight(nullptr)
- {
- addSprite();//添加精灵
- addLights();//添加光源
- scheduleUpdate();//帧更新
- //设置摄像机位置
- autos=Director::getInstance()->getWinSize();
- //参数1:透视相机的视野,通常在40-60度范围
- //参数2:相机的长宽比,通常视窗的宽度除以视窗的高度
- //参数3:近点平面距离
- //参数4:原点平面距离
- autocamera=Camera::createPerspective(60,(GLfloat)s.width/s.height,1.0f,1000.0f);
- camera->setCameraFlag(CameraFlag::USER1);//设置相机Flag
- camera->setPosition3D(Vec3(0.0,100,100));//设置相机3D坐标
- //参数1:目标的中心位置,参数2:向上的向量
- camera->lookAt(Vec3(0.0,0.0,0.0),Vec3(0.0,1.0,0.0));
- addChild(camera);
- //添加相机转换的开光,Label控件
- TTFConfigttfConfig("fonts/arial.ttf",30);
- _ambientLightLabel=Label::createWithTTF(ttfConfig,"AmbientLightON");
- _ambientLightLabel->retain();
- automenuItem0=MenuItemLabel::create(_ambientLightLabel,CC_CALLBACK_1(LightTest::SwitchLight,this,LightType::AMBIENT));
- _directionalLightLabel=Label::createWithTTF(ttfConfig,"DirectionalLightOFF");
- _directionalLightLabel->retain();
- automenuItem1=MenuItemLabel::create(_directionalLightLabel,LightType::DIRECTIONAL));
- _pointLightLabel=Label::createWithTTF(ttfConfig,"PointLightOFF");
- _pointLightLabel->retain();
- automenuItem2=MenuItemLabel::create(_pointLightLabel,LightType::POINT));
- _spotLightLabel=Label::createWithTTF(ttfConfig,"SpotLightOFF");
- _spotLightLabel->retain();
- automenuItem3=MenuItemLabel::create(_spotLightLabel,LightType::SPOT));
- automenu=Menu::create(menuItem0,menuItem1,menuItem2,menuItem3,nullptr);
- menu->setPosition(Vec2::ZERO);
- menuItem0->setAnchorPoint(Vec2::ANCHOR_TOP_LEFT);
- menuItem0->setPosition(Vec2(VisibleRect::left().x,VisibleRect::top().y-50));
- menuItem1->setAnchorPoint(Vec2::ANCHOR_TOP_LEFT);
- menuItem1->setPosition(Vec2(VisibleRect::left().x,VisibleRect::top().y-100));
- menuItem2->setAnchorPoint(Vec2::ANCHOR_TOP_LEFT);
- menuItem2->setPosition(Vec2(VisibleRect::left().x,VisibleRect::top().y-150));
- menuItem3->setAnchorPoint(Vec2::ANCHOR_TOP_LEFT);
- menuItem3->setPosition(Vec2(VisibleRect::left().x,VisibleRect::top().y-200));
- addChild(menu);
- }
- //析构资源
- LightTest::~LightTest()
- {
- if(_spotLightLabel)
- _spotLightLabel->release();
- if(_pointLightLabel)
- _pointLightLabel->release();
- if(_directionalLightLabel)
- _directionalLightLabel->release();
- if(_spotLight)
- _spotLight->release();
- if(_pointLight)
- _pointLight->release();
- if(_directionalLight)
- _directionalLight->release();
- if(_ambientLight)
- _ambientLight->release();
- }
- voidLightTest::addSprite()
- //创建3D对象,c3b是二进制文件,通过FBX模型文件进行二次转换得到。
- //obj:FBX是一种通用导出格式,可通过maya和max导出,maya和max默认导出obj格式文件。
- //c3t:通过FBX模型文件转换后生成的Json文件,体积大载入慢,不提倡使用
- //c3b:二进制文件,数据内容与c3t一样,体积小,速度快,提倡使用
- //注意:.c3b文件的使用需和它对应的贴图拷贝到Resource目录下,否则,运行时找不到资源。
- std::stringfileName="orc.c3b";
- //创建3D精灵对象
- autosprite=Sprite3D::create(fileName);
- sprite->setRotation3D(Vec3(0.0,180.0,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> sprite->setPosition(Vec2(0.0,0.0));
- sprite->setScale(2.0);
- //创建3D精灵对象
- autosp=Sprite3D::create("axe.c3b");
- //通过骨骼名称获得连接点
- sprite->getAttachNode("Bip001RHand")->addChild(sp);
- //创建3D动画
- autoanimation=Animation3D::create(fileName);
- if(animation)
- autoanimate=Animate3D::create(animation);
- sprite->runAction(RepeatForever::create(animate));//3D精灵执行3D动画
- addChild(sprite);
- //设置精灵的Mask,该值与相机的flag进行&运算为真,则对相机可见
- sprite->setCameraMask(2);
- //同上
- std::stringfileName="sphere.c3b";
- sprite->setPosition(Vec2(30.0,248); margin:0px!important; padding:0px 3px 0px 10px!important"> sprite->setCameraMask(2);
- //同上
- std::stringfileName="sphere.c3b";
- autosprite=Sprite3D::create(fileName);
- sprite->setScale(0.5f);
- sprite->setPosition(Vec2(-50.0,248); margin:0px!important; padding:0px 3px 0px 10px!important"> sprite->setPosition(Vec2(-30.0,10.0));
- voidLightTest::addLights()
- autos=Director::getInstance()->getWinSize();
- //环境光
- _ambientLight=AmbientLight::create(Color3B(200,200,200));
- _ambientLight->retain();
- _ambientLight->setEnabled(true);//开启光源
- addChild(_ambientLight);
- _ambientLight->setCameraMask(2);//确保相机可见
- //方向光,参数1:光源方向.参数2:光源颜色
- _directionalLight=DirectionLight::create(Vec3(-1.0f,-1.0f,0.0f),Color3B(200,200));
- _directionalLight->retain();
- _directionalLight->setEnabled(false);//光源关闭
- addChild(_directionalLight);
- _directionalLight->setCameraMask(2);//确保相机可见
- //点光,参数1:光源的位置,参数2:光源的颜色。参数3:光源范围
- _pointLight=PointLight::create(Vec3(0.0f,0.0f,200),10000.0f);
- _pointLight->retain();
- _pointLight->setEnabled(//光源关闭
- addChild(_pointLight);
- _pointLight->setCameraMask(2);//聚光,参数1:方向。参数2:位置。参数3:颜色,参数4:内圆弧度。参数5:外圆弧度。参数6:光源范围
- _spotLight=SpotLight::create(Vec3(-1.0f,Vec3(0.0f,0.5,10000.0f);
- _spotLight->retain();
- _spotLight->setEnabled( addChild(_spotLight);
- _spotLight->setCameraMask(2); autotintto1=TintTo::create(4,255);
- autotintto2=TintTo::create(4,0);
- autotintto3=TintTo::create(4,0);
- autotintto4=TintTo::create(4,255);
- autoseq=Sequence::create(tintto1,tintto2,tintto3,tintto4,248); margin:0px!important; padding:0px 3px 0px 10px!important"> _ambientLight->runAction(RepeatForever::create(seq));//光源执行渐隐动作
- autotintto1=TintTo::create(4,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> autotintto2=TintTo::create(4,248); margin:0px!important; padding:0px 3px 0px 10px!important"> autotintto3=TintTo::create(4,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> autotintto4=TintTo::create(4,248); margin:0px!important; padding:0px 3px 0px 10px!important"> autoseq=Sequence::create(tintto1,nullptr);
- _directionalLight->runAction(RepeatForever::create(seq));//光源执行渐隐动作
- autoseq=Sequence::create(tintto2,tintto1,248); margin:0px!important; padding:0px 3px 0px 10px!important"> _pointLight->runAction(RepeatForever::create(seq)); autoseq=Sequence::create(tintto3,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> _spotLight->runAction(RepeatForever::create(seq));voidLightTest::update(floatdelta)
- staticfloatangleDelta=0.0;
- if(_directionalLight)
- _directionalLight->setRotation3D(Vec3(-45.0,-CC_RADIANS_TO_DEGREES(angleDelta),0.0f));//设置旋转角度,宏是弧度转化为角度
- //cosf与sinf:float版的cos和sin
- if(_pointLight)
- _pointLight->setPositionX(100.0f*cosf(angleDelta+2.0*delta));
- _pointLight->setPositionY(100.0f);
- _pointLight->setPositionZ(100.0f*sinf(angleDelta+2.0*delta));
- if(_spotLight)
- _spotLight->setPositionX(100.0f*cosf(angleDelta+4.0*delta));
- _spotLight->setPositionY(100.0f);
- _spotLight->setPositionZ(100.0f*sinf(angleDelta+4.0*delta));
- _spotLight->setDirection(-Vec3(cosf(angleDelta+4.0*delta),sinf(angleDelta+4.0*delta)));
- angleDelta+=delta;
- //update(delta);
- //光源开关
- voidLightTest::SwitchLight(Ref*sender,LightTypelightType)
- switch(lightType)
- caseLightType::AMBIENT:
- charstr[32];
- boolisON=!_ambientLight->isEnabled();
- sprintf(str,"AmbientLight%s",isON==true?"ON":"OFF");
- _ambientLight->setEnabled(isON);
- _ambientLightLabel->setString(str);
- break;
- caseLightType::DIRECTIONAL:
- boolisON=!_directionalLight->isEnabled();
- "DirectionalLight%s",108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> _directionalLight->setEnabled(isON);
- _directionalLightLabel->setString(str);
- caseLightType::POINT:
- boolisON=!_pointLight->isEnabled();
- "PointLight%s",108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> _pointLight->setEnabled(isON);
- _pointLightLabel->setString(str);
- caseLightType::SPOT:
- boolisON=!_spotLight->isEnabled();
- "SpotLight%s",108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> _spotLight->setEnabled(isON);
- _spotLightLabel->setString(str);
- default:
- break;
- }
3、使用
在HelloWorldScene.cpp中的createScene()中,创建LightTest的对象,加入Scene