Sign in to follow this  
EvilNando

OpenGL Sprite Rendering how-to?

Recommended Posts

EvilNando    96
Im trying to create a sprite rendering class for opengl +3.X but I cant seem to get around it

Ive made my basic shaders and setup the context

What Im having trouble is the creation of vertices and assign them texture to them

Maybe would it be possible to have a function like:

Sprite.Draw();

[code]
where sprite has something like
{
float x , y;
int w, h;
rectangle texture_portion;
uint texture_id;
}
[/code]

:S looks like Im really lost here

Share this post


Link to post
Share on other sites
bluntman    255
[quote name='EvilNando' timestamp='1305816834' post='4813015']
Im trying to create a sprite rendering class for opengl +3.X but I cant seem to get around it

Ive made my basic shaders and setup the context

What Im having trouble is the creation of vertices and assign them texture to them

Maybe would it be possible to have a function like:

Sprite.Draw();

[code]
where sprite has something like
{
float x , y;
int w, h;
rectangle texture_portion;
uint texture_id;
}
[/code]

:S looks like Im really lost here
[/quote]

You could do it like that. Personally I like to separate my game data from my rendering method, so instead you would have something like:
[code]

struct Sprite
{
float x, y;
float w, h;
// blah blah
}[/code]


Then you would have:
[code]

struct Scene
{
Sprite[] sprites;
};

struct Renderer
{
void render(Scene scene)
{
foreach(Sprite sprite in scene.sprites)
{
draw_sprite(sprite);
}
}

void draw_sprite(Sprite sprite)
{
// draw sprite
}
}

[/code]

The benefits of this are: keeping your sprite class clean and small, and keeping your rendering code all in one place. Later on you can easily write another class called Renderer2 that uses some other rendering API or renders sprites in a different way.

Share this post


Link to post
Share on other sites
EvilNando    96
thanks

Im having trouble how to figure out the most efficient way to draw the sprites

Ive read that batching is the way to go but my textures are grouped by game objects (1 texture for player, 1 for each type of enemy, etc...)

I would like to add all my vertices in one array and send them to draw but it looks like it would be impossible because the way Ive planned my resources?

Share this post


Link to post
Share on other sites
bluntman    255
You should pack your sprites into sprite sheets, this should allow you to fit most sprites into a single texture. It also means you only need to bind a single texture, generate a single vertex buffer, use a default index buffer to draw your sprites. There are a few utilities for generating sprite sheets around, e.g. [url="http://spritesheetpacker.codeplex.com/"]http://spritesheetpacker.codeplex.com/[/url]

So your code would look something like:
[code]
index_buffer indices;
indices = generate_index_buffer(); // makes a single index buffer you can use for drawing all your sprites, looks like: [0,1,2,3,4,5,6,7,8,9,...,n] where n is a big number (as many as you are going to have active sprites * 4, preferably).

vertex_buffer verts;
while(playing_this_awesome_game)
{
verts.clear();
foreach(Sprite sprite in activeSprites)
{
verts.add(Vertex(sprite.x, sprite.y, sprite.u, sprite.v));
verts.add(Vertex(sprite.x + sprite.w, sprite.y, sprite.u2, sprite.v));
verts.add(Vertex(sprite.x + sprite.w, sprite.y + sprite.h, sprite.u2, sprite.v2));
verts.add(Vertex(sprite.x, sprite.y + sprite.h, sprite.u, sprite.v2));
}
load_vertex_buffer(verts);
draw_index_array(indices, 0, activeSprites.count() * 4);
}
[/code]

Obviously this is over-simplified, you need to do things like setting up your vertex format, stride etc, as well, or maybe load your sprite positions and sprite uvs into different buffers.
Also you might want to update active sprites directly into the vertex array instead and use a dynamic index buffer to only render the ones you are using.
I'm really no expert on sprite rendering though so you are best to look into this yourself more.

Share this post


Link to post
Share on other sites
EvilNando    96
I assume for this to work I should previously bind a texture?


Do I really have to group all textures? I mean Im using sprite sheets dont get me wrong but Im not using ONE spritesheet, Im using one for each object in my game, as I said earlier ...

one sheet for the player one for each type of enemies etc


Ive tried this in XNA and no problem what so ever why is this so different under OGL?

Share this post


Link to post
Share on other sites
Katie    2244
Because opengl is not a game development framework. Opengl is the equivalent of DirectX. If you want to equivalent of XNA, look at something like unity.


1. You could bind multiple sprite sheets and do work in the pixel shader to choose which one is used.

2. You could just bind one sheet at a time and render all the things which use that sheet by putting their data in different sections of the input VBO.

3. Make bigger sprite sheets. Modern opengl is happy with them being 1000s of pixels on a side.

Share this post


