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类中已讲解过,在这里就不罗嗦了,接下来给读者分析材质渲染。





已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页