Creating grass... transparent textures and texture position?

Started by
26 comments, last by Thaumaturge 15 years, 11 months ago
Hi! I need help with one more thing... I'm supposed to create a simple grass using the method described here: http://http.developer.nvidia.com/GPUGems/gpugems_ch07.html I don't need to make it animated, though. I started with making one grass cell, but I have two problems with it... first, I'm not sure how to position the texture on each quad. Right now it seems that the texture is not only positioned differently on each quad, but also it's moving in strange ways, even though there are no animations connected with the grass cell... the only animations in the scene are a rotating cube next to it, and a moving light. Another problem is with the transparency. Right now my texture is a 200 x 100 PNG one with a green text on transparent background. (it's just temporary, not the final one for the grass ;) ) Here's what I do to make the texture appear on the grass cell: The grass cell object has a GLuint _grasstexture private field, which is set in the constructor... I'm calling the constructor with one of the parameters as bindTexture(QImage("/home/piotrek/qt/projekt/bin/meep.png")) and I assign it to the _grasstexture field. In the render() method of the grass object, I do this first: glBindTexture(GL_TEXTURE_2D, _grassTexture); and rendering one quad looks like this: glBegin(GL_QUADS); glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.0f); glVertex3f(1.0f, 1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 0.0f); glEnd(); Here's the grass cell I get (well, it's not grass yet, but I want it to be grass eventually :D ) http://i11.photobucket.com/albums/a156/Miracle86/transptexture.png When I don't use a texture image, but simply set the quad color to semitransparent, it's working well. As you can see, the places which should be transparent are gray, and the texture is positioned in a really weird way... how can I fix it?
Advertisement
First of all, I don't see any setting of texture coordinates in your quad code. Much as with vertices and normals, this has an OpenGL call of its own: glTexCoord.

Secondly, are you sure that you have blending enabled?

MWAHAHAHAHAHAHA!!!

My Twitter Account: @EbornIan

Hi Thaumaturge!

Thanks for the reply...yes, I have blending enabled... at least I think so. I have this in initializeGL():

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

and when I use a semitransparent RGBA color instead of texture, then it's working well.

As for texture coordinates, I tried using glTexCoord, but it didn't change anything. But I've just thought about something else... I have shadow mapping in that program, and shadow mapping uses GL_TEXTURE_2D. Since the texture on the "grass" is changing when the light is moving, then maybe the texture is somehow projected on the surface from the light in the same way as the shadow map is?
Ah do you have a 32bit texture with alpha channel used for alpha blending setup? Also unless you have a GL2.0 card 200x100 textures aren't going to work unless you called gluBuild2DMipmaps(). So resize to 256x128 and try again.
Yes, it's a PNG file with a transparent background. The texture appears when I render it, except that it's gray where it should be transparent. My video card is GeForce 8400, so I think it supports OpenGL 2.0 :)
Quote:Originally posted by Starshine_
Hi Thaumaturge!

Thanks for the reply...


Hello, and my pleasure. ^_^

Quote:Originally posted by Starshine_
yes, I have blending enabled... at least I think so. I have this in initializeGL():

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


Good good - that looks as though it should be okay.

Quote:Originally posted by Starshine_
As for texture coordinates, I tried using glTexCoord, but it didn't change anything.


Fair enough - although I do think that, unless they're set elsewhere (which I don't think should work with the immediate-mode calls that you seem to be using), you should be setting them within your quad generation code. I would recommend putting in texture coordinates and leaving them in while you look elsewhere; you can always remove experimentally them once you have the texturing working, I imagine.

Quote:Originally posted by Starshine_
I have shadow mapping in that program, and shadow mapping uses GL_TEXTURE_2D. Since the texture on the "grass" is changing when the light is moving, then maybe the texture is somehow projected on the surface from the light in the same way as the shadow map is?


Hmm... This is plausible. Are you perhaps altering the texture matrix for your shadow mapping (as I would imagine that you are), and not re-loading the original matrix afterwards?

MWAHAHAHAHAHAHA!!!

My Twitter Account: @EbornIan

Hi! The main problem I have with glTexCoord is that I'm not exactly sure how to use it, especially since it has only two parameters... when I think about positioning a texture on a 2D surface, I'm not really sure how it can be done without four parameters... the coordinates of the top-left point, and the bottom-right point, relative to the quad...

As for the texture, here's how it's done in my program... I did shadow mapping in exactly the same way as in this tutorial: http://www.paulsprojects.net/tutorials/smt/smt.html

The only differences are that I'm using QT which makes some things simpler, and I have my own scene that's different than the scene in the tutorial... so the GL_TEXTURE_2D is used for the shadow mapping in the whole program. Before rendering the third pass, there are a few glTexGeni functions called, which apparently define how the GL_TEXTURE_2D is projected on the objects in the scene... is there some way to make OpenGL kind of forget all that before rendering the grass cell, and then restore it? Or maybe it can be fixed in some different way?
Warning: long explanation ahead. ;)

You use glTexCoord in much the same way that you might use glVertex, to specify coordinates in a space, in this case the space of your texture (commonly a two dimensional space, of course), as opposed to the space of your model. While the vertex coordinates specify where the object's vertices are in world-space, the texture coordinates, as I recall, specify where it is in texture space.

So, for example, take the following quad in world-space:

 (-1, 1, 0)             (1, 1, 0)           o-----------o           |           |    y           |           |    |  z           |           |    | /           |           |    |/___ x           o-----------o (-1, -1, 0)             (1, -1, 0)


