View Full Version : gluScaleImage and 9 fps.
LongJumper
2003.10.16, 09:26 PM
I'm working on a little terrain engine. I had it set up where it loaded a targa image in as a heightfield, rendered it using a repeated texture that looked like grass.
Well, now I set it up(modifying some code I found on the internet) so that it takes a 256x256 image and scales it across the entire terrain. Looks nifty, problem is what was once 60 fps is now 9. That is really bad....
Now, the code looks somewhat like this.
glNewList(terrainList,GL_COMPILE);
glPushMatrix();
glFrontFace(GL_CCW);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MO DULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glEnable(GL_TEXTURE_2D);
for(int z = 0;z<mapZ-1;z++)
{
for(int x = 0;x<mapX-1;x++)
{
LoadTile(z,x);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0.0, 1.0); glVertex3f(terrain[x][z+1][0],terrain[x][z+1][1],terrain[x][z+1][2]);
glTexCoord2f(0.0, 0.0); glVertex3f(terrain[x][z][0],terrain[x][z][1],terrain[x][z][2]);
glTexCoord2f(1.0, 1.0); glVertex3f(terrain[x+1][z+1][0],terrain[x+1][z+1][1],terrain[x+1][z+1][2]);
glTexCoord2f(1.0, 0.0); glVertex3f(terrain[x+1][z][0],terrain[x+1][z][1],terrain[x+1][z][2]);
glEnd();
}
}
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glPopMatrix();
glEndList();
When I move glBegin(GL_TRIANGLE_STRIP) and glEnd() outside of the double loop, it doesn't work, it just repeats a small portion of the picture.
Here is LoadTile:
void XTerrain::LoadTile(int row, int col)
{
int border = 1; //switch to 0 for no border
int level, levelWidth, levelHeight;
levelWidth = texWidthLevel0;
levelHeight = texHeightLevel0;
for (level=0; level<=maxTextureLevel; ++level)
{
int tileWidth = levelWidth / texWidthTiles;
int tileHeight = levelHeight / texHeightTiles;
int skipPixels = col * tileWidth + (1 - border);
int skipRows = row * tileHeight + (1 - border);
glPixelStorei(GL_UNPACK_ROW_LENGTH, levelWidth+2);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skipPixels);
glPixelStorei(GL_UNPACK_SKIP_ROWS, skipRows);
glTexImage2D(GL_TEXTURE_2D, level, 4,
tileWidth + 2*border, tileHeight + 2*border,
border, GL_RGBA, GL_UNSIGNED_BYTE, texImageLevel[level]);
if (levelWidth > 1) levelWidth = levelWidth / 2;
if (levelHeight > 1) levelHeight = levelHeight / 2;
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
}
The only problem with this code is...I'm not completly sure what it does, I just know it works real slow. :) Any help speeding this up would be super.
MattDiamond
2003.10.16, 09:38 PM
This is code that sets up a display list "terrainList". Are you calling this code each frame? If so, you shouldn't. Just use the display list that it builds.
Mars_999
2003.10.17, 12:07 AM
Make sure you check to see if you are doing what Matt said. Do not make a new display list each frame move that display list out of the rendering loop into initialization or somewhere else.
I don't know what you are doing for sure with LoadTile() but I would get rid of that and get a .tga or whatever texture loader on the net and load a .tga texture and setup that texture and Bind it once and if you decide to add in more textures you will have to either rebind the texture or use multi-texturing.
Speed up, do what I stated above, and either use vertex arrays and not immediate mode or if Mac has them use VBO's. Culling will also speed up your engine.
HTH.
Originally posted by Mars_999
Speed up, do what I stated above, and either use vertex arrays and not immediate mode or if Mac has them use VBO's. Culling will also speed up your engine.I am not sure if vertex arrays would be much faster than a display list.
I am doing almost the same thing, except that I am tiling my texture. I get about 55 FPS solid on my 600 MHz G3 so it appears that your scaling of the texture is the slow down.
Mars_999
2003.10.17, 12:35 AM
Originally posted by jabber
I am not sure if vertex arrays would be much faster than a display list.
I am doing almost the same thing, except that I am tiling my texture. I get about 55 FPS solid on my 600 MHz G3 so it appears that your scaling of the texture is the slow down.
Oh it will if you are not culling your terrain and if he is using map_x as his map size and its 256x256 like mine. Hold on the speed breaks are engaged if he is going to use immediate mode. WAY TO MUCH overhead. That is alot of function calls per frame for the CPU.
But you maybe right Jabber if he is only doing something like 32x32 immediate mode is ok to play around with.
And if I remember right vertex arrays are never to be slower than a display list but could be faster than one depending on your situation.
LongJumper
2003.10.17, 12:56 AM
Originally posted by MattDiamond
This is code that sets up a display list "terrainList". Are you calling this code each frame? If so, you shouldn't. Just use the display list that it builds.
I'm not sure what you mean. I create the list and each frame it calls glCallList(terrainList); Are you thinking that I'm setting up the list and then just rewriting the code in my draw function? I'm not _that_ dumb. :)
As for what you are suggesting...if I bind a texture, it's going to repeat this texture across each triangle strip and the whole thing will be one texture. I am displaying a picture that is 256x256 over an entire terrain, so if the terrain were flat it would look exactly like the picture file if you viewed it in photoshop.
And yes, the terrain is 32x32 and the map scale is 10.
LoadTile takes a chunk of an image file and uses that as the texture for that one triangle strip.
Mars_999
2003.10.17, 01:05 AM
Originally posted by LongJumper
I'm not sure what you mean. I create the list and each frame it calls glCallList(terrainList); Are you thinking that I'm setting up the list and then just rewriting the code in my draw function? I'm not _that_ dumb. :)
As for what you are suggesting...if I bind a texture, it's going to repeat this texture across each triangle strip and the whole thing will be one texture. I am displaying a picture that is 256x256 over an entire terrain, so if the terrain were flat it would look exactly like the picture file if you viewed it in photoshop.
And yes, the terrain is 32x32 and the map scale is 10.
LoadTile takes a chunk of an image file and uses that as the texture for that one triangle strip.
Unless I am missing something you aren't stretching the image across your 32x32 map. You are tiling it. Your texture coordinates are 0.0 and 1.0.
Also you might want to disable texturing at the end of that display list as it stands you are trying to enable texturing each time its called
chainsawmcgraw
2003.10.17, 04:33 PM
**Warning: I'm a newbie, so take my advice with a grain of salt**
It appears like you're calling glTexImage2d every frame and multiple times in that frame (within loadTile). It is my understanding that glTexImage2d sends the texture data to the opengl context. Doing this multiple times during every frame may cause some slowdown (if I understand glTexImage2d) and it may be better to initialize some texture objects at the beginning, and then reference them every frame.
And just so I'm clear: Is any of what I'm saying correct? :wacko:
MattDiamond
2003.10.17, 04:55 PM
Originally posted by chainsawmcgraw
**Warning: I'm a newbie, so take my advice with a grain of salt**
It appears like you're calling glTexImage2d every frame and multiple times in that frame (within loadTile). It is my understanding that glTexImage2d sends the texture data to the opengl context. Doing this multiple times during every frame may cause some slowdown (if I understand glTexImage2d) and it may be better to initialize some texture objects at the beginning, and then reference them every frame.
And just so I'm clear: Is any of what I'm saying correct? :wacko:
Longjumper assures us that LoadTile is not being called every frame. So what you say would only be true if the _loading_ of the texture was itself stored in the display list, but display lists don't store that step, just the operations involving the texture object itself.
As Mars says, this should all be doable with only one texture object, simply by setting the texture coords properly for each vertex.
I also recommend running it through a profiler. Unfortunately, display lists tend to hide the details of what's going on, but at least Longjumper could verify that most of the time is being spent in the display list and not somewhere else.
Possibly Longjumper is running into a "slow path" conditions with the display list. Might want to search Apple's opengl mailing list archives; people there sometimes discuss specific cases that cause sudden slowdowns, usually because they disable hardware acceleration.
What version of MacOS you are running? What video card?
chainsawmcgraw
2003.10.17, 05:17 PM
I see. So display lists only take into account gl commands. My bad. :blush:
Mars_999
2003.10.17, 07:13 PM
Originally posted by chainsawmcgraw
I see. So display lists only take into account gl commands. My bad. :blush:
And to top that off only certain OpenGL commands. Good to see you around chainsaw when did you break away from IMG??:wow:
Bachus
2003.10.18, 03:31 AM
I'll bet you anything that the slowdown is being caused by LoadTile. Breaking up a large single texture into multiple little textures like that is a bad idea. Just bind the texture once before you enter the for loops, remove the call to LoadTile, and fix the texture coordinates in the glTexCoord2f calls.
Also, display lists and vertex arrays are about equal in speed in X.2. However, if you use vertex arrays then you can use VAR extension (GL_APPLE_vertex_array_range) which is a huge speedup if your card supports it. My fps jumped from 70 to 125 after I implemented VAR.
OneSadCookie
2003.10.18, 06:24 AM
Display lists on 10.2 use VAR if able... in my experience, they're very much the fast path. On 10.1, display lists are slow and there is no VAR...
Straight vertex arrays are a huge step up on immediate mode for speed, but they're very slow compared to what's possible.
Bachus
2003.10.19, 06:01 AM
As long as we're on VAR and vertex array extensions...
Is ARB_vertex_buffer_object in Panther? Isn't it supposed to be the bee's knees on the PC side as far as vertex arrays go?
Mars_999
2003.10.19, 11:44 PM
Originally posted by Bachus
As long as we're on VAR and vertex array extensions...
Is ARB_vertex_buffer_object in Panther? Isn't it supposed to be the bee's knees on the PC side as far as vertex arrays go?
I am using VBO's on my PC. I have used both vertex arrays and VBO for the same engine. In my experience VBO's are faster.
OneSadCookie
2003.10.19, 11:52 PM
I believe that an upcoming ARB extension (known currently only as ARB_žber_buffers) will essentially replace ARB_vertex_buffer_object, and that Apple doesn't ever intend to implement ARB_vertex_buffer_object.
I have filed a feature request bug asking that it be added, but have had no feedback.
If you want the extension, file a bug report.
If you don't care about cross-platform source, APPLE_vertex_array_range is probably faster than ARB_vbo would be.
I get no speed up using APPLE_var...
Mars_999
2003.10.20, 12:17 AM
Originally posted by OneSadCookie
I believe that an upcoming ARB extension (known currently only as ARB_žber_buffers) will essentially replace ARB_vertex_buffer_object, and that Apple doesn't ever intend to implement ARB_vertex_buffer_object.
I have filed a feature request bug asking that it be added, but have had no feedback.
If you want the extension, file a bug report.
If you don't care about cross-platform source, APPLE_vertex_array_range is probably faster than ARB_vbo would be.
Huh? unless APPLE_vertex_array_range changes the speed of the RAM on the videocard how can that be?
But back to the point I was going to make, if APPLE_vertex_array_range access VRAM instread of AGP RAM or system RAM then it would be just as good as VBO's. vertex arrays are system RAM, VBO's are VRAM unless I am wrong but pretty sure that is how they are setup?
Mars_999
2003.10.20, 12:19 AM
What version of OpenGL is Apple on now? If they are at 1.4 how the hell can they say they are compliant? VBO's are part of 1.3 if I remember right or maybe 1.4. And most likely it will have to be implemented by your videocard drivers.
OneSadCookie
2003.10.20, 12:33 AM
Neither APPLE_vertex_array_range nor ARB_vertex_buffer_object guarantees where your vertices will be stored. Each has different usage policies which provide different storage modes. Each can place vertices in VRAM, AGP memory or system RAM as required.
Josh, what are you doing with VAR (and on what hardware) that you see no improvement?
ARB_vertex_buffer_object is required by OpenGL 1.5. The extension specification was finished after the 1.4 spec, so how could it be included in that? :rolleyes: .
Apple's OpenGL implementation supports OpenGL 1.4, however to my knowledge no renderers yet support higher than 1.3. In the case of the GeForce FX and Radeon 9500+, this is a driver issue rather than a hardware issue at least.
Mars_999
2003.10.20, 12:45 AM
Originally posted by OneSadCookie
ARB_vertex_buffer_object is required by OpenGL 1.5. The extension specification was finished after the 1.4 spec, so how could it be included in that? :rolleyes: .
What I should have said or meant to say is that VBO's have been around since 1.4 has been around. So they could be supported if your drivers have VBO's implemented. :blush:
vBulletin® v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.