Deformable/destructible terrains used as texture

Started by lorcán, November 13, 2008, 20:40:05

Previous topic - Next topic

lorcán

Waaaaaw! Thank you very much, bobjob. I really appreciate your kind help and explanations!

I've just gone through your FBO demo and I understand what happens, thank you.

Quote1. Load all Main textures, keep a copy of them all unchanged.

Which textures precisely? The main scene and/or ... ?

Quote2. generate 2 FBO's with a new texture wrapped to each one, ill attach another example, but i think its best to understand the tutorial as well as go through the lwjgl version of it (the link from before).

Do you mean empty texture when saying new texture?

Quote3. before starting draw the main scene texture onto both of the FBOs (as these are the textures that will be manipulated during runtime).

We'll "edit" only one of the 2 FBOs, right?

Quote4. When manipulating the scene (again this wont make much sence till you go through the tutorial):
you would bind the first FBO.
a. "Cut out" Images would be drawn before the main scene, at a z = 1 (therefore closer to the viewer) with the color mask set to false.
b. the second FBO texture (copy of the scene) would be drawn at z = 0.
c. "stairs" would be drawn after the scene but still with a z = 1 (same 'z' as "cut out" images).

a. Do you mean :
#1 : drawing on a single QUAD (altering a single texture during runtime)
or
#2 : using several QUADS with different textures for each imprint/impact (added one after the other)

I'd prefer method #1 since method #2 requires a lot of processing for almost nothing (storing every imprint...), doesn't it? What would you advise me to do?

Same remarks and questions go for point (b)
#1 : drawing on a single QUAD (altering a single texture during runtime)
or
#2 : using several QUADS with different textures for step of the stears (added one after the other)

Quotethen you would draw the first FBO onto the second. (this is done because if you draw the scene onto the new scene, Im guessing there will be errors, its good to have the "temp" copy refering to step (b)).

I can't understand yet why it's necessary drawing the 1st FBO on the second FBO (=unchanged scene texture). Maybe I'll realize later what would happen without using the 2nd FBO. Maybe you mean making FBO#2 an exact copy of FBO#1. I'm not sure I understand what you really mean here.

QuoteNote: The way the stairs are drawn can be different, you could disable depthTesting, and not worry about its z value, but it might be confusing tryn to track weather on not depth testing is currently enabled, so I suggest just do it the way i explained for starters, you can always tweek the code later.

OK

QuoteAs for collision detection, Im guessing that will be per pixel, so you would need to get the value of each indivual pixel you want to test at a time, and check if its alpha value is = 0, or if you want you could make it if alpha < 0.25f (as that should be close enough). The 0.25f would also look cool, cuz you could have them going through semi-transperant tunnels and not getting blocked :D

For collision detection and so on, I think I should use a 2-dimensions array as told earlier because each pixel has several properties (not only transparent or not, but also destructible or not, maybe destructible in only one direction (left to right, right to left, from top to bottom, and so on) maybe a terrain area on which lemmings drop through, ....). Handling collision using alpha values is not enough, so I have to handle collision in a separate array, regardless of graphics. However using alpha values like 0.25f for tunnels is a great idea, thank you! ;)

QuoteYou have actually tempted me to make my own online turn bassed Worms game, as a side project.

Great!!! :D

I do think the use of FBO is a really good idea since it would also allow me to upscale/downscale a level depending on display resolution without having to worry about resolution when drawing the scene with lemmings, handling collision detection and so on. To do this I'd also have to draw the other sprites into the FBO? What do you think about this feature?

Thank you very much Bobjob. You're an excellent teacher ;)

bobjob

dude do yo use MSN?
maybe just add me on that and I can clear up the points in order.

with non destructable pixels, you could probably seperate this and make it a whole different texture.

lorcán

ok.

I also (rather) use gtalk (google talk). And you?

I have to leave now (going to work)

Thanks!

wolf_m

Quote from: lorcán on November 20, 2008, 09:29:15
For collision detection and so on, I think I should use a 2-dimensions array as told earlier because each pixel has several properties (not only transparent or not, but also destructible or not, maybe destructible in only one direction (left to right, right to left, from top to bottom, and so on) maybe a terrain area on which lemmings drop through, ....). Handling collision using alpha values is not enough, so I have to handle collision in a separate array, regardless of graphics. However using alpha values like 0.25f for tunnels is a great idea, thank you! ;)
As I said from the start, I'd do those things with generated textures. They're basically 2-dimensions arrays anyway, with 4D vectors in each cell in the RGBA case (Range [0f-1f]). So you can write different properties into different channels.
For example, you'd write a depth test of characters only to a monochrome texture and XOR that with the stuff you could collide with, there's your collision test result. No iteration through boolean[][] with test+write each step or whatever. That's just one way to do it.

