Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Bitmap region vs Transforms for a camera

This thread is locked; no one can reply to it. rss feed Print
Bitmap region vs Transforms for a camera
Rodolfo Lam
Member #16,045
August 2015

So I was looking at the wiki for examples of a camera implementation for Allegro 5.0.10 (yes, I know 5.1 has now a camera somewhere around) and found two different options, drawing a bitmap region to the screen and calculate myself the camera position, or using an ALLEGRO_TRANSFORM to move the display to the position where the camera must be.

But would like to have advice on which method could be better in the long term

Thomas Fjellstrom
Member #476
June 2000
avatar

Well, I think for a camera, you'd keep track of the camera position and only draw the bits of your level/game that fit in the current screen area. You can use transforms to store your camera position, but its probably easier to just use some regular old variables[1] to track the position.

I'm imagining you have a 2d map, maybe a side scroller or a tile map. In these cases you don't really want to do any bitmap region magic or transforms to move the drawing around because you can just take the camera position and figure out the current bits of the map to draw from that (from the camera origin minus half the screen, to camera origin plus half the screen, or something similar).

References

  1. not HTML! kekekeke. old joke

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Rodolfo Lam
Member #16,045
August 2015

Seems pretty reasonable... The solution I right now have for the tilemap is drawing everything (all the layers, the entire map) to the screen directly, so the amount of offscreen objects is huge and will definitely not scale with even bigger maps. Wanted to get away with not translating the world coords to screen coords with the transform ;D lazy me... Thanks!

Mark Oates
Member #1,146
March 2001
avatar

tilemap is drawing everything (all the layers, the entire map) to the screen directly

Yikes. Yea, that'll cost ya.

I much prefer to use the transforms.

It can be kinda tricky, but once your camera is setup it's not difficult to translate both to and from world and camera coordinates. You get the advantage of having zoom and rotation which is nice to have in your pocket, and you won't have pos-camera_x, pos-camer_y cluttering all your drawing code. Overall, you get more control, simplicity, and power if you choose to use transforms, but there is a learning curve.

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Thomas Fjellstrom
Member #476
June 2000
avatar

Yikes. Yea, that'll cost ya.

Depends. It should be fine if you use tile sheets and bitmap holding.

I don't really see how a transform is any better than just clipping like I suggested. Using transforms for translation implies you're drawing everything unless you also handle not drawing around where the transform is (which needs you to keep track of the translation separately...)

But yeah, if you want things like simple zoom and rotation, a transform is the way to go, but i think you still want to store the camera coordinates separately and then just "translate" to that in the transform.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Mark Oates
Member #1,146
March 2001
avatar

Depends. It should be fine if you use tile sheets and bitmap holding.

Which I didn't :P, and it was naaaysty ;D

But even with bitmap holding and sprite sheets, I've run into (extremer) cases where performance took a hit, (probably because you're still sending a lot of drawing calls, and allegro is building transforms for each al_draw_bitmap call on the backend). I think the ultimate optimization is making the tilemap one large ALLEGRO_VERTEX tile_map_prim[], every tile being 2 triangles, and the texture is the tile atlas. That's my next pet project, really looking forward to trying that out.

Quote:

I don't really see how a transform is any better than just clipping like I suggested. Using transforms for translation implies you're drawing everything unless you also handle not drawing around where the transform is (which needs you to keep track of the translation separately...)

Not separately, you can extract them from the transform. If your camera has a camera_width and camera_height, you can al_transform_coordinates() on camera_x, camera_y, camera_x+camera_width, and camera_y+camera_hight. That'll give you your clipping rectangle in world coordinates. If you then divide each coordinate by 16 (or whatever your tile size is), then you get the row/column of the tilemap.

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Chris Katko
Member #1,881
January 2002
avatar

I'm reading this tutorial as we speak.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Thomas Fjellstrom
Member #476
June 2000
avatar

