1
$\begingroup$

How do I rotate around the instance itself instead of the rotating the entire shader? You can see what I mean by rotating the entire shader in the images below:Not RotatedRotated

Here is the main.c:

#include <glad/glad.h>#include <GLFW/glfw3.h>#include <cglm/cglm.h>#include <stdio.h>#include "file.h"const unsigned int SCR_WIDTH  = 1280;const unsigned int SCR_HEIGHT = 720;const char* vert_shader_path = "<path_to_project>/shaders/inst_shader.vert";const char* frag_shader_path = "<path_to_project>/shaders/inst_shader.frag";int main(){    // Initialize GLFW    glfwInit();    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);    // Create window and make it the current context    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "MINIMAL INSTANCING", 0, 0);    if(window == 0)    {        printf("Failed to create GLFW window\n");        glfwTerminate();        return -1;    }    glfwMakeContextCurrent(window);    // Initialize Open GL via glad    if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))    {        printf("Failed to init GLAD\n");        glfwTerminate();        return -1;    }    int err;    char* vert_shader_src;    char* frag_shader_src;    // Read in the shader file binary data    err = read_file_binary(vert_shader_path, &vert_shader_src);    if(err)        return err;    err = read_file_binary(frag_shader_path, &frag_shader_src);    if(err)        return err;    // Create Vertex Shader    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);    glShaderSource(vertexShader, 1, (const char**)&vert_shader_src, 0);    glCompileShader(vertexShader);    int success;    char infoLog[512];    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);    if(!success)    {        glGetShaderInfoLog(vertexShader, 512, 0, infoLog);        printf("ERROR VERTEX %s\n", infoLog);    }    // Create Fragment Shader    unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);    glShaderSource(fragmentShader, 1, (const char**)&frag_shader_src, 0);    glCompileShader(fragmentShader);    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);    if(!success)    {        glGetShaderInfoLog(fragmentShader, 512, 0, infoLog);        printf("ERROR FRAGMENT %s\n", infoLog);    }    // Create Shader Program and Link the Vertex / Fragment shaders    unsigned int shaderProgram = glCreateProgram();    glAttachShader(shaderProgram, vertexShader);    glAttachShader(shaderProgram, fragmentShader);    glLinkProgram(shaderProgram);    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);    if(!success)    {        glGetProgramInfoLog(shaderProgram, 512, 0, infoLog);        printf("ERROR LINKING %s\n", infoLog);    }    // Delete the shaders since they are linked to the shader program    glDeleteShader(vertexShader);    glDeleteShader(fragmentShader);    free(frag_shader_src);    free(vert_shader_src);    // Instance setup and memory allocation    unsigned int instance_count = 264;    float* instance_data;    instance_data = (float*)malloc(sizeof(float) * 2 * instance_count);    // Build the offests    int inst_index = 0;    float inst_offset = 0.1f;    for(int y = -12; y < 12; y += 2)    {        for(int x = -22; x < 22; x += 2)        {            instance_data[inst_index + 0] = (float) x / 10.0f + inst_offset;            instance_data[inst_index + 1] = (float) y / 10.0f + inst_offset;            inst_index += 2;        }    }    // Generate the instance buffers    unsigned int instVBO;    glGenBuffers(1, &instVBO);    glBindBuffer(GL_ARRAY_BUFFER, instVBO);    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 2 * instance_count, &instance_data[0], GL_STATIC_DRAW);    glBindBuffer(GL_ARRAY_BUFFER, 0);    // Vertex positions and vertex colors    float vertices[] = {         0.05f,  0.05f, /* top     right */ 0.0f, 0.0f, 1.0f, // Blue         0.05f, -0.05f, /* bottom  right */ 1.0f, 0.0f, 0.0f, // Red        -0.05f, -0.05f, /* bottom  left  */ 1.0f, 1.0f, 0.0f, // Yellow        -0.05f,  0.05f, /* top     left  */ 0.0f, 1.0f, 0.0f  // Green    };    // Indices for each triangle in the quad    unsigned int indices[] = {        0, 1, 3,            // first  triangle        1, 2, 3             // second triangle    };    // Generate quad arrays and buffers    unsigned int quadVAO, quadVBO, quadEBO;    glGenVertexArrays(1, &quadVAO);    glGenBuffers(1, &quadVBO);    glGenBuffers(1, &quadEBO);    // Bind the Vertex Array before manipulation    glBindVertexArray(quadVAO);    // Bind the Array Buffer and set the data from the vertices array    glBindBuffer(GL_ARRAY_BUFFER, quadVBO);    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);    // Bind the Element Buffer and set the data from the indices array    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadEBO);    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);    // Setup the quad buffer layout    //  0: 2 / 5 ITEMS @ 0 [X, X, -, -, -]    glEnableVertexAttribArray(0);    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);    //  1: 3 / 5 ITEMS @ 2 [-, -, X, X, X]    glEnableVertexAttribArray(1);    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));    // Setup the instance buffer layout    //  0: 2 / 2 ITEMS @ 0 [X, X]    glEnableVertexAttribArray(2);    glBindBuffer(GL_ARRAY_BUFFER, instVBO);    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);    glBindBuffer(GL_ARRAY_BUFFER, 0);    // This tells OpenGL this is an instanced vertex attribute    glVertexAttribDivisor(2, 1);    glBindVertexArray(0);    mat4 projection, view, rotation;    vec3 eye = {0.0f, 0.0f, 3.0f};    vec3 center = {0.0f, 0.0f, 0.0f};    vec3 up = {0.0f, 1.0f, 0.0f};    vec3 pivot, axis;    float angle;    glm_vec3_zero(pivot);    glm_vec3_zero(axis);    pivot[0] = 0.0f;    pivot[1] = 0.0f;    axis[2] = 1.0f;    angle = 45.0f;    glm_mat4_identity(rotation);    glm_rotate_at(rotation, pivot, glm_rad(angle), axis);    while(!glfwWindowShouldClose(window))    {        if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)            glfwSetWindowShouldClose(window, 1);        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);        glm_perspective(glm_rad(45.0f), (float)SCR_WIDTH/(float)SCR_HEIGHT, 0.1f, 1000.0f, projection);        glm_lookat(eye, center, up, view);        glUseProgram(shaderProgram);        glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, &projection[0][0]);        glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, &view[0][0]);        glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "rotation"), 1, GL_FALSE, &rotation[0][0]);        glBindVertexArray(quadVAO);        glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0, instance_count);        glBindVertexArray(0);        glfwSwapBuffers(window);        glfwPollEvents();    }    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);    glBindBuffer(GL_ARRAY_BUFFER, 0);    glDeleteVertexArrays(1, &quadVAO);    glDeleteBuffers(1, &quadVBO);    glDeleteProgram(shaderProgram);    glfwTerminate();    return 0;}

Here is the shader code:

#version 330 corelayout (location = 0) in vec2 aPos;layout (location = 1) in vec3 aColor;layout (location = 2) in vec2 aOffset;uniform mat4 projection;uniform mat4 view;uniform mat4 rotation;out vec3 fColor;void main(){    fColor = aColor;    gl_Position = projection * view * rotation * vec4(aPos + aOffset, 0.0, 1.0);}

Any help I can get would be greatly appreciated, I have been stuck on this for a while now.

askedNov 21 at 20:31
cvolpe's user avatar
$\endgroup$

1 Answer1

1
$\begingroup$

In order to apply the rotation to each instance rather than the whole scene, you need to apply the rotation to each instance's vertex position andnot apply it to the offset.

gl_Position = projection * view * (      rotation * vec4(aPos, 0.0, 1.0)    + vec4(aOffset, 0.0, 0.0));
answeredNov 22 at 16:00
Kevin Reid's user avatar
$\endgroup$
2
  • $\begingroup$Interesting, that worked for me but why does it change the spacing? With that they become much more tightly packed$\endgroup$CommentedNov 22 at 19:03
  • $\begingroup$@cvolpe If you rotate squares by 45 degrees without changing the grid arrangement at all, the corners will become closer to each other, but in exchange, there will be more empty space diagonally — it becomes closer to a checkerboard pattern. If that's not what you mean, a picture will be needed, and it may be a different question.$\endgroup$CommentedNov 23 at 0:19

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.