【OpenGL】Create a window 0

Preliminary

版本: 面向OpenGL3.3

特性:对Extension的支持。

状态机(State Machine):OpenGL是一个很大的状态机 → 通过改变OpenGL的状态,告诉OpenGL怎么绘图,到底是画三角形还是画线段。

对象: 用C语言写的。可以把对象object看作一个风格的结构体Struct

1
2
3
struct object_name {
xxx
};

Cmake:使用预定义好的CMake脚本,根据不同IDE的工程文件,生成不同的工程文件。

首先打开CMake,然后将/glfw-3.3.9作为源文件,将/glfw-3.3.9/build作为build bineries。这样生成的工程文件就在build。

🤨什么是.sln文件?: visual studio solution file

编译:.sln.lib(库文件)

自定义Lib和Include文件夹:但是对于

Visual Studio创建一个C++空项目

链接第三方库

  1. 右键Demo0,然后选择VC++ Directories → 修改Library Directories 和 Include Directories.
  2. Linker → 输入

GLAD开源库

下载一个GLAD,然后#include

DEBUG#include<iostream>无法找到“源文件” → https://blog.csdn.net/weixin_38592956/article/details/94668920

用源代码自己编译的怎么整都不行,最后用了预编译好的二进制文件,并且最后用了上面的DEBUG。

ps:

  1. 不要忘记把DEBUG中的x86改成x64
  2. 用预编译的不是glfw3.lib,而是glfw3_mt.lib
  3. 不要忘记在Linker → Input中加入opengl32.lib

Code

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
#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>
// 注册函数 register a function
// 窗口改变(window) -> 视口改变(viewport) : viewport is waiting for changing from window
// 总结:谁waiting/被动 -> 谁就call_back
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void process_input(GLFWwindow* window);


const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;


int main()
{
// 初始化glfw
glfwInit();
// 初始化版本号 -> 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

// 初始化window
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
// 如果没有创建成功
if (window == NULL) {
std::cout << "cant create a window" << std::endl;
glfwTerminate();
return -1;
}
//设置当前渲染上下文,其实就是告诉gl我现在要渲染的是 : window这个current context
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);



// 初始化GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
// 没有成功初始化GLAD
std::cout << "cant initialize the GLAD" <<std::endl;
return -1;
}

// 用一个while循环来简单渲染
while (!glfwWindowShouldClose(window)) {
// 处理输入
process_input(window);

// 先设置清除缓存的color
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

// 颜色缓冲绘图
glfwSwapBuffers(window);
// 监测有没有中断事件
glfwPollEvents();
}

glfwTerminate();
return 0;
}

void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}

void process_input(GLFWwindow* window) {
// 如果用户按了ESC按键,就关闭窗口,如果没按下就会返回GLFW_RELEASE
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
std::cout << "you have press esc" << std::endl;
// !!!不是glfwWindowshouldclose 而是 set_xxx
glfwSetWindowShouldClose(window, true);
}
}

总结

先要初始化glfw(引入的用于绘图的第三方库),然后初始化window,并且在每次初始化的时候都要监测是否创建成功。

最后要搞清楚,什么是主动的,什么是被动的。

例如这里的glfwWindowShouldClose,就是OpenGL永远是主动的一方,而window是被动的,即放在参数里的。