Skip to main content
gamedev.net
🔒 Locked

Multitexturing issues

Started by MARS_999 Aug 2, 2003 at 9:50 PM 18 replies 1.6k views
Original Post
MARS_999
MARS_999
Ok, I have just got my code up and running for multitexturing and now am having a problem with my textures going all to hell. I am not sure about this but its probably wrong and hopefully someone will tell me so! If I just render a quad with two textures using any two texture units, e.g. I have a Radeon 9700, unit7 and unit 6 or 0 and 1 I am fine as long as I only do those two and not the rest of my polygons. Now the rest of my polygons are using glTexCoord2f() along with the quad is using glMultiTexCoord2fARB(). Is this the problem? Are you not able to mix the two function calls? I have these in a compiled list. So my understanding also of the 8 texture units on my card is, I can apply 8 textures in one pass? So what if I need 100 textures in the scene? Also does glTexCoord2f() use texture unit 0 as a default? If so why can''t I just jump over it and use texture unit 1 and unit 2 along with my glTexCoor2f()? Thanks
MARS_999
MARS_999
I hope someone still answers my first question I posted. But I now have another one. I seem to have gotten the multitexturing to work now, but my textures that I have that are drawn on the same quad are not blending right? I have a blue and white checkerboard and a yellow box on another one. The areas where the textures are overlapping the color is green? Thanks
MazyNoc
MazyNoc
screenshots?

and what texture environment modes are you using on your texture units?
MARS_999
MARS_999
Sorry about that. I don''t have a webpage to put my screenshot on. The texture enviroment is GL_MODULATE. I have tried GL_REPLACE and that doesn''t work either? Could haveing a white background instead of black be causing a problem? Isnt'' multitexturing kind of like alpha testing and using alpha channel? Or is multitexturing going to blend the two images together and whatever color the first texture is and the 2nd is mixed together thats what you get? e.g. Yellow and blue = green?
Oh BTW doesn''t Radeon 9700Pro''s have 8 texture units?
MARS_999
MARS_999
Oh my GOD! Am I correct in saying multitexturing is expensive? I used two texture units on 132,000 polygons GL_TEXTURE0_ARB and GL_TEXTURE1_ARB and I went from 115fps to 44fps! and when I added in the thrid unit 24fps! Ouch!
MARS_999
MARS_999
I have a new headache now that is driving me nuts! I have multitexturing on for my water. The rest I am using glTexCoord2f(). My skybox is now textured with my water texture? I am using glDisable(GL_TEXTURE_2D) after I am done with multitexturing. Since I am using GL_TEXTURE0_ARB and GL_TEXTURE1_ARB I have to use glDisable(GL_TEXTURE_2D) 2x right???? Argh!
CodeMunkie
CodeMunkie
Yes, you have to call it twice. Any texture state changes you make affect only the currently active texture unit:

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture0);

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture1);

...//draw stuff

//GL_TEXTURE1_ARB is still the active unit
glDisable(GL_TEXTURE_2D);

glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);

As for the blending, the textures are applied in the reverse order that you bind them. So in this example, texture1 will be applied first and then texture0 will be blended (since you are using GL_MODULATE). That can make a difference in the final effect. I don''t know how fast it should be on a Radeon 9700, but it should be pretty fast.
"When you die, if you get a choice between going to regular heaven or pie heaven, choose pie heaven. It might be a trick, but if it's not, mmmmmmm, boy."
How to Ask Questions the Smart Way.
MARS_999
MARS_999
THanks codemunkie that fixed the skybox and water texturing issue I wasnt' calling glActiveTextureARB() and then glDisable(GL_TEXTURE_2D) I was just doing glDisable(GL_TEXTURE_2D) 2x. Thanks

I am about to give up on multitexturing! No matter what I do I always am running 20fps on my Radeon9700Pro!!!!! I have beaten my head against my desk for days. It makes no sense that multipass is 2x as fast as multitexturing! I am rendering 256x256 terrain using GL_TRIANGLE_STRIP and that is around 132,000 polygons. When I use multitexturing on my terrain it kills my performance???? I am only using 2 texture units.



//enable multitexturing here

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[GRASS]);

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[GRASS_DETAIL]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);
//I draw my terrain here

//using

glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
//for each vertex changing the texture coordinates as needed

//this is the same setup for my water texturing also

glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);



This is the function I use to setup multitexturing

void CTerrain::SetupMultiTexturing(void)
{
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)wglGetProcAddress("glMultiTexCoord2fARB");
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB");
glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)wglGetProcAddress("glClientActiveTextureARB");
}


