漫画のスタイルでレンダリングするために、水をシミュレートする SPH 粒子から表面を取得する必要があるプロジェクトに取り組んでいます。これを行うために、最初のステップは、このパーティクル セットからデプス マップを取得する方法に従っています。このパーティクル セットは、フレーム バッファ オブジェクトで画面外にレンダリングし、画面上にテストして、結果を確認します。Web サイト Swiftless のチュートリアルに従って、最初にこの FBO で何かをレンダリングし、クワッドで画面上にレンダリングしようとしているため、現時点ではまだパーティクルをレンダリングしていません。もちろん、そこで説明されている方法は、私が取り組んでいるプロジェクトに追加しました。
私の最初のステップは、グレーのティーポットが表示されたグリーン スクリーンをレンダリングすることでした。
次に、画面外で FBO にレンダリングしようとしましたが、画面中央のクワッドにレンダリングされましたが、ここでわかるように、緑色のクワッドしか得られません。
私が使用しているコードは、前に述べたチュートリアルから直接取得したもので、次のとおりです。
変数:
GLuint fbo;
GLuint fbo_depth;
GLuint fbo_texture;
int windowWidth = 1024;
int windowHeight = 768;
FBO とそのテクスチャの設定:
void initFrameBufferDepthBuffer ()
{
glGenRenderbuffersEXT(1, &fbo_depth); // Generate one render buffer and store the ID in fbo_depth
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo_depth); // Bind the fbo_depth render buffer
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, windowWidth, windowHeight); // Set the render buffer storage to be a depth component, with a width and height of the window
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo_depth); // Set the render buffer of this buffer to the depth buffer
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); // Unbind the render buffer
}
void initFrameBufferTexture ()
{
glGenTextures(1, &fbo_texture); // Generate one texture
glBindTexture(GL_TEXTURE_2D, fbo_texture); // Bind the texture fbo_texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, windowWidth, windowHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard texture with the width and height of our window
// Setup the basic texture parameters
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Unbind the texture
glBindTexture(GL_TEXTURE_2D, 0);
}
void initFrameBuffer () {
glEnable(GL_TEXTURE_2D); // Enable texturing so we can bind our frame buffer texture
glEnable(GL_DEPTH_TEST); // Enable depth testing
initFrameBufferDepthBuffer(); // Initialize our frame buffer depth buffer
initFrameBufferTexture(); // Initialize our frame buffer texture
glGenFramebuffersEXT(1, &fbo); // Generate one frame buffer and store the ID in fbo
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // Bind our frame buffer
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo_texture, 0); // Attach the texture fbo_texture to the color buffer in our frame buffer
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo_depth); // Attach the depth buffer fbo_depth to our frame buffer
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // Check that status of our generated frame buffer
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) // If the frame buffer does not report back as complete
{
printf ( "Couldn't create frame buffer\n");
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our frame buffer
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
}
FBO でティーポットをレンダリングする:
void renderTeapotScene ()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // Bind our frame buffer for rendering
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // Push our glEnable and glViewport states
glViewport(0, 0, windowWidth, windowHeight); // Set the size of the frame buffer view port
glClearColor (0.0f, 1.0f, 0.0f, 1.0f); // Set the clear color
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the depth and color buffers
glLoadIdentity(); // Reset the modelview matrix
glTranslatef(0.0f, 0.0f, -5.0f); // Translate back 5 units
glColor4f(0.5f, 0.5f, 0.5f, 1.0f);
glutSolidTeapot(1.0f); // Render a teapot
glPopAttrib(); // Restore our glEnable and glViewport states
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our texture
}
アプリケーションの開始時に 1 回だけ発生するプロセスで FBO を設定します。
initFrameBuffer(); // Create our frame buffer object
そして、フレームごとに発生するプロセス全体:
glEnable(GL_TEXTURE_2D); // Enable texturing so we can bind our frame buffer texture
glEnable(GL_DEPTH_TEST); // Enable depth testing
renderTeapotScene();
glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations
glTranslatef(0.0f, 0.0f, -10.0f);
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
もちろん、これらのコードははるかに大きなプロジェクトにあり、おそらくこの動作を引き起こす可能性のある何かを有効にしていると思いますが、それが何であるかはわかりません. 私の FBO の幅と高さはスクリーン フレーム バッファと同じであると言うことが重要だと思います。
さて、これが今の私のシナリオです。最初の画像を 2 番目の画像の中央にあるクワッドにテクスチャとしてレンダリングする方法を誰かが知っていますか?