But even with bitmap holding and sprite sheets, I've run into (extremer) cases where performance took a hit, (probably because you're still sending a lot of drawing calls, and allegro is building transforms for each al_draw_bitmap call on the backend). I think the ultimate optimization is making the tilemap one large ALLEGRO_VERTEX tile_map_prim[], every tile being 2 triangles, and the texture is the tile atlas. That's my next pet project, really looking forward to trying that out.

Yeah, your best bet is to draw the geometry in one go. Bitmap holding is supposed to do that, as long as you only use the same actual texture for ALL calls. Of course using a single batch for all of the map is going to need to use the same texture regardless.

Though I've been experimenting with setting up multiple texture atlases, and having the geometry data send in the texture id to pick the correct one. If more things supported Texture Arrays, this would be so much simpler, but its not a 100% supported thing yet.

Quote:

Not separately, you can extract them from the transform. If your camera has a camera_width and camera_height, you can al_transform_coordinates() on camera_x, camera_y, camera_x+camera_width, and camera_y+camera_hight. That'll give you your clipping rectangle in world coordinates. If you then divide each coordinate by 16 (or whatever your tile size is), then you get the row/column of the tilemap.

You could but I'm not sure how that's simpler or better ;D

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Mark Oates
Member #1,146
March 2001
avatar

Though I've been experimenting with setting up multiple texture atlases, and having the geometry data send in the texture id to pick the correct one. If more things supported Texture Arrays, this would be so much simpler, but its not a 100% supported thing yet.

That's cool. I've ended up just using a custom ALLEGRO_VERTEX that includes the 3D normal for, well, everything 3D. It's just use it by default now.

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Thomas Fjellstrom
Member #476
June 2000
avatar

I've ended up just using a custom ALLEGRO_VERTEX that includes the 3D normal for, well, everything 3D. It's just use it by default now.

What are you using it for? Isn't it normally for doing lighting and stuff like that?

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Mark Oates
Member #1,146
March 2001
avatar

Yea, lighting. And anything for shader materials like reflectance, skybox, specular shading, normal maps, etc. use a normal.

  typedef struct
  {
    float x, y, z;
    float u, v;
    ALLEGRO_COLOR color;
    float nx, ny, nz;
  } ALLEGRO_VERTEX_WITH_NORMAL;

I also meant to say I'm using ALLEGRO_PRIM_TEX_COORD instead of allegro's default ALLEGRO_PRIM_TEX_COORD_PIXEL. So UV coordinates are in 0.0 to 1.0 rather than texture_width or texture_height.

Here's what my vertex declaration looks like.

  ALLEGRO_VERTEX_ELEMENT elems[] = {
    {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, offsetof(ALLEGRO_VERTEX_WITH_NORMAL, x)},
    {ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(ALLEGRO_VERTEX_WITH_NORMAL, u)},
    {ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ALLEGRO_VERTEX_WITH_NORMAL, color)},
    {ALLEGRO_PRIM_USER_ATTR, ALLEGRO_PRIM_FLOAT_3, offsetof(ALLEGRO_VERTEX_WITH_NORMAL, nx)},
    {0, 0, 0}
  };

  vertex_declaration = al_create_vertex_decl(elems, sizeof(ALLEGRO_VERTEX_WITH_NORMAL));

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Thomas Fjellstrom
Member #476
June 2000
avatar

Yeah, thats more or less what I have.

ALLEGRO_VERTEX_ELEMENT elements[] = {
    { ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, offsetof(CustomVertex, pos) },
    { ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(CustomVertex, txcoord) },
    { ALLEGRO_PRIM_USER_ATTR, ALLEGRO_PRIM_FLOAT_1, offsetof(CustomVertex, tx_page) },
    { ALLEGRO_PRIM_COLOR_ATTR, ALLEGRO_PRIM_FLOAT_4, offsetof(CustomVertex, color) },
    { 0, 0, 0 }
  };

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Go to: