Sign in to follow this  

Sprite blitting

This topic is 2319 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Heya guys.

So, I am working on a series of algorithms that will make up the basic framework of a 2D game. I am using C++ with SDL/OpenGL. When it comes to sprite blitting I have a number of was I could possibly achieve this, but when I start to get to the code, I hesitate and wonder if I am going about it the correct way. I wish to render using OpenGL, so I thought first I could split it into rectangles and sprites. where I simply setup a polygon and add a texture to it. I am struggling to find a nice way to draw this rectangle however within a class method, I need to pass arguments for the x, y coords of each vertices, would I not just be able to give the top left and bottom right coords to draw it?

Any help on how I should go about doing this will be appretiated, I am aiming for an object oreintated design.

Thanks.

Share this post


Link to post
Share on other sites
SDL: Can almost do everything you want. Gets user input (keyboard), can draw a window, can initialise OpenGL but can also do things OpenGL does. However, OpenGL is better.
OpenGL: Draws pixels onscreen for the graphical content (within the window).

This was taken from another post in another forum, which applies well here. This person also programs in SDL and OpenGL, using OpenGL to handle graphics and SDL to handle everything else.

As for how you decide to render, I can be of no help as I do not use SDL or OpenGL.

Share this post


Link to post
Share on other sites
Thank you for the response. It does not help me with my problem however, I am fully aware of what each API is and is not capable of, I am just having a bit of a block when it comes to implementing it.

Share this post


Link to post
Share on other sites
I implemented a sprite engine which takes;

* a texture buffer which contains an atlas of sprite images
* a texture buffer which contains floating point numbers

The latter contains my sprite data; x,y position, width, height, sprite number from the sheet to use.

I draw the thing using gl instancing and rendering another vertex buffer which contains the four corners of the idealised sprite; so it's got (0,0,0) (1,0,0), (1,1,0), (0,1,0) in it.

Using the instance number I pull the sprite data for this sprite, cook up the X,Y,Z, R,G,B, TX,TY values inside the vertex shader. The pixel shader is a trivial transparency paint operation.

(One GL call therefore renders my entire sprite set)

To do the updates, I map the float texture buffer and simply write new X.Y, FRAME values into the appropriate slots. It's fairly trivial from this to add things rotation angles and so on.

If this sounds like something you could use, I'll happily share some code.

Share this post


Link to post
Share on other sites
Hidden
I forgot to say, why even use OpenGL in a 2d game. What other than sprites are you planning on drawing, or are you planning on using 3d models and rendering in a 2d environment?

Share this post


Link to post
Use SFML. It already has an image and sprite class. Image holds the image buffer, which gets loaded once, and Sprite would get the singular image buffer.

SFML also runs on top of OpenGL, so you don't have to mix to SDK's (SDL and OpenGL) to get maximum 2D graphics alleceration. And, it provides just about everything you need for eery other part of your program, and better than SDL.

[url="http://sfml-dev.org"]sfml-dev.org[/url]

Share this post


Link to post
Share on other sites
[quote name='BeerNutts' timestamp='1312566858' post='4845114']
Use SFML. It already has an image and sprite class. Image holds the image buffer, which gets loaded once, and Sprite would get the singular image buffer.

SFML also runs on top of OpenGL, so you don't have to mix to SDK's (SDL and OpenGL) to get maximum 2D graphics alleceration. And, it provides just about everything you need for eery other part of your program, and better than SDL.

[url="http://sfml-dev.org"]sfml-dev.org[/url]
[/quote]

Thanks for the reply. I need to write my own sprite blitting algorithm however, this is for a uni project.

Share this post


Link to post
Share on other sites
OK, I had a look at the code and it's not really something I can "just post" because it uses a lot of my own utility classes.

I can talk you through the main points though.

Probably the easiest way to do this is to evolve your way gently towards it.

So the thing is to put all your images into one texture -- a texture atlas.

Draw your sprites using immediate calls for now setting up each x,y,z and texture coords. You should have a working, but slow engine.

Put a shader in -- the vertex can just pass things through, the pixel shader is a simple texture read.

Pass in uniforms for the sprite X,Y,W,H and rotation. (next step is to turn it into something faster). Also you'll need columns and rows for the images in the atlas and also a uniform to say which image to use. Now your shader can compute the screen X,Y coords and texture coords. You use the supplied coords to tell whether to add width/height values to the coords. Just draw a square at (0,0),(1,0),(1,1),(0,1) in immediate mode after setting up the uniforms for each sprite.

This is still slow but getting there.

Now turn the immediate mode square into a VBO, draw the four verticies out of it each time.

So the next part is supplying the sprite data in a texture buffer...

(to be continued...)

Share this post


Link to post
Share on other sites
(continued)

This is actually easier than the examples all make it seem.

What you do is create a texture buffer object and a vertex buffer object using glGenTextures and glGenBuffers. Set the size of the VBO to the number of floats in your sprite data[1] times the number of sprites you'll want to use.

Use glBindBuffer(GL_TEXTURE_BUFFER,id) to attach the VBO and glBindTexture(GL_TEXTURE_BUFFER, id) to attach the texture.

Instead of uploading a texture to the tbo, you attach the vbo to it using either glTexBufferARB or glTexBufferEXT (whichever one is non-zero on your system).

You say something like "glTexBufferARB(GL_TEXTURE_BUFFER,GL_INTENSITY32F_ARB,your_vbo_id);

When you set up your shader, bind the texture buffer to one of the shader units.

Now comes the neat bit.

Inside your shader, you can now say "something = texelFetchBuffer( sampler2, n ).r" and this will read you the Nth floating point number out of the VBO. Just like that. So can basically pass arbitrary stuff in that buffer. If you set a uniform for the sprite number, then it's easy to go

x = texelFetchBuffer( sampler2, sptnumber * 10 + 0 ).r;
y = texelFetchBuffer( sampler2, sptnumber * 10 + 1 ).r;

And so on.

So it's really easy to read out your X,Y,W,H etc instead of using a uniform.

The only remaining thing is to get it to do more than sprite at a time. And that's fairly easy; you bind the VBO containing the square coords as before, but instead of calling drawElements, you call glDrawArraysInstancedEXT or glDrawArraysInstanced, passing in (GL_QUADS,0,4,number_of_sprite_slots)

What happens here is that your shader now gets gl_InstanceID set when it's run -- it ticks up for each one of the squares drawn.. so it's the "sptnumber".

Modifying the data is easy; just map the buffer. Convert the void* pointer to a float* and you can just write to it like it's a big array of float.

Make sure you remember to unmap the buffer before trying to draw it.

{Oh yeah -- how do you disable a particular sprite slot? Easy. Make the W and H both zero. It will produce a degenerate quad which will never be rasterised.}

The reason I'd advise going slowly and evolving towards this is that there's a lot of opengl code to add and a lot of things which could go wrong. If you go slowly step-by-step and test it at each stage, there's less code to debug each time.



[1] Eg; "X,Y,W,H"=4, "red, green, blue, alpha coloration"=4, image number, rotation =2 -- a total of 10 floats per sprite.

Share this post


Link to post
Share on other sites
Thanks again, your advice has been a great help. I need to get myself an OpenGL reference book, but I am afraid of getting one as they contain deprecated functions.. I will have to wait until December when they bring the 4.x stuff out.

Share this post


Link to post
Share on other sites
Ahhh, I just use google searches for that stuff these days.

It's mostly like that at my day job as well -- there's just too much stuff to know to actually keep it all in my head or on paper...

Share this post


Link to post
Share on other sites

This topic is 2319 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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