How to draw to Surface?

Hi,

I've just started into using Agate.

I've seen a few places in the forums that talk about writing/rendering to a surface instead of directly to the display. This seems exactly what I want to do, but I don't see the methods to do this. Can someone explain what I need to do to write from one surface to another?

The idea is as follows: I have a surface loaded from a file with all my terrain tiles (mountains, trees and the like). I want to create another Surface that is composed of these tiles. The resulting surface doesn't change for the length of the level, so I figured I would just create the level surface and do a DrawRect of its clipping rectangle to the display based on the scroll value. What I am working on is a scrolling arcade style thing.

Any help would be greatly appreciated.

Thanks

kanato
Posted - Fri, 02/19/2010 - 15:27

Are you using the 0.3.1 version, or the svn head version? The procedure is slightly different for them.

For the 0.3.1 version, create a Surface object passing the size you want it to be, and then do

  1. Display.RenderTarget = mySurface;
  2. Display.BeginFrame();
  3.  
  4. // draw to surface
  5.  
  6. Display.EndFrame();

For the svn head, you do the same basic thing, but you create a FrameBuffer object to render to instead of a surface. Then the frame buffer has a property to get the attached surface.

kanato
Posted - Fri, 02/19/2010 - 19:13

Oh yeah, don't forget to reset the render target to your display window after doing the above.

Torrent
Posted - Sat, 02/20/2010 - 02:57

I thought I posted this comment already, but it isn't showing.

I downloaded the trunk and started up with using the FrameBuffer objects. They work when using the Agate-Drawing driver, but the initialization of the FrameBuffer throws errors under OTK. I can debug through to the return code from GK which is OpenTK.Graphics.OpenGL.FramebufferErrorCode.FramebufferIncompleteMissingAttachment when it has gotten to initing it without a stencil or depth.

The line in my code is simple:
FrameBuffer fb = new FrameBuffer(640, 480);

Where should I start looking for a solution?

kanato
Posted - Sat, 02/20/2010 - 09:23

What OS / video card drivers are you using? Some cards have poor support for the OpenGL Framebuffer extension. The code should use a fallback if framebuffers aren't supported, but it sounds like it is not properly detecting that it needs to do this.

kanato
Posted - Sat, 02/20/2010 - 10:47

Well, I submitted a patch which would catch the exception and fall back to glCopyTexSubImage. It should work, but it will be slow. Still, I am interesting in knowing what video card / drivers you are using in case this error can be fixed.

Torrent
Posted - Sun, 02/21/2010 - 08:07

ATI Radeon HD 3650 is what is listed under my System Config for graphics cards. OS is Vista.

When I get a chance this week I will toss the code to my laptop and see if I get any better results with the FrameBuffer stuff. At the moment, I'll get your patch and see what happens. 'slow' still better than AgateDrawing?

kanato
Posted - Sun, 02/21/2010 - 11:38

Well, I think that card definitely should support framebuffers. How up-to-date are your video card drivers?

'Slow' frame buffer support probably is still better than AgateDrawing, especially if you are doing lots of drawing and using few frame buffers. Since you're on Windows, another option is to use AgateSDX, which shouldn't have any problems supporting frame buffers.

Torrent
Posted - Sun, 02/21/2010 - 21:58

The card drivers should be fine. This isn't an old computer nor a stripped down dev box. This is my normal gaming computer, and I run all kinds of games on it without issues.

I tried very quickly to get SDX to load, but it gave me missing reference errors about SlimDex. At which point my doorbell rang and I got distracted again. As for the other option in the patch, I haven't gotten a chance to load it up yet either. At the moment, he only thing I need the Framebuffers for is to create my master 'level' surface from the tile file I have so that I can move about of the level using just the clipping rectangle of the level surface and not have to keep rebuilding the level. I should hope that one slow call at the beginning shouldn't cause problems.

BTW thanks for the quick replies.

kanato
Posted - Sun, 02/21/2010 - 22:16

Hmm yes for AgateSDX you probably need the SlimDX redistributable: http://slimdx.org/download.php

Let me know if it works out, or better yet if it doesn't so we can work towards fixing it.

Torrent
Posted - Thu, 02/25/2010 - 10:23

HeyO. I made time to work with this stuff again. Here is what I found.

agate\Drivers\AgateOTK\Legacy\FrameBufferReadPixels.cs function BeginRender()
GL.Clear(ClearBufferMask.ColorBufferBit |
ClearBufferMask.DepthBufferBit);
throws an exception of InvalidFramebufferOperationExt

I then tried SlimDX. I downloaded the SDK for SlimDX and added all the refereneces. Same code as above throws the following exception.
agate\Drivers\AgateSDX\D3DDevice.cs function Clear(ClearFlags flags, int color, float zdepth, int stencil)

D3DERR_INVALIDCALL: Invalid call (-2005530516)

I am having the sneaky feeling that I am doing something wrong (either syntax-wise or just general idea wise with the offscreen target thing).

I may just try this evening redrawing the level with some fancy math to figure out which pieces need to be out there every time. We shall see.

kanato
Posted - Thu, 02/25/2010 - 13:53

Well, the only thing I can think of that you might be doing wrong is creating the FrameBuffer before you create your first DisplayWindow.

Torrent
Posted - Thu, 03/18/2010 - 10:15

I never did figure out why my implementation didn't like the Framebuffer stuff. However, I've had some time since then to play with Agate more and found out that I can get the framerate I want without the Framebuffer just with carefully cropped lists of Sprites/Surfaces.

I also started looking at the GUI System that is in the SVN branch. It is pretty cool. It is not yet so easy to use/overwrite, so I may take a crack at writing my own, but it is a nice starter thing to be able to look at. Do you have any sort of documentation about the GUI? Maybe if I could understand it better I would use it more directly. It seems to wind itself in circles a little bit.
I am quite impressed with the Lib and am happy to see my little project move forward.

kanato
Posted - Fri, 03/19/2010 - 20:33

There is no documentation for the GUI. I am not very happy with its status right now, so I am planning to do some major refactoring of it in the near future. So yeah, I wouldn't recommend using it at the moment.