Cocos2d-x3.3RC0之LightTest分析

1、头文件

//LightTest.h
class LightTest : public Layer
{
public:
    CREATE_FUNC(LightTest);
    LightTest();
    virtual ~LightTest();
    
    virtual void update(float delta);
    void SwitchLight(Ref* sender, LightType lightType);//转换光源
    
private:
    
    void addSprite();//添加精灵
    void addLights();//添加光源
    
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();//帧更新
    
    //设置摄像机位置
    auto s = Director::getInstance()->getWinSize();
    //参数1:透视相机的视野,通常在40-60度范围
    //参数2:相机的长宽比,通常视窗的宽度除以视窗的高度
    //参数3:近点平面距离
    //参数4:原点平面距离
    auto camera = 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控件
    TTFConfig ttfConfig("fonts/arial.ttf", 30);
    _ambientLightLabel = Label::createWithTTF(ttfConfig,"Ambient Light ON");
    _ambientLightLabel->retain();
    auto menuItem0 = MenuItemLabel::create(_ambientLightLabel, CC_CALLBACK_1(LightTest::SwitchLight,this,LightType::AMBIENT));
    _directionalLightLabel = Label::createWithTTF(ttfConfig,"Directional Light OFF");
    _directionalLightLabel->retain();
    auto menuItem1 = MenuItemLabel::create(_directionalLightLabel, CC_CALLBACK_1(LightTest::SwitchLight,this,LightType::DIRECTIONAL));
    _pointLightLabel = Label::createWithTTF(ttfConfig,"Point Light OFF");
    _pointLightLabel->retain();
    auto menuItem2 = MenuItemLabel::create(_pointLightLabel, CC_CALLBACK_1(LightTest::SwitchLight,this,LightType::POINT));
    _spotLightLabel = Label::createWithTTF(ttfConfig,"Spot Light OFF");
    _spotLightLabel->retain();
    auto menuItem3 = MenuItemLabel::create(_spotLightLabel, CC_CALLBACK_1(LightTest::SwitchLight,this,LightType::SPOT));
    auto menu = 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();
}
//添加精灵
void LightTest::addSprite()
{
    auto s = Director::getInstance()->getWinSize();
    
    {
        //创建3D对象,c3b是二进制文件,通过FBX模型文件进行二次转换得到。
        //obj:FBX是一种通用导出格式,可通过maya和max导出,maya和max默认导出obj格式文件。
        //c3t:通过FBX模型文件转换后生成的Json文件,体积大载入慢,不提倡使用
        //c3b:二进制文件,数据内容与c3t一样,体积小,速度快,提倡使用
        //注意:.c3b文件的使用需和它对应的贴图拷贝到Resource目录下,否则,运行时找不到资源。
        std::string fileName = "orc.c3b";
        //创建3D精灵对象
        auto sprite = Sprite3D::create(fileName);
        sprite->setRotation3D(Vec3(0.0, 180.0, 0.0));
        sprite->setPosition(Vec2(0.0, 0.0));
        sprite->setScale(2.0);
        //创建3D精灵对象
        auto sp = Sprite3D::create("axe.c3b");
        //通过骨骼名称获得连接点
        sprite->getAttachNode("Bip001 R Hand")->addChild(sp);
        //创建3D动画
        auto animation = Animation3D::create(fileName);
        if (animation)
        {
            auto animate = Animate3D::create(animation);
            sprite->runAction(RepeatForever::create(animate));//3D精灵执行3D动画
        }
        
        addChild(sprite);
        //设置精灵的Mask,该值与相机的flag进行&运算为真,则对相机可见
        sprite->setCameraMask(2);
    }
    
    {
        //同上
        std::string fileName = "sphere.c3b";
        auto sprite = Sprite3D::create(fileName);
        sprite->setPosition(Vec2(30.0, 0.0));
        addChild(sprite);
        sprite->setCameraMask(2);
    }
    
    {
        //同上
        std::string fileName = "sphere.c3b";
        auto sprite = Sprite3D::create(fileName);
        sprite->setScale(0.5f);
        sprite->setPosition(Vec2(-50.0, 0.0));
        addChild(sprite);
        sprite->setCameraMask(2);
    }
    
    {
        //同上
        std::string fileName = "sphere.c3b";
        auto sprite = Sprite3D::create(fileName);
        sprite->setScale(0.5f);
        sprite->setPosition(Vec2(-30.0, 10.0));
        addChild(sprite);
        sprite->setCameraMask(2);
    }
}
//添加光源
void LightTest::addLights()
{
    auto s = 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, 200));
    _directionalLight->retain();
    _directionalLight->setEnabled(false);//光源关闭
    addChild(_directionalLight);
    _directionalLight->setCameraMask(2);//确保相机可见
    
    //点光,参数1:光源的位置,参数2:光源的颜色。参数3:光源范围
    _pointLight = PointLight::create(Vec3(0.0f, 0.0f, 0.0f), Color3B(200, 200, 200), 10000.0f);
    _pointLight->retain();
    _pointLight->setEnabled(false);//光源关闭
    addChild(_pointLight);
    _pointLight->setCameraMask(2);//确保相机可见
    
    //聚光,参数1:方向。参数2:位置。参数3:颜色,参数4:内圆弧度。参数5:外圆弧度。参数6:光源范围
    _spotLight = SpotLight::create(Vec3(-1.0f, -1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Color3B(200, 200, 200), 0.0, 0.5, 10000.0f);
    _spotLight->retain();
    _spotLight->setEnabled(false);//光源关闭
    addChild(_spotLight);
    _spotLight->setCameraMask(2);//确保相机可见
    
    {
        auto tintto1 = TintTo::create(4, 0, 0, 255);
        auto tintto2 = TintTo::create(4, 0, 255, 0);
        auto tintto3 = TintTo::create(4, 255, 0, 0);
        auto tintto4 = TintTo::create(4, 255, 255, 255);
        auto seq = Sequence::create(tintto1,tintto2, tintto3, tintto4, nullptr);
        _ambientLight->runAction(RepeatForever::create(seq));//光源执行渐隐动作
    }
    
    {
        auto tintto1 = TintTo::create(4, 255, 0, 0);
        auto tintto2 = TintTo::create(4, 0, 255, 0);
        auto tintto3 = TintTo::create(4, 0, 0, 255);
        auto tintto4 = TintTo::create(4, 255, 255, 255);
        auto seq = Sequence::create(tintto1,tintto2, tintto3, tintto4, nullptr);
        _directionalLight->runAction(RepeatForever::create(seq));//光源执行渐隐动作
    }
    
    {
        auto tintto1 = TintTo::create(4, 255, 0, 0);
        auto tintto2 = TintTo::create(4, 0, 255, 0);
        auto tintto3 = TintTo::create(4, 0, 0, 255);
        auto tintto4 = TintTo::create(4, 255, 255, 255);
        auto seq = Sequence::create(tintto2, tintto1, tintto3, tintto4, nullptr);
        _pointLight->runAction(RepeatForever::create(seq));//光源执行渐隐动作
    }
    
    {
        auto tintto1 = TintTo::create(4, 255, 0, 0);
        auto tintto2 = TintTo::create(4, 0, 255, 0);
        auto tintto3 = TintTo::create(4, 0, 0, 255);
        auto tintto4 = TintTo::create(4, 255, 255, 255);
        auto seq = Sequence::create(tintto3, tintto2, tintto1, tintto4, nullptr);
        _spotLight->runAction(RepeatForever::create(seq));//光源执行渐隐动作
    }
}
//帧更新
void LightTest::update( float delta )
{
    static float angleDelta = 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), 1.0, sinf(angleDelta + 4.0 * delta)));
    }
    
    angleDelta += delta;
    
