1、 移动鼠标可以控制相机的视角
2、 滚动鼠标滚轮从而拉近/远视角
3、 按键盘的空格键重置相机位置
4、 按键盘的w、s,控制人物向前后移动
5、 按键盘的a、d控制人物向左、右转
6、 按键盘的ESC键退出游戏
场景设计和显示
通过层级建模的方式建立多个虚拟物体,由多个虚拟物体组成一个虚拟场景,
添加纹理
为场景中主要物体添加纹理贴图 。
添加光照、材质、阴影效果
实现光照效果、材质、阴影等。
用户交互实现视角切换完成对场景的任意角度浏览
完成相机变换。
通过交互控制物体
实现物体的变换,通过键盘和鼠标实现场景中物体的控制(移动,旋转,缩放等等)。
首先obj文件中分别含有顶点信息、纹理信息、颜色信息、法线信息,我们需要将所有的信息进行读取,并且进行保存。
顶点信息是以v开头的字符串、纹理信息是以vt开头的字符串、法线信息是以vn开头的字符串,因此我们只需要识别对应的字符,即可保存相关的信息。
因为obj文件中并没有颜色信息,因此我们可以使用法线信息来代替颜色信息(tips:需要将法线信息进行取正操作)
具体的实现如下:
将obj文件中的信息保存完成之后,我们需要进行存储操作,即将对应的信息进行重组,从而获得我们需要的信息,具体过程如下:
我们读取一个汽车模型来进行测试,结果如下图:
首先我们定义一个light类,然后添加和光照相关的一些参数到类当中,如下图:
然后我们需要添加一个全局光照,并且设置光照点的位置、环境光、镜面反射、衰减系数,如下:
最后对于每一个模型,我们都给它添加一些光照参数,使之看起来更加真实,如下图:
首先我们需要先设置阴影投影矩阵,如下:
然后进行对每一个模型,我们都进行独立的阴影绘制,如下:
最后查看阴影效果,如下图:
对于相机视角的移动,我们通过改变俯仰角、偏航角、滚轮角来进行实现
经过数学推导之后,可以得到:
即,我们通过改变俯仰角、偏航角可以变更相机的视角方向。
这里我们通过使用鼠标位置移动,来改变相机视角,在main函数当中绑定mousepos函数:
然后我们控制俯仰角不能小于-89,也不能小于89,从而保证用户只能看到天空或脚下但是不能更进一步超越过去,实现如下:
然后我们通过滚动鼠标滚轮来控制相机的视野大小。在主函数当中当顶sroll函数:
然后我们在主函数中使用glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED),从而将鼠标的光标进行隐藏,将鼠标定在我们的场景中,从而提高用户体验。
这样我们就可以通过滚动鼠标滚轮、移动鼠标,从而达到控制相机视角的效果。
首先,先确定人物各个模块关系,如下图:
即:body->head->hat
Body->left_upper_arm->left_lower_arm
Body->right_upper_arm->right_lower_arm
Body->left_upper_leg->left_lower_leg
Body->right->upper_leg->right->lower_leg
然后我们首先为每一个部位单独写一个绘制函数,方便后续在人物总体绘制函数当中调用绘制
以body为例:
接着,创建一个用于保存变换矩阵的类,用于保存各个层级的变换矩阵,如下图:
然后写一个人物绘制主函数,在主函数当中调用上述的函数,进行依次绘制,如下图:
为了使人物的移动不那么硬核,我们为每一部位添加一个关节角,然后在键盘控制人物进行移动的时候改变关节角,从而实现手、脚在人物移动的过程中进行规律的摆动,如下图:
首先实现人物在移动的过程中,手和脚的摆动。
设置一个记录帧数的变量,然后在使用键盘控制人物移动的时候,改变该变量,如下图:
然后编写一个函数,用于改变人物的关节角,如下图:
接着我们写一个改变人物位置的函数,方便键盘函数的调用,如下图:
然后在键盘回应函数当中,写入当按下w、s键时,分别改变人物的位置参数,如下图:
为了实现按下键盘w、s的时候,人物朝前、后移动,需要根据人物的朝向(关节角)来改变人物的位置参数,数学推导如下:
函数如下图:
然后在键盘的a、d被按下时,改变人物的朝向(关节角),如下图:
这样就实现了通过键盘的a、d改变人物朝向,通过键盘的w、s控制人物向前(后)移动。
效果图如下:
为了让场景更加写实,添加一个天空盒。
首先需要获取天空盒资源,即一个立方体贴图,如下:
然后分别绘制六个正方形,并且将立方体贴图分别贴到对应的正方形中,六个正方形需要构成一个完整的正方体,数据如下:
然后为back、front、top、buttom、left、right面分别写一个绑定纹理贴图的函数,如下图:
然后在主函数中进行绘制,如下:
天空盒的效果如下: