
使用GLFW创建窗口
首先引用头文件
#include <glad/glad.h>
#include <GLFW/glfw3.h>
//注意头文件引用的先后顺序
glfwInit();
//设置窗口标识
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//glfw大版本
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//glfw小版本
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//opengl库
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);//在mac平台下需要这样设置
windowHandler = glfwCreateWindow(1280, 800, "GLFW created window", nullptr, nullptr);//创建1280*800大小的窗口,同时设定了窗口标题
if(!windowHandler){
Debug::GetInstance()->LogE("Creating GLFW window FAIL!", "Window");
glfwTerminate();
return;
}
//设定当前线程的绘制在刚刚创建的窗口上进行
glfwMakeContextCurrent(windowHandler);
//加载opengl库函数
if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
Debug::GetInstance()->LogE("GLAD init FAILD", "Window");
return;
}
//设置viewport大小
glViewport(0, 0, 1280, 800);
//设置窗口大小改变事件回调,当窗口的大小被用户改变时回调用_WindowResizeCallBack函数
glfwSetFramebufferSizeCallback(windowHandler, _WindowResizeCallBack);
//窗口大小改变事件回调函数的定义
void _WindowResizeCallBack(GLFWwindow *win, int w, int h){
glViewport(0, 0, w, h);
}
定义四边形(两个三角形)
//VAO
unsigned int vao;
glGenVertexArrays(1, &vao);//生成一个vao
glBindVertexArray(vao);//绑定vao
//VBO
float vs[] = {//定义四边形的四个点的3d坐标
0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f // top left
};
unsigned int indices[] = {//定义两个三角形所使用的点,索引vs中的顶点
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
unsigned int vbo;//vbo储存所有顶点信息
glGenBuffers(1, &vbo);//生成一个buffer,并将id储存到vbo中
glBindBuffer(GL_ARRAY_BUFFER, vbo);//将array buffer绑定到vbo
glBufferData(GL_ARRAY_BUFFER, sizeof(vs), vs, GL_STATIC_DRAW);//自动将vs中的顶点数据传输到array buffer所绑定的buffer即vbo中
//EBO
unsigned int ebo;//ebo用来储存索引vbo中的信息
glGenBuffers(1, &ebo);//生成一个buffer,并将id储存到ebo中
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);//将element array buffer绑定到ebo中
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//自动将indices中的索引数据传输到element array buffer所绑定的buffer即ebo中
//linking vertex attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//设定第0号顶点信息配置,每个顶点占用3个GL_FLOAT的元素(即3d坐标),同时向量化设为否,一个顶点数据的长度为3 * sizeof(float)
glEnableVertexAttribArray(0);//启用第0号顶点信息配置,这里的编号对应于vertex shader 中的layout(location = 0)
glBindVertexArray(0);//取消绑定vao
加载顶点着色器(vertex shader)和片元着色器(fragment shader)
//vertex shader
//读取顶点着色器源代码
string verString = FileHelper::ReadString(theApp->currentExecutionPath + "/shaders/ver.txt");
unsigned int ver = glCreateShader(GL_VERTEX_SHADER);//创建顶点着色器
auto verCString = verString.c_str();
Debug::GetInstance()->LogI(verCString, "vertex shader");
glShaderSource(ver, 1, &(verCString), nullptr);//向shader添加源代码
glCompileShader(ver);//编译shader
int success;
char infoLog[512];
glGetShaderiv(ver, GL_COMPILE_STATUS, &success);//获取是否编译成功
if(!success)
{
glGetShaderInfoLog(ver, 512, nullptr, infoLog);//获取编译信息
Debug::GetInstance()->LogE(infoLog, "Vertex Shader Compile Error");
}
//fragment shader
//获取片元着色器源代码
string fragString = FileHelper::ReadString(theApp->currentExecutionPath + "/shaders/frag.txt");
unsigned frag = glCreateShader(GL_FRAGMENT_SHADER);//创建片元着色器
auto fragCString = fragString.c_str();
Debug::GetInstance()->LogI(fragCString, "fragment shader");
glShaderSource(frag, 1, &(fragCString), nullptr);//向shader添加源代码
glCompileShader(frag);//编译shader
glGetShaderiv(frag, GL_COMPILE_STATUS, &success);//获取是否编译成功
if(!success)
{
glGetShaderInfoLog(frag, 512, nullptr, infoLog);//获取编译信息
Debug::GetInstance()->LogE(infoLog, "Fragment Shader Compile Error");
}
//shader program
unsigned int shaderProgram = glCreateProgram();//创建一个program
glAttachShader(shaderProgram, ver);//添加顶点着色器
glAttachShader(shaderProgram, frag);//添加片元着色器
glLinkProgram(shaderProgram);//执行链接操作
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);//获取是否链接成功
if(!success)
{
glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);//获取链接消息
Debug::GetInstance()->LogE(infoLog, "Shader Program Link Error");
}
glUseProgram(shaderProgram);//使用program
glDeleteShader(ver);//释放顶点着色器
glDeleteShader(frag);//释放片元着色器
绘制定义好的四边形(在循环中执行的渲染过程)
//清屏操作
glClearColor(0.2f, 0.1f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
//设置以线框模式绘制
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glUseProgram(theShaderProgram);//使用之前编译好的shader program
glBindVertexArray(theVAO);//绑定vao,之后的绘制函数都将在绑定的vao上进行
//glDrawArrays(GL_TRIANGLES, 0, 3);//绘制vbo
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//绘制ebo
//glBindVertexArray(0);//取消绑定vao
glfwSwapBuffers(windowHandler);
glfwPollEvents();
顶点着色器和片元着色器的源代码
Vertex Shader
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}fragment Shader
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(0.4f, 0.6f, 0.7f, 1.0f);
}关于VAO,VBO, EBO

VAO会储存VBO, EBO以及设置好的顶点信息配置。所以在添加VBO和EBO之前,先绑定好VAO。然后在后续的绘制渲染过程仅需要提供VAO即可,VBO,EBO和顶点信息配置都能通过VAO获取。
版权声明:本文为weixin_39843782原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。