当前位置:网站首页>第 7 篇:绘制旋转立方体
第 7 篇:绘制旋转立方体
2022-07-28 20:14:00 【代码骑士】
目录
1、Z-缓冲


//开启深度测试
glEnable(GL_DEPTH_TEST);2、GLM库函数

3、PVM矩阵

4、PVM矩阵的使用
我们需要引入GLM函数库的头文件:
#include<glm/glm.hpp>
#include<glm/gtc/matrix_transform.hpp>
#include<glm/gtc/type_ptr.hpp>设置vew矩阵的相关参数:
//相机参数
glm::vec3 camera_position = glm::vec3(0.0f, 0.0f, 3.0f); //摄像机位置
glm::vec3 camera_front = glm::vec3(0.0f, 0.0f, -1.0f); //摄像机方向
glm::vec3 camera_up = glm::vec3(0.0f, 1.0f, 0.0f); //摄像机上向量设置project矩阵视野fov:
float fov = 45.0f;
// Transform坐标变换矩阵
glm::mat4 model(1);//model矩阵,局部坐标变换至世界坐标
model = glm::translate(model, glm::vec3(0.0,0.0,0.0));
model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(0.5f, 1.0f, 0.0f));
model = glm::scale(model, glm::vec3(1.0f,1.0f,1.0f)); 
glm::mat4 view(1);//view矩阵,世界坐标变换至观察坐标系
view = glm::lookAt(camera_position, camera_position + camera_front, camera_up);

glm::mat4 projection(1);//projection矩阵,投影矩阵
projection = glm::perspective(glm::radians(fov), (float)screen_width / screen_height, 0.1f, 100.0f);

int model_location = glGetUniformLocation(shader.ID, "model"); //获取着色器内某个参数的位置

glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model));//写入参数值 
gl_Position=projection*view*model*vec4(aPos,1.0);5、工程文件结构

