Shadow Maps and FBOs!

Hi all!

Im wondering if i should use 1 FBO and 1 shadow map for each light… or using only 1 FBO and attach mutltiple shadow map to it?

for now im doing this for each light:

  
		glGenFramebuffersEXT(1, &m_FrameBuffer);
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_FrameBuffer);
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, m_FrameTexture->GetDimension(), m_FrameTexture->GetId(), 0);
		OpenGL::GetFrameBuffer()->CheckStatus();

		glGenRenderbuffersEXT(1, &m_DepthBuffer);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_DepthBuffer);
		glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, m_MapSize, m_MapSize);
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, m_DepthTexture->GetDimension(), m_DepthTexture->GetId(), 0);
		OpenGL::GetFrameBuffer()->CheckStatus();

it turns out to be slower then using glCopyTexImage2D… so i do have a doubt.

any hint would be welcome!

thx

well off the top of my head you can only have one depth buffer and that will only save one shadowmap, so you would have to do a pass for each shadowmap if you use only one FBO. Now if you have multiple FBO’s you could do it all in one pass AFAIK… Now if you can render the depth into a color texture which I am not sure how you can you could then use one FBO with N color attachments where each one is mapped to each light you have.

Now if you can render the depth into a color texture
humm… there is no GL_DEPTH_ATTACHMENT*_EXT wich i guess would be a good thing to have… sigh…

there is another thing that im wondering about… why do we have to setup a glGenFramebuffersEXT when we only need the depth buffer?
when dealing only with depth buffer… is it possible to use:

glGenRenderbuffersEXT(1, &m_DepthBuffer);

and not bother with the:

glGenFramebuffersEXT(1, &m_FrameBuffer);
???

Originally posted by Golgoth:

there is another thing that im wondering about… why do we have to setup a glGenFramebuffersEXT when we only need the depth buffer?
when dealing only with depth buffer… is it possible to use:

There is no need to setup the color buffer if depth only rendering is required. This is even mentioned as one example in the EXT_framebuffer_object specification . The example given in the specification is:

// Given:  depth_tex - TEXTURE_2D depth texture object
//         fb        - framebuffer object

// Enable render-to-texture

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

// Set up depth_tex for render-to-texture
      
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depth_tex, 0);

// No color buffer to draw to or read from
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);

// Check framebuffer completeness at the end of initialization.
CHECK_FRAMEBUFFER_STATUS();

<draw something>

// Re-enable rendering to the window
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

glBindTexture(GL_TEXTURE_2D, depth_tex);

<draw to the window, reading from the depth_tex>

RBO are attached to FBO and they can’t live without FBO so you simply can’t generate an RBO without any FBO… Or maybe I misunderstood your question ?

Originally posted by Golgoth:
[b]for now im doing this for each light:

  
		glGenFramebuffersEXT(1, &m_FrameBuffer);
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_FrameBuffer);
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, m_FrameTexture->GetDimension(), m_FrameTexture->GetId(), 0);
		OpenGL::GetFrameBuffer()->CheckStatus();
  glGenRenderbuffersEXT(1, &m_DepthBuffer);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_DepthBuffer);
  glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, m_MapSize, m_MapSize);
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, m_DepthTexture->GetDimension(), m_DepthTexture->GetId(), 0);
  OpenGL::GetFrameBuffer()->CheckStatus();
[/b]

Tell me I’m misunderstanding you. Tell me you’re not really calling Gen+Bind for each light, togheter with checking glError, not to mention allocating the storage on a sub-frame basis!

Tell me you’re not really calling Gen+Bind for each light

  

the code above was only at initialization, it did this every frame for each light:

void Light::SetBuffer()
{
	if (m_FrameBuffer != 0)
	{
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_FrameBuffer);
		glClear(GL_COLOR_BUFFER_BIT);
	}
	if (m_DepthBuffer != 0)
	{
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_DepthBuffer);
		glClear(GL_DEPTH_BUFFER_BIT);
	}
}

void Light::UnsetBuffer()
{
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}

and draw with minimum states enable in between those 2 calls…

I ve implemented komat sample… I got a huge increase in speed… which is awesome! among the other examples in the dinosaur buffer specs… it just slipped to my attention…

thx again guys!