these are global in the terrain.cpp file


//glext support

PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = NULL;
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;
PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL;

I call the setupmultitexturing function after I setup opengl. I know the texturing is working but its not working fast! My water looks good and has the detailed texturing moving around the water texture.

Any help in figuring out why multitexturing is slower than using multipass would be a great help. Thanks

[edited by - Mars_999 on August 7, 2003 2:20:51 PM]

[edited by - Mars_999 on August 7, 2003 2:21:07 PM]

[edited by - Mars_999 on August 7, 2003 2:23:31 PM]
Sander
Sander
Well, you are rendering 132,000 triangles in immediate mode :-) Well, at least you make 132,000 * 2 = 264,000 calls per frame to glMultiTexCoord2fARB(...). I think that''s hogging your system. This function is actually a function pointer (extension) and is thus a tiny little bit slower than a native glTexCoord2f(...) call.

I suggest you switch to using vertex buffers or VBO''s. That should give you a very high speed boost.

Sander Maréchal
[Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]


GSACP: GameDev Society Against Crap Posting
To join: Put these lines in your signature and don''t post crap!
MARS_999
MARS_999
Sander I am using display lists for my terrain. Yes I am looking into using VBO's once I can get some help?!!!! Is it possible to put this into a VBO?



struct Vertex
{
float vx;
float vy;
float vz;
float nx;
float ny;
float nz;
};

//or should I use a float array as one long array?


float terrain[calculate size];


From what I can tell using a struct isn't going to work well with VBO's? Looks like I am going to need a single array?
Update to my problem! I am unsure what this means but hopefully someone who know more than me can help me! I am using display lists to render my terrain, I took out my rendering code for the terrain with multitexturing and put the function in the rendering loop. I get the same fps! Does this mean my 9700 has hit its fill rate? That seems sad for only 132,000 polygons with multitexturing and using multitexturing on about another 20,000 for water. If I reduce my map size to 128x128 I jump to 68-70fps??

[edited by - Mars_999 on August 8, 2003 7:14:09 PM]
Sander
Sander
Run your program and then resize the window size. If the framerate goes up a lot, it''s a fillrate problem.

I haven''t had experience with VBO''s yet but normal vertex arrays work almost the same and should provide a speedup as well. For an example: Follow my signature to my site and grab the terrain.zip demo. It uses triangle strips, quadtree and multitexturing with vertex arrays, running nice with 40 fps on my PIII 600 with TNT2 board.

AFAIK you should be able to use your struct with regular vertex arrays. Just use the glDrawArraysInterleaved command. Personally i use separate arays though which I render with indices through glDrawElements.

Sander Maréchal
[Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]


GSACP: GameDev Society Against Crap Posting
To join: Put these lines in your signature and don''t post crap!
MARS_999
MARS_999
quote:
Original post by Sander
Run your program and then resize the window size. If the framerate goes up a lot, it''s a fillrate problem.

I haven''t had experience with VBO''s yet but normal vertex arrays work almost the same and should provide a speedup as well. For an example: Follow my signature to my site and grab the terrain.zip demo. It uses triangle strips, quadtree and multitexturing with vertex arrays, running nice with 40 fps on my PIII 600 with TNT2 board.

AFAIK you should be able to use your struct with regular vertex arrays. Just use the glDrawArraysInterleaved command. Personally i use separate arays though which I render with indices through glDrawElements.

Sander Maréchal
[Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]


GSACP: GameDev Society Against Crap Posting
To join: Put these lines in your signature and don''t post crap!



Thanks for the reply. I switched my resolutions from 800x600 to 1600x1200 and no difference in fps?
Sander
Sander
In that case, you are not fillrate limited. I also highly doubt you are geometry limited. 130.000 triangles in strips is about 130.000 * 1.5 = 195.000 vertices. 195.000 * 20 fps = 3.9 million vertices per second. The 9700 can take much more. I looked at ATI''s site but they don''t list it. In comparison though: The GeForce4 TI can do about 113 million vertices / second.

That leaves two other options:

- CPU limited: What are you doing besides rendering. Are you heavily updating your terrain every frame? Expensive math functions like sin(), cos() or sqrt()?

- bandwidth limited: Highly doubtfull. 195.000 vertices of 3 floats is about 2,34 mb. This should fit into your video memory (where display lists are normally stored). So no transfer needed. Only thing that can cause this is if you spend all the video memory on textures and the like and there''s no more room. In that case, data needs to be streamed from CPU to GPU memory every frame. If this is a lot, it can slow you down.

The only other option is that you do some very expensive opertion like reading the backbuffer or the color buffer.

Sander Maréchal
[Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]


GSACP: GameDev Society Against Crap Posting
To join: Put these lines in your signature and don''t post crap!
MARS_999
MARS_999
I am unsure until I get my texturing to look right with vertex arrays, but so far I have 2x my fps using them? Now when I reduced my screen resolution my fps go up. If you use glGenTextures() and glBindTextures() isn''t the texture data supposed to be stored in VRAM? If not how do I get the textures to be stored in VRAM only? I am seeing 70meg in Task Manager and KNOW their is no way I have 70megs of data. I do have 32megs of textures though.
Sander
Sander
With 32 megs of textures it''s very likely that your display lists (and some of the textures) cannot be stored on your card. Check how many memory is on your video card. Try to reduce it. Smaller textures for example. Or switch of mipmapping if you can. Or simply less textures. Anything that is not in VRAM must be streamed to the GPU so you can be bandwidth limited.

OTOH, if you reduce resolution and the framerate goes up a lot (how much does it go up in your app?) then you''re fillrate limited. Try to reduce overdraw. Draw up-close objects first, further away objects later (z-buffer will cull). Or use occlusion culling.

Also, if you are *very* sure you don''t use 70 megs of ram then you are probabely leaking memory somewhere. Hunt it down!

Sander Maréchal
[Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]


GSACP: GameDev Society Against Crap Posting
To join: Put these lines in your signature and don''t post crap!
MARS_999
MARS_999
Well I doubt my videocard is running out of RAM it's a Radeon 9700Pro 128MB. I am not using to much new/delete only on my texture loading right now and I use a delete for each new. So that shouldn't be leaking. I don't do any culling I am rendering the whole scene each loop. I really don't want to cut corners to boost fps. Right now I am rendering a 256x256 map. I haven't added in my water yet so until then I am unsure of what the final FPS will be compared to display lists. Oh BTW the fps didn't ever go up when I turned down the resolution with display lists but with vertex arrays it goes up. Thanks

[edited by - Mars_999 on August 13, 2003 5:26:07 AM]
MARS_999
MARS_999
Now that I have vertex arrays up and running and can display one texture I am having issues displaying a detailed texture with it. I had no problems before using immediate mode.

void CTerrain::Draw(unsigned int *texture)
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
glEnable(GL_RESCALE_NORMAL);
glEnable(GL_TEXTURE_2D);

for(int z = 0; z < MAP_Z - 1; z++)
glDrawElements(GL_TRIANGLE_STRIP, MAP_X * 2, GL_UNSIGNED_INT, &indices[z * MAP_X * 2]);

glDisable(GL_TEXTURE_2D);
glDisable(GL_NORMALIZE);
glDisable(GL_LIGHT1);
glDisable(GL_LIGHTING);
}
//init textures here in a seperate function

glTexCoordPointer(2, GL_FLOAT, 0, tex_coord);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[GRASS]);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_TEXTURE_2D);

glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[GRASS_DETAIL]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);



now my terrain only shows up as a gray texture? Seems like the texture unit 1 is only called or for some reason now the blending isn''t correct? Thanks
Trienco
Trienco
its no surprise that only unit 1 is used if you disable unit 0.
f@dzhttp://festini.device-zero.de
MARS_999
MARS_999


//called in my init function

glVertexPointer(3, GL_FLOAT, 0, terrain);
glTexCoordPointer(2, GL_FLOAT, 0, tex_coord);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[GRASS]);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[GRASS_DETAIL]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);
//end of init function


void CTerrain::Draw(unsigned int *texture)
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
glEnable(GL_RESCALE_NORMAL);
glEnable(GL_TEXTURE_2D);

for(int z = 0; z < MAP_Z - 1; z++)
glDrawElements(GL_TRIANGLE_STRIP, MAP_X * 2, GL_UNSIGNED_INT, &indices[z * MAP_X * 2]);

glDisable(GL_TEXTURE_2D);
glDisable(GL_NORMALIZE);
glDisable(GL_LIGHT1);
glDisable(GL_LIGHTING);
}


There is the code. I am still getting gray detailed textures and no grass? Do I have to do anything with glActiveTextureARB even though I am using glClientActiveTextureARB???
Basiror
Basiror
can t you guys read the red book its available for free


clientactive.... is to specify the texcoord pointer and nothing else



http://www.8ung.at/basiror/theironcross.html

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.