How to draw multiple triangles in the same display ?

  • eewano
    Likes 0

    Problem Description

    Modern OpenGL C++ 3D Game Tutorial Series - Section2 15. Shader Files -

     

    I’m learning the method that draw an triangle with 3 colors.

    So, this project build succeeded and an triangle were drawn on the window.

    Next, I will try to draw 2 or 3 triangles using “for” statement. But, I cannot correct the program well…

     

    If it is good, please give me some advices.

     

     

     

  • Sonar Systems admin
    Likes 0

    What exactly is the problem you are trying to correct?

  • eewano
    Likes 0

    I’m sorry for lack of information.

    This is my source code. I want to try to draw 2 triangles in a window. But I don’t understand the configuration or function of GLFW, yet. So, I have no idea what code is important and how to fix...

    #include <iostream>
    //GLEW
    #define GLEW_STATIC
    #include <GL/glew.h>
    //GLFW
    #include <GLFW/glfw3.h>
    
    #include "Shader.h"
    //window dimensions
    const GLint WIDTH = 800, HEIGHT = 600;
    
    int main()
    {
        //Init GLFW
        glfwInit();
        
        //Set all the required options for GLFW
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //macでは必要
        glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
        
        //Create a GLFWwindow object that we can use for GLFW's functions
        GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Learn OpenGL", nullptr, nullptr);
        
        int screenWidth, screenHeight;
        glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
        
        if(nullptr == window)
        {
            std::cout << "Failed to create GLFW window" << std::endl;
            glfwTerminate();
            
            return EXIT_FAILURE;
        }
        
        glfwMakeContextCurrent(window);
        
        //Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
        glewExperimental = GL_TRUE;
        
        //Initialize GLEW to setup the OpenGL Function pointers
        if(GLEW_OK != glewInit())
        {
            std::cout << "Failed to initialize GLEW" << std::endl;
            
            return -1;
        }
        
        //Define the viewport dimentions
        glViewport(0, 0, screenWidth, screenHeight);
        
        Shader ourShader("resources/shaders/core.vs", "resources/shaders/core.frag");
        
        GLfloat vertices[] =
        {
            //position and color
            -0.5f, -0.5f, 0.0f,     1.0f, 0.0f, 0.0f, //bottom left
            0.5f, -0.5f, 0.0f,      0.0f, 1.0f, 0.0f, //bottom right
            0.0f, 0.5f, 0.0f,       0.0f, 0.0f, 1.0f, //middle top
        };
        
        GLuint VBO, VAO;
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        
        glBindVertexArray(VAO);
        
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
        
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6/*position & color total*/ * sizeof(GLfloat), (GLvoid * )0);
        glEnableVertexAttribArray(0);
        
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid * )(3 * sizeof(GLfloat)));
        glEnableVertexAttribArray(1);
        
        glBindVertexArray(0);
        
        while(!glfwWindowShouldClose(window))
        {
            //Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
            glfwPollEvents();
            
            //Render
            //Clear the colorbuffer
            glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
            
            ourShader.Use();
            glBindVertexArray(VAO);
            glDrawArrays(GL_TRIANGLES, 0, 3);
            glBindVertexArray(0);
            
            //Swap the screen buffers
            glfwSwapBuffers(window);
        }
        
        glDeleteVertexArrays(1, &VAO);
        glDeleteBuffers(1, &VBO);
        
        //Terminate GLFW, clearing any resources allocated by GLFW.
        glfwTerminate();
        
        return 0;
    }

    Shader.hpp is same as the GitHub
    SnoarSystems / Modern-OpenGL-Tutorials / [GETTING STARTED] / [2] Shaders / Shader.h

    If you know, please give me some advices.

     

    Best regards

  • Sonar Systems admin
    Likes 0

    Are you getting any errors in the console?

  • eewano
    Likes 0

    I’m sorry I didn’t make it clear enough.

    First, I tried to draw 9 quadrangles using “for” sentence.

    #include <iostream>
    #include <GLFW/glfw3.h>
    
    GLFWwindow *window;
    
    const GLint WINDOW_WIDTH = 800;
    const GLint WINDOW_HEIGHT = 600;
    
    int main(int argc, const char * argv[]) {
    
        if(!glfwInit()) {
            return EXIT_FAILURE;
        }
        
        window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Simple_Quadrangle", nullptr, nullptr);
        
        glfwSetErrorCallback(ErrorCallback);
        glfwMakeContextCurrent(window);
        
        while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0) {
            
            glfwPollEvents();
            glClear(GL_COLOR_BUFFER_BIT);
            
            for(int i = 0; i < 9; i++) {
                
                glBegin(GL_POLYGON);
                
                if(i % 2 == 0) {
                    glColor3d(1.0, 0.2, 0.5);
                    glVertex2d(-0.9 + (i * 0.1), -0.9 + (i * 0.1));
                    
                    glColor3d(0.8, 0.5, 0.0);
                    glVertex2d(0.9 - (i * 0.1), -0.9 + (i * 0.1));
                    
                    glColor3d(0.0, 1.0, 0.0);
                    glVertex2d(0.9 - (i * 0.1), 0.9 - (i * 0.1));
                    
                    glColor3d(1.0, 1.0, 1.0);
                    glVertex2d(-0.9 + (i * 0.1), 0.9 - (i * 0.1));
                }
                else {
                    glColor3d(0.0, 0.0, 0.0);
                    glVertex2d(-0.9 + (i * 0.1), -0.9 + (i * 0.1));
                    
                    glColor3d(0.0, 0.0, 0.0);
                    glVertex2d(0.9 - (i * 0.1), -0.9 + (i * 0.1));
                    
                    glColor3d(0.0, 0.0, 0.0);
                    glVertex2d(0.9 - (i * 0.1), 0.9 - (i * 0.1));
                    
                    glColor3d(0.0, 0.0, 0.0);
                    glVertex2d(-0.9 + (i * 0.1), 0.9 - (i * 0.1));
                }
                
                glEnd();
            }
            glFlush();
            
            glfwSwapBuffers(window);
        }
        
        glfwTerminate();
        return 0;
    }

    This code built succeeded. But, it’s an old method to draw polygons.

    So, I want to try to draw the same polygons with modern method.

  • Sonar Systems admin
    Likes 0

    Have you drawn one quad using the modern method?

  • eewano
    Likes 0

    Yes, I do. This is my code to draw one quadrangle.

    #include <iostream>
    
    #include <GL/glew.h>
    #include <GLFW/glfw3.h>
    
    #include "Shader.h"
    
    struct Vec2 {
        GLint x, y;
    };
    
    const Vec2 WINDOW_SIZE = {800, 600};
    
    int main(int argc, const char *argv[]) {
    
        if (!glfwInit()) {
            return EXIT_FAILURE;
        }
    
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
        glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    
        GLFWwindow *window = glfwCreateWindow(WINDOW_SIZE.x, WINDOW_SIZE.y, "Simple_Quadrangle", nullptr, nullptr);
    
        Vec2 screensize;
        glfwGetFramebufferSize(window, &screensize.x, &screensize.y);
    
        if (window == nullptr) {
            std::cout << "Failed to create GLFW window.\n";
            glfwTerminate();
            return EXIT_FAILURE;
        }
    
        glfwMakeContextCurrent(window);
    
        glewExperimental = GL_TRUE;
    
        if (GLEW_OK != glewInit()) {
            std::cout << "Failed to initialize GLEW.\n";
            return -1;
        }
    
        glViewport(0, 0, screensize.x, screensize.y);
    
        Shader shader("resource/shader/core.vs", "resource/shader/core.fs");
    
        //{ posX, posY, posZ, R, G, B }
        GLfloat vertices[] = {
            -0.9f, -0.9f, 0.0f, 1.0f, 0.0f, 0.0f,
            0.9f, -0.9f, 0.0f, 0.0f, 1.0f, 0.0f,
            0.9f, 0.9f, 0.0f, 0.0f, 0.0f, 1.0f,
            -0.9f, 0.9f, 0.0f, 1.0f, 1.0f, 0.0f
        };
    
        GLuint VAO, VBO;
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        glBindVertexArray(VAO);
    
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(
                GL_ARRAY_BUFFER,
                sizeof(vertices),
                vertices,
                GL_STATIC_DRAW
        );
    
        glVertexAttribPointer(
                0,
                3,
                GL_FLOAT,
                GL_FALSE,
                6 * sizeof(GLfloat),
                (GLvoid *) 0
        );
        glEnableVertexAttribArray(0);
    
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid *) (3 * sizeof(GLfloat)));
        glEnableVertexAttribArray(1);
    
        glBindVertexArray(0);
    
        while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0) {
    
            glfwPollEvents();
    
            glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
    
            shader.Use();
            glBindVertexArray(VAO);
            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
            glBindVertexArray(0);
    
            glfwSwapBuffers(window);
        }
    
        glDeleteVertexArrays(1, &VAO);
        glDeleteBuffers(1, &VBO);
    
        glfwTerminate();
        return 0;
    }

    And here is the result. But I have no idea how to modify this code for drawing 9 quadrangles.

    If it is good, please give me some advices.

  • Sonar Systems admin
    Likes 0

    Continue watching the series, I cover drawing multiple objects.

  • eewano
    Likes 0

    It was too difficult for me to fix code…

    In the section 2 and No.19 -Camera-, you showed how to draw multiple cubes. (same sizes and different positions)

    But there were no lecture how to draw multiple objects such as “same positions and different sizes”.

    I tried again and again, so I could fixed code somehow.

    ------------------------------main.cpp------------------------------
    #include <iostream>
    
    #define GLEW_STATIC
    #include <GL/glew.h>
    #include <GLFW/glfw3.h>
    
    #include "Shader.h"
    
    struct Vec2 {
        GLint x, y;
    };
    
    const Vec2 WINDOW_SIZE = {800, 600};
    
    GLFWwindow *window;
    
    int main(int argc, const char *argv[]) {
    
        if (!glfwInit()) {
            return EXIT_FAILURE;
        }
    
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
        glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    
        window = glfwCreateWindow(WINDOW_SIZE.x, WINDOW_SIZE.y, "Polygon_Practice", nullptr, nullptr);
    
        Vec2 screen;
        glfwGetFramebufferSize(window, &screen.x, &screen.y);
    
        if (window == nullptr) {
            std::cout << "Failed to create GLFW window.\n";
            glfwTerminate();
            return EXIT_FAILURE;
        }
    
        glfwMakeContextCurrent(window);
    
        glewExperimental = GL_TRUE;
    
        if (GLEW_OK != glewInit()) {
            std::cout << "Failed to initialize GLEW.\n";
            return -1;
        }
    
        glViewport(0, 0, screen.x, screen.y);
    
        Shader shader("resources/VertexShader.glsl", "resources/FragmentShader.glsl");
    
        GLuint VBO, VAO;
    
        while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0) {
            glfwPollEvents();
    
            glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
    
            for (GLint i = 0; i < 9; i++) {
    
                if (i % 2 == 0) {
                    GLfloat vertices[] = {
                            0.9f - (i * 0.1f), 0.9f - (i * 0.1f), 0.0f, 0.0f, 1.0f, 0.0f, //Top Right
                            0.9f - (i * 0.1f), -0.9f + (i * 0.1f), 0.0f, 0.8f, 0.5f, 0.0f, //Bottom Right
                            -0.9f + (i * 0.1f), -0.9f + (i * 0.1f), 0.0f, 1.0f, 0.2f, 0.5f, //Bottom Left
                            -0.9f + (i * 0.1f), 0.9f - (i * 0.1f), 0.0f, 1.0f, 1.0f, 1.0f //Top Left
                    };
    
                    glGenVertexArrays(1, &VAO);
                    glGenBuffers(1, &VBO);
                    glBindVertexArray(VAO);
                    glBindBuffer(GL_ARRAY_BUFFER, VBO);
                    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
                    //Position attribute
                    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid *) 0);
                    glEnableVertexAttribArray(0);
                    //Color attribute
                    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid *) (3 * sizeof(GLfloat)));
                    glEnableVertexAttribArray(1);
    
                    shader.Use();
                    glBindVertexArray(VAO);
                    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    
                    glBindVertexArray(0);
    
                } else {
                    GLfloat vertices[] = {
                            0.9f - (i * 0.1f), 0.9f - (i * 0.1f), 0.0f, 0.0f, 0.0f, 0.0f, //Top Right
                            0.9f - (i * 0.1f), -0.9f + (i * 0.1f), 0.0f, 0.0f, 0.0f, 0.0f, //Bottom Right
                            -0.9f + (i * 0.1f), -0.9f + (i * 0.1f), 0.0f, 0.0f, 0.0f, 0.0f, //Bottom Left
                            -0.9f + (i * 0.1f), 0.9f - (i * 0.1f), 0.0f, 0.0f, 0.0f, 0.0f //Top Left
                    };
    
                    glGenVertexArrays(1, &VAO);
                    glGenBuffers(1, &VBO);
                    glBindVertexArray(VAO);
                    glBindBuffer(GL_ARRAY_BUFFER, VBO);
                    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
                    //Position attribute
                    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid *) 0);
                    glEnableVertexAttribArray(0);
                    //Color attribute
                    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid *) (3 * sizeof(GLfloat)));
                    glEnableVertexAttribArray(1);
    
                    shader.Use();
                    glBindVertexArray(VAO);
                    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    
                    glBindVertexArray(0);
                }
            }
    
            glfwSwapBuffers(window);
        }
    
        glDeleteVertexArrays(1, &VAO);
        glDeleteBuffers(1, &VBO);
    
        glfwTerminate();
        return 0;
    }

    And here is the FragmentShader and VertexShader codes.

    ------------------------------FragmentShader.glsl------------------------------
    #version 330 core
    
    in vec3 ourColor;
    
    out vec3 color;
    
    void main() {
        color = ourColor;
    }
    
    
    ------------------------------VertexShader.glsl------------------------------
    #version 330 core
    
    layout (location = 0) in vec3 position;
    layout (location = 1) in vec3 color;
    
    out vec3 ourColor;
    
    void main() {
        gl_Position = vec4(position, 1.0f);
        ourColor = color;
    }

    Program build succeeded.

    Is this code correct writing style?

    If it is good, give me some advices to fix it in a better way.

  • Sonar Systems admin
    Likes 0

    Looks good.

Login to reply