NVIDIA Forceware 75.90 => OpenGL 2.0.0 & fbo

Finally I got working depth buffering using FBO. This is with new FW 76.43. I didn’t try with older 75 drivers. Here is a complete setup code:

  
Init code:

	// create FBO
	glGenFramebuffersEXT(1, &fb);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

	// create color texture	& attach to FBO
	glGenTextures(1, &color_tex);
	glBindTexture(GL_TEXTURE_2D, color_tex);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEXX, TEXY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glGenerateMipmapEXT(GL_TEXTURE_2D);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, color_tex, 0);

	// initialize depth renderbuffer
	glGenRenderbuffersEXT(1, &depth_rb);
	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, TEXX, TEXY);
	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);

	// create depth texture & attach to FBO
	glGenTextures(1, &depth_tex);
	glBindTexture(GL_TEXTURE_2D, depth_tex);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, TEXX, TEXY, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depth_tex, 0);


This is GLSL shader code:

uniform sampler2DShadow depthTex; 

void main(void)
{
	gl_FragColor = texture2D(depthTex, gl_TexCoord[0]);
}

And this is render code:

	glBindTexture(GL_TEXTURE_2D, depth_tex);
	glEnable(GL_TEXTURE_2D);

	sh->Program.Bind(); // use GLSL shader
	sh->Program.sendUniform("depthTex", 0);
	glColor3f(1,1,1);
	glBegin(GL_QUADS);		// draw quad
	{
		glTexCoord2f(0,0);	glVertex3f(-5, -5, 0);
		glTexCoord2f(1,0);	glVertex3f( 5, -5, 0);
		glTexCoord2f(1,1);	glVertex3f( 5,  5, 0);
		glTexCoord2f(0,1);	glVertex3f(-5,  5, 0);
	}
	glEnd();
	glDisable(GL_TEXTURE_2D);
	sh->Program.Unbind(); // "unuse" shader

yooyo

Hello,

I’ve just got the extension FrameBuffer_Object working on my GF6600(drivers 76.40) but I am having some questions remaining.

  • Is using 32bits floats really slower than 16bits one for color_attachments(they will be binded later as a texture2D)?
  • Can we have more than one depth buffer for a framebuffer?(I know the question might seem weird…)
  • Can we render to more than one framebuffer in a same pass?
  • When rendering to a framebuffer having multiple color_attachment, is using gl_FragData[n] in my fragment shaders the good way for writing to the specific color_attachment buffer “n”?

When you initialize a float texture, you should put “GL_FLOAT” for the type in glTexImage2D right?
Why is 3B using GL_INT???

Cheers, Jeff.

3B: No way, I tried with GL_RGBA16F_ARB and GL_RGBA32F_ARB, it still produce NULL texels.

Switching back to GL_RGBA8 makes it work again, so I assume I activated the right things.
I’m not using blending.

I assume my Geforce FX 5200 is able to support thoses float textures extensions, right ?

The tricky things is maybe that I’m using 3 different textures in my second pass:
Whereas the first pass just write values to the FBO without the help of any other texture datas, the second use 3 different textures, and one of these is the result of FBO. It’s working when I bind a RGBA8 FBO, but it doesn’t when binding RGBA16F or RGBA32F.

To set 3 different textures for the second pass, I proceed as follow:

	glActiveTextureARB(GL_TEXTURE1_ARB);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D,Material->GLDiff);
	glActiveTextureARB(GL_TEXTURE2_ARB);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D,Material->GLDisp);
	glActiveTextureARB(GL_TEXTURE0_ARB);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D,FBOTexture);


	glUniform1iARB(FBOTexLoc, 0);
	glUniform1iARB(DiffuseTexLoc, 1);
	glUniform1iARB(DisplaceTexLoc, 2);

Then when I need to use the FBO I just switch off texture0 like this:

			glBindTexture(GL_TEXTURE_2D, 0);
			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBOObject);

And reactivate it for the second pass like this:

			glBindTexture(GL_TEXTURE_2D,FBOTexture);
			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

Is something wrong ?

GL_RGBA16F_ARB is part of ARB_texture_float which is similar to ATI version, but GF FX doesn’t support any of these extensions. You must use NV_float_buffer extension but beware of the restrictions(eg. rectangular textures)

Originally posted by Matt Zamborsky:
GL_RGBA16F_ARB is part of ARB_texture_float which is similar to ATI version, but GF FX doesn’t support any of these extensions. You must use NV_float_buffer extension but beware of the restrictions(eg. rectangular textures)
So, on the GF FX I could use texture rectangle and the internal formats from NV_float_buffer (e.g. GL_FLOAT_RGBA32_NV) together with EXT_framebuffer_object? So wouldn’t need pbuffer in conjunction with NV_float_buffer ?

This would be fine because my dev machine has just a GF FX and I don’t want to install VS on my test machine with the GF 6800.

Yes, you could use framebuffer object in conjuction with NV_float_buffer, I get it work right now and it works perfectly. I think the spec of NV_float_buffer will be updated after complete implementing of framebuffer object extension.

If someone wants the demo of EXT_framebuffer_object with NV_float_buffer and ARB_texture_rectangle + GLSL just say and I post it. :wink:

Originally posted by Matt Zamborsky:
If someone wants the demo of EXT_framebuffer_object with NV_float_buffer and ARB_texture_rectangle + GLSL just say and I post it. :wink:
I see this as a clear invitation :slight_smile:

Thanks in advance!

Matt, I’d like to have a look at it too ! :slight_smile:

here it is. And have a fun.

framebuffer demo

Revision: If you downloaded it, pls download it again, I made some changes to code.

Matt, you wrote a note in your readme about a possible fallback to fixed point values ? How is that possible ? I want to write float values comprised between 0.0 and 1.0 I cannot because the drivers will make them fallback to fixed point values ??

Fallback to fixed point isnt allowed, but it’s good to make a test if implementation doesnt make any unallowed things :slight_smile: , the driver doesn’t implement this extension in all way, and how can I be sure if I have floating point format ? :slight_smile:

Thanks for sharing the code. I played a little bit with your code, also doing the storing/setting of the viewport like your second revision. I added some animation so now I see that something is happenging :cool: . Anyone interested?

Which hw / driver are do you use? I use a GF FX 5600 go and the 75.90 drivers. I had to change textureRect into texture2DRect because otherwise I got a compilation error.

Checking the spec says that your code is the correct one, maybe you have a newer driver than me?

Edit: I upgraded to FW 76.41 and now GLSL behaves as it should :slight_smile:

How do I render to depth texture while also rendering to color texture? I tried both of the following, but I only got a white depth texture? My intention is to render the depth into a texture and use that texture as a luminance value in a subsequent render pass, so no shadow mapping.

    // generate framebuffer
    glGenFramebuffersEXT(1, &fb);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
   		
    // generate 2D texture(color buffer)
    glGenTextures(1, &color_tex);
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, color_tex);
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_FLOAT_RGBA32_NV, rt_w, rt_h, 0, GL_RGBA, GL_FLOAT, NULL);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, color_tex, 0);

	CHECK_FRAMEBUFFER_STATUS();

	// generate depth renderbuffer
	glGenRenderbuffersEXT(1,&depth_rb);
	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,depth_rb);
	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT24,rt_w,rt_h);
	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, depth_rb);
	
	CHECK_FRAMEBUFFER_STATUS();

	// Depth texture
	glGenTextures(1, &depth_tex);
	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, depth_tex);
	glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, rt_w, rt_h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, depth_tex, 0);

	CHECK_FRAMEBUFFER_STATUS();
    
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

My fragment shader looks like this:

varying vec2 T;

uniform samplerRect texture;

void main (void)
{
   gl_FragColor = textureRect(texture,T);
}

Where did you get thoses 76.41 ? :confused:

76.41: http://downloads.guru3d.com/download.php?det=1022

In some rieviews i read that FSAA in DOOM3 wasn’t working.

Ok, it works now. I was just to stupid to see it, even with glasses :wink: . The depth values in my z texture were nearly one, so it’s clear that it seemed to be white. Now I adjusted the position of my object and it does what it is supposed to do:

Thats the final setup code, with NV_float_buffer and ARB_texture_rectangle. There is no need for a depth renderbuffer when using a texture as depth attachment.

    // generate framebuffer
    glGenFramebuffersEXT(1, &fb);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
   		
    // generate 2D texture(color buffer)
    glGenTextures(1, &color_tex);
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, color_tex);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);    
	
	glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_FLOAT_RGBA32_NV, rt_w, rt_h, 0, GL_RGBA, GL_FLOAT, NULL);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, color_tex, 0);
	CHECK_FRAMEBUFFER_STATUS();
	
	// Depth texture
	glGenTextures(1, &depth_tex);
	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, depth_tex);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);    

	glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, rt_w, rt_h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, depth_tex, 0);
	CHECK_FRAMEBUFFER_STATUS();

OK, thanks for downloading demo :slight_smile: .
I have GF FX5900 with 76.41 driver.
I play a little with depth buffer of framebuffer object and I found out that, I cant use NPOT depth buffer like 1024x768, but I found nothing about this restriction in spec. So the solve for this problem is depth rectangle texture, I think. But I couldnt setup it correctly. Now I see your code for this I am going to try it.

Tried anyone doing HDR with this extension? I am doing some test and as I see the speed doesnt fall down with 16bit per channel. Maybe because I have 256bit bandwith and my bottleneck is pixel shader performance. So HDR wont be so hurting for rendering with this extension, am I right?
ofcourse if dont calculate the time for tonemapping.

do 76.41 drivers have working stencil renderbuffers yet? or mipmap generation on cubemaps?

Originally posted by 3B:
[b] [quote]Originally posted by Overmind:
Just out of curiosity, could you try the speed of the same scene without framebuffer switches? That is, rendering the reflection passes on screen instead of to the texture…
quick hack of just skipping the BindFramebufferEXT with no other code changes looks to be about ~7-10% higher frame rate for the normal or clear only cases…
planning on doing a real pbuffer and copy from backbuffer version for more valid comparison at some point once I’m more awake, will depend on how much time I spend on optimizations or making it look nicer instead :slight_smile:

edit: more numbers to confuse the issue :slight_smile:
remembered that I was rendering to float textures, so tried GL_RGBA instead…
GL_RGBA16F: with BindFramebuffer = 35fps, without = 39
GL_RGBA: with bind = 41fps, without = 60fps…

actually, looks like without the BindFramebuffers, its wasting a lot of time doing glClears on the entire window instead of just the 256x256 area, so the above numbers are quite a bit lower than they should be, rough guess looks like about a factor of 2x…[/b][/QUOTE]It’s quite old post, but you can use scissor test to specify only 256x256 area and then call clear.

Originally posted by Matt Zamborsky:
It’s quite old post, but you can use scissor test to specify only 256x256 area and then call clear.
Are you sure? I think that glClear clears everything even if glScissor is enabled. I don’t have documentation here but this is what I recall.

Hope this helps.

[EDIT] It seems you are right:
http://www.mevis.de/~uwe/opengl/glClear.html
“The pixel ownership test, the scissor test, dithering and the buffer writemasks affect the operation of glClear. The scissor box bounds the cleared region. Alpha function, blend function, logical operation, stenciling, texture mapping, and z-buffering are ignored by glClear.”

Hi,

Anyone succeeded in using float buffers in 32 bits precision? I have a GF6600 with the 76.41 drivers and when specifying a GL_RGB32F_ARB textures color attachments, my framebuffer fails to create.

I really need 32 bits floats cause I am having serious visual artefacts when rendering.

Thanks in advance,
Jeff.