700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > OpenGL绘制旋转立方体。

OpenGL绘制旋转立方体。

时间:2018-09-14 18:09:06

相关推荐

OpenGL绘制旋转立方体。

首先要用到glm库。在进行PVM变换时可以帮助我们方便地运算。

下载:/g-truc/glm/tags

首先是处理顶点数据,由于是一个正方体,有六个面,每个面两个三角形,一共36个点。输入顶点有顶点坐标和顶点的颜色值。这里的坐标是处在模型空间的坐标。

const float vertices[] = {//立方体数组-0.5f, -0.5f, -0.5f, 1.0f,0.0f,0.0f, //六个面,每个面两个三角形。0.5f, -0.5f, -0.5f, 1.0f,0.0f,0.0f, //每一行前三个为顶点的坐标,0.5f, 0.5f, -0.5f, 1.0f,0.0f,0.0f, //后三个值为顶点颜色值0.5f, 0.5f, -0.5f, 1.0f,0.0f,0.0f,-0.5f, 0.5f, -0.5f, 1.0f,0.0f,0.0f,-0.5f, -0.5f, -0.5f, 1.0f,0.0f,0.0f,-0.5f, -0.5f, 0.5f, 0.0f,1.0f,0.0f,0.5f, -0.5f, 0.5f, 0.0f,1.0f,0.0f,0.5f, 0.5f, 0.5f, 0.0f,1.0f,0.0f,0.5f, 0.5f, 0.5f, 0.0f,1.0f,0.0f,-0.5f, 0.5f, 0.5f, 0.0f,1.0f,0.0f,-0.5f, -0.5f, 0.5f, 0.0f,1.0f,0.0f,-0.5f, 0.5f, 0.5f, 0.0f,0.0f,1.0f,-0.5f, 0.5f, -0.5f, 0.0f,0.0f,1.0f,-0.5f, -0.5f, -0.5f, 0.0f,0.0f,1.0f,-0.5f, -0.5f, -0.5f, 0.0f,0.0f,1.0f,-0.5f, -0.5f, 0.5f, 0.0f,0.0f,1.0f,-0.5f, 0.5f, 0.5f, 0.0f,0.0f,1.0f,0.5f, 0.5f, 0.5f, 0.5f,0.0f,0.0f,0.5f, 0.5f, -0.5f, 0.5f,0.0f,0.0f,0.5f, -0.5f, -0.5f, 0.5f,0.0f,0.0f,0.5f, -0.5f, -0.5f, 0.5f,0.0f,0.0f,0.5f, -0.5f, 0.5f, 0.5f,0.0f,0.0f,0.5f, 0.5f, 0.5f, 0.5f,0.0f,0.0f,-0.5f, -0.5f, -0.5f, 0.0f,0.5f,0.0f,0.5f, -0.5f, -0.5f, 0.0f,0.5f,0.0f,0.5f, -0.5f, 0.5f, 0.0f,0.5f,0.0f,0.5f, -0.5f, 0.5f, 0.0f,0.5f,0.0f,-0.5f, -0.5f, 0.5f, 0.0f,0.5f,0.0f,-0.5f, -0.5f, -0.5f, 0.0f,0.5f,0.0f,-0.5f, 0.5f, -0.5f, 0.0f,0.0f,0.5f,0.5f, 0.5f, -0.5f, 0.0f,0.0f,0.5f,0.5f, 0.5f, 0.5f, 0.0f,0.0f,0.5f,0.5f, 0.5f, 0.5f, 0.0f,0.0f,0.5f,-0.5f, 0.5f, 0.5f, 0.0f,0.0f,0.5f,-0.5f, 0.5f, -0.5f, 0.0f,0.0f,0.5f};

很繁杂,但是一般模型都是导入的,不用自己去一个个顶点的写。

接下来根据坐标转换流程来写:

PVM变换矩阵就对应于这个过程。

model矩阵对应模型变换过程,将局部坐标转换到世界坐标。view矩阵对应

接下来是PVM变换矩阵。实际的变换顺序是“MVP”。Model矩阵用于将模型坐标转化为世界坐标。view矩阵用于从世界坐标转移到观察坐标,要设置观察摄像机的位置,观察方向和头顶方向。projection对应从观察空间到剪裁空间的变换,指定了坐标的范围。

在进入主循环后,得到pvm三个矩阵:

// Transform坐标变换矩阵glm::mat4 model(1);//model矩阵,局部坐标变换至世界坐标model = glm::translate(model, glm::vec3(0.0, 0.0, 0.0));model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(0.5f, 1.0f, 0.0f));model = glm::scale(model, glm::vec3(1.0f, 1.0f, 1.0f));glm::mat4 view(1);//view矩阵,世界坐标变换至观察坐标系view = glm::lookAt(camera_position, camera_position + camera_front, camera_up);glm::mat4 projection(1);//projection矩阵,投影矩阵projection = glm::perspective(glm::radians(fov), (float)screen_width / screen_height, 0.1f, 100.0f);

这里之前要设置view矩阵中摄像机的各参数:

glm::vec3 camera_position = glm::vec3(0.0f, 0.0f, 3.0f); // 摄像机位置glm::vec3 camera_front = glm::vec3(0.0f, 0.0f, -1.0f);// 摄像机方向glm::vec3 camera_up = glm::vec3(0.0f, 1.0f, 0.0f); // 摄像机上向量

以及projection矩阵中的视角:

float fov=45.0f;

首先计算的是model矩阵

首先要创建一个model矩阵,glm::mat4 model(1)创建一个4*4的单位矩阵。glm::translate()函数用于进行平移变换,将物体平移(0,0,0),也就是不变。glm::rotate()函数用于旋转。第二个参数为旋转角度,第三个参数为旋转轴。这里的glfwGetTime是获取glfw初始化到当前状态所经过的秒数。如果是一个常数的话,就不会旋转了。那是因为每次进入循环之后矩阵在初始状态,都旋转同一个角度,那么肯定就看不到旋转。每次循环旋转不同角度,且这个角度的大小随时间变换,才能看得到旋转效果。glm::scale()函数用于缩放,vec3指定x,y,z三个方向上的缩放比例。

glm::mat4 model(1);//model矩阵,局部坐标变换至世界坐标model = glm::translate(model, glm::vec3(0.0,0.0,0.0)); model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(0.5f, 1.0f, 0.0f)); model = glm::scale(model, glm::vec3(1.0f,1.0f,1.0f));

接着是view矩阵

首先还是要创建一个4*4的单位矩阵通过lookAt函数计算。第一个参数是相机位置,第二个参数是相机所正对的目标的坐标,这里用camera_position+camera_front(相机的方向)进行向量加法后可以得到相机正对的坐标。第三个参数是相机的上向量。

glm::mat4 view(1);//view矩阵,世界坐标变换至观察坐标系view = glm::lookAt(camera_position, camera_position + camera_front, camera_up);

最后是projection矩阵

这是一个投影透视矩阵第一个参数fov是角度值,定义了视野。对一个真实的观察效果,通常设置为45,如果要看到更多东西需要设置一个更大的值.第二个参数设置宽高比,也就是屏幕宽度比上屏幕高度。第三个和第四个参数设置了平截头体(也就是一个四棱台)的近和远平面。通常设置最近距离为0.1,最远距离为100.0。所有在近平面和远平面的顶点且处于平截头体内的顶点都会被渲染。

glm::mat4 projection(1);//projection矩阵,投影矩阵projection = glm::perspective(glm::radians(fov), (float)screen_width / screen_height, 0.1f, 100.0f);

以上对model,view,projection矩阵进行初始化后,还要将这三个矩阵传入着色器内。

glGetUniformLocation函数可以获得某个着色器中参数的位置,第一个参数为着色器id,第二个参数为该参数的名字

int model_location = glGetUniformLocation(shader.ID, "model");

glUniformMatrix4fv函数用于向指定位置传入一个4*4矩阵值。

glUniformMatrx4fv(model_location,1,GL_FALSE,glm::value_ptr(model));

接下来看顶点着色器的内容:

#version 330 corelayout (location = 0) in vec3 aPos;layout (location = 1) in vec3 PosColor;out vec3 positionColor;uniform mat4 model;uniform mat4 view;uniform mat4 projection;void main(){gl_Position = projection * view * model * vec4(aPos, 1.0);positionColor=PosColor;}

可以看到这里的参数和我们在程序内设置的是对应的。

注意顺序。由于opengl的向量是列向量,与行向量算的方式相反。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。