Is FBO Size Tied To glViewport?

I'm finally trying to learn how to do shadow mapping with GLSL. I have the basic shader working (just basic lighting with diffuse and shadow right now) and I have the shadow map rendering nicely and it correctly places the shadows. Unfortunately it is *horribly* aliased, in part because I'm using a 512 x 512 shadow map. I can do some extra samples to anti-alias it a bit, but I get much improved results just using a bigger shadow map. So I tried to bump up the size of the shadow map to 1024 but then discovered that you can't just do that all willy-nilly since apparently you can't set glViewport to bigger than your window (or "drawable", is probably more correct terminology?), and my window starts off at a smaller size than 1024. If I try doing this then there's garbage in part of my texture until I make the window bigger or go to a higher resolution in full screen. After that everything is fine. Okay, seems to make sense that I'm limited there.

SO ... I figured, well then I guess I might be able to use an FBO and get whatever size I want (within the max tex size and performance of course), right? Apparently not. I switched to using an FBO for the shadow map texture instead of glCopyTexSubImage2D but I still get garbage in part of my texture until I change the size of the window. Am I not supposed to be doing things this way? What size can I get away with? How do I get the FBO to be the size I want without garbage at first? I'm new to this shadow mapping (and FBO) business, so any help and/or pointers would be greatly appreciated.

It doesn't seem to be changing as it should, so I must be missing something. Here's some code (unrefined early development and experimentation). Not sure what else I should include. I added comments to help trace some of my thinking. I hope they aren't too non-sensical:

// make sure that we aren't accessing the shadowMapTexture by accident, which would result in undefined behavior
glBindTexture(GL_TEXTURE_2D, 0);

// save the existing viewport and set a new one for the FBO rendering
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE);
glClearDepth(1.0f);
glClear(GL_DEPTH_BUFFER_BIT);

The GLUT test works as advertised. The only difference I see is that I'm rendering to a depth texture, which is significant, but the technique appears to be the same.

I tried the glGetIntegerv(GL_VIEWPORT, ...) idea and it says the viewport is what it is supposed to be, when it is supposed to be (tried it in a bunch of places).

I don't see any obvious unbalanced push/pops (of course they aren't usually obvious).

So if the FBO and the context states have nothing to do with each other, then why is the amount of garbage in my depth (shadow) texture directly proportional to the size of my window? As I grow the window, the garbage goes away and doesn't come back if I then shrink it. It's as if memory in the FBO texture just isn't being allocated or accessible until I grow the context's viewport large enough. I don't see how they could be tied together, but it really *appears* that way.

I also noticed that it appears that my shadow map texture disappears when I turn the shader off. That is, I can texture a quad with the shadow map texture while the shader is on, but not when it's off. The two issues could (very likely) be entirely unrelated, but I was able to texture with the shadow map back when I was using the glCopyTexSubImage2D technique with no shader.

Yes, that works as advertised as well, but dammit, if I knew you were going to do that I wouldn't have already gone and done it myself!

Thanks though, I really appreciate it, big-time.

Here was my somewhat more elaborate version. Change RENDER_DEPTH_TEXTURE to 0 to render a colored cube instead. [adding] I'm sure it probably spins at a million rotations per second on a faster machine, since I didn't do any time calculation [/]:

This brought up another question about FBOs actually. I just started researching on it, but haven't found anything yet. When rendering the colored cube, is there a particular reason why the depth testing seems not to work when rendering to an FBO texture? Does it not have a depth buffer or something? Maybe there's a different type of attachment to be using. Or perhaps I missed something in my code... Whatever, it's not totally important to the problem at hand, but as long as I'm learning a little about FBOs I figure it's worth my trouble to find out what's up with that too, if I can.

[Edit] Never mind. This got fixed! [/edit]

At any rate, the GLUT demos have me 99.9% convinced that it is completely my fault, whatever that may be. I guess I'll have to start restructuring the code and isolating things more carefully.

It's doing exactly what you asked it to do; when RENDER_DEPTH_TEXTURE=0, you're not attaching anything to the FBO's depth attachment, hence you get no depth testing.

When you create a window, and provide a pixel format, there is some logic that looks at the pixel format and says "Oh, you asked for a color buffer-- let's allocate one. Oh, you asked for a depth buffer-- let's allocate one." And so on.

An FBO is a little container object which you attach buffers to. The pixel format logic is replaced with you explicitly allocating buffers and attaching them. See the spec for the overview, gory details, and examples.

arekkusu Wrote:An FBO is a little container object which you attach buffers to. The pixel format logic is replaced with you explicitly allocating buffers and attaching them. See the spec for the overview, gory details, and examples.

[shudders] That particular spec doc scares the bejeezus out of me. I've been trying to weed through some of it, but it's a challenge for me to say the least. BUT, thank you for pointing it out again, in addition to your explanation that I didn't get depth because I didn't tell it to attach a depth buffer. I got it working now, using one of the examples found in there. I'll edit the above GLUT code to include it.

arekkusu Wrote:You can inspect what you've got at any given moment, for example:

Ah yes, thanks for the reminder. I almost always forget to glGet important information which could give me some feedback instead of trying to blindly guess everything. Needs to be like: printf("FBO %d has %d depth bits\n", myFBOThatWasMadeEarlier, bits[0]); though, or else it just prints an address (minor detail).

Now that we got that settled, I still need to figure out what's up with my other shadow texture, so back to sleuthing I shall go...