1
votes

I have a renderer2D that is very basic but doesn't render my basic 2D quad correctly. It renders it as a single pixel at the bottom left of the window. The window size is 800x600

The orthographic projection matrices are calculated using glm::ortho(0.0f, 800.0f, 0.0f, 600.0f). For some reason it only renders a single pixel at the wrong location. And to make it even more weirder, If i set the Model Matrix to translate to the middle of the screen, It renders that lone pixel at the middle of the screen

I call it like this in my renderer class :

m_Renderer2D.RenderQuad(glm::vec3(400.0f, 300.0f, 1.0f), &m_CrosshairTexture, &m_Camera2D);

Renderer class :

    class Renderer2D    
    {
        public:
    
            Renderer2D();
        
            void RenderQuad(const glm::vec2& position, GLClasses::Texture* texture, OrthographicCamera* camera);
    
        private : 
    
            GLClasses::VertexBuffer m_VBO;
            GLClasses::VertexArray m_VAO;
            GLClasses::IndexBuffer m_IBO;
            GLClasses::Shader m_DefaultShader;
    };
    
cpp file : 

    Renderer2D::Renderer2D() : m_VBO(GL_ARRAY_BUFFER)
    {
        GLuint index_buffer[6] = { 0,1,2,2,3,0 };

        m_VAO.Bind();
        m_VBO.Bind();
        m_IBO.Bind();
        m_VBO.VertexAttribPointer(0, 3, GL_FLOAT, 0, 5 * sizeof(GLfloat), (void*)0);
        m_VBO.VertexAttribPointer(0, 2, GL_FLOAT, 0, 5 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
        m_IBO.BufferData(6 * sizeof(GLuint), index_buffer, GL_STATIC_DRAW);
        m_VAO.Unbind();

        m_DefaultShader.CreateShaderProgramFromFile("Shaders/2DElementShaderVert.glsl", "Shaders/2DElementShaderFrag.glsl");
        m_DefaultShader.CompileShaders();
    }

    void Renderer2D::RenderQuad(const glm::vec2& position, GLClasses::Texture* texture, OrthographicCamera* camera)
    {
        glDisable(GL_DEPTH_TEST);

        const std::array<GLfloat, 8> texture_coords = texture->GetTextureCoords();

        float x, y, w, h;

        x = position.x;
        y = position.y;
        w = position.x + texture->GetWidth(); // The width and height of the texture is correct
        h = position.y + texture->GetHeight();

    GLfloat Vertices[] = {
        w, y, 0.0f, texture_coords[0], texture_coords[1],
        w, h, 0.0f, texture_coords[2], texture_coords[3],
        x, h, 0.0f, texture_coords[4], texture_coords[5],
        x, y, 0.0f, texture_coords[6], texture_coords[7],
    };

        m_DefaultShader.Use();

        glm::mat4 proj = glm::ortho(0.0f, 800.0f, 0.0f, 600.0f);

        texture->Bind(1);
        m_DefaultShader.SetMatrix4("u_Projection", proj, 0);
        m_DefaultShader.SetMatrix4("u_View", camera->GetViewMatrix(), 0);
        m_DefaultShader.SetMatrix4("u_Model", glm::mat4(1.0f), 0);
        m_DefaultShader.SetInteger("u_Texture", 1, 0);
        
        // Draw the 2D quad 
        m_VAO.Bind();
        m_VBO.BufferData(20 * sizeof(GLfloat), Vertices, GL_STATIC_DRAW);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0);
        m_VAO.Unbind();

        glEnable(GL_DEPTH_TEST);
    }

Shaders :

VERTEX SHADER :

#version 330 core

layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec2 a_TexCoord;

out vec2 v_TexCoord;

uniform mat4 u_Projection;
uniform mat4 u_View;
uniform mat4 u_Model;

void main()
{
    gl_Position = u_Projection * u_View * u_Model * vec4(a_Position, 1.0f);
    v_TexCoord = a_TexCoord;
}

FRAGMENT SHADER :

#version 330 core

in vec2 v_TexCoord;
out vec4 o_Color;

uniform sampler2D u_Texture;

void main()
{
    o_Color = texture(u_Texture, v_TexCoord);
}
1
What is the view matrix?user253751
@Rabbid76 Yes, I tried changing the Z coordinate to 0.0f. It still didn't work :(Samuel Rasquinha

1 Answers

3
votes

The layout locations associate the vertex coordinates to attribute index 0 and the texture coordinates to attribute index 1:

layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec2 a_TexCoord;

When you specify the arrays of generic vertex attribute data, then the vertex attribute array 0 is specified twice, but you missed to specify the vertex attribute array 1:

m_VBO.VertexAttribPointer(0, 3, GL_FLOAT, 0, 5 * sizeof(GLfloat), (void*)0);
m_VBO.VertexAttribPointer(0, 2, GL_FLOAT, 0, 5 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));

Hence the texture coordinates cover the vertex coordinates and the texture coordinate attribute is not specified at all.

The attribute index for the texture coordinates has to be 1 rather than 0:

m_VBO.VertexAttribPointer(0, 2, GL_FLOAT, 0, 5 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));

m_VBO.VertexAttribPointer(1, 2, GL_FLOAT, 0, 5 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));