shader.h
#ifndef __SHADER_H__
#define __SHADER_H__
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "string"
class Shader
{
public:
unsigned int ID;
Shader(const GLchar* vertex_shader_path, const GLchar* fragment_shader_path);
~Shader();
void Use();
void SetBool(const std::string &name, bool value) const;
void SetInt(const std::string &name, int value) const;
void SetFloat(const std::string &name, float value) const;
void SetVec2(const std::string &name, const glm::vec2 &value) const;
void SetVec2(const std::string &name, float x, float y) const;
void SetVec3(const std::string &name, const glm::vec3 &value) const;
void SetVec3(const std::string &name, float x, float y, float z) const;
void SetVec4(const std::string &name, const glm::vec4 &value) const;
void SetVec4(const std::string &name, float x, float y, float z, float w) const;
void SetMat2(const std::string &name, const glm::mat2 &value) const;
void SetMat3(const std::string &name, const glm::mat3 &value) const;
void SetMat4(const std::string &name, const glm::mat4 &value) const;
private:
int GetShaderFromFile(const GLchar* vertex_shader_path, const GLchar* fragment_shader_path,
std::string *vertex_shader_code, std::string *fragment_shader_code);
int LinkShader(const char* vertex_shader_code, const char* fragment_shader_code);
int GetUniform(const std::string &name) const;
void CheckCompileErrors(GLuint shader, std::string type);
};
#endif // !__SHADER_H__
#ifndef __SHADER_H__
#define __SHADER_H__
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "string"
class Shader
{
public:
unsigned int ID;
Shader(const GLchar* vertex_shader_path, const GLchar* fragment_shader_path);
~Shader();
void Use();
void SetBool(const std::string &name, bool value) const;
void SetInt(const std::string &name, int value) const;
void SetFloat(const std::string &name, float value) const;
void SetVec2(const std::string &name, const glm::vec2 &value) const;
void SetVec2(const std::string &name, float x, float y) const;
void SetVec3(const std::string &name, const glm::vec3 &value) const;
void SetVec3(const std::string &name, float x, float y, float z) const;
void SetVec4(const std::string &name, const glm::vec4 &value) const;
void SetVec4(const std::string &name, float x, float y, float z, float w) const;
void SetMat2(const std::string &name, const glm::mat2 &value) const;
void SetMat3(const std::string &name, const glm::mat3 &value) const;
void SetMat4(const std::string &name, const glm::mat4 &value) const;
private:
int GetShaderFromFile(const GLchar* vertex_shader_path, const GLchar* fragment_shader_path,
std::string *vertex_shader_code, std::string *fragment_shader_code);
int LinkShader(const char* vertex_shader_code, const char* fragment_shader_code);
int GetUniform(const std::string &name) const;
void CheckCompileErrors(GLuint shader, std::string type);
};
#endif // !__SHADER_H__
#ifndef __SHADER_H__
#define __SHADER_H__
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "string"
class Shader
{
public:
unsigned int ID;
Shader(const GLchar* vertex_shader_path, const GLchar* fragment_shader_path);
~Shader();
void Use();
void SetBool(const std::string &name, bool value) const;
void SetInt(const std::string &name, int value) const;
void SetFloat(const std::string &name, float value) const;
void SetVec2(const std::string &name, const glm::vec2 &value) const;
void SetVec2(const std::string &name, float x, float y) const;
void SetVec3(const std::string &name, const glm::vec3 &value) const;
void SetVec3(const std::string &name, float x, float y, float z) const;
void SetVec4(const std::string &name, const glm::vec4 &value) const;
void SetVec4(const std::string &name, float x, float y, float z, float w) const;
void SetMat2(const std::string &name, const glm::mat2 &value) const;
void SetMat3(const std::string &name, const glm::mat3 &value) const;
void SetMat4(const std::string &name, const glm::mat4 &value) const;
private:
int GetShaderFromFile(const GLchar* vertex_shader_path, const GLchar* fragment_shader_path,
std::string *vertex_shader_code, std::string *fragment_shader_code);
int LinkShader(const char* vertex_shader_code, const char* fragment_shader_code);
int GetUniform(const std::string &name) const;
void CheckCompileErrors(GLuint shader, std::string type);
};
#endif // !__SHADER_H__
shader.cpp
#include "Shader.h"
#include "fstream"
#include "sstream"
#include "iostream"
Shader::Shader(const GLchar* vertex_shader_path, const GLchar* fragment_shader_path)
{
std::string vertex_shader_code;
std::string fragment_shader_code;
if (GetShaderFromFile(vertex_shader_path, fragment_shader_path, &vertex_shader_code, &fragment_shader_code))
{
return;
}
if (LinkShader(vertex_shader_code.c_str(), fragment_shader_code.c_str()))
{
return;
}
}
Shader::~Shader()
{
}
void Shader::Use()
{
glUseProgram(ID);
}
void Shader::SetBool(const std::string &name, bool value) const
{
SetInt(name, (int)value);
}
void Shader::SetInt(const std::string &name, int value) const
{
glUniform1i(GetUniform(name), value);
}
void Shader::SetFloat(const std::string &name, float value) const
{
glUniform1f(GetUniform(name), value);
}
void Shader::SetVec2(const std::string &name, float x, float y) const
{
glUniform2f(GetUniform(name), x, y);
}
void Shader::SetVec2(const std::string &name, const glm::vec2 &value) const
{
SetVec2(name, value.x, value.y);
}
void Shader::SetVec3(const std::string &name, float x, float y, float z) const
{
glUniform3f(GetUniform(name), x, y, z);
}
void Shader::SetVec3(const std::string &name, const glm::vec3 &value) const
{
SetVec3(name, value.x, value.y, value.z);
}
void Shader::SetVec4(const std::string &name, float x, float y, float z, float w) const
{
glUniform4f(GetUniform(name), x, y, z, w);
}
void Shader::SetVec4(const std::string &name, const glm::vec4 &value) const
{
SetVec4(name, value.x, value.y, value.z, value.w);
}
void Shader::SetMat2(const std::string &name, const glm::mat2 &value) const
{
glUniformMatrix2fv(GetUniform(name), 1, GL_FALSE, &value[0][0]);
}
void Shader::SetMat3(const std::string &name, const glm::mat3 &value) const
{
glUniformMatrix3fv(GetUniform(name), 1, GL_FALSE, &value[0][0]);
}
void Shader::SetMat4(const std::string &name, const glm::mat4 &value) const
{
glUniformMatrix4fv(GetUniform(name), 1, GL_FALSE, &value[0][0]);
}
int Shader::GetShaderFromFile(const GLchar* vertex_shader_path, const GLchar* fragment_shader_path, std::string *vertex_shader_code, std::string *fragment_shader_code)
{
std::ifstream vertex_shader_file;
std::ifstream fragment_shader_file;
vertex_shader_file.exceptions(std::ifstream::badbit | std::ifstream::failbit);
fragment_shader_file.exceptions(std::ifstream::badbit | std::ifstream::failbit);
try
{
vertex_shader_file.open(vertex_shader_path);
fragment_shader_file.open(fragment_shader_path);
std::stringstream vertex_shader_stream, fragment_shader_stream;
vertex_shader_stream << vertex_shader_file.rdbuf();
fragment_shader_stream << fragment_shader_file.rdbuf();
vertex_shader_file.close();
fragment_shader_file.close();
*vertex_shader_code = vertex_shader_stream.str();
*fragment_shader_code = fragment_shader_stream.str();
}
catch (std::ifstream::failure e)
{
std::cout << "Load Shader File Error!" << std::endl;
return -1;
}
return 0;
}
int Shader::LinkShader(const char* vertex_shader_code, const char* fragment_shader_code)
{
int vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_code, NULL);
glCompileShader(vertex_shader);
CheckCompileErrors(vertex_shader, "VERTEX");
int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_shader_code, NULL);
glCompileShader(fragment_shader);
CheckCompileErrors(fragment_shader, "FRAGMENT");
this->ID = glCreateProgram();
glAttachShader(ID, vertex_shader);
glAttachShader(ID, fragment_shader);
glLinkProgram(ID);
CheckCompileErrors(ID, "PROGRAM");
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
return 0;
}
int Shader::GetUniform(const std::string &name) const
{
int position = glGetUniformLocation(ID, name.c_str());
if (position == -1)
{
std::cout << "uniform " << name << " set failed!" << std::endl;
}
return position;
}
void Shader::CheckCompileErrors(GLuint shader, std::string type)
{
GLint success;
GLchar infoLog[512];
if (type == "PROGRAM")
{
glGetProgramiv(shader, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(shader, 512, NULL, infoLog);
std::cout << "ERROR::PROGRAM_LINKING_ERROR!\n" << infoLog << std::endl;
}
}
else
{
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::" << type << "::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
}main.cpp
//总体流程
//1. 初始化并创建窗口
//2. 加载立方体顶点VAOVBO以及着色器并开启深度测试
//3. 进入主循环清除缓冲
//4. 使用立方体着色器,构造并传入pvm矩阵,绘制
//5. 循环结束,释放VAOVBO
#include <iostream>
#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 "shader.h"
const float vertices[] = { //立方体数组
-0.5f, -0.5f, -0.5f, 1.0f,0.0f,0.0f,
0.5f, -0.5f, -0.5f, 1.0f,0.0f,0.0f,
0.5f, 0.5f, -0.5f, 1.0f,0.0f,0.0f,
0.5f, 0.5f, -0.5f, 1.0f,0.0f,0.0f,
-0.5f, 0.5f, -0.5f, 1.0f,0.0f,0.0f,
-0.5f, -0.5f, -0.5f, 1.0f,0.0f,0.0f,
-0.5f, -0.5f, 0.5f, 0.0f,1.0f,0.0f,
0.5f, -0.5f, 0.5f, 0.0f,1.0f,0.0f,
0.5f, 0.5f, 0.5f, 0.0f,1.0f,0.0f,
0.5f, 0.5f, 0.5f, 0.0f,1.0f,0.0f,
-0.5f, 0.5f, 0.5f, 0.0f,1.0f,0.0f,
-0.5f, -0.5f, 0.5f, 0.0f,1.0f,0.0f,
-0.5f, 0.5f, 0.5f, 0.0f,0.0f,1.0f,
-0.5f, 0.5f, -0.5f, 0.0f,0.0f,1.0f,
-0.5f, -0.5f, -0.5f, 0.0f,0.0f,1.0f,
-0.5f, -0.5f, -0.5f, 0.0f,0.0f,1.0f,
-0.5f, -0.5f, 0.5f, 0.0f,0.0f,1.0f,
-0.5f, 0.5f, 0.5f, 0.0f,0.0f,1.0f,
0.5f, 0.5f, 0.5f, 0.5f,0.0f,0.0f,
0.5f, 0.5f, -0.5f, 0.5f,0.0f,0.0f,
0.5f, -0.5f, -0.5f, 0.5f,0.0f,0.0f,
0.5f, -0.5f, -0.5f, 0.5f,0.0f,0.0f,
0.5f, -0.5f, 0.5f, 0.5f,0.0f,0.0f,
0.5f, 0.5f, 0.5f, 0.5f,0.0f,0.0f,
-0.5f, -0.5f, -0.5f, 0.0f,0.5f,0.0f,
0.5f, -0.5f, -0.5f, 0.0f,0.5f,0.0f,
0.5f, -0.5f, 0.5f, 0.0f,0.5f,0.0f,
0.5f, -0.5f, 0.5f, 0.0f,0.5f,0.0f,
-0.5f, -0.5f, 0.5f, 0.0f,0.5f,0.0f,
-0.5f, -0.5f, -0.5f, 0.0f,0.5f,0.0f,
-0.5f, 0.5f, -0.5f, 0.0f,0.0f,0.5f,
0.5f, 0.5f, -0.5f, 0.0f,0.0f,0.5f,
0.5f, 0.5f, 0.5f, 0.0f,0.0f,0.5f,
0.5f, 0.5f, 0.5f, 0.0f,0.0f,0.5f,
-0.5f, 0.5f, 0.5f, 0.0f,0.0f,0.5f,
-0.5f, 0.5f, -0.5f, 0.0f,0.0f,0.5f
};
float screen_width = 1280.0f; //窗口宽度
float screen_height = 720.0f; //窗口高度
//相机参数
glm::vec3 camera_position = glm::vec3(0.0f, 0.0f, 3.0f); //摄像机位置
glm::vec3 camera_front = glm::vec3(0.0f, 0.0f, -1.0f); //摄像机方向
glm::vec3 camera_up = glm::vec3(0.0f, 1.0f, 0.0f); //摄像机上向量
//视野
float fov = 45.0f;
int main() {
// 初始化GLFW
glfwInit(); // 初始化GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // OpenGL版本为3.3,主次版本号均设为3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 使用核心模式(无需向后兼容性)
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 如果使用的是Mac OS X系统,需加上这行
glfwWindowHint(GLFW_RESIZABLE, FALSE); // 不可改变窗口大小
// 创建窗口(宽、高、窗口名称)
auto window = glfwCreateWindow(screen_width, screen_height, "Cube", nullptr, nullptr);
if (window == nullptr) { // 如果窗口创建失败,输出Failed to Create OpenGL Context
std::cout << "Failed to Create OpenGL Context" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window); // 将窗口的上下文设置为当前线程的主上下文
// 初始化GLAD,加载OpenGL函数指针地址的函数
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// 指定当前视口尺寸(前两个参数为左下角位置,后两个参数是渲染窗口宽、高)
glViewport(0, 0, screen_width, screen_height);
Shader shader("res/shader/task-cube.vs", "res/shader/task-cube.fs");//加载着色器
// 生成并绑定VAO和VBO
GLuint vertex_array_object; // == VAO
glGenVertexArrays(1, &vertex_array_object);
glBindVertexArray(vertex_array_object);
GLuint vertex_buffer_object; // == VBO
glGenBuffers(1, &vertex_buffer_object);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object);
// 将顶点数据绑定至当前默认的缓冲中
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glEnable(GL_DEPTH_TEST);
// Render loop主循环
while (!glfwWindowShouldClose(window)) {
//进入主循环,清理颜色缓冲深度缓冲
glClearColor(0.0f, 0.34f, 0.57f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清理颜色缓冲和深度缓冲
shader.Use();
// Transform坐标变换矩阵
glm::mat4 model(1);//model矩阵,局部坐标变换至世界坐标
model = glm::translate(model, glm::vec3(0.0,0.0,0.0));
model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(0.5f, 1.0f, 0.0f));
model = glm::scale(model, glm::vec3(1.0f,1.0f,1.0f));
glm::mat4 view(1);//view矩阵,世界坐标变换至观察坐标系
view = glm::lookAt(camera_position, camera_position + camera_front, camera_up);
glm::mat4 projection(1);//projection矩阵,投影矩阵
projection = glm::perspective(glm::radians(fov), (float)screen_width / screen_height, 0.1f, 100.0f);
// 向着色器中传入参数
int model_location = glGetUniformLocation(shader.ID, "model"); //获取着色器内某个参数的位置
glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model));//写入参数值
int view_location = glGetUniformLocation(shader.ID, "view");
glUniformMatrix4fv(view_location, 1, GL_FALSE, glm::value_ptr(view));
int projection_location = glGetUniformLocation(shader.ID, "projection");
glUniformMatrix4fv(projection_location, 1, GL_FALSE, glm::value_ptr(projection));
//绘制
glBindVertexArray(vertex_array_object);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
//释放VAOVBO
glDeleteVertexArrays(1, &vertex_array_object);
glDeleteBuffers(1, &vertex_buffer_object);
// 清理所有的资源并正确退出程序
glfwTerminate();
return 0;
}输出结果:

