現在地 >> メニュー >> 基本編10 >> FrameBufferObject >> FBO::作成
>> FBO::描画

バッファオブジェクトの作成


まず、以下の2つについて
  • フレームバッファオブジェクト(FBO)
  • レンダーバッファオブジェクト(RBO)

フレームバッファオブジェクト(FBO)


作り方はVBOと似ている。主に使う関数は以下の3つ

  • void glGenFramebuffersEXT(GLsizei n, GLuint* ids) //作成用
  • void glDeleteFramebuffersEXT(GLsizei n, const GLuint* ids) //削除用
  • void glBindFramebufferEXT(GLenum target, GLuint id) //バインド用



■void glGenFramebuffersEXT(GLsizei n, GLuint* ids)
フレームバッファを作成
「n」:作成したいフレームバッファの個数
「ids」:フレームバッファのID。IDが「0」という事は「window-system provided framebuffer」を表す。


■void glBindFramebufferEXT(GLenum target, GLuint id)
FBOをバインドする。
「target」:GL_FRAMEBUFFER_EXT固定
「id」:FBOのID。「0」が「window-system provided framebuffer」を表す。
FBOのアンバインド時は、「0」を指定すればよい。


■void glDeleteFramebuffersEXT(GLsizei n, const GLuint* ids)
FBOをもう使わないという時には、削除する。
引数は「glGenFramebuffersEXT関数」参照


【例】
GLuint fboId; //FBO用ID
... ...
glGenFramebuffersEXT(1, &fboId);//FBO作成
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);//バインド
... ...
glDeleteFramebuffersEXT(1, &fboId);//削除


レンダーバッファオブジェクト(RBO)


renderbuffer object(RBO)」はFBOで定義されたもので、
テクスチャオブジェクト等と同様に、データをためておくストレージの1種。
OpenGLがレンダリングプロセスの際に、出力先として使用できるものである。


「オフスクリーンレンダリング」をするには、レンダリング用バッファオブジェクトが必要である。
RBO」は、テクスチャオブジェクトに書き込むのではなく、直接レンダリングバッファに書き込む事ができる。

使う関数は以下の5つ

  • void glGenRenderbuffersEXT(GLsizei n, GLuint* ids) → 作成
  • void glDeleteRenderbuffersEXT(GLsizei n, const Gluint* ids)  → 削除
  • void glBindRenderbufferEXT(GLenum target, GLuint id) → バインド
  • void glRenderbufferStorageEXT(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height) → メモリ確保
  • void glGetRenderbufferParameterivEXT(GLenum target, GLenum param, GLint* value); → 各種パラメータ情報を取得する



■void glGenRenderbuffersEXT(GLsizei n, GLuint* ids)
■void glDeleteRenderbuffersEXT(GLsizei n, const Gluint* ids)
RBOの作成と削除の関数。引数はFBOと同様である。
「RBO」のIDで「0」はOpenGLで予約済みとなっている。


■void glBindRenderbufferEXT(GLenum target, GLuint id)
RBOをバインド。第一引数は「GL_RENDERBUFFER_EXT」で固定。


■void glRenderbufferStorageEXT(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height)
「glGenRenderbuffersEXT関数」で「RBO」を作成しても、
まだデータ格納領域(データストレージ)が確保されたわけではない。
この関数でメモリを確保する。
「target」:「GL_RENDERBUFFER_EXT」で固定。
「internalFormat」:GL_RGB, GL_RGBA、GL_DEPTH_COMPONENT、GL_STENCIL_INDEXなど
「width」「height」:レンダーバッファのピクセル単位でのサイズ。「GL_MAX_RENDERBUFFER_SIZE_EXT」以下ならOK。



RBOの作り方はテクスチャに近い。
  1. 「glGenRenderbuffersEXT()関数」で作成し、
  2. 「glBindRenderbufferEXT()関数」でバインドし
  3. 「glRenderbufferStorageEXT()関数」でメモリ確保
をする。


【例】
GLuint rboId; //RBOのID

//RBOのサイズ
const int RBO_WIDTH = 256; 
const int RBO_HEIGHT = 256;
...   ...
glGenRenderbuffersEXT(1, &rboId);//作成

//バインド
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId);
//メモリ確保
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, RBO_WIDTH, RBO_HEIGHT);

//デフォルトにバインド
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

FBOとの対応付け


FBOで書いたように、FBOそれ自体にはメモリ格納領域はない。
代わりに、「テクスチャオブジェクト」や「RBO」をFBOに対応づける。



これによって、高速なフレームバッファの切り替えができる。
(※つまり、FBO自体を入れ替えるような仕組みではないという事)

例えば、なんらかのメモリストレージを2つのFBOで関連付けたら、
2つのFBOで別々にデータを保持するのではなく、共有することになる。

テクスチャオブジェクト → FBOの関連付けの場合


テクスチャオブジェクトへの関連付けは、「glFramebufferTexture2DEXT関数」で行う。
glFramebufferTexture2DEXT(
	GLenum target, 
	GLenum attachmentPoint,
	GLenum textureTarget,
	GLuint textureId,
	GLint  level
)

第1引数:target
  • 「GL_FRAMEBUFFER_EXT」で固定。

第2引数:attachmentPoint
テクスチャオブジェクトをどれと関連付けるかを決める。
  • GL_COLOR_ATTACHMENT0_EXT, ..., GL_COLOR_ATTACHMENTn_EXT(⇒複数の対応付けが可能)
  • GL_DEPTH_ATTACHMENT_EXT
  • GL_STENCIL_ATTACHMENT_EXT
等を指定する。

第3引数:textureTarget
  • GL_TEXTURE_2D(たいていはコレ)

第4引数:textureId
  • テクスチャのIDを指定する

第5引数: level
  • ミップマップのレベル

もし、「第4引数:textureId」に「0」が指定されたら、テクスチャオブジェクトの関連付けが外される。
また、FBOとの関連が残ったままテクスチャを破棄したら、自動的に関連付けも外れる。

ただし、複数のFBOと関連付けをしていた場合は、現在のFBOのみと関連付けが外れるだけである。
したがって、複数のFBOと関連付けを行った場合は気を付ける必要がある。


【例】
GLuint textureId;
glGenTextures(1, &textureId);

... ...
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0);
... ...

RBO → FBOの関連付けの場合


RBOをFBOと関連付ける時は、「glFramebufferRenderbufferEXT関数」を使う。
void glFramebufferRenderbufferEXT(
	GLenum target,
	GLenum attachmentPoint,
	GLenum renderbufferTarget,
	GLuint renderbufferId
)

第1引数、第2引数
  • glFramebufferTexture2DEXT()関数と同じものが指定できる

第3引数:renderbufferTarget
  • GL_RENDERBUFFER_EXTで固定。

第4引数:renderbufferId
  • RBOのId

「第4引数:renderbufferId」に「0」を指定した時の動作も
「glFramebufferTexture2DEXT()」同じ。


【例】
GLuint rboId;
glGenRenderbuffersEXT(1, &rboId);
... ...
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId);
... ...


>> FBO::描画

メモ


FBOを作成したら、作成できているかをチェックするとよい。

bool checkFramebufferStatus()
{
	// check FBO status
	GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
	switch(status)
	{
	case GL_FRAMEBUFFER_COMPLETE_EXT:
		std::cout << "Framebuffer complete." << std::endl;
		return true;

	case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
		std::cout << "[ERROR] Framebuffer incomplete: Attachment is NOT complete." << std::endl;
		return false;

	case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
		std::cout << "[ERROR] Framebuffer incomplete: No image is attached to FBO." << std::endl;
		return false;

	case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
		std::cout << "[ERROR] Framebuffer incomplete: Attached images have different dimensions." << std::endl;
		return false;

	case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
		std::cout << "[ERROR] Framebuffer incomplete: Color attached images have different internal formats." << std::endl;
		return false;

	case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
		std::cout << "[ERROR] Framebuffer incomplete: Draw buffer." << std::endl;
		return false;

	case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
		std::cout << "[ERROR] Framebuffer incomplete: Read buffer." << std::endl;
		return false;

	case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
		std::cout << "[ERROR] Unsupported by FBO implementation." << std::endl;
		return false;

	default:
		std::cout << "[ERROR] Unknow error." << std::endl;
		return false;
	}
}

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます