2012-04-24 18 views
0

多くの光源を使ってOpenGLでシーンをレンダリングしたいと思います。 しかし、OpenGLの最大光源は8です。私はFBOを使ってそれをしようとしています。 だから、私は8つのライトと FBO2 = FBO2 + FBO1(テクセルのコンポーネントを追加する)のFBO1シーンにレンダリングするようなものを持っています。 FBO2は最終的な画像を蓄積します。 (thatsはアイデア)。しかし、私は "いくつかの" コーディングの問題を持っている:)ここに私のコードは次のとおりです。2つのFBO(opengl)と落雷の質問を追加する

レンダリング:

glEnable(GL_TEXTURE_RECTANGLE_NV); 
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // Push our glEnable and glViewport states 
glViewport(0, 0, OPT.m_nWidth, OPT.m_nHeight); 

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the depth and colour buffers 
glLoadIdentity(); // Reset the modelview matrix 


int iIndeks = 0, iLoopIndeks = 0, iLightsUsed = 0; 
float *pM = scene3D->oCamera.SetMatrixs(); 
glLoadMatrixf(pM); 
delete []pM; 

int iAccumMult = xLightsToRender.size/MAX_OPENGL_LIGHTS; 

while(iIndeks < xLightsToRender.size) 
{  
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, iFrameBufferAccumulation); 

    glShadeModel(GL_SMOOTH); 
    float *pM = scene3D->oCamera.SetMatrixs(); 
    glLoadMatrixf(pM); 
    delete []pM; 

    glMatrixMode(GL_MODELVIEW); 

    iLightsUsed = xLightsToRender.size > (iLoopIndeks+1) * MAX_OPENGL_LIGHTS ? MAX_OPENGL_LIGHTS : (xLightsToRender.size - iLoopIndeks * MAX_OPENGL_LIGHTS); 

    iIndeks+=iLightsUsed; 
    glPushMatrix(); 
    //initilise lights 
    setLights(iLoopIndeks * MAX_OPENGL_LIGHTS, iLightsUsed, xLightsToRender); 
    for (int i=0;i<scene3D->data.m_nObjectCount;i++) 
    { 
     //glutSolidTeapot(1.0f); // Render a teapot 
     scene3D->RenderObjectWithOpenGL(i); 
    } 
    if(scene3D->data.bMovingObjectIni ) 
    { 
     scene3D->RenderObjectWithOpenGL(-1, true); 
    }  



    glPopMatrix(); 

    iLoopIndeks++; 
    //xShader.bind(); 

    //xShader.unbind(); 
    glPopAttrib(); // Restore our glEnable and glViewport states 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our texture 
    //render to second buffer 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, iFrameBuffer); 
    glBindTexture(GL_TEXTURE_RECTANGLE_NV, iTextureImgAccumulation); // Bind our frame buffer texture 
    glTranslatef(0.0f, 0.0f, -2.0f); 
    glBegin(GL_QUADS); 
    glTexCoord2f(0,OPT.m_nHeight); 
    glVertex3f(-1,-1,0); 

    glTexCoord2f(OPT.m_nWidth,OPT.m_nHeight); 
    glVertex3f(1,-1,0); 

    glTexCoord2f(OPT.m_nWidth,0); 
    glVertex3f(1,1,0); 

    glTexCoord2f(0,0); 
    glVertex3f(-1,1,0); 

    glEnd(); 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our texture 
} 

ここではFBOsの初期化です:

void OpenGlRenderer::initFrameBufferTexture(void) 
    { 
glGenTextures(1, &iTextureImg); // Generate one texture 


glEnable(GL_TEXTURE_RECTANGLE_NV); 
glBindTexture(GL_TEXTURE_RECTANGLE_NV, iTextureImg); 

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD/*GL_DECAL*/); 
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_COMPARE_MODE, GL_NONE); 
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP); 
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP); 
glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGB16F /*GL_FLOAT_R32_NV*/, OPT.m_nWidth, OPT.m_nHeight, 0, GL_RED, GL_FLOAT, NULL); 

glGenTextures(1, &iTextureImgAccumulation); // Generate one texture 
glEnable(GL_TEXTURE_RECTANGLE_NV); 
glBindTexture(GL_TEXTURE_RECTANGLE_NV, iTextureImgAccumulation); 

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD/*GL_DECAL*/); 
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_COMPARE_MODE, GL_NONE); 
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP); 
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP); 
glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGB16F /*GL_FLOAT_R32_NV*/, OPT.m_nWidth, OPT.m_nHeight, 0, GL_RED, GL_FLOAT, NULL); 



// Setup the basic texture parameters 



// Unbind the texture 
glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0); 
    } 


    void OpenGlRenderer::initFrameBufferDepthBuffer(void) 
    { 

    glGenRenderbuffersEXT(1, &iDepthBuffer); // Generate one render buffer and store the ID in iDepthBuffer 
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, iDepthBuffer); // Bind the iDepthBuffer render buffer 

    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, OPT.m_nWidth, OPT.m_nHeight); // 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, iDepthBuffer); // Set the render buffer of this buffer to the depth buffer 

    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); // Unbind the render buffer 
    } 


    void OpenGlRenderer::initFrameBuffer(void) 
    { 
    initFrameBufferDepthBuffer(); // Initialize our frame buffer depth buffer 

    initFrameBufferTexture(); // Initialize our frame buffer texture 

    glGenFramebuffersEXT(1, &iFrameBufferAccumulation); // Generate one frame buffer and store the ID in iFrameBufferAccumulation 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, iFrameBufferAccumulation); // Bind our frame buffer 

    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, iTextureImgAccumulation, 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, iDepthBuffer); // Attach the depth buffer iDepthBuffer to our frame buffer 

    glGenFramebuffersEXT(1, &iFrameBuffer); // Generate one frame buffer and store the ID in iFrameBufferAccumulation 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, iFrameBuffer); // Bind our frame buffer 

    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_NV, iTextureImg, 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, iDepthBuffer); // Attach the depth buffer iDepthBuffer to our frame buffer 

    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // Check that status of our generated frame buffer 
    checkFramebufferStatus(); 
    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) // If the frame buffer does not report back as complete 
    { 
    std::cout << "Couldn't create frame buffer" << std::endl; // Output an error to the console 
    exit(0); // Exit the application 
    } 
    } 

だから、基本的に私はiFrameBufferAccumulationにレンダリングしたい、その後、相対テクスチャは、glTexEnvf(GL_TEXTURE_ENV、GL_TEXTURE_ENV_MODE、GL_ADD)で毎回 をiFrameBufferにレンダリングします。この2つのフレームバッファを効果的に追加する必要がありますか?

また、雷の強さを1.0より大きくすることができますか(私のプログラムではatmと同じように機能します)、正しい結果がFBOにレンダリングされますか?私はGL_RGB16Fテクスチャ形式を使用します。それは大丈夫ですか、私は32ビットのテクスチャを使用する必要がありますか? sooならレンダリング後にFBOを表示するためにシェーダを使用する必要がありますか?

+0

ようこそスタックオーバーフロー。将来、行頭に '> 'マークを付けるべきではありません。それらは、あなたがあなた自身を引用しているときではなく、あなたが他の人を引用しているときのためのものです。 –

答えて

1

また、私は雷の強さを1.0より大きくすることができますか(私のプログラムではatmと同じように機能します)、正しい結果をFBOにレンダリングしますか?私はGL_RGB16Fテクスチャ形式を使用します。それは大丈夫ですか、私は32ビットのテクスチャを使用する必要がありますか? sooならレンダリング後にFBOを表示するためにシェーダを使用する必要がありますか?

一般に、事実上、テクスチャフェッチ時またはフレームバッファに書き込まれた時点で、またはそれ以外の時間に、固定機能のすべての演算がクランプされます。

実際の浮動小数点演算を実行する場合は、固定機能を放棄してシェーダに切り替える必要があります。

関連する問題