思路:
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 第十一篇:錄影機一 =》基礎知識