OpenGL Render To Frame Buffer with no render output, while the program is able to render to default frame

-2

my project is at RocketArticle. When not using framebuffer, the scene will show as normal, but with framebuffer enabled, there will be only clear color in the bind framebuffer. Also, Renderdoc shows that, vertex output is fine, but fragment shader has no output. Below is render result
No Framebuffer Output
Render To Default Frame
RenderDoc Mesh View
And the main render loop is as follow:
Render Main Loop

#include <glad/glad.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <vector>
#include <iostream>

struct PerFrameConstants
{
    glm::mat4 viewMatrix;        // 64 bytes
    glm::mat4 projectionMatrix;  // 64 bytes
    glm::vec4 camPos;            // 16 bytes
};

struct PerBatchConstants
{
    glm::mat4 modelMatrix;  // 64 bytes
};

void AttachShader( GLuint program, GLenum type, const char* src )
{
    GLuint shader = glCreateShader( type );
    glShaderSource( shader, 1, &src, NULL );
    glCompileShader( shader );
    CheckStatus( shader, true );
    glAttachShader( program, shader );
    glDeleteShader( shader );
}

void CheckStatus( GLuint obj, bool isShader )
{
    GLint status = GL_FALSE, log[ 1 << 11 ] = { 0 };
    ( isShader ? glGetShaderiv : glGetProgramiv )( obj, isShader ? GL_COMPILE_STATUS : GL_LINK_STATUS, &status );
    if( status == GL_TRUE ) return;
    ( isShader ? glGetShaderInfoLog : glGetProgramInfoLog )( obj, sizeof( log ), NULL, (GLchar*)log );
    std::cerr << (GLchar*)log << "\n";
    std::exit( EXIT_FAILURE );
}

int main()
{
    float orthoLeft = -10 * 1.7 * 0.5f;
    float orthoRight = 10 * 1.7 * 0.5f;
    float orthoBottom = -10 * 0.5f;
    float orthoTop = 10 * 0.5f;

    PerFrameConstants frame_data { glm::mat4(1.0f), glm::ortho(orthoLeft, orthoRight,orthoBottom, orthoTop, -1.0, 1.0), glm::vec4(0.0) };
    PerBatchConstants batch_data { glm::mat4(1.0f) };

    uint32_t shader_id = glCreateProgram();
    AttachShader( shader_id, GL_VERTEX_SHADER, vert );
    AttachShader( shader_id, GL_FRAGMENT_SHADER, frag );
    glLinkProgram( shader_id );
    CheckStatus( shader_id, false );
    glUseProgram( shader_id );

    struct Vertex
    {
        glm::vec4 mPosition;
        glm::vec4 mColor;
        glm::vec2 mTexCoord;
        float index;
        float tiling;
    };
    const std::vector< Vertex > vert =
    {
        { glm::vec4( -0.5f, -0.5f, 0, 0), glm::vec4( 1.0f, 0.0f, 0.0f,1), glm::vec2(0, 0), 0, 1},
        { glm::vec4(  0.5f, -0.5f, 0, 0), glm::vec4( 0.0f, 1.0f, 0.0f,1), glm::vec2(0, 1), 0, 1},
        { glm::vec4(  0.0f,  0.5f, 0, 0), glm::vec4( 0.0f, 0.0f, 1.0f,1), glm::vec2(1, 0), 0, 1},
    };

    glBufferData( GL_ARRAY_BUFFER, sizeof( Vertex ) * verts.size(), verts.data(), GL_STATIC_DRAW );

    GLuint vao = 0;
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );
    glEnableVertexAttribArray( 0 );
    glVertexAttribPointer( 0 , 4, GL_FLOAT, GL_FALSE, sizeof( Vertex ), (GLvoid*)offsetof( Vertex, mPosition ) );
    glEnableVertexAttribArray( 1 );
    glVertexAttribPointer( 1 , 4, GL_FLOAT, GL_FALSE, sizeof( Vertex ), (GLvoid*)offsetof( Vertex, mColor ) );
    glEnableVertexAttribArray( 2 );
    glVertexAttribPointer( 1 , 2, GL_FLOAT, GL_FALSE, sizeof( Vertex ), (GLvoid*)offsetof( Vertex, mTexCoord ) );
    glEnableVertexAttribArray( 3 );
    glVertexAttribPointer( 1 , 1, GL_FLOAT, GL_FALSE, sizeof( Vertex ), (GLvoid*)offsetof( Vertex, index ) );
    glEnableVertexAttribArray( 4 );
    glVertexAttribPointer( 1 , 1, GL_FLOAT, GL_FALSE, sizeof( Vertex ), (GLvoid*)offsetof( Vertex, tiling ) );

    uint32_t texture_id;
    uint32_t white_tex = 0xffffffff;
    glGenTextures(1, &texture_id);
    glBindTexture(GL_TEXTURE_2D, texture_id);

    // set the texture wrapping parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    // set texture filtering parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &white_tex);
    glGenerateMipmap(GL_TEXTURE_2D);

    uint32_t m_Framebuffer;

    // Gen Frame Buffer
    glGenFramebuffers(1, &m_Framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, m_Framebuffer);
    
    // Bind Color
    uint32_t m_ColorAttachments;
    uint32_t m_ColorSpecifications[1];

    glBindTexture(GL_TEXTURE_2D, m_ColorAttachments);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1280, 720, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
                
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_ColorAttachments, 0);

    glBindTexture(GL_TEXTURE_2D, 0);
    
    m_ColorSpecifications[0] = GL_COLOR_ATTACHMENT0;
    glDrawBuffers(1, m_ColorSpecifications);
    
    // Bind Depth Texture
    glGenTextures(1, &m_DepthAttachment);
    glBindTexture(GL_TEXTURE_2D, m_DepthAttachment);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1280, 720, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_DepthAttachment, 0); 

    glBindTexture(GL_TEXTURE_2D, 0);

    ASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Framebuffer is incomplete!");
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // Generate UBO
    uint32_t m_uboFrame, m_uboBatch;
    auto BufferSize = sizeof(PerFrameConstants);
    glGenBuffers(1, &m_RendererID);
    glBindBuffer(GL_UNIFORM_BUFFER, m_uboFrame);
    glBufferData(GL_UNIFORM_BUFFER, m_BufferSize, NULL, GL_STATIC_DRAW);
    glBindBuffer(GL_UNIFORM_BUFFER, 0);

    BufferSize = sizeof(PerBatchConstants);
    glGenBuffers(1, &m_RendererID);
    glBindBuffer(GL_UNIFORM_BUFFER, m_uboBatch);
    glBufferData(GL_UNIFORM_BUFFER, m_BufferSize, NULL, GL_STATIC_DRAW);
    glBindBuffer(GL_UNIFORM_BUFFER, 0);

    while(!glfwWindowShouldClose( window ) )
{
    
    // Generate VAO, VBO, IBO for render
    // Get Camera Matrix

    // Set the color to clear the screen to.
    glClearColor(0.2f, 0.3f, 0.4f, 1.0f);
    // Clear the screen and depth buffer.
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Set UBO view projection matrix data
    glBindBuffer(GL_UNIFORM_BUFFER, m_uboFrame);
    glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(PerFrameConstants), frame_data); 
    glBindBuffer(GL_UNIFORM_BUFFER, 0);

    // Bind Framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, m_Framebuffer);
    glViewport(0, 0, 1280, 720);

    // Set OpenGL State
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    glDepthMask(GL_TRUE);

    // Set Blender Mode
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // Set Cullface Mode
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

    // Clear Framebuffer
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Bind Shader
    glUseProgram(shader_id);

    // Bind UBO to shader
    auto frame_block_index = glGetUniformBlockIndex(shader_id, "PerFrameConstants");
    if (frame_block_index != GL_INVALID_INDEX)
    {
        int32_t blockSize;
        glGetActiveUniformBlockiv(shader_id, frame_block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
        RK_GRAPHICS_ASSERT(blockSize >= sizeof(PerFrameConstants), "PerBatchConstants Size Error");
        glUniformBlockBinding(shader_id, frame_block_index, 0);
        glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_uboFrame);
    }
    frame_block_index = glGetUniformBlockIndex(shader_id, "PerBatchConstants");
    if (frame_block_index != GL_INVALID_INDEX)
    {
        int32_t blockSize;
        glGetActiveUniformBlockiv(shader_id, frame_block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
        RK_GRAPHICS_ASSERT(blockSize >= sizeof(PerBatchConstants), "PerBatchConstants Size Error");
        glUniformBlockBinding(shader_id, frame_block_index, 1);
        glBindBufferBase(GL_UNIFORM_BUFFER, 1, m_uboBatch);
    }

    // Set Texture Ids
    int32_t samplers[16];
    for (uint32_t i = 0; i < 16; i++)
        samplers[i] = i;
    GLint location = GetLocation("u_Textures");
    glUniform1iv(location, 16, samplers);

    // Set Model Matrix
    glBindBuffer(GL_UNIFORM_BUFFER, m_uboBatch);
    glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(PerFrameConstants), batch_data); 
    glBindBuffer(GL_UNIFORM_BUFFER, 0);

    // Bind VAO
    glBindVertexArray(vao);
    // Bind Textures at different slot
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture_id);

    glDrawElements(GL_TRIANGLES, index_count, GL_STATIC_DRAW, nullptr);

    // Unbind Framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    glfwSwapBuffer();
}
}

