天天看點

openGL 第十篇:坐标系統三 =》3D效果

思路:

1,立方體的每個面都是通過頂點數組進行拼接而成的。一個三角形3個頂點, 一個面由兩個三角形組成,總共6個面=》3*2*6 = 36 個頂點

2,這裡隻有一個立方體模型,即一個VAO  我們在此循環渲染了 cubeList 的length 個立方體。

3,立方體的位移都是通過模型矩陣來進行的。

4,渲染順序的問題導緻立方體怪怪的,我們需要開啟深度測試,開啟後每次循環都需要清除它。深度測試是openGL 自動完成的,我們隻需要在合适的時機開啟與清理即可。

coordinate3D.hpp 代碼:

#ifndef coordinate3D_hpp
#define coordinate3D_hpp

#include <stdio.h>

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <stdio.h>
#include "../../common/stb_image.h"

#include "../../common/shader.hpp"
#include "../../common/texture2D.hpp"
#include "../coordinateBase.hpp"
class coordinate3D{
public:
    GLFWwindow* window;
    
    coordinate3D(GLFWwindow* window);
   void show();
};
#endif /* coordinate3D_hpp */
           

coordinate3D.cpp 代碼:

/**
1,通過拼接6個面 形成一個 立方體
 2,因每個面都是由三角形組成,在一個面上重複繪制
 3,通過z緩沖(z-buffer)解決
 */
#include "coordinate3D.hpp"

using namespace::std;

   const unsigned int SCR_WIDTH = 800;
   const unsigned int SCR_HEIGHT = 600;
coordinate3D::coordinate3D(GLFWwindow* window){
    this->window = window;
}


void coordinate3D:: show()
{
    glEnable(GL_DEPTH_TEST);

    //着色器程式加載 編譯
    shader  ourShader("coordnateSystems/coordinate.vs", "coordnateSystems/coordinate.fs");

    // 2d => 3d
    /**
       立方體 6個面 * 每個面2個三角形 * 每個三角形3個點 = 36個點
     */
    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
    };

    unsigned int VBO, VAO, EBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // texture coord attribute
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);


    // 紋理
    texture2D *texture1 = new texture2D();
    texture2D * texture2 = new texture2D();
    texture1->setFormatSrcOrDes(GL_RGB, GL_RGB);
    texture1->createTexture("textures/container.jpg");
    texture2->setFormatSrcOrDes(GL_RGBA, GL_RGB);
    texture2->createTexture("textures/awesomeface.png");

    //設定紋理單元的位置
    ourShader.use();
    ourShader.setInt("texture1", 0);
    ourShader.setInt("texture2", 1);

    //立方體坐标
    glm::vec3 cubePositions[] = {
      glm::vec3( 10.0f,  -3.0f,  -20.0f),
      glm::vec3( 9.0f,  1.0f, -10.0f),
      glm::vec3(-11.0f, -0.2f, -20.5f),
      glm::vec3(-0.8f, -1.0f, -20.3f),
      glm::vec3( 10.4f, -0.4f, -30.5f),
      glm::vec3(-1.7f,  1.0f, -90.5f),
      glm::vec3( 1.3f, -1.0f, -10.5f),
      glm::vec3( 0.5f,  1.0f, -20.5f),
      glm::vec3( 0.5f,  0.2f, -1.5f),
      glm::vec3(-1.0f,  0.0f, -1.5f)
    };

    while (!glfwWindowShouldClose(window))
    {
        
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glActiveTexture(GL_TEXTURE0);
        texture1->bind();
        glActiveTexture(GL_TEXTURE1);
        texture2->bind();

        ourShader.use();

        /*****************   觀察矩陣    *******************/
        glm::mat4 view          = glm::mat4(1.0f);
        view  = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
        unsigned int viewLoc  = glGetUniformLocation(ourShader.ID, "view");
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view[0][0]);
      
        /*****************   投影矩陣    *******************/
        glm::mat4 projection    = glm::mat4(1.0f);
        projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
        ourShader.setMatrix4("projection",projection);

        //綁定VAO
        glBindVertexArray(VAO);
        
        //循環渲染length個立方體
        glm::vec3 *pbeg = begin(cubePositions);
        glm::vec3 *pend = end(cubePositions);
        auto length = pend - pbeg;
        for(unsigned int i = 0; i <length; i++)
        {
            /*****************   模型矩陣    *******************/
          glm::mat4 model = glm::mat4(1.0f);
          model = glm::translate(model, cubePositions[i]);
          float angle = 20.0f * (float)glfwGetTime();
          model = glm::rotate(model, glm::radians(angle), glm::vec3(0.0f, 1.0f, .0f));
          unsigned int modelLoc = glGetUniformLocation(ourShader.ID, "model");
          glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
            /**
            發送渲染指令
             */
          glDrawArrays(GL_TRIANGLES, 0, 36);
        }
      

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);

    glfwTerminate();
}


           

上一篇:openGL 第九篇:坐标系統二 =》 應用紋理旋轉

下一篇:openGL 第十一篇:錄影機一  =》基礎知識

繼續閱讀