Advertisement

Decals

Started by January 15, 2002 05:25 PM
23 comments, last by Locke 23 years, 1 month ago
Would anyone have any ideas as to apply decals. ie, have one texture on a face, but then, have another texture, with a trnslucent border, be drawn on the same face, so you can see the textures ''on top'' of each other. Any ideas would be greatly appreciated, Brendan ''Locke'' Hennessy
Brendan ''Locke'' Hennessy"I heard life sucks, so that''s why I don''t have one"
I''ve never tried to do decals before, but that should work if you use the depth test as less than or equls to (not just less than). Then aslong as you drew the decal after the surface, it would show.



Beer - the love catalyst
good ol'' homepage
Beer - the love catalystgood ol' homepage
Advertisement
Multitexturing is the way to go.
But multitexturing is a bit complex to implement, and some graphics card do not support it (very rare not to support it nowadays though).


Otherwise, you can emulate with by drawing the second face with depth testing enabled to GL_EQUAL :
  GLenum depth_func;GLuint texture_back = ...; // set here your texture id for the overlapped textureGLuint texture_front = ...; // set here you texture id for the overlapping texture. may have an alpha channelglGetIntegerv(GL_DEPTH_FUNC, &depth_func); // get depth function. probably GL_LESS or GL_LEQUAL// draw the polygons a first timeglBindTexture(GL_TEXTURE_2D, texture_back); // draw those polygons with the "back" texture.drawMyPolygons();glDepthFunc(GL_EQUAL); // ask the depth buffer to accept only the polygons which depth equals the depth of already drawn polygons.// draw the polygons a second timeglBindTexture(GL_TEXTURE_2D, texture_front); // draw those polygons with the "front" texture.drawMyPolygons();glDepthFunc(depth_func); // restore the depth function back to the one that was activated before  

Needless to say, texture mapping must be enabled using glEnable(GL_TEXTURE_2D); (if your texture has 2 dimensions of course).

Note that your 2 textures may not use the same texture coordinates. In that case, you have to change the code a little bit. (Not very complex, "I''ll let it as an exercise for the reader" )

It is very important that the 2 sets of polygons (1 set for the back, 1 set for the front) have exactly the same coordinates, or else the depth test will fail and result in undesirable effects.


That''s just an example to see how decal works.
But for faster implementations (say, if a lot of polygons use decals), I recommend using multitexturing.
Thanks heaps, I reckon I''ll have to look into multitexturing, but, I think I get what you''re saying, thanks =)
Brendan ''Locke'' Hennessy"I heard life sucks, so that''s why I don''t have one"
Hi,
I''m new to ogl (playing with NeHe''s firsts tuts) and can''t really figure it out but i guess send polys more than once in the pipeline is not a really efective way to work with decals.

I''ve never used textures but I think copy/paste and blend texs in video memory is fast so why not :

- calculate or aproximate decals coords on the back texture
- make a copy of the back texture in video memory
- copy the decal(s) on the copy of the back tex (with a transparency color if needed)
- draw the poly with the new tex (back tex + decals)
- destroy the new tex because video memory''s not infinite

now the things i don''t know :
- can we do that with ogl?
- is it an efective way of working with decals?
Salut Melgo,
Et un français de plus, un

Your technique is very clever, but may not be applied in "the general case".
If the two textures are always drawn together, you can do it and it will be faster, because obviously simpletexturing is the fastest way if possible.

But the textures might not be used together only. The back "texture" may be used somewhere else, and probably the "decal" texture too. In that case, you could still do your method, but you may not free the "back" and "decal" textures, and so it would overload the memory.

There''s also another problem if you want to make the decal "float" over the back texture (for instance, a shadow over a surface) : as your method is static, it would not be possible unless you compute your texture again at each frame (very expensive).


Also, to answer your questions:

> can we do that with ogl?
Yes we can. And it can be very fast if you do it well.

> is it an efective way of working with decals?
It is the most effective way, but it requires some conditions, as shown above.


Generally, if your method is used, it may not be done by OpenGL.
The texture could be computed by the software which saved the picture.
In most games, that kind of preprocessing is rarely done on-the-fly (eg while running the game) because it slows down the program (even if it''s done in the starting : it slows down the starting which is undesirable too).
Advertisement
NO NO NO!

Assuming you really are talking about decalling, rather than multitexturing, there is an extention which helps you out here:-

glPolygonoffset()

Look at:-

http://www.opengl.org/developers/faqs/technical/polygonoffset.htm

http://www.google.com/search?hl=en&q=glpolygonoffset

I have seen a demo using this somewhere - I'm sure if you dig deeply enough you'll find it!

Edited by - Shag on January 16, 2002 2:04:45 PM
Well hem, sorry, but I would not recommend using polygon offset.
I know it works quite well, but it's specialized for other cases IMO.

In that case, polygon offset is probably slower and surely give some artefacts, even though those artefacts are rarely "visible".

However, if your polygons where to apply the textures are be a little bit different (I mean, they don't have exactly the same vertex coordinates), you'll need polygon offset ; because the depth test would fail (with GL_EQUAL) and without polygon offset you could not guarantee the polygons to overlap perfectly.

Edited by - vincoof on January 16, 2002 2:41:45 PM
Nope, polygon offset is *exactly* for that case. Furthermore, it won''t make *any* speed difference, because it''s implemented in hardware in the OpenGL pipeline.

It is used to *remove* artifacts you get from the zbuffer, if your 2 decals do not match 100% accurate, because they do not share the same vertices. Polygon offsets now simply applies an offset to the z value written in the buffer, to avoid z-fighting artifacts. It works very well.

And I wouldn''t use multitexturing for decals. It''s a waste of texture units. And not all decal effects are possible using multitexturing. Imagine a big wall (with a repeated texture on it) with several different decals applied at different positions on the wall. The whole thing is lit with a lightmap.

Now, not using multitexturing you do the following: Draw the wall with the wall texture in Unit0, the lightmap in Unit1. You have a perfectly lit wall in a single pass. Now render the small decals with polygon offset and the decal texture in Unit0 (lightmap is still in Unit1). Perfectly lit decals, without any artifacts.

You could do the wall/decal drawing with multitexturing, but that would require splitting the geometry. And even with a single decal on a single wall: Never forget, that if you use up all your texture units for things like decals, then you won''t have them, if you want to light your scene (or apply effects such as bumpmaps), and then you are in trouble. You''d have to do several lighting passes, and that kills framerate. Texture units are a precious resource, don''t waste them.

I definately agree for the multitexturing thingy. Moreover, I could not have explained better myself

But IMO, if texture units are not a problem (say, if there''s no lightmap, no bump) I think multitexturing remains the best choice.
The thing is, I don''t know what Locke looks for.

About polygon offset, I agree that it''s useful when the surfaces do not perfectly match, but I disagree about the non-existence of the artefacts.
Polygon offset is by definition an artefact.
But as I alreay wrote, I admit those artefacts are rarely "visible".

This topic is closed to new replies.

Advertisement