Search code examples
c++openglglslglfw

Frag Y coord goes from -600 to 0 after adding frame buffer?


After adding a frame buffer and then drawing to it, the default frame buffers frag coordinate y becomes -600 at the bottom and the top is 0, rather than bottom being 0 and top being 600.

I've messed around with the window size, the frame buffer size, and the viewport. But nothing has changed the frag coordinate from being negative.

The moment I draw to the frame buffer, the frag coordinate changes.

To test the frag coord, I check if the y coord is over -300, and brighten the colour if so. Since it goes to -600, half the screen lights up.

Here's the code to reproduce the error, the shaders are included in the same page for simplicity:

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

#include <iostream>

// vertex shader
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
"   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";

// fragment shader
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"vec4 light = vec4(0.1f, 0.1f, 0.1f, 0.1f);\n"
"void main()\n"
"{\n"
"if (gl_FragCoord.y > -300)\n"
"{\n"
"light = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
"}\n"
"FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f) * light;\n"
"}\n\0";

const int Width = 800;
const int Height = 600;

int main()
{
    glfwInit();

    GLFWwindow* window = glfwCreateWindow(Width, Height, "Test", 
      NULL, NULL);

    glfwMakeContextCurrent(window);

    
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    // vertex shader
    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

    // fragment shader
    unsigned int fragmentShader = 
    glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    // link shaders
    unsigned int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);


    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);


    float square[] = {
        -1.0f,  1.0f,
        -1.0f, -1.0f,
         1.0f, -1.0f,

        -1.0f,  1.0f,
         1.0f, -1.0f,
         1.0f,  1.0f,
    };

    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(square), square, 
      GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * 
      sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindVertexArray(0);

    float vertices[] = {
        // pos      // tex
        -1.0f,  1.0f,  0.0f, 1.0f,
        -1.0f, -1.0f,  0.0f, 0.0f,
         1.0f, -1.0f,  1.0f, 0.0f,

        -1.0f,  1.0f,  0.0f, 1.0f,
         1.0f, -1.0f,  1.0f, 0.0f,
         1.0f,  1.0f,  1.0f, 1.0f
    };

    unsigned int FBO;
    unsigned int quadVAO;
    unsigned int texture;

    glGenVertexArrays(1, &quadVAO);

    glGenBuffers(1, &VBO);
    glBindVertexArray(quadVAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, 
      GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * 
      sizeof(float), (void*)0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    // load framebuffer
    glGenFramebuffers(1, &FBO);
    glBindFramebuffer(GL_FRAMEBUFFER, FBO);

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Width, Height, 0, 
      GL_RGB, GL_UNSIGNED_BYTE, NULL);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
      GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
      GL_NEAREST);
    glBindTexture(GL_TEXTURE_2D, 0);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
      GL_TEXTURE_2D, texture, 0);
    // renderbufferobject
    unsigned int RBO;
    glGenRenderbuffers(1, &RBO);
    glBindRenderbuffer(GL_RENDERBUFFER, RBO);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 
      Width, Height);

    glBindRenderbuffer(GL_RENDERBUFFER, 0);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == 
      GL_FRAMEBUFFER_COMPLETE)
    {
        std::cout << "FBO connected" << "\n";
    }
    else
    {
        std::cout << "Unable to connect to FBO" << 
        glCheckFramebufferStatus(GL_FRAMEBUFFER) << "\n";
    }


    // render loop
    while (!glfwWindowShouldClose(window))
    {
        // frame buffer
        glBindFramebuffer(GL_FRAMEBUFFER, FBO);
        glClearColor(0.11f, 0.16f, 0.32f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glEnable(GL_DEPTH_TEST);
        
        // draw square
        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);
        // not drawing here stops the issue
        glDrawArrays(GL_TRIANGLES, 0, 6);

        // back to default frame buffer
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glDisable(GL_DEPTH_TEST);
        glClearColor(0.11f, 0.16f, 0.32f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // draw square
        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 6);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

Solution

  • I found out it's a driver bug, I ran it on a different pc and there was no change in frag coordinates.