Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » How to use the z-buffer?

This thread is locked; no one can reply to it. rss feed Print
How to use the z-buffer?
kovarex
Member #14,203
April 2012

Hello,
I just upgraded to new allegro, and I would like to use the z-buffer, so I can draw the isometric projection objects in any order I want (ordered by atlases).

I would expect the allegro to have function like al_draw_bitmap_with_z_buffer, that would just take one float defining the "height" of the bitmap, but I can't see anything like that there, only some al_clear_depth_buffer function, that I don't really understand.

The ex_depth_mask seems to be doing something far more complicated than this.

Could you advice me how to do this? It should be quite simple shouldn't it?

Edit: When I tried to set the option ALLEGRO_FLOAT_DEPTH, the render became 5 times slower

www.factorio.com - a factory building game.

Arthur Kalliokoski
Second in Command
February 2005
avatar

The z buffer is normally used to allow proper ordering in 3D scenes, and it's used by drawing with 3D vertices (x, y, z). You can still use isometric perspective, but you need to use a z component to make the z buffer work properly.

[EDIT]

I'd think it'd be easier to make a struct or class with two members, one is an int to the desired order in the hierarchy, and the other is a pointer to the object to be drawn. Then you'd simply sort these structs using the int as the key, and draw the items (in proper order in the list) via the pointers.

They all watch too much MSNBC... they get ideas.

Thomas Fjellstrom
Member #476
June 2000
avatar

I'd think it'd be easier to make a struct or class with two members, one is an int to the desired order in the hierarchy, and the other is a pointer to the object to be drawn. Then you'd simply sort these structs using the int as the key, and draw the items (in proper order in the list) via the pointers.

That doesn't work so well when you want to sort drawing by the atlas the item's sprites are contained in.

--
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

Arthur Kalliokoski
Second in Command
February 2005
avatar

Ok, so have the pointer point to a RECT struct with the texture coordinates.

They all watch too much MSNBC... they get ideas.

Thomas Fjellstrom
Member #476
June 2000
avatar

Ok, so have the pointer point to a RECT struct with the texture coordinates.

Now how do you handle depth? ;) if you're drawing in order of the item's atlas, things won't be layered properly (without a depth buffer or something).

--
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

Arthur Kalliokoski
Second in Command
February 2005
avatar

Now how do you handle depth? ;) if you're drawing in order of the item's atlas, things won't be layered properly (without a depth buffer or something).

I haven't used the A5 primitives, or the "A5" way of doing things, but with my OGL GUI I simply disable depth testing and whatever's drawn last overwrites anything that was there first.

They all watch too much MSNBC... they get ideas.

Thomas Fjellstrom
Member #476
June 2000
avatar

I haven't used the A5 primitives, or the "A5" way of doing things, but with my OGL GUI I simply disable depth testing and whatever's drawn last overwrites anything that was there first.

But you can't draw in FIFO order when you're not sorting by z-order. The sprites will be drawn in some order depending on which atlas they are in. In some cases there could be things drawn in the wrong order.

--
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

Arthur Kalliokoski
Second in Command
February 2005
avatar

The sprites will be drawn in some order depending on which atlas they are in.

You mean the A5 primitives draw all textures from one sheet before moving on to the next? Half the time using automatic stuff to "make it easy" works against you. (think 'Make Game' button here) I'm content with binding a texture when I need it, thank you very much.

They all watch too much MSNBC... they get ideas.

Thomas Fjellstrom
Member #476
June 2000
avatar

You mean the A5 primitives draw all textures from one sheet before moving on to the next?

No, but he is doing that. using an atlas can greatly speed up drawing.

--
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

kovarex
Member #14,203
April 2012

Yes, as I discussed somewhere else, the motivation to use z-buffer is to be able to draw isometric quickly when resources are divided in more atlases, in other words, to be able to switch to every atlas only once.

If I use z-buffer I don't have to order the drawing according to the projection (as I do now), but rather by it's atlas.

But, if the Z-BUFFER usage slows down the render 5 times or more as I experience, it hardly beats those savings.

www.factorio.com - a factory building game.

Thomas Fjellstrom
Member #476
June 2000
avatar

I'm not sure ALLEGRO_FLOAT_DEPTH is the right option? Might be better to not set that, or set it to false. I don't think you want a floating point depth buffer at all. Integer should be fine. The ALLEGRO_DEPTH_SIZE option should be what you want.

--
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

kovarex
Member #14,203
April 2012

Thanks for the advice.
I tried the integer depth, and the max I was able to set and start the application was 24 (found by trial and error).