It's really smart to do it with textures as data structures because you can then use those textures directly for painting stuff, you inherit proper dimensions if you set 'em up right, it's trivial to check and change values in subsets and you're doing native stuff then, you can use GLSL code to manipulate them without having to do magic or shovel data over to your accelerator per frame, OpenGL is optimized for them ..

Anyway, if you're thinking about making something naiive like
boolean[][] collides = new boolean[width][height];
foreach cell: init;
logic{
       handleInput;
       foreach cell of collides: checkCollisions;
       solveCollisions;
       updateGL;
}

.. then you're going to run into problems. Going through a few million values every frame is not a good idea. Reducing the number of values to check is easy, yes, but XORing two monochrome textures (instead of running through an array) and then solving collisions with the result is so cheap that it makes more sense in my book.

Again, don't want to detract from what you two guys are coming up with, maybe you've got it all figured out already. Just wanted to throw my 2 cents in there.

bobjob

If you dont have msn maybe just go on the IRC channel

lorcán

> bobjob: I've just created a new msn account and you're added to my contact list :)

> wolf_m: thank you for your contribution :) I take good note of your advice and I'll try it out. It's not sure yet of every method I'll use in the game. I must perform lots of tests, comparing stuff, ... and learn quite a lot of things! ;)

lorcán

> bobjob : certainly due to the time difference (gmt+1 here) it appears not to be easy to talk to each other using MSN  :P When are you usually connected? (using your local time, I think gmt+11). You can also use the address used by my MSN account in order to send me emails (lorcan....[at]gmail.com)

Ciardhubh

Quote from: lorcán on November 18, 2008, 16:41:38
> Ciardhubh :
QuoteRemoving destroyed terrain could be done with Alpha Testing (e.g. glAlphaFunc with GL_GREATER = 0.5) and a texture that is transparent in the area of the explosion (disable blending, write over background)
Do you mean using an additional texture with only "holes" over the current scene texture? Could you also tell me and explain me the opengl syntax to use in your example?

My idea was to use an additional texture for a single explosion. This texture would have the shape an explosion cuts out, represented by pixels with alpha set to 0. The rest of the texture has alpha = 1. Colour is irrelevant. With alpha testing enabled, you could only write transparent pixels where the area of the explosion is (alpha = 0) and thus cut out the shape of an explosion from the scenery. Each explosion would punch a hole into the scenery that stays there.


  • set glAlphaFunc to GL_LESS, 0.5f (only pixels with alpha < 0.5 are drawn)
  • disable GL_BLEND (so that the transparent pixels aren't blended with existing pixels but instead overwrite existing pixels)
  • enable GL_ALPHA_TEST
  • write explosion cut-out texture over scenery, thus overwriting the explosion area with fully transparent pixels
  • disable GL_ALPHA_TEST
  • reenable GL_BLEND (if needed)

glAlphaFunc operates on all pixel write operations, according to the OpenGL spec. I haven't yet tried this myself so it's an untested idea.

lorcán

Thank you for your help.

How would you draw new graphics (stairs being built by lemmings) to the scene where lemmings previously destroyed this terrain area?  (Stairs are parts of the scene) Please note that terrain removing and stairs building are two operations which can be repeated a number of times at the same position :

1) a first lemming dig in the soil
2) a second lemming builds stairs where the 1st lemming has removed the soil
3) a 3rd lemming dig again at the same position (removing parts of the stairs)
4) a 4th lemming builds new stairs again at the same position
5) and so on...

Thanks!

Quote from: Ciardhubh on December 01, 2008, 15:44:36
Quote from: lorcán on November 18, 2008, 16:41:38
> Ciardhubh :
QuoteRemoving destroyed terrain could be done with Alpha Testing (e.g. glAlphaFunc with GL_GREATER = 0.5) and a texture that is transparent in the area of the explosion (disable blending, write over background)
Do you mean using an additional texture with only "holes" over the current scene texture? Could you also tell me and explain me the opengl syntax to use in your example?

