0

多くの光源を使用して、opengl でシーンをレンダリングしたいと考えています。ただし、opengl の最大光源数は 8 です。FBO を使用してそれを実行しようとしています。したがって、8つのライトを使用してFBO1シーンにレンダリングし、次にFBO2 = FBO2 + FBO1(テクセルコンポーネントを追加)でレンダリングするようなものがあります。したがって、FBO2 は最終イメージを蓄積します。(それがアイデアです)。ただし、「いくつかの」コーディングの問題があります:)これが私のコードです:

レンダリング:

    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  
}

FBO の初期化は次のとおりです。

    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 は私のプログラムでそのように動作します - 関数 setLights )、FBO に正しい結果をレンダリングするかどうかも尋ねたいと思いますか? GL_RGB16F テクスチャ フォーマットを使用します。それは大丈夫ですか、それとも 32 ビット テクスチャを使用する必要がありますか? そうであれば、レンダリング後にシェーダーを使用して FBO を表示する必要がありますか?

4

1 に答える 1

1

また、雷の強度を 1.0 よりも大きくすることができるかどうか (atm は私のプログラムでそのように動作します - 関数 setLights )、FBO に正しい結果をレンダリングするかどうかを尋ねたいですか? GL_RGB16F テクスチャ フォーマットを使用します。それは大丈夫ですか、それとも 32 ビット テクスチャを使用する必要がありますか? そうであれば、レンダリング後にシェーダーを使用して FBO を表示する必要がありますか?

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

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

于 2012-04-24T15:20:37.597 に答える