現在、C++ と OpenGL を使用して 2D 横スクロール ゲームをプログラミングしています。ウィンドウを取得するために SFML を使用していますが、すべてのクワッドを OpenGL で直接描画しているため、これは関係ありません。問題は、Framebuffer オブジェクトを使用してライト テクスチャを描画し、それをシーンのマスクとして使用すると、フレームレートが低下することです。通常、ゲームは 60 fps で限界に達しますが、fbo を使用すると、約 40 fps、場合によっては 30 fps になります。この効果は素晴らしいと思います:D フレームバッファを使用したことがないので、 テクスチャへのフレームバッファ FBO レンダリングは非常に遅いです。 Android で OpenGL ES 2.0 を使用しているのはなぜですか? 役に立たないようです。だから私の質問:私は何を間違っていますか?それとも、同じ効果を達成するためのもっと簡単な方法がありますか? Ubuntu 12.04で実行しています。私のコード:
void init() {
GLuint fbo, mask; //framebufferobject and texture
glewInit();
glGenTextures(1, &mask);
glBindTexture(GL_TEXTURE_2D, mask);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1024, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE,
0);
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mask,
0);
glClearColor(darkness, darkness, darkness, 1);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) !=
GL_FRAMEBUFFER_COMPLETE)CMain::game.usefbo = false;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void render() {
//render usual stuff, then
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glClear(GL_COLOR_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, 1024, 600);
glBlendFunc(GL_SRC_COLOR, GL_ONE);
//render lights
glPopAttrib();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
//render fbo over the screen:
glBindTexture(GL_TEXTURE_2D, mask);
glTranslatef(0, 0, 9);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2i(0, 0);
glTexCoord2f(0, 1); glVertex2i(0, 600);
glTexCoord2f(1, 1); glVertex2i(1024, 600);
glTexCoord2f(1, 0); glVertex2i(1024, 0);
glEnd();
glLoadIdentity();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//display
}
編集: //render lights では、3 つのライト テクスチャ (円形、放射状、黒から白) が glBegin(GL_QUADS) などを介して fbo にレンダリングされます。もちろん、後でもっと多くのライトを使用したいと思います。ライトが移動して互いに重なり合っているため、フレームごとに fbo を更新する必要があります。
レンダー ライト:
for(std::vector<LightSource*>::iterator it = lights.begin(); it != lights.end(); it++) {
(*it)->draw();
}
ここで、lights は LightsSources のベクトルです。光源::描画():
void LightsSource::draw() {
if (visible()) {
if (activated) {
glTranslatef(this->x, this->y, 0);
glBindTexture(GL_TEXTURE_2D, this->texture);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2i(0, 0);
glTexCoord2f(0, 1); glVertex2i(0, height);
glTexCoord2f(1, 1); glVertex2i(width, height);
glTexCoord2f(1, 0); glVertex2i(width, 0);
glEnd();
glLoadIdentity();
}
}
}
visible() と activate は通常 true です。