opengl核心模式教程之二维变换和三维变换

提示

此教程在OpenGL核心模式入门使用教程全部完成的基础上操作。
只用修改渲染循环中的绘制部分(在绑定纹理单元之后)(写矩阵),以及顶点着色器中的内容(使用矩阵)。

请确保你已掌握二维变换和三维变换的相关知识,本文章只介绍如何应用到opengl核心模式中。

环境

已安装数学库

二维/三维变换

需要用到三个函数,三个函数封装了矩阵的基本二/三维变换运算,我们最终将运算后矩阵设置为着色器的全局变量,并对顶点左乘这些变换矩阵,从而实现变换。
注意:着色器,每次只处理一个顶点,类似流水线式处理

平移glm::translate(原矩阵, 平移向量);
向量三个值分别为xyz轴平移方向,二维情况下z=0

旋转 glm::rotate(原矩阵,角度, 旋转轴向量);
旋转轴向量可以为 glm::vec3(0.0f, 0.0f, 1.0f) ,二维情况下z设为1,表示该旋转轴是与z轴平行的向量。

缩放 glm::scale(原矩阵, 缩放向量);
向量三个值分别为xyz方向的缩放比例,二维情况下z可设为0

具体用法如下

        glm::mat4 transform = glm::mat4(1.0f); // 初始化单位矩阵
        /*变换一,平移旋转*/
        transform = glm::translate(transform, glm::vec3(0.5f, -0.5f, 0.0f));
        transform = glm::rotate(transform, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));//右乘在前面的矩阵,即新的旋转矩阵乘在旧矩阵的右边。
        //最终效果为  变换矩阵=平移矩阵*旋转矩阵。
        //而在顶点着色器中定义为 变换矩阵*顶点坐标。
        //由此导致,后设置的旋转矩阵先生效。

        unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");//找到全局变量在我们要的着色器中的位置
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));//把矩阵传给全局变量

        glBindVertexArray(VAO);//绑定vao给opengl上下文,之后着色器程序会调用vao的数据
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//绘制6个点

       /*变换二,平移旋转*/
        transform = glm::mat4(1.0f); // 重置为单位矩阵
        transform = glm::translate(transform, glm::vec3(-0.5f, 0.5f, 0.0f));//平移矩阵
        float scaleAmount = sin(glfwGetTime());//缩放值随时间变换
        transform = glm::scale(transform, glm::vec3(scaleAmount, scaleAmount, scaleAmount));//缩放矩阵
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, &transform[0][0]); // 这次把矩阵值数组的第一个元素的地址作为矩阵数组的内存指针值
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

三维变换时,会引入投影的概念

顶点着色器一般是如下,通过三个全局变量,来进行三种变换

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;

out vec2 TexCoord;

uniform mat4 model;//模型变换
uniform mat4 view;//观察变换
uniform mat4 projection;//投影变换

void main()
{
        // 注意opengl的乘法要从右向左运算,左乘的
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    TexCoord = aTexCoord;
}

注意事项

三维物体观察时需要开启深度测试,opengl就可以自动帮你计算物体前后遮盖的关系。前面的物体就会挡住后面的物体了。

glEnable(GL_DEPTH_TEST);//可以加在任意位置,只要在调用绘图函数之前。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//同时修改绘图循环里的这个函数,加上清空深度缓冲区

待续写

好文推荐http://geekfaner.com/shineengine/blog8_OpenGLESv2_7.html