[OpenGL]MVP矩阵变换(坐标变换)

文章目录[x]
  1. 1:新建测试类
  2. 2:修改Render类

新建测试类


#pragma once

#include "../TestBed.h"

class HelloCoordinate : public TestBed
{

public:
    HelloCoordinate()
    {
    }

private:
    virtual const std::string GetShaderPath(const std::string shaderName) const override
    {
        return "SandBox/06_Coordinate/" + shaderName;
    }

};

 

修改Render类


Renderer::Renderer()
{
    GLCall(glEnable(GL_DEPTH_TEST)); //开启深度测试
}

void Renderer::Clear(float r /*= 0.0f*/, float g /*= 0.0f*/, float b /*= 0.0f*/, float a /*= 0.0f*/) const
{
    glClearColor(r, g, b, a);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 因为开启了深度测试,所以这里增加一个 GL_DEPTH_BUFFER_BIT
}

 

PerspectiveMVPMatrix
class PerspectiveMVPMatrix : public SubTestBed
{
    glm::mat4 m_Model = glm::identity<glm::mat4>();
    glm::mat4 m_View = glm::identity<glm::mat4>();
    glm::mat4 m_Projection;
public:
    PerspectiveMVPMatrix(const std::string& shaderPath) : SubTestBed(shaderPath) { }

    virtual void Setup() override
    {
        float vertices[] = {
            // --- 位置 ---   -- 纹理坐标 --
            -0.5f, -0.5f, 0,  0.0f, 0.0f,
            +0.5f, -0.5f, 0,  1.0f, 0.0f,
            +0.5f, +0.5f, 0,  1.0f, 1.0f,
            -0.5f, +0.5f, 0,  0.0f, 1.0f
        };

        unsigned int indices[] = {
            0, 1, 2,
            2, 3, 0
        };

        m_VA[0] = new VertexArray();
        m_VB[0] = new VertexBuffer(vertices, sizeof(vertices));
        VertexBufferLayout layout;
        layout.Push<float>(3);
        layout.Push<float>(2);
        m_VA[0]->AddBuffer(*m_VB[0], layout);
        m_IB[0] = new IndexBuffer(indices, 6);
        m_Texture[0] = new Texture("Resources/Textures/container.jpg");
        m_Texture[1] = new Texture("Resources/Textures/awesomeface.png");

        m_Model = glm::rotate(m_Model, glm::radians(-55.0f), glm::vec3(1, 0, 0)); // 绕x轴旋转-55度
        m_View = glm::translate(m_View, glm::vec3(0.0f, 0.0f, -3.0f));
        m_Projection = glm::perspective(glm::radians(45.0f), SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.1f, 100.0f);

        m_VB[0]->UnBind();
        m_VA[0]->UnBind();
        m_IB[0]->UnBind();
        m_Texture[0]->UnBind();
        m_Texture[1]->UnBind();
    }

    virtual void Render() override
    {
        m_Texture[0]->Bind(0);
        m_Texture[1]->Bind(1);
        this->m_Renderer.Draw(*m_VA[0], *m_IB[0], *m_Shader[0]);
        m_Shader[0]->SetUniform1i("u_Texture0", 0);
        m_Shader[0]->SetUniform1i("u_Texture1", 1);
        m_Shader[0]->SetUniformMat4f("u_Model", m_Model);
        m_Shader[0]->SetUniformMat4f("u_View", m_View);
        m_Shader[0]->SetUniformMat4f("u_Projection", m_Projection);
    }
};
#Shader Vertex
#version 330 core

layout(location = 0) in vec4 a_position;
layout(location = 1) in vec2 a_TexCoord;

out vec2 v_TexCoord;

uniform mat4 u_Model;
uniform mat4 u_View;
uniform mat4 u_Projection;

void main()
{
    gl_Position = u_Projection * u_View * u_Model * a_position;
    v_TexCoord = a_TexCoord;
}


#Shader Fragment
#version 330 core

out vec4 fragColor;

in vec2 v_TexCoord;

uniform sampler2D u_Texture0;
uniform sampler2D u_Texture1;

void main()
{
    vec4 texColor0 = texture(u_Texture0, v_TexCoord);
    vec4 texColor1 = texture(u_Texture1, v_TexCoord);
    fragColor = mix(texColor0, texColor1, 0.2);
};

 

Single3DBox
class Single3DBox : public SubTestBed
{
protected:
    glm::mat4 m_Model = glm::identity<glm::mat4>();
public:
    Single3DBox(const std::string& shaderPath) : SubTestBed(shaderPath) { }