Below is shader program used in render shaders

vertex shader
#version 410
layout(location = 0) in vec4 a_Position;
layout(location = 1) in vec4 a_Color;
layout(location = 2) in vec2 a_TexCoord;
layout(location = 3) in float a_TexIndex;
layout(location = 4) in float a_TilingFactor;

layout(std140) uniform PerFrameConstants
{
    mat4 viewMatrix;        // 64 bytes
    mat4 projectionMatrix;  // 64 bytes
    vec4 camPos;            // 16 bytes
    ivec4 numLights;        // 16 bytes
} PerFrame;                 // total 160 bytes

layout(std140) uniform PerBatchConstants
{
    mat4 modelMatrix;       
} PerBatch;


out vec4 v_Color;
out vec2 v_TexCoord;
out float v_TexIndex;
out float v_TilingFactor;

void main()
{
    v_Color = a_Color;
    v_TexCoord = a_TexCoord;
    v_TexIndex = a_TexIndex;
    v_TilingFactor = a_TilingFactor;
    gl_Position = PerFrame.projectionMatrix * PerFrame.viewMatrix * PerBatch.modelMatrix * vec4(a_Position.xyz, 1.0f);
}
fragment shader
#version 410
layout(location = 0) out vec4 color;

uniform sampler2D u_Textures[16];

layout(location = 0) in vec4 v_Color;
layout(location = 1) in vec2 v_TexCoord;
layout(location = 2) in float v_TexIndex;
layout(location = 3) in float v_TilingFactor;

void main()
{
    vec4 texColor = v_Color;
    switch(int(v_TexIndex))
    {
        case  0: texColor *= texture(u_Textures[ 0], v_TexCoord * v_TilingFactor); break;
        case  1: texColor *= texture(u_Textures[ 1], v_TexCoord * v_TilingFactor); break;
    }
    color = texColor;
}
c++
opengl
glsl
glfw
framebuffer
asked on Stack Overflow Feb 11, 2021 by yf z • edited Feb 14, 2021 by yf z

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0