您的位置:首页 > 移动开发 > Cocos引擎

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

2017-01-19 09:36 288 查看
笔者介绍:姜雪伟,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类中已讲解过,在这里就不罗嗦了,接下来给读者分析材质渲染。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息