2D Graphics Engine

Overview
Hello, so I'm slowly progressing with my OpenTK, OpenGL and whole c# adventure. I'm taking opportunity to start development diary so here I am :) I have started writing a small engine with OpenTK, that handles ONLY 2D rendering, but completely removes need to use any OpenGL function, while cooperating with other parts of OpenTK. I haven't decided for the name yet but that's not important I think.

The goal is to build a small, easy to use engine capable of building small 2D games together with OpenTK.

Engine doesn't use any scene-graph, you must draw each image every frame manually. I think this way it's cleaner and faster when working with 2D graphics. However, Gui uses a GuiManager which will draw all widgets at once.
To use engine, engine code is linked directly with game code. If you don't need some parts of engine just don't link them.

The colors are passed as unsigned bytes (0-255).
The positions and sizes are passed as integers, meaning the x and y position of pixel on screen, where 0,0 is in the top left part of the screen.

Features implemented:
- Images loading/drawing (rotating, scaling, blending, drawing part of image)
- Animations(Sprite) (frames rendered from one texture, same options as image)
- Particle systems (uses single VBO, Point sprites)

Features planned:
- Basic Gui(first widgets done)
- Complete documentation/examples(some examples done)
- Shaders

Screenshots:
Free Image Hosting at www.ImageShack.usFree Image Hosting at www.ImageShack.usFree Image Hosting at www.ImageShack.usFree Image Hosting at www.ImageShack.us
Free Image Hosting at www.ImageShack.us

AttachmentSize
Mines.zip464.13 KB
PointSprites.zip467.25 KB

Comments

Re: 2D Graphics Engine
posted by objarni

How do you draw your particles? Blending? What graphics primitive is it? It looks quite nice :)

Re: 2D Graphics Engine
posted by flopoloco

Hi there and welcome, cool project you're working on :). There seem to exist lots of particles, are you getting decent FPS?

Re: 2D Graphics Engine
posted by lubos

@objarni: The particle system just stores reference to image and draws him for each partcile, no magic :) The image used for particle is from NeHe, just scaled down and blended directly with engine. Thx for comment ;)

@flopoloco: Thx, I didn't make any optimizations, the second one with 10k particles gets just around 13fps on my GeForce 7600 and dual core cpu. It seems that CPU is fully eated, I will look around if its possible to split it to two cores.

Re: 2D Graphics Engine
posted by lubos

I'm still improving engine, altought school takes much of my free time. I have posted two new screenies to the main post. I'm planning to release some kind of demo so if somebody could be that nice and test it so I know how it works on other PCs :) I will post the demo soon.

Re: 2D Graphics Engine
posted by objarni

Are you doing additive blending with saturation or multiplicative? That is, is your equation something like

final red = texture red * texture alpha * fragment red

or

final red = min (1, texture red * texture alpha + fragment red)

... if you know what I mean..?

Re: 2D Graphics Engine
posted by lubos

all I do so far is enabling gl blending with specified color

Re: 2D Graphics Engine
posted by lubos

Main post updated. Particles can be animated now!

Re: 2D Graphics Engine
posted by Inertia

nice project and progress, keep it up :)

How are you drawing the sprites? GL.DrawArrays and quads?

Regarding dual core CPUs, Fiddler mentioned the bold idea to use double buffering to avoid excessive locking and problems with thread safety. Basically you'd use 2 arrays of particles and anticipate the next frame in the backbuffer, while the frontbuffer is drawn, then flip pointers to the arrays. Hope this helps :)

Re: 2D Graphics Engine
posted by hshutao

nice project.how to get your sourcecode.

Re: 2D Graphics Engine
posted by lubos

-Inertia
Yes, drawing is done with vertex arrays using GL.DrawArrays, but its not any efficient currently since every image holds its own vertex array. Should I create one big array which will store all vertices? Or maybe one for particles, one for images etc

-hshutao
Thanks. I'm sorry but source is not yet avalaible. I don't think you would be any productive with it currently, still a lot of work needs to be done :)

Re: 2D Graphics Engine
posted by Inertia

While developing, functionality is much more important than speed optimizations. However it's always nice to keep the number of GL. calls as low as possible (around 300-500 calls per frame was said to be realistic in a whitepaper), so grouping all particles which share the same texture is a good idea. Or use a bigger texture which holds all 4 numbers (refering to your "letter" particle system here) so you can draw the whole particle system with the same texture bound, only changing uv coordinates.

The orange book takes a whole different approach, using a static array for the particle system and calculating the animation in GLSL.

I was just curious how you draw them, because it seems using point sprites or the geometry shader to create the quads for you is quite popular at opengl.org, because it only requires 1 vertex per particle instead of 4. I've tried point sprites so far, but they seem to have the limitation that you cannot rotate the quad they create, and I was kinda hoping you figured out how to do that ;) (Geometry shaders require DX 10 hardware so couldn't toy around with that yet.)

Re: 2D Graphics Engine
posted by lubos

So I'm going to group particle systems into one array ;) I was also looking at VBOs, but since it needs openGL 1.5 I will implement them later as optional feature. Regarding "letter" particle system, it already uses one bigger texture, the particle just holds frame number, which is used to calculate texture coordinates.

I know nothing about shader programming, but will add it to roadmap. i will check point sprites also, looks like great idea!

Re: 2D Graphics Engine
posted by lubos

Just a small update. A more than week passed and I have done so little. Particle systems already uses vertex arrays, still some problems but I will hopefully fix them this weekend, as well have a look at point sprites :)

Re: 2D Graphics Engine
posted by the Fiddler

Love the flaming text, this must look awesome in movement! :)

Re: 2D Graphics Engine
posted by objarni

Are you using "classic vertex arrays" or VBOs?

The classic VAs of OpenGL is not recommended in OpenTK, if you are going to scale up and need more performance. Go for display lists or VBOs instead.

Re: 2D Graphics Engine
posted by lubos

I'm using "classic VAs". I read that VBOs need OpenGL 1.5 so I decided not to use it(or, not to use it as main method) as this is just 2D engine for 2D games which should run even on older machines. Yeah, the particle system with 20k paticles runs at only about 8 fps currently, but that much particles will never be used in game.
Why its not recommended in OpenTK? Its because of c#?
About display lists, how should I do that? The only way I see is to rebuild all lists everytime when particles get moved.
Thanks for suggestions :)

Re: 2D Graphics Engine
posted by the Fiddler

When using VAs, it is your responsibility to keep the data pointers intact for as long as you are using the VA. This is no simple task in an environment with a compacting GC like .Net - unless you are taking precautions, your app will start displaying garbage or crash after a variable period of time (it depends on the runtime, the number of cores in your machine and the memory pressure).

VBOs do not suffer from this issue. Geforce FX and higher have 1.5 compliant drivers, so you can just go ahead and use VBOs. You'll need to work a little more in order to support older cars: you could use the ARB VBO extensions in GL.Arb, and fall back to display lists / immediate mode if these features are not supported.

Edit: Check this pdf for VBO support on older cards: http://www.g-truc.net/article/vbo-en.pdf

It looks like VBOs are supported from Riva TNT 1 and up (should be old enough for ya!), in one form or another.

Re: 2D Graphics Engine
posted by objarni

Fiddler: maybe my "not recommended" is too weak? you also have to use "pinning" (or what it is called) to actually make the program semantically correct/stable to use VAs in OpenTK, right?

But when you do use VAs (with pinning), it is really slow, right?

It would be really nice if IntelliSense told users that DrawArrays etc. is not the recommended way ( unless it's via VBO's ). This will bite lots of beginners of OpenTK since VAs are immensely popular, since it's really fast and easy to use in C/C++.

Re: 2D Graphics Engine
posted by the Fiddler

Yeah, it's an understatement. VAs are pretty much forbidden in .Net, for the very reason you mentioned (they require long-term pinning which will kill GC performance).

I'm working on a system that will allow us to add comments to specific OpenGL functions. It requires some rather extensive modifications to the generator however, and I don't have the time for that right now. I'll add a comment by hand for the time being, warning users on the pitfalls.

Re: 2D Graphics Engine
posted by lubos

Update! I finally managed to sit down and code :) It's 1:13 AM and drawing is now done using VBOs :P As a next step I decided to clean code a bit before I start with point-sprites.

Re: 2D Graphics Engine
posted by the Fiddler

Nice! Did performance improve?

Re: 2D Graphics Engine
posted by lubos

Hm I didn't notice any performance gain. The thing is that all particles are still moving so I must rebuild VBO every time on update, is this correct?

Re: 2D Graphics Engine
posted by the Fiddler

Of course, as long as the CPU has to update all these particles, it will be the bottleneck. I wondered if there was any thing to be gained anyway (maybe the driver would be better able to optimize the data before sending it?), but it looks not :)

Re: 2D Graphics Engine
posted by lubos

I tried to run engine on other pc but the window just blinked for the second and then exited without any error message, do you have any idea why it crashes on other pc? It works here normal both in debug and release mode, I use VC# 2008 express

Re: 2D Graphics Engine
posted by the Fiddler

Ok, required info for the failing platform:

  1. Operating system and .Net version.
  2. Video card and version of the drivers.
  3. OpenTK version (0.9.0?)

Suggestions: invoke your program through the commandline. See if any exception is reported there.

It will also be very helpful to compile a debug version of OpenTK and run Examples.exe on that PC. Examples.exe generate a debug.log which will help pinpoint the problem.

To compile OpenTK, open a commandline window and head to opentk-0.9.0/Build. Then type:

build vs
OpenTK.sln

Press finish to convert the project to VC# 2008 and press F6 to build. Zip up the bin/Debug/Exaples/ folder and try it on the problematic PC.

Re: 2D Graphics Engine
posted by lubos

1. Windows Vista, comes with .Net 3.0 I think
2. Same as here, nVidia GeForce7600gt, 7.15.10.9689
3. 0.9.0

no messages from command line

When I run OpenTK examples they run fine, but when I run "First shader" example, it reports that I need atleast OpenGL 2.0, so it seems like opentk doesnt use hardware acceleration or what?

Re: 2D Graphics Engine
posted by the Fiddler

What does GL.GetString with the Vendor, Renderer and Version tokens return?

Re: 2D Graphics Engine
posted by Mincus

If I'm reading the nvidia driver version correctly there, you're running a pretty old driver.
Try updating that?

Re: 2D Graphics Engine
posted by lubos

renderer: GDI Generic
vendor: Microsoft Corporation
version: 1.1.0

Re: 2D Graphics Engine
posted by the Fiddler

Definitely software accelerated then. The string should read "Nvidia Corporation blah blah blah".

First step is to update the drivers for the video card - I'd give a 90% chance that this will fix the problem.

Second step is to set the monitor at 32bit color.

Is he able to run other *opengl* applications?