This is a detailed explanation of the code at the end of the [OpenGL combat 1] article, and it is also the first step to enter OpenGL programming! !
In the previous section, we used glfw and glad to create an OpenGL development environment (Windows) based on VS2015.
In the test code, we don't know what the code does.
In this section, let's analyze and explain the code mentioned in the previous section.
Thinking: What should I do if I want to call OpenGL? It's very simple, keep reading
Since we are using GLFW and GLAD, we need to include a reference to it. (If not, please go back to the previous section)
#include "glad\glad.h" #include "glfw3.h"
[First step] Initialize GLFW and version specification.
int main() { //Initialize GLFW glfwInit(); //Define the version of OPEN as 3.3 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // main version glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); //Minor version // use core mode glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); }
In the main function, we call glfwInit to initialize the glfw library. There have been many versions of openGL developed to this day.
We need to define the opengl version we want to use as 3.3 in the code, using the core mode Core. This is done.
In fact, you can imagine that the OpenGL drawing environment is likened to a blackboard, and we can draw anything on it.
So, how do you create a blackboard? Because it is based on Windows, which blackboard should also be based on the Win window.
[Step 2] Create a Window rendering window.
Creating a windows window with the glfw library is also very simple, specify the width, height, and window title and then make comes out.
//Create a Win window GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL_01", NULL, NULL); if (window==NULL) { printf("Failed to create GLFW window!"); glfwTerminate();//Release return -1; } glfwMakeContextCurrent(window);
Now that the Win window is available, what about the blackboard? Now we go ahead and create a "blackboard" specifying how big this blackboard is.
The function used is glViewport(0, 0, width, height);
However, if the window is resized, our blackboard should also be resized, so we define a resize method
//render size adjustment void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); }Register this method with the window, and whenever the window size changes, call to reset the rendering size, like this
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
Regarding this blackboard, we can't use it directly, because there are many specifications in opengl, and we need to hand it over to glad for unified management.
At this time, glad comes on stage, just initialize it
//load GLAD if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { printf("Failed to initialize GLAD!"); return -1; }
* A little trick, the position of the window is not fixed each time it is started. For obsessive-compulsive disorder, setting the center of the window is the best choice:
//Set the window to center int* winWidth=new int; int* winHeight= new int; glfwGetWindowSize(window, winWidth, winHeight); GLFWmonitor* monitor = glfwGetPrimaryMonitor(); const GLFWvidmode* mode = glfwGetVideoMode(monitor); glfwSetWindowPos(window, (mode->width - *winWidth) / 2, (mode->height - *winHeight) / 2);
【Step 3】A never-ending cycle.
Why do you need a loop? Imagine that we draw a little person on the blackboard, which only represents one frame of the image and does not move.
We want the same effect as playing a movie, which requires many frames to be drawn continuously, showing a picture of continuous motion to the human eye.
So we define a while loop that persists until the close command issued by glfw to exit. like this
// render loop while (!glfwWindowShouldClose(window)) { }
[Step 4] Accept keyboard commands and buffer exchange
We mentioned in step 3 that the while loop will wait until the close instruction is issued and then exit.
This command can be triggered by many situations, the most common is that we press the ESC key of the keyboard and then exit the program.
Next, we bind ESC on the window, listen for keyboard input, and if ESC is pressed, we let it exit.
//Press ESC to exit void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); }
Because this listener is continuous, we call it in a while loop. processInput(window);
Let's talk about a little knowledge, what is double buffering?
Double Buffer
There may be a problem with image flickering when the application uses single-buffered drawing. This is because the resulting image is not drawn all at once, but is drawn pixel by pixel from left to right, top to bottom. The final image is not displayed to the user in an instant, but is generated step by step, which results in a very unrealistic rendering. To circumvent these problems, we apply double buffering to render windowed applications. The front buffer holds the final output image, which is displayed on the screen; all rendering instructions are drawn on the back buffer. When all rendering instructions have been executed, we swap (Swap) the front buffer and the back buffer, so that the image is rendered immediately, and the previously mentioned unrealism is eliminated.
It can be found that if double buffering is not used, what we draw to the window will flicker.
So, the next step is to call the API to exchange buffers. glfwSwapBuffers(window);
Finally, it's time to witness the miracle! !
Everything is ready. Now that I have a blackboard, how do I draw it? ? Don't worry, before drawing, you must first learn to "wipe the blackboard".
There is a "wipe the blackboard" method in OpenGL. glClear
Moreover, in addition to erasing the contents of the blackboard, you can also specify what base color to fill the blackboard with by default. glClearColor
Next, we fill this blackboard with dark teal. code show as below:
// render instruction glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT);
In VS2015, press debug to run.
Well, the effect of this section is exactly the same as the first section. But I believe you already understand the principle.
The complete C++ code is as follows, I have commented it in Chinese:
#include "glad\glad.h" #include "glfw3.h" #include <iostream> void framebuffer_size_callback(GLFWwindow* window, int width, int height); void processInput(GLFWwindow *window); int main() { //Initialize GLFW glfwInit(); //Define the version of OPEN as 3.3 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // main version glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); //Minor version // use core mode glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //Create a Win window GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL_01", NULL, NULL); if (window==NULL) { printf("Failed to create GLFW window!"); glfwTerminate();//Release return -1; } glfwMakeContextCurrent(window); //Reset the rendering size whenever the window size changes glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); //load GLAD if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { printf("Failed to initialize GLAD!"); return -1; } // render loop while (!glfwWindowShouldClose(window)) { // input processInput(window); // render instruction glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // Check and call the event glfwPollEvents(); // swap buffer glfwSwapBuffers(window); } //freed glfwTerminate(); return 0; } //render size adjustment void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } //Press ESC to exit void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); }
Now that we have the drawing board, shouldn't we draw something decent on it? ?
You are right, the next article will learn to draw with OpenGL with you.
Please pay attention~