思路:
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();
}