From today on we start to learn OpenGL, starting from scratch, of course, it is a prerequisite to have a C++ foundation.
First include the header files of glad and GLFW
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
Initialize GLFW
In the main function, we first use glfwInit to initialize GLFW, and then we can use glfwWindowHint to configure GLFW. The options and meaning of this configuration can be found inGLFW: Window Guide A very detailed explanation can be found in it. It is better to refer to this as a tool. The place we really want to operate is not here in the window initialization
int main() {
glfwInit(); // 初始化GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // 指定创建的内容必须兼容的客户端 API 版本
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // 指定创建的内容必须兼容的客户端 API 版本
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 指定要为其创建内容的 OpenGL 配置文件
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 指定 OpenGL 内容是否应向前兼容
return 0;
}
Create window object
Next, we need to create a window object.The first two parameters of the glfwCreateWindow function are the width and height of the window, the third parameter is the name of the window, and the last two parameters are The role of can be found inGLFW: Window Guide
glfwMakeContextCurrent(window)Tell GLFW to treat the contents of the window as the main content on the current thread
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
Initialize GLAD
GLAD manages OpenGL's function pointers and needs to be initialized before calling any OpenGL function. We pass a function to GLAD to load the address of the operating system-specific OpenGL function pointer. GLFW provides us with glfwGetProcAddress, which is defined according to the operating system we compiled. the correct function
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
Render window adjustment
Use glViewport to set the size of the OpenGL rendering window. The first two parameters set the position of the lower left corner of the window. The third and fourth parameters set the width and height of the rendering window in pixels. If the viewport size is set to be smaller than the GLFW size value; all OpenGL rendering will then be displayed in a smaller window
glViewport(0, 0, 800, 600);
When the user resizes the window, the viewport should also adjust accordingly. Register a function that takes GLFWwindow as its first parameter and two integers representing the new window size as its first parameter.
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
Tell GLFW to call this function every time the window is resized by registering it
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
render loop
Create a while loop, call it a render loop, that runs until we tell GLFW to stop,
while(!glfwWindowShouldClose(window))
{
glfwSwapBuffers(window);
glfwPollEvents();
}
The glfwWindowShouldClose function checks at the beginning of each loop iteration whether GLFW has been instructed to close. If so, the function returns and the rendering loop stops running, after which we can close the application
glfwSwapBuffers will swap the color buffer used for rendering during this rendering iteration (a large 2D buffer that contains the color value of each pixel in the GLFW window) and display it as output to the screen
double buffer
When an application draws into a single buffer, the resulting image may exhibit flickering issues. This is because the resulting output image is not drawn instantaneously, but rather pixel by pixel, typically from left to right and top to bottom.
Because this image is not immediately visible to the user when rendered, the results may contain artifacts. To circumvent these problems, windowed applications should use double buffering for rendering.
The frontendbuffer contains the final output image displayed on the screen, while all rendering commands are drawn tothe backendBuffer.
Once all rendering commands have completed, we swap the back buffer to the front buffer so that the image can be displayed , without having to still render into it, thus removing all of the above artifacts.
The glfwPollEvents function checks whether any events are triggered (such as keyboard input or mouse movement events), updates the window state, and calls the corresponding function (we can register through the callback method)
Once we exit the render loop, we want to properly clean/delete all allocated GLFW resources. We can do this through the glfwTerminate function called at the end of the main function
glfwTerminate();
return 0;
Compile and run
If everything goes well then running the program we will see a black window
If not, please see the full source code analysis
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include<iostream>
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
int main() {
glfwInit(); // 初始化窗口
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // 指定创建的内容必须兼容的客户端 API 版本
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // 指定创建的内容必须兼容的客户端 API 版本
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 指定要为其创建内容的 OpenGL 配置文件
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 指定 OpenGL 上下文是否应向前兼容
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); // 注册窗口调整调用函数
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
while(!glfwWindowShouldClose(window))
{
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
If you want to change the color, you can use glClearColor to specify the color to clear the screen. Whenever we call glClear and clear the color buffer, the entire color buffer will be filled with the color configured by glClearColor. The color options are rgb and transparency. Channel parameters
glClearColor(0.0f,0.5f,0.5f,1.0f);
while(!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();