Cocos2d-x 3.x 图形学渲染系列二十

笔者介绍:姜雪伟IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。

接下来给读者介绍关于材质渲染也就是通常说的Shader渲染,3D开发不论是游戏还是VR/AR都会涉及到材质的渲染处理,作为程序开发者,这些是必不可少的,下面给读者介绍一下关于Cocos2d-x中的3D渲染。

模型品质的好坏在一定程度上也是由材质的渲染决定的,在给读者具体介绍Shader编写之前,先把材质的加载流程介绍给读者,默认情况下,也就是不需要对材质做处理的情况下,直接加载模型即可,因为模型本身也会包含纹理贴图信息,只需要执行如下代码段即可:

	addSearchFilePath("C_model005");
	//创建模型
	auto sprite1 = Sprite3D::create("C_model005_01.c3t");
	sprite1->setPosition3D(Vec3(0, 0, 0));
	sprite1->setRotation3D(Vec3(-90, 0, 0));
	addChild(sprite1);

上面的代码段就是把模型加载到场景中,注意addchild是必须要加的,它的作用表示将加载的模型作为场景的孩子结点加入到场景中。如果不加addchild函数,模型将不会显示。另外也可以通过setPosition函数和setRotation函数设置模型在世界空间的位置和旋转方向。材质渲染的处理方式有两种:一种是通过加载material脚本文件做渲染处理,另一种是通过加载vert顶点着色器和frag片段着色器的方式。接下来先给读者介绍加载material文件的处理,代码片段如下所示:

	//创建材质
	auto mat = Sprite3DMaterial::createWithFilename("c_model005_black.material");
	//设置材质
	auto _state_sprite1 = mat->getTechniqueByIndex(0)->getPassByIndex(0)->getGLProgramState();
	sprite1->setMaterial(mat);

在上述代码片段中,调用了函数createWithFilename用于材质的创建,实现如下所示:

Sprite3DMaterial* Sprite3DMaterial::createWithFilename(const std::string& path)
{
auto validfilename = FileUtils::getInstance()->fullPathForFilename(path);
	if (validfilename.size() >0) {
	auto it = _materials.find(validfilename);
		if (it != _materials.end())
			return (Sprite3DMaterial*)it->second->clone();

		auto material = new (std::nothrow) Sprite3DMaterial();
		if (material->initWithFile(path))
        {
            material->_type = Sprite3DMaterial::MaterialType::CUSTOM;
		_materials[validfilename] = material;

			return (Sprite3DMaterial*)material->clone();
        }
			CC_SAFE_DELETE(material);
    }
	return nullptr;
}

createWithFilename函数中调用了initWithFile函数对材质进行初始化操作,函数如下所示:


bool Material::initWithFile(const std::string& validfilename)
{
	Properties* properties = Properties::createNonRefCounted(validfilename);

	// 获取第一个材质
	parseProperties((strlen(properties->getNamespace()) >0) ? properties : properties->getNextNamespace());

	CC_SAFE_DELETE(properties);
	return true;
}

	initWithFile函数的功能主要是加载材质,同时调用了接口parseProperties用于脚本解析,parseProperties函数已给读者介绍过,这里就不多说了。另一种材质渲染的方式是直接加载vert顶点着色器和frag片段着色器,也可以实现对材质的渲染,比如在Cocos2d-x引擎中实现天空盒的渲染,代码段如下所示:
	//加载天空盒顶点着色器和片段着色器
	 auto shader = GLProgram::createWithFilenames("Sprite3DTest/cube_map.vert",
	"Sprite3DTest/cube_map.frag");
    auto state = GLProgramState::create(shader);

    // 加载天空盒纹理图片
    _textureCube = TextureCube::create("Sprite3DTest/skybox/left.jpg",
                                       "Sprite3DTest/skybox/right.jpg",
					"Sprite3DTest/skybox/top.jpg",
					"Sprite3DTest/skybox/bottom.jpg",
                                       "Sprite3DTest/skybox/front.jpg",
                                       "Sprite3DTest/skybox/back.jpg");
   //设置纹理参数
    Texture2D::TexParams tRepeatParams;
    tRepeatParams.magFilter = GL_LINEAR;
    tRepeatParams.minFilter = GL_LINEAR;
    tRepeatParams.wrapS = GL_MIRRORED_REPEAT;
    tRepeatParams.wrapT = GL_MIRRORED_REPEAT;
    _textureCube->setTexParameters(tRepeatParams);

    // 把纹理取样参数传递给自定义的Shader脚本文件
    state->setUniformTexture("u_cubeTex", _textureCube);

    // 创建天空盒
    _skyBox = Skybox::create();
    _skyBox->setCameraMask(s_CM[LAYER_BACKGROUND]);
    _skyBox->setTexture(_textureCube);
    _skyBox->setScale(700.f);

在上述代码片段中调用了接口setUniformTexture函数对自定义的Shader进行赋值操作,它的作用是把图片传递给Shader中已定义的纹理参数,GPU会对其进行渲染。这些函数接口在GLProgram类中已讲解过,在这里就不罗嗦了,接下来给读者分析材质渲染。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海洋_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值