OpenGL官方文档中的入门教程源代码:在3维空间中自由移动
创始人
2024-02-23 06:02:09
0

OpenGL官方文档中的入门教程源代码:在3维空间中自由移动

  • 项目总览:
  • 一、开发前的准备工作
        • 1.将以上链接中的三个文件分别放到自己硬盘的一个文件夹中:例如D盘/OpenGL/...
        • 2.打开VS2022创建一个项目,右击窗体选择属性
        • 3.配置这3个文件的一些环境到你的项目中,这里可以参考:[这节视频](https://www.bilibili.com/video/BV11W411N7b9/?spm_id_from=333.999.0.0&vd_source=ee4dc98d9036bcc310740dff78231cf7),同时这也是一节非常好的OpenGL课程,感谢傅老师!
  • 二、代码目录
        • 1.头文件Camera.h
        • 2.源文件Camera.cpp
        • 3.头文件Shader.h
        • 4.源文件Shader.cpp
        • 5.源文件main.cpp
  • 三、着色器
        • 1.顶点着色器vertexSource.txt
        • 2.片段着色器fragmentSource.txt
  • 四、效果展示:

项目总览:

1.开发语言:C++语言
2.IDE:VS2022
3.开发用时:一周
4.本项目是OpenGL官方文档https://learnopengl.com中《入门》栏目的案例,素材和函数功能都可在官方文档找到。
5.源码已上传到我的GitHub,链接:https://github.com/2394799692/OpenGLpractice1 或点此跳转


以下是本篇文章正文内容,欢迎朋友们进行指正,一起探讨,共同进步。——来自读研路上的lwj。QQ:2394799692(请标明来意)

一、开发前的准备工作

链接:https://pan.baidu.com/s/1dtXE22PZw14hif0ui3r2qA?pwd=z22g 提取码:z22g

1.将以上链接中的三个文件分别放到自己硬盘的一个文件夹中:例如D盘/OpenGL/…

在这里插入图片描述

2.打开VS2022创建一个项目,右击窗体选择属性

在这里插入图片描述

3.配置这3个文件的一些环境到你的项目中,这里可以参考:这节视频,同时这也是一节非常好的OpenGL课程,感谢傅老师!

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、代码目录

在这里插入图片描述

1.头文件Camera.h

定义源文件Camera.cpp中所使用到的函数和变量,这两个文件的作用是定义鼠标为摄像机的位置,从而实现在3维坐标中上下左右的移动

#pragma once#include 
#include class Camera
{
public:Camera(glm::vec3 position, glm::vec3 target, glm::vec3 worldup);Camera(glm::vec3 position, float pitch, float yaw, glm::vec3 worldup);glm::vec3 Position;glm::vec3 Forward;glm::vec3 Right;glm::vec3 Up;glm::vec3 WorldUp;float Pitch;float Yaw;float SenseX = 0.001f;float SenseY = 0.001f;float speedZ = 0;glm::mat4 GetViewMatrix();void ProcessMouseMovement(float deltaX, float deltaY);void UpdateCameraPos();
private:void UpdateCameraVectors();
};

2.源文件Camera.cpp

#include "Camera.h"Camera::Camera(glm::vec3 position, glm::vec3 target, glm::vec3 worldup)
{Position = position;WorldUp = worldup;Forward = glm::normalize(target - position);//转为单位向量Right = glm::normalize(glm::cross(Forward, WorldUp));//cross是叉乘的意思Up = glm::normalize(glm::cross(Forward, Right));
}
Camera::Camera(glm::vec3 position, float pitch, float yaw, glm::vec3 worldup)
{Position = position;WorldUp = worldup;Pitch = pitch;Yaw = yaw;Forward.x = glm::cos(Pitch) * glm::sin(Yaw);Forward.y = glm::sin(Pitch);		   Forward.z = glm::cos(Pitch) * glm::cos(Yaw);Right = glm::normalize(glm::cross(Forward, WorldUp));//cross是叉乘的意思Up = glm::normalize(glm::cross(Forward, Right));
}glm::mat4 Camera::GetViewMatrix()
{return glm::lookAt(Position, Position + Forward, WorldUp);
}
void Camera::UpdateCameraVectors()
{Forward.x = glm::cos(Pitch) * glm::sin(Yaw);Forward.y = glm::sin(Pitch);Forward.z = glm::cos(Pitch) * glm::cos(Yaw);Right = glm::normalize(glm::cross(Forward, WorldUp));//cross是叉乘的意思Up = glm::normalize(glm::cross(Forward, Right));
}
void Camera::ProcessMouseMovement(float deltaX, float deltaY)
{Pitch -= deltaY* SenseX;Yaw -= deltaX* SenseY;UpdateCameraVectors();
}
void Camera::UpdateCameraPos()
{Position += Forward*speedZ*0.01f;
}

3.头文件Shader.h

结合shader.cpp和着色器资源实现渲染/着色功能

#pragma once
#include
using namespace std;
class Shader
{
public:Shader(const char* vertexPath,const char* fragmentPath);string vertexString;string fragmentString;const char* vertexSource;const char* fragmentSource;unsigned int ID;//shader program idvoid use();private:void checkCompileErrors(unsigned int ID, std::string type);
};

4.源文件Shader.cpp

#include "Shader.h"
#include
#include
#include
#define GLEW_STATIC
#include
#include
using namespace std;
//shader命名空间下的shader方法
Shader::Shader(const char* vertexPath, const char* fragmentPath)
{ifstream vertexFile;ifstream fragmentFile;stringstream vertexSStream;stringstream fragmentSStream;vertexFile.open(vertexPath);fragmentFile.open(fragmentPath);vertexFile.exceptions(ifstream::failbit || ifstream::badbit);fragmentFile.exceptions(ifstream::failbit || ifstream::badbit);try{if (!vertexFile.is_open() || !fragmentFile.is_open()){throw exception("open file error");}vertexSStream << vertexFile.rdbuf();fragmentSStream << fragmentFile.rdbuf();vertexString = vertexSStream.str();fragmentString = fragmentSStream.str();vertexSource = vertexString.c_str();fragmentSource = fragmentString.c_str();unsigned int vertex, fragment;//承载gpu返还的shadervertex = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertex, 1, &vertexSource, NULL);glCompileShader(vertex);checkCompileErrors(vertex, "VERIEX");fragment = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragment, 1, &fragmentSource, NULL);glCompileShader(fragment);checkCompileErrors(fragment, "FRAGMENT");ID = glCreateProgram();glAttachShader(ID, vertex);glAttachShader(ID, fragment);glLinkProgram(ID);checkCompileErrors(ID, "PROGRAM");glDeleteShader(vertex);glDeleteShader(fragment);}catch (const std::exception& ex){printf(ex.what());}
}void Shader::use() {glUseProgram(ID);
}
void Shader::checkCompileErrors(unsigned int ID, string type)
{int success;char infoLog[512];if (type != "PROGRAM"){glGetShaderiv(ID, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(ID, 512, NULL, infoLog);cout << "shader compile error:" << infoLog << endl;}}else{glGetProgramiv(ID, GL_LINK_STATUS, &success);if (!success){glGetProgramInfoLog(ID, 512, NULL, infoLog);cout << "program link error:" << infoLog << endl;}}
}

5.源文件main.cpp

#include
#define GLEW_STATIC
#include
#include#include "Shader.h"#include 
#include 
#include 
#include "Camera.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
//float vertices[] = {
//	//     ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -
//		 0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   // 右上
//		 0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   // 右下
//		-0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // 左下
//		-0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    // 左上
//};
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 indices[] = {0,1,2,2,3,0
}; glm::vec3 cubePositions[] = {glm::vec3(0.0f,  0.0f,  0.0f),glm::vec3(2.0f,  5.0f, -15.0f),glm::vec3(-1.5f, -2.2f, -2.5f),glm::vec3(-3.8f, -2.0f, -12.3f),glm::vec3(2.4f, -0.4f, -3.5f),glm::vec3(-1.7f,  3.0f, -7.5f),glm::vec3(1.3f, -2.0f, -2.5f),glm::vec3(1.5f,  2.0f, -2.5f),glm::vec3(1.5f,  0.2f, -1.5f),glm::vec3(-1.3f,  1.0f, -1.5f)
};float lastX;
float lastY;
bool firstMouse = true;
//引入class类//Camera camera(glm::vec3(0,0,3.0f),glm::vec3(0,0,0),glm::vec3(0,1.0f,0));
Camera camera(glm::vec3(0, 0, 3.0f), glm::radians(15.0f), glm::radians(180.0f), glm::vec3(0, 1.0f, 0));
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS){glfwSetWindowShouldClose(window, true);}if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS){camera.speedZ=1.0f;}else if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS){camera.speedZ = -1.0f;}else {camera.speedZ = 0;}}
void mouse_callback(GLFWwindow* window, double xPos, double yPos)
{if (firstMouse == true){lastX = xPos;lastY = yPos;firstMouse = false;}float deltaX, deltaY;deltaX = xPos - lastX;deltaY = yPos - lastY;lastX = xPos;lastY = yPos;camera.ProcessMouseMovement(deltaX, deltaY);/*printf("%f \n", deltaX);*/
}
int main()
{glfwInit();//初始化glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//打开一个窗体GLFWwindow* window = glfwCreateWindow(800, 600, "My OpenGL Game", NULL, NULL);if (window == NULL){printf("open window failed.");glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);//消失鼠标glfwSetCursorPosCallback(window, mouse_callback);//init glewglewExperimental = true;if (glewInit() != GLEW_OK){printf("Init GLEW failed.");glfwTerminate();return -1;}glViewport(0, 0, 800, 600);glEnable(GL_CULL_FACE);glCullFace(GL_BACK);//背面剔除,正面:GL_FRONT//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//显示边框glEnable(GL_DEPTH_TEST);//做深度缓冲Shader* myShader = new Shader("vertexSource.txt", "fragmentSource.txt");unsigned int VAO;glGenVertexArrays(1, &VAO);glBindVertexArray(VAO); unsigned int VBO;glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);unsigned int EBO;glGenBuffers(1, &EBO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);/*glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);*/glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(2);unsigned int TexBufferA;glGenTextures(1, &TexBufferA);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, TexBufferA);int width, height, nrChannel;stbi_set_flip_vertically_on_load(true);//图像翻转unsigned char* data = stbi_load("container.jpg", &width, &height, &nrChannel, 0);if (data){glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);glGenerateMipmap(GL_TEXTURE_2D);}else{printf("load image failed.");}stbi_image_free(data);unsigned int TexBufferB;//载入笑脸glGenTextures(1, &TexBufferB);glActiveTexture(GL_TEXTURE3);glBindTexture(GL_TEXTURE_2D, TexBufferB);unsigned char* data2 = stbi_load("awesomeface.png", &width, &height, &nrChannel, 0);if (data2){glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2);glGenerateMipmap(GL_TEXTURE_2D);}else{printf("load image failed.");}stbi_image_free(data2);glm::mat4 trans;//trans = glm::translate(trans, glm::vec3(-0.01f, 0, 0));//平移//trans = glm::rotate(trans,glm::radians(45.0f), glm::vec3(0, 0, 1.0f));//旋转45度//trans = glm::scale(trans, glm::vec3(2.0f, 2.0f, 2.0f));//缩放glm::mat4 modelMat;modelMat = glm::rotate(modelMat, glm::radians(-45.0f), glm::vec3(0, 1.0f, 1.0f));glm::mat4 viewMat;//viewMat = glm::translate(viewMat, glm::vec3(0, 0, -3.0f));//viewMat = camera.GetViewMatrix();glm::mat4 projMat;projMat = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);while (!glfwWindowShouldClose(window)){/*glm::mat4 trans;//定义在里面每次重置角度不会转太快trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0));trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0, 0, 1.0f));*/processInput(window);glClearColor(0.2f, 0.3f, 0.3f, 1.0f);/*glClear(GL_COLOR_BUFFER_BIT);*/glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//加了一个清除上一轮深度缓冲glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, TexBufferA);glActiveTexture(GL_TEXTURE3);glBindTexture(GL_TEXTURE_2D, TexBufferB);glBindVertexArray(VAO);//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);viewMat = camera.GetViewMatrix();for (int i = 0; i < 10; i++) {glm::mat4 modelMat2;modelMat2 = glm::translate(modelMat2, cubePositions[i]);myShader->use();glUniform1i(glGetUniformLocation(myShader->ID, "ourTexture"), 0);glUniform1i(glGetUniformLocation(myShader->ID, "ourFace"), 3);//glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "transform"), 1, GL_FALSE, glm::value_ptr(trans));glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "modelMat"), 1, GL_FALSE, glm::value_ptr(modelMat2));glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "viewMat"), 1, GL_FALSE, glm::value_ptr(viewMat));glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "projMat"), 1, GL_FALSE, glm::value_ptr(projMat));glDrawArrays(GL_TRIANGLES, 0, 36);//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);}glfwSwapBuffers(window);glfwPollEvents();camera.UpdateCameraPos();}glfwTerminate();return 0;
}

