前言
本节讲解OpenGL的环境配置,并用代码绘制一个三角形,开始我们的计算机图形学学习之路
重新开始学习OpenGL和记笔记,也不知道能坚持多久,分享的同时激励自己吧。开始系统学习计算机图形学,概念的东西没记太细,之后有需要补
个人知识和能力有限,有错误还望大家指出,共同进步。
目录
一、GLFW、GLAD介绍及VS环境配置
1. GLFW
GLFW是一个轻量级的,开源的,跨平台的库。支持OpenGL及OpenGL ES,用来管理窗口,读取输入,处理事件等。是继GLUT,FreeGLUT之后,当前最新的用来创建OpenGL上下文,以及操作窗口的第三方库。(glut配置可参考这里,glut比较古老,推荐使用GLFW)
2. GLAD
用于管理OpenGL的函数指针,使用OpenGL函数之前需要初始化GLAD(具体作者也不是很了解,留个坑,之后懂了来补充,也欢迎大佬补充)
3. GLFW及GLAD配置
(1) 编译器使用VisualStudio2019
(2) 从GLFW官网下载库文件,解压后如图,我们使用的是VS2019,所以下面配置库时使用lib-vc2019中的库文件
(3) 进入GLAD在线配置地址,选择好语言及opengl版本,这里选择3.3,目前显卡基本都支持。下载完后文件夹中只有一个src和一个include
(4) 打开VS并新建C++空项目,打开项目属性 > C/C++ > 附加包含目录 > 编辑,在目录下添加glfw和glad的include目录(这边是我自己的相对目录,实际按自己的目录来配置)
(5) 接下来依旧在属性页,链接器 > 输入 > 附加依赖项 > 编辑,添加下面两个依赖库
glfw3.lib
opengl32.lib
(6) 在源文件下添加main.c,并且添加现有项,将glad/src/glad.c添加到源文件下
(7) 至此opengl环境配置完毕
二、绘制三角形
代码如下,复制进main.c中即可编译运行,下节将对该代码进行解析
#include "glad/glad.h"
#include <GLFW/glfw3.h>
#include <iostream>
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT 720
int main(void)
{
//初始化GLFW
if (GLFW_FALSE == glfwInit())
return -1;
//主次版本号
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
//创建窗口
GLFWwindow* window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "First", nullptr, nullptr);
if (nullptr == window)
{
std::cout << "Failed create window" << std::endl;
return -1;
}
//设置上下文
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to load glad" << std::endl;
return -1;
}
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
//生成和绑定VAO、VBO
const float triangle[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
//VAO
GLuint vertex_array_object;
glGenVertexArrays(1, &vertex_array_object);
glBindVertexArray(vertex_array_object);
//VBO
GLuint vertext_buffer_object;
glGenBuffers(1, &vertext_buffer_object);
glBindBuffer(GL_ARRAY_BUFFER, vertext_buffer_object);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//解绑VAO、VBO
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//着色器代码
const char* vertex_shader_source =
"#version 330 core\n"
"layout(location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos, 1.0);\n"
"}\n\0";
const char* fragment_shader_source =
"#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);"
"}\n\0";
//编译顶点着色器
int vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
glCompileShader(vertex_shader);
int success;
char info_log[512];
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
std::cout << info_log << std::endl;
}
//编译片段着色器
int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
std::cout << info_log << std::endl;
}
int shader_program = glCreateProgram();
glAttachShader(shader_program, vertex_shader);
glAttachShader(shader_program, fragment_shader);
glLinkProgram(shader_program);
glGetShaderiv(fragment_shader, GL_LINK_STATUS, &success);
if (!success)
{
std::cout << "error3" << std::endl;
return -1;
}
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
//绘制三角形
while (!glfwWindowShouldClose(window))
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader_program);
glBindVertexArray(vertex_array_object);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &vertex_array_object);
glDeleteBuffers(1, &vertext_buffer_object);
glfwTerminate();
return 0;
}
运行结果