[solved] I can't get my 2D projection right..

Started by
-1 comments, last by PixelPants 12 years, 9 months ago
So I'm using an FBO to allow me to render the entire scene onto a texture, and then stretching that texture 2x'd over the screen.

The problem I'm having is that when the underlying FBO texture is resized and reattached to the FBO, things either stop rendering completely or are partially off the screen.

CheckIfWeNeedToResizeOffscreenBuffer()
This code just checks if the size of the window is too large for the underlying FBO buffer, and if it is, it deletes the existing texture and creates a new one that fits (always a power of 2 size)
[source]
private void CheckIfWeNeedToResizeOffscreenBuffer()
{
int TheExtent = Math.Max(this.ClientSize.Width, this.ClientSize.Height);
if (TheExtent > MyOffscreenTextureSize)
{
if (MyOffscreenTexture != 0)
cTexture.DeleteTexture(ref MyOffscreenTexture);

MyOffscreenTextureSize = 1;
while (MyOffscreenTextureSize < TheExtent)
MyOffscreenTextureSize *= 2;

cTexture.GenerateTexture(MyOffscreenTextureSize, out MyOffscreenTexture);
sCheckError();
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, MyFrameBufferObject);
GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext,
TextureTarget.Texture2D, MyOffscreenTexture, 0);
FramebufferErrorCode TheRet = GL.CheckFramebufferStatus(FramebufferTarget.FramebufferExt);
if (TheRet != FramebufferErrorCode.FramebufferComplete)
throw new Exception("Fatal framebuffer error: " + TheRet.ToString() + ".");
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
}
}
[/source]

SetProjection()
This code sets up the Ortho for if the destination is the FBO or for the main window.
[source]
private void SetProjection(bool TheForFBO)
{
if (TheForFBO)
{
GL.Viewport(0, 0, MyOffscreenTextureSize, MyOffscreenTextureSize);
sCheckError();
}
else
GL.Viewport(0, 0, this.ClientSize.Width, this.ClientSize.Height);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
if (TheForFBO)
{
GL.Ortho(0, MyOffscreenTextureSize, MyOffscreenTextureSize, 0, -1.0, 1.0);
sCheckError();
}
else
GL.Ortho(0, this.ClientSize.Width, this.ClientSize.Height, 0, -1.0, 1.0);

GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();

double TheTranslate = 0.375;
GL.Translate(TheTranslate, TheTranslate, 0.0);
}
[/source]

oh and.. on the form's resize event, this is what gets called


CheckIfWeNeedToResizeOffscreenBuffer();
SetProjection(true);


and lastly...

sDisplay() and DrawOffscreenTexture()
Display gets called when the rendering to the FBO is finished, and it's time to draw it to the screen (which DrawOffscreenTexture()) is does.
[source]
public void sDisplay()
{
CheckContext();

/* Unbind the FBO and bind the texture we've been rendering to. */
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);
GL.BindTexture(TextureTarget.Texture2D, MyOffscreenTexture);
SetProjection(false);
DrawOffscreenTexture();
MyControl.SwapBuffers();
sCheckError();
SetProjection(true);

GL.BindFramebuffer(FramebufferTarget.FramebufferExt, MyFrameBufferObject);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.ClearColor(Color.Black);
}

private void DrawOffscreenTexture()
{
double TheSourceLeftX = 0;
double TheSourceRightX = 1;// MyForm.MyWidth / (double)MyOffscreenTextureSize;
double TheSourceTopY = 1;
double TheSourceBottomY = 0;// ClientSize.Height / (double)MyOffscreenTextureSize;

int[] TheViewport = new int[4];
GL.GetInteger(GetPName.Viewport, TheViewport);

double TheDestLeftX = 0;
double TheDestRightX = ClientSize.Width;
double TheDestTopY = ClientSize.Height;
double TheDestBottomY = 0;

//double TheSourceLeftX = 0;
//double TheSourceRightX = MyForm.MyWidth/ (double)MyOffscreenTextureSize;
//double TheSourceTopY = ClientSize.Height / (double)MyOffscreenTextureSize;
//double TheSourceBottomY = MyForm.MyHeight / (double)MyOffscreenTextureSize;

/* Now draw the offscreen buffer onto the screen. */
GL.Begin(BeginMode.Quads);
GL.Color4(Color.White);

/* Bottom Left.*/
GL.TexCoord2(TheSourceLeftX, TheSourceBottomY);
GL.Vertex2(TheDestLeftX, TheDestBottomY);

/* Top Left. */
GL.TexCoord2(TheSourceLeftX, TheSourceTopY);
GL.Vertex2(TheDestLeftX, TheDestTopY);

/* Top Right. */
GL.TexCoord2(TheSourceRightX, TheSourceTopY);
GL.Vertex2(TheDestRightX, TheDestTopY);

/* Bottom Right, */
GL.TexCoord2(TheSourceRightX, TheSourceBottomY);
GL.Vertex2(TheDestRightX, TheDestBottomY);
GL.End();
}
[/source]

DrawOffscreenTexture is in a bit of a bad state atm because I'm essentially using trial&error to try and see which parameter may be off, but it's not helping; I'm completely stumped.



Edit:
I solved it.


This topic is closed to new replies.

Advertisement