//    update(delta);
}
//光源开关
void LightTest::SwitchLight( Ref* sender, LightType lightType )
{
    switch (lightType)
    {
        case LightType::AMBIENT:
        {
            char str[32];
            bool isON = !_ambientLight->isEnabled();
            sprintf(str, "Ambient Light %s", isON == true? "ON":"OFF");
            _ambientLight->setEnabled(isON);
            _ambientLightLabel->setString(str);
        }
            break;
            
        case LightType::DIRECTIONAL:
        {
            char str[32];
            bool isON = !_directionalLight->isEnabled();
            sprintf(str, "Directional Light %s", isON == true? "ON":"OFF");
            _directionalLight->setEnabled(isON);
            _directionalLightLabel->setString(str);
        }
            break;
            
        case LightType::POINT:
        {
            char str[32];
            bool isON = !_pointLight->isEnabled();
            sprintf(str, "Point Light %s", isON == true? "ON":"OFF");
            _pointLight->setEnabled(isON);
            _pointLightLabel->setString(str);
        }
            break;
            
        case LightType::SPOT:
        {
            char str[32];
            bool isON = !_spotLight->isEnabled();
            sprintf(str, "Spot Light %s", isON == true? "ON":"OFF");
            _spotLight->setEnabled(isON);
            _spotLightLabel->setString(str);
        }
            break;
            
        default:
            break;
    }
}

3、使用

在HelloWorldScene.cpp中的 createScene()中,创建LightTest的对象,加入Scene


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值