GLFWwindow

Firstly we need to create a GLFW window. After creating a window we should create an infinite loop for render purposes. Of course, we don’t render anything except a black screen for now.

#include <GLFW/glfw3.h>

#include <iostream>

int main(){
    // |>----------<>----------<>----------<>----------<>----------<|
    // |>                    CREATE GLFW WINDOW                    <|
    // |>----------<>----------<>----------<>----------<>----------<|

    glfwInit(); // Init GLFW

    // We say to glfw "We will use opengl version 3.3"
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Major of version -> 3.0
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Minor of version -> 0.3

    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
    // GLFW_OPENGL_COMPAT_PROFILE -> We can use some legacy opengl stuff 
    // GLFW_OPENGL_CORE_PROFILE -> We cannot use some legacy opengl stuff 


    // We create glfw window 
    GLFWwindow* window = glfwCreateWindow(640, 480, "My 3D app", NULL, NULL);

    if (window == NULL) // If glfw cannot create window program finish 
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return EXIT_FAILURE;
    }

    // This function makes the OpenGL or OpenGL ES context of the specified window current on the calling thread.
    glfwMakeContextCurrent(window); // https://www.glfw.org/docs/3.3/group__context.html



    // |>----------<>----------<>----------<>----------<>----------<|
    // |>                       RENDER LOOP                        <|
    // |>----------<>----------<>----------<>----------<>----------<|

    // When we press X button of the window. glfwWindowShouldClose() returns true
    while (!glfwWindowShouldClose(window)) { // returns the value of the close flag

        glfwSwapBuffers(window); // Swaps the front and back buffers
        glfwPollEvents(); 
        // This function processes only those events that are already in the event queue and then returns immediately.Processing events will cause the window and input callbacks associated with those events to be called.
        // https://www.glfw.org/docs/3.3/group__window.html#ga37bd57223967b4211d60ca1a0bf3c832
    }

}


Legacy Triangle

GLAD will manage OpenGL function pointers for us. In other words we need to initialize GLAD before using OpenGL functions…

#include <glad/glad.h> // we include glad 
#include <GLFW/glfw3.h> // glad HAVE TO include before glfw


#include <iostream>

int main(){
    // |>----------<>----------<>----------<>----------<>----------<|
    // |>                    CREATE GLFW WINDOW                    <|
    // |>----------<>----------<>----------<>----------<>----------<|

    glfwInit(); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

    // We create glfw window 
    GLFWwindow* window = glfwCreateWindow(640, 480, "My 3D app", NULL, NULL);
    if (window == NULL){
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return EXIT_FAILURE;
    }
    glfwMakeContextCurrent(window); 

    // |>----------<>----------<>----------<>----------<>----------<|
    // |>               LOAD OPENGL FUNCTION POINTERS              <|
    // |>----------<>----------<>----------<>----------<>----------<|

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        std::cout << "Failed to initialize GLAD" << std::endl;
        exit(EXIT_FAILURE);
    }
    // Now we can use OpenGL functions 


    // |>----------<>----------<>----------<>----------<>----------<|
    // |>                       RENDER LOOP                        <|
    // |>----------<>----------<>----------<>----------<>----------<|


    while (!glfwWindowShouldClose(window)) { 

        glClearColor(0.2f, 0.2f, 0.2f, 1.0f); // Background color -clear color- 
        glClear(GL_COLOR_BUFFER_BIT); // clear color of current buffer 

        glColor3f(0.2f, 0.8f, 0.2f); // Color of triangle

        // Beginning of draw -
        // GL_TRIANGLES: draw triangles on the screen 
        // GL_LINE_STRIP: draw line strip 
        // ...
        glBegin(GL_TRIANGLES);
        glVertex2f(-0.5, -0.5);  // We define our vertex 
        glVertex2f(0.0, 0.5);    // Opengl only shows the area between -1 and 1
        glVertex2f(0.5, -0.5);
        glEnd(); // End of draw 


        glfwSwapBuffers(window);
        glfwPollEvents();         
    }

}

Size callback

When we scale our window’s frame the render content aren’t scaled together. We should add an function for this this purpose. Firstly we create a function like that:

void size_callback(GLFWwindow* window, int width, int height) {
    std::cout << "New width: " << width << "\theight: " << height << std::endl; 
    glViewport(0, 0, width, height);
}

After that we bind this function:

glfwSetFramebufferSizeCallback(window, size_callback);

whole code:

#include <glad/glad.h> // we include glad 
#include <GLFW/glfw3.h> // glad HAVE TO include before glfw
#include <iostream>

// our size_callback function
void size_callback(GLFWwindow* window, int width, int height) {
    std::cout << "New width: " << width << "\theight: " << height << std::endl; 
    glViewport(0, 0, width, height);
}

int main() {
    // |>----------<>----------<>----------<>----------<>----------<|
    // |>                    CREATE GLFW WINDOW                    <|
    // |>----------<>----------<>----------<>----------<>----------<|

    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

    // We create glfw window 
    GLFWwindow* window = glfwCreateWindow(640, 480, "My 3D app", NULL, NULL);
    if (window == NULL) {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return EXIT_FAILURE;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, size_callback); // we bind callback to our size_callback func. 

    // |>----------<>----------<>----------<>----------<>----------<|
    // |>               LOAD OPENGL FUNCTION POINTERS              <|
    // |>----------<>----------<>----------<>----------<>----------<|

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        std::cout << "Failed to initialize GLAD" << std::endl;
        exit(EXIT_FAILURE);
    }
    // Now we can use OpenGL functions 


    // |>----------<>----------<>----------<>----------<>----------<|
    // |>                       RENDER LOOP                        <|
    // |>----------<>----------<>----------<>----------<>----------<|


    while (!glfwWindowShouldClose(window)) {

        glClearColor(0.2f, 0.2f, 0.2f, 1.0f); // Background color -clear color- 
        glClear(GL_COLOR_BUFFER_BIT); // clear color of current buffer 

        glColor3f(0.2f, 0.8f, 0.2f); // Color of triangle

        // Beginning of draw -
        // GL_TRIANGLES: draw triangles on the screen 
        // GL_LINE_STRIP: draw line strip 
        // ...
        glBegin(GL_TRIANGLES);
        glVertex2f(-0.5, -0.5);  // We define our vertex 
        glVertex2f(0.0, 0.5);    // Opengl only shows the area between -1 and 1
        glVertex2f(0.5, -0.5);
        glEnd(); // End of draw 


        glfwSwapBuffers(window);
        glfwPollEvents();
    }

}



Comments

Leave a Reply

Your email address will not be published. Required fields are marked *