0
\$\begingroup\$

I'm trying to make a simple example in OpenGL and C++ to draw a square and change position and size through an array.

my problem lies precisely in the passage of the matrix to the shader.

I initially had this code:

#include <iostream>

#include <glad.h>
#include <GLFW/glfw3.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

using namespace std;
using namespace glm;

const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec2 aPos;\n"
"layout (location = 1) in mat4 model;\n"
"uniform mat4 projection;\n"
"void main()\n"
"{\n"
    "gl_Position = projection * model * vec4(aPos.x, aPos.y, 0.0, 1.0f);\n"
"}\0";

const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"   FragColor = vec4(0.8f, 0.3f, 0.02f, 1.0f);\n"
"}\n\0";

GLfloat vertices[] = {
    -1.0f, +1.0f,
    -1.0f, -1.0f,
    +1.0f, -1.0f,
    +1.0f, +1.0f
};

GLint indices[] = {
    0, 1, 2,
    0, 2, 3
};

const glm::vec2 win_size(800, 800);

int main(){
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    
    GLFWwindow* win = glfwCreateWindow(win_size.x, win_size.y, "Test", NULL, NULL);
    if (win == NULL) {
        cout << "Window creation failed" << endl;
        glfwTerminate();
    }

    glfwMakeContextCurrent(win);

    gladLoadGL();
    glViewport(0, 0, win_size.x, win_size.y);

    // ---------------------------------------------------------------------------------

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);

    glLinkProgram(shaderProgram);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    // ---------------------------------------------------------------------------------

     glm::mat4 projection = glm::mat4(1);
    projection = glm::ortho(0.0f, win_size.x, win_size.y, 0.0f, -1.0f, 1.0f);
    
    glm::vec2 size(200, 200);
    glm::vec2 position(200,200);

    glm::mat4 model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(position, 0.0));
    model = glm::translate(model, glm::vec3(size.x * 0.5, size.y * 0.5, 0.0));
    model = glm::scale(model, glm::vec3(size.x * 0.5, size.y * 0.5, 0.0));

    // ---------------------------------------------------------------------------------

    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    GLuint ivbo;
    glGenBuffers(1, &ivbo);
    glBindBuffer(GL_ARRAY_BUFFER, ivbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4), &model, GL_STATIC_DRAW);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), 0);
    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (const void*) (1 * sizeof(glm::vec4)));
    glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (const void*) (2 * sizeof(glm::vec4)));
    glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (const void*) (3 * sizeof(glm::vec4)));
    
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glEnableVertexAttribArray(3);
    glEnableVertexAttribArray(4);

    glVertexAttribDivisor(1, 1);
    glVertexAttribDivisor(2, 1);
    glVertexAttribDivisor(3, 1);
    glVertexAttribDivisor(4, 1);

    GLuint ebo;
    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    // ---------------------------------------------------------------------------------

    GLint projectionUni = glGetUniformLocation(shaderProgram, "projection");
    while (!glfwWindowShouldClose(win)) {
        glClearColor(1.0f,1.0f,1.0f,1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(shaderProgram);
        glUniformMatrix4fv(projectionUni, 1, GL_FALSE, glm::value_ptr(projection));
        glBindVertexArray(vao);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 

        glfwSwapBuffers(win);
        glfwPollEvents();
    }

    // ---------------------------------------------------------------------------------

    glDeleteVertexArrays(1, &vao);
    glDeleteBuffers(1, &vbo);
    glDeleteBuffers(1, &ivbo);
    glDeleteBuffers(1, &ebo);
    glDeleteProgram(shaderProgram);

    glfwDestroyWindow(win);
    glfwTerminate();

    return 0;
}

this code works perfectly (let me know if there are any problems or suggestions for this code)

However, this is just an example, which serves as a starting point to then create a code for drawing different objects, I then modify the code, introducing the concept of "binding point", since I need several VBOs that have in common the same VAO.

This is the code:

#include <iostream>

#include <glad.h>
#include <GLFW/glfw3.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

using namespace std;
using namespace glm;

const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec2 aPos;\n"
"layout (location = 1) in mat4 model;\n"
"uniform mat4 projection;\n"
"void main()\n"
"{\n"
    "gl_Position = projection * model * vec4(aPos.x, aPos.y, 0.0, 1.0f);\n"
"}\0";

const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"   FragColor = vec4(0.8f, 0.3f, 0.02f, 1.0f);\n"
"}\n\0";

GLfloat vertices[] = {
    -1.0f, +1.0f,
    -1.0f, -1.0f,
    +1.0f, -1.0f,
    +1.0f, +1.0f
};

GLint indices[] = {
    0, 1, 2,
    0, 2, 3
};

const glm::vec2 win_size(800, 800);

int main(){
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    
    GLFWwindow* win = glfwCreateWindow(win_size.x, win_size.y, "Test", NULL, NULL);
    if (win == NULL) {
        cout << "Window creation failed" << endl;
        glfwTerminate();
    }

    glfwMakeContextCurrent(win);

    gladLoadGL();
    glViewport(0, 0, win_size.x, win_size.y);

    // ---------------------------------------------------------------------------------

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);

    glLinkProgram(shaderProgram);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    // ---------------------------------------------------------------------------------

     glm::mat4 projection = glm::mat4(1);
    projection = glm::ortho(0.0f, win_size.x, win_size.y, 0.0f, -1.0f, 1.0f);
    
    glm::vec2 size(200, 200);
    glm::vec2 position(200,200);

    glm::mat4 model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(position, 0.0));
    model = glm::translate(model, glm::vec3(size.x * 0.5, size.y * 0.5, 0.0));
    model = glm::scale(model, glm::vec3(size.x * 0.5, size.y * 0.5, 0.0));

    // ---------------------------------------------------------------------------------

    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
    glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 0);
    glVertexAttribFormat(2, 4, GL_FLOAT, GL_FALSE, 1 * sizeof(glm::vec3));
    glVertexAttribFormat(3, 4, GL_FLOAT, GL_FALSE, 2 * sizeof(glm::vec3));
    glVertexAttribFormat(4, 4, GL_FLOAT, GL_FALSE, 3 * sizeof(glm::vec3));
    
    glVertexAttribBinding(0, 0);
    glVertexAttribBinding(1, 1);
    glVertexAttribBinding(2, 1);
    glVertexAttribBinding(3, 1);
    glVertexAttribBinding(4, 1);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glEnableVertexAttribArray(3);
    glEnableVertexAttribArray(4);

    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    GLuint ivbo;
    glGenBuffers(1, &ivbo);
    glBindBuffer(GL_ARRAY_BUFFER, ivbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4), &model, GL_STATIC_DRAW);

    glVertexBindingDivisor(1, 1);
    glVertexAttribDivisor(2, 1);
    glVertexAttribDivisor(3, 1);
    glVertexAttribDivisor(4, 1);

    GLuint ebo;
    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    // ---------------------------------------------------------------------------------

    GLint projectionUni = glGetUniformLocation(shaderProgram, "projection");
    while (!glfwWindowShouldClose(win)) {
        glClearColor(1.0f,1.0f,1.0f,1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(shaderProgram);
        glUniformMatrix4fv(projectionUni, 1, GL_FALSE, glm::value_ptr(projection));

        glBindVertexArray(vao);
        glBindVertexBuffer(0, vbo, 0, 2 * sizeof(float));
        glBindVertexBuffer(1, ivbo, 0, sizeof(glm::mat4));

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 

        glfwSwapBuffers(win);
        glfwPollEvents();
    }

    // ---------------------------------------------------------------------------------

    glDeleteVertexArrays(1, &vao);
    glDeleteBuffers(1, &vbo);
    glDeleteBuffers(1, &ivbo);
    glDeleteBuffers(1, &ebo);
    glDeleteProgram(shaderProgram);

    glfwDestroyWindow(win);
    glfwTerminate();

    return 0;
}

The problem is that it doesn't work, i.e. I'm doing something wrong in the matrix step, but I don't understand what

\$\endgroup\$

0

You must log in to answer this question.

Browse other questions tagged .