OpenGL学习笔记(1)

基于VS的OpenGL的配置

一.Cmake下载

选择在镜像网站上进行下载
https://cmake.org/files

二.glfw&glad

下载glfw的未编译文件,使用Cmake对glfw进行编译,得到lib文件,放入学习Opengl的工程文件中的lib文件夹中.

将下载的glfw中的GLFW和KHR文件夹放入工程文件中的include

在vs中配置glfw

配置glad:GLAD提供给你了一个zip压缩文件,包含两个头文件目录,和一个glad.c文件。将两个头文件目录(glad和KHR)复制到你的Include文件夹中(或者增加一个额外的项目指向这些目录),并添加glad.c文件到你的工程中。

三.测试OpenGL

1
2
#include <glad/glad.h>
#include <GLFW/glfw3.h>

请确认是在包含GLFW的头文件之前包含了GLAD的头文件。GLAD的头文件包含了正确的OpenGL头文件(例如GL/gl.h),所以需要在其它依赖于OpenGL的头文件之前包含GLAD。

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>
//注册函数,一个是回调函数,当窗口大小被调整的时候被调用.
//这个函数需要一个GLFWwindow作为它的第一个参数,以及两个整数表示窗口的新维度。每当窗口改变大小,GLFW会调用这个函数并填充相应的参数供你处理。
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);

// 设置窗口的数据,高和宽
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

int main()
{
//对glfw进行初始化,并告诉glfw我们使用的OpenGL的版本号
//glfwWindHint函数的第一个参数是选项,我们可以从以GLFW_开头的枚举值中选择,该函数的所有的选项以及对应的值都可以在 GLFW’s window handling(http://www.glfw.org/docs/latest/window.html#window_hints) 这篇文档中找到
//
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//针对macOS系统的特殊处理
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

//创建一个窗口对象,GLFWwindow的指针,调用glfwCreateWindow,这个函数接收宽和高作为参数,第三个参数表示窗口的名称,最后两个暂时忽略.
//这个函数返回的是一个GLFWwindow对象
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
//通知GLFW将新创建的窗口window作为当前线程的主上下文了.
glfwMakeContextCurrent(window);
//注册framebuffer_size_callback函数,用glfwSetFramebufferSizeCallback告诉glfw每次当我们希望调整他的第一个类型为窗口的参数(窗口window)时候会调用作为第二个参数的函数.
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

// 初始化GLAD,使用glfwGetProcAddress函数来给GLAD传入用来加载系统相关的OpenGL函数指针地址.它会根据我们编译的系统定义正确的函数.
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}

// 渲染循环,首先判断窗口是否应该关闭.
while (!glfwWindowShouldClose(window))
{
//调用processInput函数,参数为window.
processInput(window);

// 渲染指令
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//设置清空屏幕所用的颜色
glClear(GL_COLOR_BUFFER_BIT);//这是一个清空缓冲的函数,他接受一个缓冲位(Buffer Bit),这里用的缓冲位是GL_COLOR_BUFFER_BIT,当我们调用了glclear函数以后,整个颜色缓冲会被填充为glClearColor里所设置的颜色.


glfwSwapBuffers(window);//交换颜色缓冲(它是一个储存着GLFW窗口每一个像素颜色值的大缓冲),它在这一迭代中被用来绘制,并且将会作为输出显示在屏幕上。
glfwPollEvents();//检查有没有触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,并调用对应的回调函数(可以通过回调方法手动设置)。
}

// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
glfwTerminate();
return 0;
}

// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------

//使用GLFW的glfwGeKey函数,他需要一个窗口对象和一个按键作为参数
void processInput(GLFWwindow *window)
{
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
//这里我们检查用户是否按下了Esc键,如果没有按下esc,则函数glfwGetKey会返回GLFW_RELEASE
//如果按下了,则会通过glfwSetwindowShouldClose把window的WindowShouldClose属性调整为true
//这个函数会在每次渲染循环中被调用
//---------------------------------------------------------------------------------------------
//这个帧缓冲大小函数需要一个GLFWwindow作为它的第一个参数,以及两个整数表示窗口的新维度。每当窗口改变大小,GLFW会调用这个函数并填充相应的参数供你处理。
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
}

状态设置函数和状态使用函数

OpenGL本身是一个巨大的状态机,它使用了一系列的变量来描述OpenGL目前是怎样运行的. 这就叫Context(上下文)

OpenGL中有两类函数,一类是修改了OpenGL中某些变量,即改变了上下文的状态设置函数(State-changing Function),另一类是状态使用函数(State-using Function),这类函数会读取OpenGL的状态来进行一些操作.

比如,在实例代码中的渲染循环使用了glClearColor()和glClear(GL_COLOR_BUFFER_BIT)两个函数.其中,glClearColor()函数作为状态设置函数,设置了一个颜色作为清空颜色缓冲时候的用的颜色.而glClear()函数,作为一个状态使用函数,会读取glClearColor设置的颜色,作为清除颜色缓冲时候替代的颜色.

双缓冲