什么是必要的步骤来渲染我的场景到帧缓冲区对象(FBO),然后渲染FBO到屏幕? [英] What are the steps necessary to render my scene to a Framebuffer Object(FBO) and then render that FBO to the screen?

查看:153
本文介绍了什么是必要的步骤来渲染我的场景到帧缓冲区对象(FBO),然后渲染FBO到屏幕?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个相当复杂的场景,我需要渲染许多GL_POINTS。场景将在很大程度上静态的,所以我想将它渲染到帧缓冲区对象,然后只更新FBO的时候,我的场景实际上改变。那么我想渲染FBO到屏幕的每一帧。

I've got a fairly complicated scene with many GL_POINTS that I need to render. The scene will be largely static, so I'd like to render it to a Framebuffer Object and then only update that FBO when my scene actually changes. I'd then like to render the FBO to the screen each frame.

我发现,渲染FBO到纹理的例子。我发现,渲染FBO到渲染(仍然不是很确定那是什么)的例子。我不知道什么样的步骤来实现这一目标。我需要渲染到纹理和绘制纹理画面?

I've found examples that render an FBO into a texture. I've found examples that render an FBO into a RenderBuffer (still not quite sure what that is). I'm not sure what the steps are to achieve this. Do I need to render to a texture and the draw the texture to the screen?

您可以请列举的步骤(理想情况下,即使在伪code或实际code)来渲染我的场景到一个FBO,然后绘制FBO到屏幕上。

Can you please enumerate the steps (ideally even in pseudocode or actual code) to render my scene to an FBO and then draw that FBO to the screen.

画()足以占位符,我自己的绘图功能。

draw() is sufficient for a placeholder for my own drawing functions.

推荐答案

我提供了一个<一个href="https://github.com/datenwolf/$c$csamples/blob/master/samples/OpenGL/minimalfbo/minimalfbo.c">minimal FBO例如的只是为这个

I provide a minimal FBO example just for this

基本步骤是:深度渲染和颜色纹理附件创建FBO。为增加对FBO解除目标的质地,结合FBO,渲染到FBO。拆散FBO,绑定纹理渲染。

Basically the steps are: Create FBO with depth renderbuffer and color texture attachment. To render to FBO unbind the target texture, bind FBO, render to FBO. Unbind FBO, bind texture, render.

#include <GL/glew.h>
#include <GL/glut.h>

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

void init();
void display();

int const fbo_width = 512;
int const fbo_height = 512;

GLuint fb, color, depth;

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );

    glutCreateWindow("FBO test");
    glutDisplayFunc(display);
    glutIdleFunc(glutPostRedisplay);

    glewInit();

    init();
    glutMainLoop();

    return 0;
}

void CHECK_FRAMEBUFFER_STATUS()
{                                                         
    GLenum status;
    status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); 
    switch(status) {
    case GL_FRAMEBUFFER_COMPLETE:
        break;

    case GL_FRAMEBUFFER_UNSUPPORTED:
    /* choose different formats */
        break;

    default:
        /* programming error; will fail on all hardware */
        fputs("Framebuffer Error\n", stderr);
        exit(-1);
    }
}

float const light_dir[]={1,1,1,0};
float const light_color[]={1,0.95,0.9,1};

void init()
{
    glGenFramebuffers(1, &fb);
    glGenTextures(1, &color);
    glGenRenderbuffers(1, &depth);

    glBindFramebuffer(GL_FRAMEBUFFER, fb);

    glBindTexture(GL_TEXTURE_2D, color);
    glTexImage2D(   GL_TEXTURE_2D, 
            0, 
            GL_RGBA, 
            fbo_width, fbo_height,
            0, 
            GL_RGBA, 
            GL_UNSIGNED_BYTE, 
            NULL);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);

    glBindRenderbuffer(GL_RENDERBUFFER, depth);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fbo_width, fbo_height);
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);

    CHECK_FRAMEBUFFER_STATUS();
}

void prepare()
{
    static float a=0, b=0, c=0;

    glBindTexture(GL_TEXTURE_2D, 0);
    glEnable(GL_TEXTURE_2D);
    glBindFramebuffer(GL_FRAMEBUFFER, fb);

    glViewport(0,0, fbo_width, fbo_height);

    glClearColor(1,1,1,0);
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, 1, 1, 10);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHTING);

    glEnable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    glLightfv(GL_LIGHT0, GL_POSITION, light_dir);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);

    glTranslatef(0,0,-5);

    glRotatef(a, 1, 0, 0);
    glRotatef(b, 0, 1, 0);
    glRotatef(c, 0, 0, 1);

    glutSolidTeapot(0.75);

    a=fmod(a+0.1, 360.);
    b=fmod(b+0.5, 360.);
    c=fmod(c+0.25, 360.);
}

void final()
{
    static float a=0, b=0, c=0;

    const int win_width  = glutGet(GLUT_WINDOW_WIDTH);
    const int win_height = glutGet(GLUT_WINDOW_HEIGHT);
    const float aspect = (float)win_width/(float)win_height;

    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    glViewport(0,0, win_width, win_height);

    glClearColor(1.,1.,1.,0.);
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, aspect, 1, 10);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0,0,-5);

    glRotatef(b, 0, 1, 0);

    b=fmod(b+0.5, 360.);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, color);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glDisable(GL_LIGHTING);

    float cube[][5]=
    {
        {-1, -1, -1,  0,  0},
        { 1, -1, -1,  1,  0},
        { 1,  1, -1,  1,  1},
        {-1,  1, -1,  0,  1},

        {-1, -1,  1, -1,  0},
        { 1, -1,  1,  0,  0},
        { 1,  1,  1,  0,  1},
        {-1,  1,  1, -1,  1},
    };
    unsigned int faces[]=
    {
        0, 1, 2, 3,
        1, 5, 6, 2,
        5, 4, 7, 6,
        4, 0, 3, 7,
        3, 2, 6, 7,
        4, 5, 1, 0
    };

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glVertexPointer(3, GL_FLOAT, 5*sizeof(float), &cube[0][0]);
    glTexCoordPointer(2, GL_FLOAT, 5*sizeof(float), &cube[0][3]);

    glCullFace(GL_BACK);
    glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, faces);

    glCullFace(GL_FRONT);
    glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, faces);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

}

void display()
{
    prepare();
    final();

    glutSwapBuffers();
}

这篇关于什么是必要的步骤来渲染我的场景到帧缓冲区对象(FBO),然后渲染FBO到屏幕?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