Sign in to follow this  
PixelPants

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

Recommended Posts

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.

[b]CheckIfWeNeedToResizeOffscreenBuffer()[/b]
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]

[b]SetProjection()[/b]
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

[code]
CheckIfWeNeedToResizeOffscreenBuffer();
SetProjection(true);
[/code]

and lastly...

[b]sDisplay() and DrawOffscreenTexture()[/b]
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.



[b]Edit:
[/b]I solved it.
[b]

[/b] Edited by PixelPants

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this