cocos2d-x lua 3D模块学习(1)----摄像机

因为工作需要,要在原来的项目基础上使用cocos2d-x 的3D引擎部分

版本是3.13,开发语言是lua ,网上是一点关于cocos lua 的3D教程都没有,只能去啃老外的英文版的,所以自己写一个也记录一下吧!

cocos2d-x 3D模块默认是关闭的,应该是3.X添加的,源代码写的并不是很好,粗略看了一下实现,有些地方都是implementes,待以后实现什么的,而且使用的物理引擎是Bullet,和2D的部分不可以公用,这一点Unity完爆了cocos!

由于零零散散的学习3D和openGL也有了一段时间,笔者对于3D游戏的学习有几点认识,尤其是对于2D工程师转向3D,需要学习如下内容:

1)3D思想,这是比较重要的,也是个人认为比较难的,包括对于摄像机光照等这些概念的理解等等,另外就是把自己的思维扩展到三维空间。

2)新api的学习,这点其实cocos2D-X程序员转到3D其实是比较方便的,总体的程序构建思想并没有变化

3)新语言,shader的学习在3D中比较重要;另外材质文件的制作也是一个新的内容的学习。

正文

本篇首先介绍摄像机,其实2D时cocos引擎就有摄像机这个概念,每个节点都拥有一个摄像机类,当时的摄像机类的使用实例就是实现节点对象的缩放旋转,因为节点本身就自带这些功能,所以摄像机使用的场合并不多,笔者只在有一次为了实现一个正面视角向前进效果的时候为了让场景有一个“假”3D的效果的时候使用了setEyeXYZ之类的接口,但在3D中,摄像机是个很重要的概念,因为如果直接在设备上显示标准几何模型的坐标,可能屏幕上什么都看不到,因为模型坐标的范围可能不与设备坐标范围相对应,显示器本身是个平面固定的二维矩形区域,显示一个三维模型需要做相应的投影和变化。

需要说明的是在cocos2D-X 2.0时代,摄像机类继承自,而现在摄像机类是Node节点类的子类,可以作为子节点加到任何一个节点上

openGL中支持两种createPerspective类型的摄像机,分别是透视摄像机(有近大远小的透视效果)和正交摄像机(一般用于建筑设计图等等)。

第一个参数是透视相机的可视角度 (角度制,一般是在40-60度之间),它的大小决定了视角的横向宽度

第二个参数是相机的长宽比(通常会使用视窗的宽度除以视窗的高度),一般是屏幕的宽高比

第三个参数和第四个参数分别是视锥顶点到近截面和远截面的距离

创建好了之后,你还可以通过getNearPlane和getFarPlane获得视锥顶点到近截面和远截面的距离

下面上lua代码:

投影摄像机:也就是3D摄像机,近大远小,是真正的视觉摄像机,适合做3D游戏!

local scene = cc.Director:getInstance():getRunningScene()
    if nil ~= scene then
        self._physicsScene = scene
        local physics3DWorld = scene:getPhysics3DWorld()
        physics3DWorld:setDebugDrawEnable(false)

        local size = cc.Director:getInstance():getWinSize()
        self._camera = cc.Camera:createPerspective(30.0, size.width / size.height, 1.0, 1000.0)
        self._camera:setPosition3D(cc.vec3(0.0, 50.0, 100.0))
        self._camera:lookAt(cc.vec3(0.0, 0.0, 0.0), cc.vec3(0.0, 1.0, 0.0))
        self._camera:setCameraFlag(cc.CameraFlag.USER1)
        self:addChild(self._camera)
end

createPerspective的参数:

第一个参数是透视相机的可视角度 (角度制,一般是在40-60度之间),它的大小决定了视角的横向宽度

第二个参数是相机的长宽比(通常会使用视窗的宽度除以视窗的高度),一般是屏幕的宽高比

第三个参数和第四个参数分别是视锥顶点到近截面和远截面的距离

创建好了之后,你还可以通过getNearPlane和getFarPlane获得视锥顶点到近截面和远截面的距离

注意!!!lookAt一定要放在setPosition3D之后,不然会看不见,然后setCameraFlag一定要写!不然就是默认相机的0!

最后一定要addChild进去,不然没用!

然后创建好了之后,之后的精灵啊图片啊,只要setCameraMask(cc.CameraFlag.USER1)就可以被摄像机看见啦,只有3D摄像机看得见! 

正交摄像机:是2D摄像机,非常简单,cocos2d-x 的默认相机就是2D摄像机,也就是近的远的是一样大的,没有放大效果!

创建方法:

    self._camera = cc.Camera:createOrthographic(winSize.width, winSize.height, -100.0, 100.0)
    self._camera:setDepth(4.0)
    self._camera:setPosition3D(cc.vec3(0.0,0.0,0.0))
    self._camera:setCameraFlag(cc.CameraFlag.USER2)
    self:addChild(self._camera)

注意这里如果是2D界面里面创建2D摄像机,一定要setDepth(),数值比0大就行,这样添加进去的组件就会显示在默认相机上面,不会出现3D被2D覆盖的现象

要想被这个摄像机看见,也可以使用setCameraMask(cc.CameraFlag.USER2),和摄像机的flag一样就可以被看见,不然就被默认相机看见!

默认摄像机用于绘制ui,它是最后被绘制的;一般来说需要一个另外的摄像机来绘制3d物体而不是默认摄像机,当深度测试未开启时,可以调整摄像机的绘制顺序;所有摄像机的绘制顺序都是先绘制2d物体和不透明3d物体,然后绘制透明3d物体。

通过调用setDepth可以设置摄像机的绘制顺序,越大的深度越绘制的靠上,所以默认摄像机默认是0,其他摄像机默认是1。

一个物体单位需要经过模型变换,视图变换和投影变换才能转换成opengl需要的信息,摄像机类可以通过调用一些函数分别获得这三个阶段的矩阵。









猜你喜欢

转载自blog.csdn.net/qq_37508511/article/details/80334470