Similarly, take the following "image". Note that in an image, we also have coordinates in a space:
     (0, 0)             (1, 0)           o-----------o     ____ x           |    __     |    |           |   /  \    |    |           |  /____\   |    |           | /      \  |    y           o-----------o     (0, 1)             (1, 1)


Just as we tell OpenGL where the above quad was in world-space, we can tell OpenGL where it lies in the space of the image:

glBegin(GL_QUADS);glTexCoord2f(0.0, 0.0);glVertex3f(-1.0, 1.0, 0.0);glTexCoord2f(0.0, 1.0);glVertex3f(-1.0, -1.0, 0.0);glTexCoord2f(1.0, 1.0);glVertex3f(1.0, -1.0, 0.0);glTexCoord2f(1.0, 0.0);glVertex3f(1.0, 1.0, 0.0);glEnd();


Note that if you have a vertex that should lie somewhere within the image, then its coordinates would probably be appropriate values below one and above zero. For example, if we instead had two quads which, between the two, should be "covered" by a single texture, with the split occurring vertically in the middle of the image, then you might have something like this:

glBegin(GL_QUADS);//Quad 1glTexCoord2f(0.0, 0.0);glVertex3f(-1.0, 1.0, 0.0);glTexCoord2f(0.0, 1.0);glVertex3f(-1.0, -1.0, 0.0);glTexCoord2f(0.5, 1.0);glVertex3f(0.0, -1.0, 0.0);glTexCoord2f(0.5, 0.0);glVertex3f(0.0, 1.0, 0.0);//Quad 2glTexCoord2f(0.5, 0.0);glVertex3f(0.0, 1.0, 0.0);glTexCoord2f(0.5, 1.0);glVertex3f(0.0, -1.0, 0.0);glTexCoord2f(1.0, 1.0);glVertex3f(1.0, -1.0, 0.0);glTexCoord2f(1.0, 0.0);glVertex3f(1.0, 1.0, 0.0);glEnd();


The first quad should run from one side to the centre of the texture, and the second quad from the centre to the opposite side.

Note the pairing of glVertex and glTexCoord calls. If I recall correctly, the glTexCoord call applies to any vertices declared after it (presuming that another change doesn't supercede it, of course).

I think that I'm correct in my axes in the image example.

NB: If I recall correctly, you are not, technically, "applying the image to the object", as I'm pretty sure that I've heard it described. While one can think of it this way, especially for situations involving 2D textures, I believe that what is technically happening is that you are specifying where the vertices of the object lie in the texture's space.

I hope that I've explained all of that clearly - if not, please let me know, and I'll try to clarify what I mean, most probably with a proper (albeit simple) picture.

As to the shadow mapping tutorial that you linked to, I didn't see any alterations to the texture matrix offhand, but then I'm not familiar with the texture generation calls that they use; I imagine that they don't change the texture matrix, however.

That said, since they would seem to be generating texture coordinates, it could well be that this is carrying over to your quads. I notice that texture generation seems to be enabled there; I suspect that it might help to disable that once you're done with it.

[Edited by - Thaumaturge on May 14, 2008 10:22:10 AM]

MWAHAHAHAHAHAHA!!!

My Twitter Account: @EbornIan

Thank you for the long explanation! It's working, and the texture is positioned correctly now :)

I still have a problem with transparency, though :( There's still gray in the place where the PNG with the image is transparent... here's a screenshot: http://i11.photobucket.com/albums/a156/Miracle86/notransparency.png

(the PNG with the texture is just a green MEEP on a transparent background, so everything except transparency is displayed correctly)

The only thing I need now to make my grass work is to find out how to do transparency... maybe I need to add the alpha channel to the texture separately somehow? But according to QT documentation, the bindTexture function uses the GL_RGBA format by default, which already includes the alpha channel...


edit: I did it! :D it's working... well, almost, but I'm happy with it. :) I had to disable GL_DEPTH_TEST before rendering the grass, and then enable it again. Now the transparency is working almost perfectly well. :) The transparent isn't perfectly transparent, but slightly white... but it's much better than what it was before. :) There's no shadow now, though.

edit2: without depth testing, the grass is visible even when it's behind other objects... :(

[Edited by - Starshine_ on May 14, 2008 12:44:28 PM]
It's my pleasure - I'm really glad to hear that you've advanced so far. ^_^

Quote:Originally posted by Starshine_
edit2: without depth testing, the grass is visible even when it's behind other objects... :(


Indeed, I'm afraid that, for objects rendered with normal transparency (as opposed to, say, additive transparency), I'm pretty sure that sorting by depth is called for. You then draw from most distant to least distant to get what should be the correct result.

As to the slight whiteness, I would suggest checking in your image editor that those regions are entirely transparent, as opposed to being, say, 90% transparent. (Note: I don't recommend doing this by inspection; instead, I recommend examining the numerical representation of the colour in your editor (the means to this might vary by editor - I should be able to help you if you happen to use the GIMP).)

As to the lack of shadow, I imagine that shadow mapping is intended to be a two- (or more) pass system, meaning that you will probably be rendering your grass twice. I haven't programmed a shadow system of this sort myself that I recall, so I'm afraid that I don't know what the appropriate method of limiting the shadow to the non-transparent regions is; technically, it sounds as though you want some sort of multiplicative blending, but the stencil buffer might work.

[edit] Finally, your results including grey fill previously prompt me to ask: when are you rendering your grass? It should be rendered after your fully-opaque geometry, I believe.

MWAHAHAHAHAHAHA!!!

My Twitter Account: @EbornIan

This topic is closed to new replies.

Advertisement