三、着色器

1.顶点着色器vertexSource.txt

顶点着色器(Vertex Shader)是几个可编程着色器中的一个。如果我们打算做渲染的话,现代OpenGL需要我们至少设置一个顶点和一个片段着色器。

#version 330 core                                
layout (location=0) in vec3 aPos;                
layout (location=1) in vec3 aColor;    
layout (location=2) in vec2 aTexCoord;    //uniform mat4 transform;
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;out vec4 vertexColor;
out vec2 TexCoord;
void main(){                                     gl_Position=projMat*viewMat*modelMat*vec4(aPos.x,aPos.y,aPos.z,1.0f);  vertexColor=vec4(aColor.x,aColor.y,aColor.z,1.0f);TexCoord=aTexCoord;
}

2.片段着色器fragmentSource.txt

片段着色器(Fragment Shader)是第二个也是最后一个我们打算创建的用于渲染三角形的着色器。片段着色器所做的是计算像素最后的颜色输出。

#version 330 core           
in vec4 vertexColor;             
in vec2 TexCoord;uniform sampler2D ourTexture;
uniform sampler2D ourFace;out vec4 FragColor; 
void main(){                FragColor = mix(texture(ourTexture,TexCoord),texture(ourFace,TexCoord), 0.2);//如果第三个值是0.0,它会返回第一个输入;如果是1.0,会返回第二个输入值。0.2会返回80%的第一个输入颜色和20%的第二个输入颜色,即返回两个纹理的混合色。
} 

四、效果展示:

视频效果:

OpenGL入门demo


图片效果:
在这里插入图片描述

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...