If I use 4 bits for the game layers, I'm left with 20 bits to sort out the isometry, 2^20 = 1 048 576
If I want the resolution 2560X1600 to be playable I might end up with 4096000 pixels, this would leave me with 1 z-buffer value for 2X2 pixel area, it is good enough.

Now I just have to find out how to use the z-buffer :)

www.factorio.com - a factory building game.

Arthur Kalliokoski
Second in Command
February 2005
avatar

kovarex said:

If I want the resolution 2560X1600 to be playable I might end up with 4096000 pixels, this would leave me with 1 z-buffer value for 2X2 pixel area, it is good enough.

The 24 bits are the depth for each pixel, i.e. you can have 16 million different objects sorted per pixel. You still need to use a 3D vertex to specify the depth.

They all watch too much MSNBC... they get ideas.

kovarex
Member #14,203
April 2012

Yes, I understand, that 24 bits are for each pixel, but I if I want the object to overlap other objects correctly, they have to have different values, thats why I have to divide possible values.

I feel like I'm repeating all the time, I just still don't feel being understood, so I will ilustrate it with picture:

On the picture, the left side has bad drawing order, the right has good one, I need to achieve the result on the right even when I draw the top tree first.

I imagine the z-buffer as 2^24 layers and I can choose the layer to draw to, is it correct?

www.factorio.com - a factory building game.

Arthur Kalliokoski
Second in Command
February 2005
avatar

How do you know in the first place which one is further away? Just use the distance in the z component of your 3D vertex. You don't have to worry about "order" then. That's the purpose and proper usage of the z buffer.

They all watch too much MSNBC... they get ideas.

kovarex
Member #14,203
April 2012

Yes, that is what I'm trying to achive! I still have to worry about the order, as I order by atlasses to optimise speed.

So we finally agreed that what I want is correct, but I still don't know HOW, I don't see any vertex in allegro, I just need the simplest example possible for drawing two overlaping sprites in one order, but seing the result in the opposite, I can handle the rest.

www.factorio.com - a factory building game.

Elias
Member #358
May 2000

You need to use al_draw_prim to set the z value of what you are drawing.

Not sure you can get 2^24 layers. I believe the values are always normalized to 0...1 by opengl/directx. But all Allegro does is enable the opengl/direct render state. If someone figures out how it works we can add it to the documentation.

--
"Either help out or stop whining" - Evert

Arthur Kalliokoski
Second in Command
February 2005
avatar

I'm working on a little OpenGL example right now.

[EDIT]

Well I can't even get something other than a black screen, trying to do too many things for the first time all at once. I'm going back to my xlib stuff.

They all watch too much MSNBC... they get ideas.

l j
Member #10,584
January 2009
avatar

I'm wondering about the exact same thing.

I was also thinking about ordering by atlas and then let the GPU handle the z-ordering.

Arthur Kalliokoski
Second in Command
February 2005
avatar

I fiddled with it some more, it seems to work except the 32 separate textures aren't transparent (obscures quite a bit). You need to supply your own "DejaVuSans.ttf" or change the name on line 26. It's here.

Maybe somebody who knows what they're doing can fix it so the backgrounds of the bitmaps are transparent.

[EDIT]

OTOH, some of the more distant bitmaps seem to be transparent, look closely at the bluish '28'. I don't know why the nearest ones seem to be opaque.

{"name":"606105","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/5\/55e94ae2c4ca7e0a0270dc330915d7ba.png","w":800,"h":600,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/5\/55e94ae2c4ca7e0a0270dc330915d7ba"}606105

They all watch too much MSNBC... they get ideas.

Elias
Member #358
May 2000

If you can make it work with al-draw-prim and al-set-render-state instead of opengl calls we could maybe include it as another example. ex-depth-mask only uses the z buffer as a boolean mask so doesn't really show what you can use it for.

--
"Either help out or stop whining" - Evert

Arthur Kalliokoski
Second in Command
February 2005
avatar

I forgot that transparency needs to be sorted from most distant to nearest, which probably explains the opaqueness for some parts of the image. If that's the case, the OP is back to his original problem again, isn't he?

[EDIT]

Well that's not the problem either, I sorted structs with the x,y,z,texnum and it still showed artifacts either way the sort order went, although the 2000 numbers displayed in each image were quite different. It did still maintain 60 fps though.

[EDIT2]

I started a new program from scratch with a visible background and three sprites. unsorted_sprites.c shows what happens if you don't sort by depth, and sorted_sprites.c does it right.

I'd have to experiment quite a bit more to get al-draw-prim and al-set-render-state etc. working correctly.

They all watch too much MSNBC... they get ideas.

Go to: