Archived

This topic is now archived and is closed to further replies.

gwihlidal

How do you do multiple passes properly?

Recommended Posts

Hi everyone, Here''s my problem, right now my OpenGL landscape terrain (advanced version of a heightmap) is multitextured with 2 texture units, one for detail texture using texture matrix scaling (like how DigiBen does it on GameTutorials) and one for a precomputed shadow map based on the "Fast computation of terrain shadow maps" paper by Mircea Marghidanu I want the approach DigiBen uses for one large texture stretched overtop of the terrain, I had that on one of the texture units, but the shadowing took priority When I draw the landscape I currently specify the texture coordinates for both texture units with: glMultiTexCoord2fARB(GL_TEXTURE0_ARB, u, v); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, u, v); followed by the vertex I obviously need to render another texture pass for the large texture map, but how do I do it? I tried something like: Bind Shadow Texture Bind Detail Texture Render World() Bind Map Texture Render World() But that didn''t seem to work =/ Also, I had vertex arrays working, but I had to revert back to per vertex gl calls because I couldn''t figure out how to multitexture with it, I had a normals, vertices, and texture coordinate array all bound and everything and the world was drawing but only one texture would ever bind? Thanks in advance! Graham

Share this post


Link to post
Share on other sites
Here is some sample of my code, on how to use multitexturing with vertex arrays.

glEnableClientState(GL_VERTEX_ARRAY);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture_cache[ground_detail_text].texture_id);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2,GL_FLOAT,0,clouds_uv);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2,GL_FLOAT,0,array_uv_main);

Height Map Editor | Eternal Lands | Fast User Directory

Share this post


Link to post
Share on other sites
Awesome thank you for that, that solved one of my problems (and will give me back my huge performance gain again

Any idea how to do the extra pass I guess for the 3rd texture though?

Thanks,

Graham

Share this post


Link to post
Share on other sites
You add the 3rd texture the same as you add the second texture,
only that you use glClientActiveTextureARB(GL_TEXTURE2_ARB); instead of glClientActiveTextureARB(GL_TEXTURE1_ARB);
Of course, you might want to check first if the video card supports more than 1 (or 2) texture units. If it doesn''t, either print an error message, or do an extra pass.

Height Map Editor | Eternal Lands | Fast User Directory

Share this post


Link to post
Share on other sites
Ya, that''s what I was thinking, but that''s my question, how do I do the 2nd pass? I tried it but didn''t seem to want to work.

Btw, I get some nice results using your heightmap editor

http://studentweb.nait.ab.ca/cst1766/Exodus/Images/Screenshots/Landscape2.jpg

I''m still tweaking things but I LOVE how well the mountain peek coloring turned out

I''d love to get that 3rd texture mapped onto it though hehe

Thanks a lot!

~Graham

Share this post


Link to post
Share on other sites
I think the trouble you may be having is that all the fragments of your second pass are being killed by the depth test. What you need to make sure is that for the second pass (and any subsequent passes), you set the depth function to accept fragments that have already been drawn .

i.e. glDepthFunc(GL_EQUAL);

Something to note, I recall hearing that using GL_LEQUAL may perform better on ATI cards (can anyone confirm?).

As for using the multitexture functions, what you will need to do for the second pass is bind you 3rd texture to the first texture unit (GL_TEXTURE0_ARB), and disable the second texture unit (GL_TEXTURE1_ARB).

something like this...

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, yourThirdTextureIdGoesHere);
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);

then make sure you are supplying your texture coords to the GL_TEXTURE0_ARB target.

Hope that helps

EDIT - stoopid formatting errors

[edited by - Bad Monkey on April 28, 2003 9:47:57 PM]

Share this post


Link to post
Share on other sites
Thank you both for your help,

k, here''s the updated situation

I tried glDepthFunc(GL_EQUAL) just to try everything I could and everything disappeared, so I tried GL_LEQUAL and for some odd reason the 3rd texture actually appears now when I make the 2nd pass?! Anyone able to plz explain what was happening?

It all draws now, having some issues with all the blending and combines everything is either super dark or super bright but I guess I just have to try different parameters for each texture unit =/

Thanks a lot!

~Graham

Share this post


Link to post
Share on other sites
Yes, by default, the multitexturing thing is useful for lightmaps, you have to use an extension if you want to actually combine the colors nicely.
text_env_add is the extension, I guess (never used it, I use the multitexturings in my game only to make the clouds on the ground/objects).


Height Map Editor | Eternal Lands | Fast User Directory

Share this post


Link to post
Share on other sites
quote:
Original post by gwihlidal
Thank you both for your help,

k, here''s the updated situation

I tried glDepthFunc(GL_EQUAL) just to try everything I could and everything disappeared, so I tried GL_LEQUAL and for some odd reason the 3rd texture actually appears now when I make the 2nd pass?! Anyone able to plz explain what was happening?

It all draws now, having some issues with all the blending and combines everything is either super dark or super bright but I guess I just have to try different parameters for each texture unit =/

Thanks a lot!

~Graham




LEQUAL means less than OR equal to. You were more than likely just using GL_LESS, which means.. only if it''s less than. The problem with this, is when you draw your 2nd pass, it is equal, and NOT less than, so it would never draw. Now that it''s less than OR equal, it does draw because.. it is equal . When you set it to EQUAL only, the first pass never renders, because your z-buffer is cleared! So, the second pass never renders either. You could do LESS for the first pass, and EQUAL for the second (which is what he was getting at I beleive). I just use GL_LEQUAL and call it a day, because that works properly for any pass, and I don''t have to change that for any pass #.

Share this post


Link to post
Share on other sites
awesome, thank you all for your help, I understand completely what was happening now

gotta figure out this blending now In the screen you see the awesome bright white on the mountains but now it''s all lightened and more of a light grey hehe

Sigh, well at least this major part works now

And since I have to do this second rendering pass it will be just as easy to enable that other texture unit as well for the cloud textures on the ground, might as well since I have to do a second pass anyways

Thx,

Graham

Share this post


Link to post
Share on other sites
quote:
Original post by Raduprv
Bad Monkey, you don't need to worry about the Z buffer, if you use multitexturing for your passes.



Ah... actually i think you do mate Ready4Dis explained it well... I probably should have elaborated a bit further.



[edited by - Bad Monkey on April 30, 2003 6:07:53 AM]

Share this post


Link to post
Share on other sites