My idea was to use an additional texture for a single explosion. This texture would have the shape an explosion cuts out, represented by pixels with alpha set to 0. The rest of the texture has alpha = 1. Colour is irrelevant. With alpha testing enabled, you could only write transparent pixels where the area of the explosion is (alpha = 0) and thus cut out the shape of an explosion from the scenery. Each explosion would punch a hole into the scenery that stays there.


  • set glAlphaFunc to GL_LESS, 0.5f (only pixels with alpha < 0.5 are drawn)
  • disable GL_BLEND (so that the transparent pixels aren't blended with existing pixels but instead overwrite existing pixels)
  • enable GL_ALPHA_TEST
  • write explosion cut-out texture over scenery, thus overwriting the explosion area with fully transparent pixels
  • disable GL_ALPHA_TEST
  • reenable GL_BLEND (if needed)

glAlphaFunc operates on all pixel write operations, according to the OpenGL spec. I haven't yet tried this myself so it's an untested idea.

Ciardhubh

Quote from: lorcán on December 04, 2008, 14:12:34
How would you draw new graphics (stairs being built by lemmings) to the scene where lemmings previously destroyed this terrain area?  (Stairs are parts of the scene) Please note that terrain removing and stairs building are two operations which can be repeated a number of times at the same position :

I'd only use a single deformable-scenery texture that initially contains the pristine level. Afterwards this texture (VBO, whatever) gets directly modified with any deforming action. Remove parts with alpha testing. For shovel digging you could use a series of cut-out textures each following the path of the shovel. Add stairs by pasting a step texture (normally, no alpha testing) onto the scenery. One texture that continuously gets modified; no discrimination between explosions, original texture, stairs etc.

bobjob

iv been helping him. Here is a copy of what i emailed him.

The problem with lemmings is, there are conditional pixels, like only remove if lemming is coming from the left/right.

So i sent him a layered example.

It changes each layer, and then adds all layer images to a single depth on the scene image.

its possible to do alpha checks, or depth checks at this point on the entire scene in 1 pass.

Keys:
1,2,3 remove from layer
q,w,e add to layer

lorcán

Hi there.

Sorry for this so late answer. I've been busy lately. Well I'm always busy and I try to find some little time for my numerous hobbies :-p but I often come here and read your posts ;)

After much hesitation, research, ... I realized that I can't use a FBO to handle the whole scene and its dynamic changes due to its large size :(. As you certainly know FBOs, like textures, have a maximum size depending on the current graphics device (usually 4096x4096). For compatibility reasons (with the old games) I intend to use 6400x640 pixels fixed scene... This is more than the usual max texture size... So I'm thinking about splitting this 6400x640px deformable scene into 50 x 5 sub textures (128x128px each) and I would update only the textures corresponding to the altered areas (holes and steps), in real time using glTexSubImage2D.

For performance reasons I might use temp copies of these areas as Image's instead of reading pixels from textures (since reading pixels inormation from textures takes lots of time). I don't know yet...

What do you think about this?

Thanks ;)

bobjob

http://www.mojang.com/notch/j4k2k6/miners4k/

Here is a 4k game that is very similar to the original lemmings, will need to be improved alot to be what you'd like.

lorcán

Quote from: bobjob on May 01, 2009, 02:16:36
http://www.mojang.com/notch/j4k2k6/miners4k/

Here is a 4k game that is very similar to the original lemmings, will need to be improved alot to be what you'd like.

Yep I remember this mini game. You told me about this 4k "remake" in one of our emails ;)

Well I know all the main (technical) mechanics of the original lemmings so this is not a problem. If I had to do my remake in Java2D it might be finished yet but due to some of the Java2D limitations and constraints (less flowing movements, FSEM not always compatible, speed issues,...) I wanted to do it using LWJGL. The real problem is my lack of knowledge of OpenGL. For instance I didn't know that FBOs have the size restrictions like textures even if it's quite logical :)

What do you think about my idea of splitting the main game deformable scene into "tiles"? Each tiles would be a single texture I'll update on the fly when needed (without displaying those out from the screen)... Thinking of this, I wonder if will meet another problem like a max number of textures? Knowing that the deformable scene would be split into 250 textures (5x50 textures measuring 128x128 px), considering the number of textures used for the lemmings sprites animations (the number of lemmings is not a proble since the same textures are used for identical lemmings) and for the objects sprites animations (traps, doors,...) + the GUI elements, do you think I could store all these textures (even if they're small)?

What do you think about these ideas? :P

bobjob

yeah, your idea is a good approach. If you break the map into tiles, its also may be a good at rendering to the scene as you wont need to draw all tiles (only the visible part).

So theres probably 2 approaches you could take.
1. Manually draw changed pixels, 1 at a time on-screen then grab the new image. Also means you will have to draw offscreen objects to the screen in order to edit them - can be buggy as copying pixels off the screen back buffer is controlled by the OS and when the program looses focus, all hell can break loose, (can be fixed with FBO's).
2. Manually edit a byteBuffer, then generate new textures each render, for the visible map.

I would recommend the second approach as you dont know much about openGL. Also maybe spend some time looking through source code for texture loading. Like 1 important note is that there are 3 bytes for each pixel if the texture is going to be RGB. which means for each pixel you will need to minipulate all 3 bytes.