1
votes

I am trying to make my first cube using open gl. Unfortunately I stucked in easy rotation. This is how it should look:

img

Instead I am getting those weird, do not even know how to called it : https://youtu.be/0A5Hi-8bygE

Vertex shader

#version 330 core

layout (location = 0) in vec2 a_position;
layout (location = 1) in vec2 a_uv;
layout (location = 2) in vec4 a_color;

out vec2 v_fragmentPosition;
out vec2 v_fragmentUV;
out vec4 v_fragmentColor;

uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_projection;

void main()
{
    gl_Position = u_projection * u_view * u_model * vec4(a_position, 0.0, 1.0);

    v_fragmentPosition = a_position;
    v_fragmentUV = vec2(a_uv.x, 1 - a_uv.y);
    v_fragmentColor = a_color;
}

Fragment

#version 330 core

out vec4 outColor;

in vec2 v_fragmentPosition;
in vec2 v_fragmentUV;
in vec4 v_fragmentColor;

void main()
{
    outColor = v_fragmentColor;
}

Main

#include <glad.h>

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

#include "Mesh.h"
#include "Shader.h"

int main(int argc,char*args[])
{
    SDL_Init(SDL_INIT_EVERYTHING);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    SDL_Window* window = SDL_CreateWindow("fdas", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL);
    SDL_GLContext context = SDL_GL_CreateContext(window);

    gladLoadGLLoader(SDL_GL_GetProcAddress);

    glEnable(GL_DEPTH_TEST);

    Shader shader;

    std::string vertex = shader.LoadFromFile("vertex.shader");
    std::string fragment = shader.LoadFromFile("fragment.shader");
    shader.CreateShaderProgram(vertex.c_str(), fragment.c_str());
    shader.useProgram();

    Mesh mesh;
    mesh.CreateVertexArray();

    bool quit = false;
    SDL_Event event;
    while (!quit)
    {
        while (SDL_PollEvent(&event))
        {
            if (event.type == SDL_QUIT)
            {
            exit(0);
                }
        }
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glm::mat4 model;
        model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));

        glm::mat4 view;
        view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));

        glm::mat4 projection;
        projection = glm::perspective(glm::radians(45.0f), 1280 / 720.0f, 0.1f, 100.0f);

        GLint u_model = shader.GetUniformLocation("u_model");
        GLint u_view = shader.GetUniformLocation("u_view");
        GLint u_projection = shader.GetUniformLocation("u_projection");

        glUniformMatrix4fv(u_model, 1, GL_FALSE, glm::value_ptr(model));
        glUniformMatrix4fv(u_view, 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(u_projection, 1, GL_FALSE, glm::value_ptr(projection));

        Rect destRect = { -0.5f, -0.5f, 1.0f, 1.0f };   
        Rect uvRect = { 0.0f, 0.0f, 1.0f, 1.0f };
        ColorRGBA color = { 255, 255, 128, 255 };

        mesh.CreateQuad(destRect, uvRect, color);
        mesh.Draw(0);

        SDL_GL_SwapWindow(window);
    }
    return 0;
}

Mesh

void Mesh::CreateVertexArray()
{
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, uv));
    glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, color));

    glBindVertexArray(0);
}

void Mesh::CreateQuad(Rect destRect, Rect uvRect, ColorRGBA color)
{
    vertex[0].color = color; // topleft
    vertex[0].setPosition(destRect.x, destRect.y + destRect.h);
    vertex[0].setUV(uvRect.x, uvRect.y + uvRect.h);

    vertex[1].color = color;
    vertex[1].setPosition(destRect.x, destRect.y); // bottom left
    vertex[1].setUV(uvRect.x, uvRect.y);

    vertex[2].color = color;
    vertex[2].setPosition(destRect.x + destRect.w, destRect.y); // bottom right
    vertex[2].setUV(uvRect.x + uvRect.w, uvRect.y);

    vertex[3].color = color;
    vertex[3].setPosition(destRect.x + destRect.w, destRect.y + destRect.h); // top right
    vertex[3].setUV(uvRect.x + uvRect.w, uvRect.y + uvRect.h);

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

    glBindVertexArray(vao);

    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(vertex), NULL, GL_STATIC_DRAW); // orphan the buffer
    glBufferSubData(GL_ARRAY_BUFFER, 0, 6 * sizeof(vertex), vertex);

    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLuint), NULL, GL_STATIC_DRAW); // orphan the buffer
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 6 * sizeof(GLuint), indices);

    glBindVertexArray(0);

}

void Mesh::Draw(GLuint texture)
{
    glBindVertexArray(vao);

  //  glEnable(GL_CULL_FACE);
   // glCullFace(GL_FRONT);
    //glFrontFace(GL_CW);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);

    glBindVertexArray(0);
}

Vertex

struct Rect {
    float x, y;
    float w, h;
};
struct Position {
    float x, y;
};

struct UV {
    float u, v;
};

struct ColorRGBA {
    GLubyte r, g, b, a;
};
class Vertex
{
public:
    Vertex();
    ~Vertex();

    void setPosition(float x, float y);
    void setcolor(ColorRGBA color);
    void setUV(float u, float v);

    UV uv;
    ColorRGBA color;
    Position position;
};

I will not show shader class, because there is all good with it.

I know it, because I did an experiment.

I created a new uniform in fragment class called u_expColor and set outColor = u_expColor and a quad's color changed.

Also I created uniform vec4 u_expPos in vertex shader and said gl_Position = e_expPos and it created quad with no problems.

Only if I want to create/multiply position by mvp in vertex shader there is a problem like on the you tube video.

How to fix it?

1
Why do you think you have to normalize the color attribute? That is why ColorRGBA color = { 255, 255, 128, 255 }; in main ` You have 6 indices, but you only have 4 vertices. Change 6 * sizeof(vertex) to 4 * sizeof(vertex). But of course that won't solve the issue` Yes, that' will not.xtkmxn
When you set up the buffer data (glBufferData, glBufferSubData) the you have to bind the array buffer... I had it like so, but some one told me that I have to have vao binded instead of vbo and ebo. Did not work, though. Which version of of the "glm" library do you use?The newest one I guess. Downloaded from original page.xtkmxn
What you want to clarify? the buffer data? I said, I understand there should be glBindBuffer(GL_ARRAY_BUFFER, vbo); and then glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); instead of ` glBindVertexArray(vao);`. Even with those options it is not working.xtkmxn

1 Answers

0
votes

I have fixed it thanks http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/#putting-it-all-together. I saw he had

glm::mat4 model = glm::mat4(1.0f) 

and it was all I had to do.