Link to post
Share on other sites
bluntman    255
[quote name='Katie' timestamp='1305826235' post='4813087']
[color=#1C2837][size=2]Modern opengl is happy with them being 1000s of pixels on a side. [/size][/color]
[color=#1C2837][size=2][/size][/color][/quote]
OpenGL is happy with it, but its the hardware/driver that decides how large a texture it will permit. Safest to stick to 2048 or 1024. I think (iirc) my HTC Hero will support 1024x1024 textures.
If you are making a game with sprites then I would guess that the sprites are usually a fixed size on screen. There is no point making the sprite texture larger than the sprite itself (I might be wrong here, but I think filtering not give better results if the texture is higher res, but will give optimal results if the texel/pixel ratio is close to 1). So unless all your sprites are massive on screen you should be able to pack a few into textures.
Still, as Katie mentioned, you could put all your 2D textures into a 3D texture, and use a w coordinate (so your uv is actually uvw) to specify which one to use.

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  

  • Similar Content

    • By pseudomarvin
      I assumed that if a shader is computationally expensive then the execution is just slower. But running the following GLSL FS instead just crashes
      void main() { float x = 0; float y = 0; int sum = 0; for (float x = 0; x < 10; x += 0.00005) { for (float y = 0; y < 10; y += 0.00005) { sum++; } } fragColor = vec4(1, 1, 1 , 1.0); } with unhandled exception in nvoglv32.dll. Are there any hard limits on the number of steps/time that a shader can take before it is shut down? I was thinking about implementing some time intensive computation in shaders where it would take on the order of seconds to compute a frame, is that possible? Thanks.
    • By Arulbabu Donbosco
      There are studios selling applications which is just copying any 3Dgraphic content and regenerating into another new window. especially for CAVE Virtual reality experience. so that the user opens REvite or CAD or any other 3D applications and opens a model. then when the user selects the rendered window the VR application copies the 3D model information from the OpenGL window. 
      I got the clue that the VR application replaces the windows opengl32.dll file. how this is possible ... how can we copy the 3d content from the current OpenGL window.
      anyone, please help me .. how to go further... to create an application like VR CAVE. 
       
      Thanks
    • By cebugdev
      hi all,

      i am trying to build an OpenGL 2D GUI system, (yeah yeah, i know i should not be re inventing the wheel, but this is for educational and some other purpose only),
      i have built GUI system before using 2D systems such as that of HTML/JS canvas, but in 2D system, i can directly match a mouse coordinates to the actual graphic coordinates with additional computation for screen size/ratio/scale ofcourse.
      now i want to port it to OpenGL, i know that to render a 2D object in OpenGL we specify coordiantes in Clip space or use the orthographic projection, now heres what i need help about.
      1. what is the right way of rendering the GUI? is it thru drawing in clip space or switching to ortho projection?
      2. from screen coordinates (top left is 0,0 nd bottom right is width height), how can i map the mouse coordinates to OpenGL 2D so that mouse events such as button click works? In consideration ofcourse to the current screen/size dimension.
      3. when let say if the screen size/dimension is different, how to handle this? in my previous javascript 2D engine using canvas, i just have my working coordinates and then just perform the bitblk or copying my working canvas to screen canvas and scale the mouse coordinates from there, in OpenGL how to work on a multiple screen sizes (more like an OpenGL ES question).
      lastly, if you guys know any books, resources, links or tutorials that handle or discuss this, i found one with marekknows opengl game engine website but its not free,
      Just let me know. Did not have any luck finding resource in google for writing our own OpenGL GUI framework.
      IF there are no any available online, just let me know, what things do i need to look into for OpenGL and i will study them one by one to make it work.
      thank you, and looking forward to positive replies.
    • By fllwr0491
      I have a few beginner questions about tesselation that I really have no clue.
      The opengl wiki doesn't seem to talk anything about the details.
       
      What is the relationship between TCS layout out and TES layout in?
      How does the tesselator know how control points are organized?
          e.g. If TES input requests triangles, but TCS can output N vertices.
             What happens in this case?
      In this article,
      http://www.informit.com/articles/article.aspx?p=2120983
      the isoline example TCS out=4, but TES in=isoline.
      And gl_TessCoord is only a single one.
      So which ones are the control points?
      How are tesselator building primitives?
    • By Orella
      I've been developing a 2D Engine using SFML + ImGui.
      Here you can see an image
      The editor is rendered using ImGui and the scene window is a sf::RenderTexture where I draw the GameObjects and then is converted to ImGui::Image to render it in the editor.
      Now I need to create a 3D Engine during this year in my Bachelor Degree but using SDL2 + ImGui and I want to recreate what I did with the 2D Engine. 
      I've managed to render the editor like I did in the 2D Engine using this example that comes with ImGui. 
      3D Editor preview
      But I don't know how to create an equivalent of sf::RenderTexture in SDL2, so I can draw the 3D scene there and convert it to ImGui::Image to show it in the editor.
      If you can provide code will be better. And if you want me to provide any specific code tell me.
      Thanks!
  • Popular Now