    virtual void Setup() override
    {
#pragma region vertices
        float vertices[] = {
            -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
             0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
             0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
             0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
            -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
            -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

            -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
             0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
             0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
             0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
            -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
            -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

            -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
            -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
            -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
            -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
            -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
            -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

             0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
             0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
             0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
             0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
             0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
             0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

            -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
             0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
             0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
             0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
            -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
            -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

            -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
             0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
             0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
             0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
            -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
            -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
        };
#pragma endregion
        m_VA[0] = new VertexArray();
        m_VB[0] = new VertexBuffer(vertices, sizeof(vertices));
        VertexBufferLayout layout;
        layout.Push<float>(3);
        layout.Push<float>(2);
        m_VA[0]->AddBuffer(*m_VB[0], layout);
        m_Texture[0] = new Texture("Resources/Textures/container.jpg", GL_REPEAT, GL_REPEAT);
        m_Texture[1] = new Texture("Resources/Textures/awesomeface.png", GL_REPEAT, GL_REPEAT);

        m_Model = glm::rotate(m_Model, glm::radians(-55.0f), glm::vec3(1, 0, 0));
        glm::mat4 view = glm::identity<glm::mat4>();
        view = glm::translate(view, glm::vec3(0.0f, 0.0f, -5.0f));
        glm::mat4 projection = glm::perspective(glm::radians(45.0f), SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.1f, 100.0f);

        m_Shader[0]->Bind();
        m_Shader[0]->SetUniformMat4f("u_View", view);
        m_Shader[0]->SetUniformMat4f("u_Projection", projection);

        m_VB[0]->UnBind();
        m_VA[0]->UnBind();
        m_Texture[0]->UnBind();
        m_Texture[1]->UnBind();
    }


    virtual void Render() override
    {
        m_Texture[0]->Bind(0);
        m_Texture[1]->Bind(1);

        this->m_Renderer.Draw(*m_VA[0], 36, *m_Shader[0]);
        m_Shader[0]->SetUniform1i("u_Texture0", 0);
        m_Shader[0]->SetUniform1i("u_Texture1", 1);
        m_Model = glm::identity<glm::mat4>();
        m_Model = glm::rotate(m_Model, glm::radians(20 * (float)(glfwGetTime())), glm::vec3(0.6f, 1, 0.3f));
        m_Shader[0]->SetUniformMat4f("u_Model", m_Model);
    }
};

 

// Shader同上

 

Multi3DBox
class Multi3DBox : public Single3DBox
{
    std::vector<glm::vec3> m_CubePositions;
public:
    Multi3DBox(const std::string& shaderPath) : Single3DBox(shaderPath) { }

    virtual void Setup() override
    {
        Single3DBox::Setup();

        m_CubePositions.push_back(glm::vec3(0.0f, 0.0f, 0.0f));
        m_CubePositions.push_back(glm::vec3(2.0f, 5.0f, -15.0f));
        m_CubePositions.push_back(glm::vec3(-1.5f, -2.2f, -2.5f));
        m_CubePositions.push_back(glm::vec3(-3.8f, -2.0f, -12.3f));
        m_CubePositions.push_back(glm::vec3(2.4f, -0.4f, -3.5f));
        m_CubePositions.push_back(glm::vec3(-1.7f, 3.0f, -7.5f));
        m_CubePositions.push_back(glm::vec3(1.3f, -2.0f, -2.5f));
        m_CubePositions.push_back(glm::vec3(1.5f, 2.0f, -2.5f));
        m_CubePositions.push_back(glm::vec3(1.5f, 0.2f, -1.5f));
        m_CubePositions.push_back(glm::vec3(-1.3f, 1.0f, -1.5f));
    }


    virtual void Render() override
    {
        m_Texture[0]->Bind(0);
        m_Texture[1]->Bind(1);

        for (unsigned int i = 0; i < m_CubePositions.size(); i++)
        {
            this->m_Renderer.Draw(*m_VA[0], 36, *m_Shader[0]);
            m_Shader[0]->SetUniform1i("u_Texture0", 0);
            m_Shader[0]->SetUniform1i("u_Texture1", 1);
            m_Model = glm::identity<glm::mat4>();
            m_Model = glm::translate(m_Model, m_CubePositions[i]);
            m_Model = glm::rotate(m_Model, glm::radians(20 * (i + 1) * (float)(glfwGetTime())), glm::vec3(0.6f, 1, 0.3f));
            m_Shader[0]->SetUniformMat4f("u_Model", m_Model);
        }

    }
};

// Shader同上

 

练习题3: 使用模型矩阵只让是3倍数的箱子旋转(以及第1个箱子),而让剩下的箱子保持静止。
// 替换掉上面 Multi3DBox 中的如下代码即可
// Old: 
// m_Model = glm::rotate(m_Model, glm::radians(20 * (i + 1) * (float)(glfwGetTime())), glm::vec3(0.6f, 1, 0.3f));
// New:
m_Model = glm::rotate(m_Model, glm::radians(20 * !(i % 3) * (float)(glfwGetTime())), glm::vec3(0.6f, 1, 0.3f));

 

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像