链接: https://pan.baidu.com/s/1cBTTbbzRCVBCX_H4jf6qMA 提取码: kj8w
一、实验概况及原理
本次实验利用OpenGL的GLFW库以及glm进行几何变换操作,月球的自转和公转分别用了其他两个按键进行了控制,核心思想是利用旋转以及平移的操作顺序以及旋转操作的实现对象让月球实现了自转和公转,详情可见实验结果部分。
同时实验也可以进行视角的变换,一共实现了以下两种变换。
1、通过按键A、S、W、D四个按键控制方向进行视角转换。
2、通过系统时间控制视角旋转。
GLFW是一个用于OpenGL应用程序开发的可移植库。它处理与OpenGL上下文创建、窗口管理、分辨率切换、键盘、鼠标、操纵杆和时间输入以及基本线程设施相关的系统特定任务。
GLEW能自动识别当前平台所支持的全部OpenGL高级扩展涵数。只要包含glew.h头文件,就能使用gl,glu,glext,wgl,glx的全部函数。GLEW支持目前流行的各种操作系统
二、实验代码说明
1、定义第三个球,即月球的model、view、projection。
model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
view = glm::mat4(1.0f);
projection = glm::mat4(1.0f);
model = glm::scale(model, glm::vec3(0.1, 0.1, 0.1));
model = glm::rotate(model, glm::radians(rev_angle), glm::vec3(0.0f, 1.0f, 0.0f)); model = glm::translate(model, glm::vec3(16, 0, 0));//先平移到地球
model = glm::rotate(model, glm::radians(rev_angle13), glm::vec3(0.0f, 1.0f, 0.0f));//再绕地球开始旋转
model = glm::rotate(model, glm::radians(moon_rev_angle), glm::vec3(0.0f, 1.0f, 0.0f));//最后绕地球平移一段距离
model = glm::translate(model, glm::vec3(4, 0, 0));
model = glm::rotate(model, glm::radians(rev_angle13), glm::vec3(0.0f, 1.0f, 0.0f));
model = glm::rotate(model, glm::radians(moon_rotate_angle), glm::vec3(0.0f, 1.0f, 0.0f));
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
//view = glm::lookAt(glm::vec3(camX, 0.0f, camZ), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
2、增加变量监听按键控制月球自转和公转
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_E) {
rev_angle += 10.0; //地球公转并且月球绕地球公转
}
if (key == GLFW_KEY_F)
rotate_angle += 10.0;//地球自转
if (key == GLFW_KEY_T)
moon_rev_angle += 10.0;//月球绕地球公转
if (key == GLFW_KEY_R)
moon_rotate_angle += 10.0;//月球自转
}
3、AWSD按钮控制视角移动,ESC按键退出窗口
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
const float cameraSpeed = 0.01f;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
{
cameraPos += cameraSpeed * cameraFront;
}
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
cameraPos -= cameraSpeed * cameraFront;
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
}
4、视角移动的两种变换的变换矩阵代码
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);//WASD控制窗口移动
view = glm::lookAt(glm::vec3(camX, 0.0f, camZ), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));//视角随系统时间移动
三、实验运行结果(包含用户输入和输出)
1、 月球的公转
1 首先第一步,先把月球平移到地球中心。
2 第二步,让月球旋转;
3 第三步,平移一个地月距离。
2、 月球的自转。
月球的自转,利用将自转的旋转变换操作放到平移了地月距离之后,这样就形成了先平移再旋转,根据上一次实验的经验,会形成月球自转的实现。
3、 AWSD按键控制视角移动。
4、 时间控制视角移动。