Boder's picture

Awesome, I'm running not walking

I was worried for no reason.

I got the SVN for the new FBO stuff, got confused with nant and realized I didn't need it for "build vs." Compiling was easy.

Started with my new project codenamed "Quick Start" (I expect many have the same codename). I had to change some things, but was simple with C# intellisense. I still hope for an updated Quick Start. Pseudo fullscreen works nicely and is the default (cool).

The only thing is the mouse cursor stays on the "loading" icon until I move it off the client area (very minor).

Now I'm on to figure out FBOs and GLSL, which I never got under C++, but should be easier now.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Boder's picture

Got FBO working. CPU Usage went to 1/4 (from rmclock) but I'm not too worried as it's a debug build.

I draw one non-pow-2 texture quad in immediate mode to a FBO, then render the FBO texture as a quad, again in immediate mode.

objarni's picture

Please, would you paste the source of your texture->FBO->color buffer code? :) Still haven't gotten around to FBO's, would be interesting learn!

Boder's picture

Sure! In all its ugly glory (Note, I do not need a depth render buffer attached for my 2D game)

public override void OnLoad(EventArgs e)
        {
            //GL.ClearColor(Color.FromArgb(33,68,85));
            //GL.Enable(EnableCap.DepthTest);
            //GL.Disable(EnableCap.DepthTest);
            GL.Enable(EnableCap.Texture2D);
            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
 
            #region LoadTexture
            GL.GenTextures(1, out texture);
            GL.BindTexture(TextureTarget.Texture2D, texture);
 
            System.Drawing.Imaging.BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
 
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
                PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
 
            bitmap.UnlockBits(data);
 
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
 
            #endregion
 
            GL.GenTextures(1, out fbo_texture);
            GL.BindTexture(TextureTarget.Texture2D, fbo_texture);
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, 512, 512, 0,
                PixelFormat.Rgba, PixelType.UnsignedByte, null);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp);
 
            // FBO
            GL.Ext.GenFramebuffers(1, out fbo);
            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, fbo);
            GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, fbo_texture, 0);
            if (GL.Ext.CheckFramebufferStatus(FramebufferTarget.FramebufferExt) != FramebufferErrorCode.FramebufferCompleteExt)
            {
                throw new Exception();
            }
            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);
 
 
            //FileStream fs = File.Create("output.txt");
            //fs.Close();
        }
public override void OnRenderFrame(RenderFrameEventArgs e)
        {
            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, fbo);
            GL.PushAttrib(AttribMask.ViewportBit);
            GL.Viewport(0, 0, 512, 512);
 
            GL.ClearColor(Color.FromArgb(25,0,0, 0));
            GL.Clear(ClearBufferMask.ColorBufferBit);
 
            //Glu.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);
            GL.BindTexture(TextureTarget.Texture2D, texture);
 
            GL.MatrixMode(MatrixMode.Texture);
            GL.LoadIdentity();
            GL.Scale(1.0, -1.0, 1.0);
            //GL.Rotate(180, 0, 0, 1);
 
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();
            GL.Translate(1000.0f / 2, 750.0f / 2, 0);
 
            //GL.Color3(Color.Firebrick);
            GL.Color3(Color.White);
            GL.Begin(BeginMode.Quads);
 
            GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(-419.0f / 2, -676.0f / 2, 0.0f);
            GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(419.0f / 2, -676.0f / 2, 0.0f);
            GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(419.0f/2, 676.0f/2, 0.0f);
            GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(-419.0f/2.0f, 676.0f/2, 0.0f);
 
            GL.End();
 
            GL.PopAttrib();
 
            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);
            GL.ClearColor(Color.FromArgb(33, 68, 85));
            GL.Clear(ClearBufferMask.ColorBufferBit);
            //| ClearBufferMask.DepthBufferBit);
 
            GL.BindTexture(TextureTarget.Texture2D, fbo_texture);
 
            GL.MatrixMode(MatrixMode.Texture);
            GL.LoadIdentity();
 
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();
            GL.Translate(1000.0f/2, 750.0f/2, 0);
 
            GL.Begin(BeginMode.Quads);
 
            float scaler = 2.0f;
            GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(-1000.0f / scaler, -750.0f / scaler, 0.0f);
            GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(1000.0f / scaler, -750.0f / scaler, 0.0f);
            GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(1000.0f / scaler, 750.0f / scaler, 0.0f);
            GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(-1000.0f / scaler, 750.0f / scaler, 0.0f);
 
            //GL.Color4(Color.FromArgb(255,0,255,255));
            //GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(108.0f, 108.0f, 0.0f);
            //GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(620.0f, 108.0f, 0.0f);
            //GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(620.0f, 620.0f, 0.0f);
            //GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(108.0f, 620.0f, 0.0f);
 
            GL.End();
 
            SwapBuffers();
        }
objarni's picture

Thanks! Are the (int) casts in TexParameter necessary? I thought OpenTK had a way of getting around those? Hurts my eyes..

the Fiddler's picture

[TexParameter casts]
Unfortunately there's no way to work around these without writing potentially hundreds of overloads (really, if there was, we'd have done it...) Hopefully GL3 will be a little more sane with parameter types.

However, there's one thing I haven't tried: can you use enums for generic constraints? If yes, it might be possible to add a few overloads in GLHelper.cs for the most common cases.

[Mouse icon problem]
It's a known issue - will be fixed in due time :)

teichgraf's picture

[Mouse icon problem]
See http://www.opentk.com/node/331

Boder's picture

VBOs are working now with the help of that great tutorial. OpenTK makes OpenGL fun again, unlike the C API with extensions and piss-poor documentation and 1000s of constants.

objarni's picture

I agree with Boder :)

Inertia's picture

[TexParameter casts]
I hope this doesn't become a philosophy session again, but actually the casting is imo not a bad thing. It tells you whether you are using the int or float overload. The situation is better for AL than for GL, but you can be sure that the current solution is as good as it can currently be. The problem is that the parameters are depending on the previous:
void Foo( enum e1, e1_enum e2, e2_enum e3); // hope this makes sense
Like Fiddler said, there's no solution to avoid the cast without a big price tag on it.

[1000s of constants]
Agreed, this is a huge advantage. You spend alot less time looking at references to make sure you pass valid parameters, because OpenTK restricts the options heavily :) *worships Fiddler for the idea to do this*

objarni's picture

[TexParameter casts]
I hope this doesn't become a philosophy session again
We'll see ;)

No I understand, in this case I can't really see any elegant way.

I guess the following is out of the question?

GL.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, TextureMinFilter.Linear);

(notice the 'i' appended to the method name, indicating the type of the last parameter. A little less parenthesis to type, a little cleaner code)