裏でこっそりフレームバッファ
2013-11-06


今までのサンプルではテクスチャなどを画面に直接描画していましたが、これを画面ではなくフレームバッファと呼ばれる自分で作成したバッファに描画することができます(画面に描画するのも、デフォルトのフレームバッファに描画するということらしいですが)。
そんなことをして何が嬉しいのかと言いますと…

昨日のサンプルでは描画しているテクスチャは一枚だけでした。これがテクスチャなどの枚数が増えてくると、描画にいくらかの時間がかかるようになります。そうすると描画途中の絵が画面に出ることになり、絵がちらついたりします。
フレームバッファを使用する場合、絵は一旦フレームバッファに描画して、全て描画した後に画面に表示します。描画途中の絵が画面に出ることはないのでちらつきはありません。オフスクリーンレンダリングと呼ばれる方法です。


フレームバッファクラス sys::FrameBufferを見てみます。
FrameBuffer.h
#ifndef ___FRAME_BUFFER_H___
#define ___FRAME_BUFFER_H___

#include "common.h"
#include "Texture.h"


namespace sys
{

/********************************
    フレームバッファテクスチャ
 ********************************/
class FrameBuffer : public Texture
{
        GLuint          frame_buffer;                   // フレームバッファオブジェクト
        GLfloat         mat_projection[4*4];    // 透視変換行列

public :

                FrameBuffer(void)                               // コンストラクタ
                {
                        frame_buffer = 0;
                }
                FrameBuffer(int _w, int _h)
                {
                        make(_w, _h);
                }
                ~FrameBuffer()                                  // デストラクタ
                {
                        clear();
                }

        void    make(int, int);                         // 作成
        void    clear(void);                            // 削除
        void    bind(void);                                     // 使用
};

}

#endif
/********************* End of File ********************************/

FrameBuffer.cpp
/*********************************************

                フレームバッファテクスチャ

 *********************************************/

#include "FrameBuffer.h"
#include "Renderer.h"


namespace sys
{

/********************************
    作成
                引数      _width  = 幅
                                _height = 高さ
 ********************************/
void    FrameBuffer::make(int _width, int _height)
{
        glGenFramebuffers(1, &ampframe_buffer);                                 // フレームバッファオブジェクト作成
        glBindFramebuffer(GL_FRAMEBUFFER, frame_buffer);

        format  = FORMAT_RGBA;                  // テクスチャフォーマット
        width   = _width;                               // 幅
        height  = _height;                              // 高さ
        Texture::make(NULL);                    // テクスチャ作成
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);        // フレームバッファにアタッチ

        glBindFramebuffer(GL_FRAMEBUFFER, 0);

        for (int i = 0; i < 4*4; i++) {                                                       // 透視変換行列初期化
                mat_projection[i] = 0.0f;
        }
        mat_projection[0]  =  2.0f/width;
        mat_projection[5]  = -2.0f/height;
        mat_projection[10] =  1.0f;
        mat_projection[15] =  1.0f;
}

/**********
    削除
 **********/
void    FrameBuffer::clear(void)
{
        if ( frame_buffer ) {
                glDeleteFramebuffers(1, &ampframe_buffer);
                frame_buffer = 0;
                Texture::clear();
        }
}

/**********
    使用
 **********/
void    FrameBuffer::bind(void)
{
        glBindFramebuffer(GL_FRAMEBUFFER, frame_buffer);
        glViewport(0, 0, width, height);                                                // ビューポート設定
        Renderer::mat_projection = mat_projection;                              // 透視変換行列設定
        if ( Renderer::current_shader ) {
                glUniformMatrix4fv(Renderer::current_shader-&gtprojection, 1, GL_FALSE, mat_projection);
        }
}

}

/**************** End of File ******************************************/


続きを読む

[Android プログラミング]

コメント(全1件)
コメントをする


記事を書く
powered by ASAHIネット