边栏推荐
- 搞事摸鱼一天有一天
- 熊市下 DeFi 的未来趋势
- Information fusion method and application of expert opinion and trust in large group emergency decision-making based on complex network
- 二 RedisTemplate的序列和反序列化机制讲解
- Openeuler embedded sig | distributed soft bus
- 详解visual studio 2015在局域网中远程调试程序
- kingbase中指定用户默认查找schema,或曰用户无法使用public schema下函数问题
- ESP8266-Arduino编程实例-SPIFFS及数据上传(Arduino IDE和PlatformIO IDE)
- 纳米金偶联抗体/蛋白试剂盒(20nm,1mg/100μg/500 μg偶联量)的制备
- What technology is needed for applet development
猜你喜欢

PyQt5快速开发与实战 5.4 网页交互

OA项目之会议通知(查询&是否参会&反馈详情)

节省70%的显存,训练速度提高2倍!浙大&阿里提出在线卷积重新参数化OREPA,代码已开源!(CVPR 2022 )

Soft test --- database (3) data operation

Edited by vimtutor

Oracle database objects

JVM 内存布局详解(荣耀典藏版)

中国科学家首次用DNA构造卷积人工神经网络,可完成32类分子模式识别任务,或用于生物标志物信号分析和诊断

Research on intangible cultural heritage image classification based on multimodal fusion
![[Bluetooth Bluetooth development] VIII. Transmission layer of ble protocol](/img/43/7c3891befcb7cbb7dc67dfdeb763e2.png)
[Bluetooth Bluetooth development] VIII. Transmission layer of ble protocol
随机推荐
KubeVela 1.4.x 官方文档
For the next generation chromebook, MediaTek launched new chipsets mt8192 and mt8195
II. Explanation of the sequence and deserialization mechanism of redistemplate
迪赛智慧数——折线图(堆叠面积图):2022年不同职业人群存款额占月收入比例排名
KubeEdge发布云原生边缘计算威胁模型及安全防护技术白皮书
微信小程序开发入门,自己开发小程序
Oracle triggers
融合LSTM与逻辑回归的中文专利关键词抽取
msfvenom制作主控与被控端
日志瘦身神操作:从5G优化到1G到底是怎么做到的!(荣耀典藏版)
Introduction to C language [detailed]
It is said that Microsoft has obtained the supply license for Xianghua! Will Huawei usher in the full lifting of the ban?
中国科学家首次用DNA构造卷积人工神经网络,可完成32类分子模式识别任务,或用于生物标志物信号分析和诊断
如何在 Web3中建立一个去中心化社区
株洲市九方中学开展防溺水、消防安全教育培训活动
网格数据生成函数meshgrid
Nano gold coupled antibody / protein Kit (20nm, 1mg/100 μ g/500 μ G coupling amount) preparation
两个全局变量__dirname和__filename 、fs模块常用功能进一步介绍
kali里的powersploit、evasion、weevely等工具的杂项记录
RHCSA第一天