PDA

View Full Version : Problems using textures



horacio
11-16-2008, 08:51 AM
Hi,
i am very new to opengl, so i guess that what i am going to ask is pretty basic.
I am using Visual Studio 2008 .net. I am trying to load a texture using glaux, everithing works fine, i was able to load the textures and displaying them as i wanted. The thing is, i wanted to load 6 textures within a loop, and the first few load without any hassle, however, the last 4 of them don't work.
I'll paste a bit of code:
[CODE]
for(Mmedia i = 0; i < 9;i++)
{
TexImg = new AUX_RGBImageRec;
.
.
TexImg= auxDIBImageLoad(dest2);
glBindTexture(GL_TEXTURE_2D, texmap[i]);
cout << "texmap[i]--->"<< texmap[i] << endl;
glTexImage2D(GL_TEXTURE_2D,
0,
3,
TexImg->sizeX,
TexImg->sizeY,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
TexImg->data);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,GL_LINEAR);
delete TexImg->data;
delete TexImg;
}

[/B][/QUOTE]
when i print out the texmap contents it prints out only two valid values, the rest is garbage.
Am i doing something wrong? Thank you very much for your help.

mfort
11-16-2008, 09:45 AM
How do you load texmap array? I cannot see any assignment to it.
The best way is to call glGenTextures()

horacio
11-16-2008, 12:13 PM
Hello mfort. Thank you very much for your response, it was one of those, i wouldn't say stupid, but rather IDIOTIC mistakes of mine.
I initialized glGenTextures(2, texmap) when i was trying to load 6 textures.
Thank you very though.

horacio
11-17-2008, 05:44 PM
Just one more question.
Textures load OK now, but they appear with a red color on top. I've tried everything to get it out. Before displaying the textures i call these functions:


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

also, when loading the textures i call


glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);

am i doing something wrong?
Thank you very much for your help

trinitrotoluene
11-17-2008, 05:57 PM
By default the texture color is multiplied by the incoming fragment color. To have only the texture color add a glTexEnvf (http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml)(GL_TEXTURE_2D,GL_TEXTURE_ENV_MODE,GL _REPLACE);.

horacio
11-17-2008, 06:04 PM
Thank you! i am trying it as we speak. But where should i place the function call? when creating the textures (right on top of glTexParameteri) or when displaying the textures?

trinitrotoluene
11-17-2008, 06:08 PM
It is better when displaying the texture just after the glBindTexture call.

horacio
11-17-2008, 06:10 PM
Thank you TNT! i've got it. RTFM for myself down here. It is a little bit late, so rational thought is to much of a hassle.
Thank you very much.

trinitrotoluene
11-17-2008, 06:18 PM
It is better when displaying the texture just after the glBindTexture call. Just to be more precise, this apply only to glTexEnvi and glTexEnvf function call not glTexParameteri and glTexImage2D.

Glad I helped you.

horacio
11-19-2008, 07:34 AM
Abusing your kindness, i'll be making another question.
I want to load a texture as window background. Is this possible? If so, should i do it like this?


display_handler()
{
background();
other_images_and_textures();
}

trinitrotoluene
11-19-2008, 07:54 AM
Yes it possible, but you have to draw a full screen quad with the texture on it. To be sure that the quad will be behind all your other image, you can use glDepthRange (http://www.opengl.org/sdk/docs/man/xhtml/glDepthRange.xml)(1.0,1.0); After you draw your background image replace the original value glDepthRange(0.0,1.0); I haven't tested this before but it should work.

Edit: For facilitate the drawing of the full screen quad you can temporarily switch to an ortho projection mode like this glOrtho(0,viewport_with,0,viewport_height) and the coordinates of your quad will be the same as the viewport.

horacio
11-26-2008, 11:46 AM
Thank you tnt, its comming along preety nice. Even though, i have jet another question. I am also importing models, and when trying to load more textures into my board, a couple of problems appear.
I'll post some code, and explain it below:


glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D,texturas_tablero[0]);
glPushMatrix();
glBegin(GL_QUADS);
glTexCoord2f(1.0f,0.0f);
glVertex3f(x_small,10.0+offset,z_big); /* top */
glTexCoord2f(1.0f,1.0f);
glVertex3f(x_big,10.0+offset,z_big);
glTexCoord2f(0.0f,1.0f);
glVertex3f(x_big,10.0+offset,z_small);
glTexCoord2f(0.0f,0.0f);
glVertex3f(x_small,10.0+offset,z_small);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);


The same code is working in another context, ie. another window alltogether, but i have disabled everything (DEPTH, etc), so there must be something wrong..
The texturas_tablero array is loaded at startup (GLuint *), by the class constructor,and, i've checked the values and there are the same. I'll post the code i use to load the textures:


imagen = loadBMP(this->get_imagen(CAMINAR_PASTO_VERDE));
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
texturas_tablero[0] = loadTexture(imagen);

Now, as i was saying, the first piece of code doesn't work. However, this does work:


glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D,texturas_tablero[0]);
glPushMatrix();
loadTexture2(imagen,texturas_tablero[0]);
glBindTexture(GL_TEXTURE_2D, ps); //Tell OpenGL which texture to edit
//Map the image to the texture
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
image->width, image->height,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
image->pixels);

glBegin(GL_QUADS);
glTexCoord2f(1.0f,0.0f);
glVertex3f(x_small,10.0+offset,z_big); /* top */
glTexCoord2f(1.0f,1.0f);
glVertex3f(x_big,10.0+offset,z_big);
glTexCoord2f(0.0f,1.0f);
glVertex3f(x_big,10.0+offset,z_small);
glTexCoord2f(0.0f,0.0f);
glVertex3f(x_small,10.0+offset,z_small);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);

As you already know, the glTexImage2D is making things slow as molasses, wich isn't that nice of a feature.
I would apreciate any help you could give me.

Komat
11-26-2008, 01:09 PM
Did you bound the texture properly before loading its content? Btw. the glTexParameter functions operates on currently bound texture. If the texture is created by the loadTexture(), as it appears from its return value, those glTexParameter() calls above it would be applied to a incorrect texture.

trinitrotoluene
11-26-2008, 01:28 PM
Call glTexImage2D only once when you load your texture at initialization (never call it while drawing). What I would do is this.

Texture initialization and loading.


glEnable(GL_TEXTURE_2D);
glGenTextures(1,&amp;texID);
glBindTexture(GL_TEXTURE_2D,texID);
image = loadBMP(this->get_imagen(CAMINAR_PASTO_VERDE));
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D,0, GL_RGB,image->width, image->height,0, GL_RGB,GL_UNSIGNED_BYTE,image->pixels);
glDisable(GL_TEXTURE_2D);


Drawing code


glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texID);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBegin(GL_QUADS);
glTexCoord2f(1.0f,0.0f);
glVertex3f(x_small,10.0+offset,z_big); /* top */
glTexCoord2f(1.0f,1.0f);
glVertex3f(x_big,10.0+offset,z_big);
glTexCoord2f(0.0f,1.0f);
glVertex3f(x_big,10.0+offset,z_small);
glTexCoord2f(0.0f,0.0f);
glVertex3f(x_small,10.0+offset,z_small);
glEnd();
glDisable(GL_TEXTURE_2D);


I notice that you call glBindTexture two time for the same texture unit, this is wrong because only the last one will be used. Do you want to do multi texturing?

horacio
11-26-2008, 02:34 PM
Thank you very much for your reply. I did exactly what you said. Even though, the texture that is beeing maped to the squares is a different one that the one identified by texID. I am pretty sure it happens because i am already using textures somewhere else, and its not binding properly. That's wy i am calling Bind two times, this is the only way it works. Is there any way of knowing if there is already a binded textures, and to save it's status, disable it, and then restoring it?
Thank you.

trinitrotoluene
11-26-2008, 03:08 PM
Even though, the texture that is beeing maped to the squares is a different one that the one identified by texID.

The only reason that such thing can happen is that somewhere you call glTexImage2D without a previous glBindTexture call so you are replacing the texture data of the previous texture id binded or you bind the wrong texture id. Verify all your glTexImage2D call and make sure that you call glBinTexture before with the right texture id.

horacio
11-26-2008, 04:09 PM
Ok, thank you again.
And what about textures sizes? are they relevant? what could hapen if i use a size that is not the right one?

trinitrotoluene
11-26-2008, 04:32 PM
And what about textures sizes? are they relevant? what could happen if i use a size that is not the right one?

The parameters that you give for glTexImage2D are very important. That include texture size, texture format and texture data type. With these parameters, OpenGL can copy the right amount of data in memory. The advice is when you pass parameters to glTexImage2D make sure that OpenGL don't read more data that the pointer given in the last parameter can hold. If it is equal or less, then this is not harmful. If it's more, trouble can happen.

Edit: Suppose you have a big texture atlas that is taller than the maximum texture size your graphic cards support (4096x4096), then you can use something like this:



GLubyte pixel[8196*8196*4];
glBindTexture(...,texId1);
...
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,4096,4096,0, GL_RGBA,
GL_UNSIGNED_BYTE,&amp;pixel[0]);

...
glBindTexture(...,texId2);
...
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,4096,4096,0, GL_RGBA,
GL_UNSIGNED_BYTE,&amp;pixel[offset1]);
...

glBindTexture(...,texId3);
...
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,4096,4096,0, GL_RGBA,
GL_UNSIGNED_BYTE,&amp;pixel[offset2]);

...
glBindTexture(...,texId4);
...
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,4096,4096,0, GL_RGBA,
GL_UNSIGNED_BYTE,&amp;pixel[offset3]);

...


So with this, OpenGL will read only memory in the range that the pointer pixel hold.

horacio
11-26-2008, 05:11 PM
No, that i get. I mean, what if want to texturize a relatively large polygon with a rather small texture (32*32, for instance) could this be a problem? Or does it only depends on the parameters?

trinitrotoluene
11-26-2008, 05:27 PM
I mean, what if want to texturize a relatively large polygon with a rather small texture (32*32, for instance) could this be a problem? Or does it only depends on the parameters.

There is no problem with that, but your small texture image will look very "pixelated" (if you have used GL_NEAREST as glTexParameteri this will be more obvious) on a big polygon in the screen (look very close to it).

The texture size is independent of the number of the final fragments count that the polygon will have on the screen. But if plan that your polygon will be often viewed close, it is better to use the right texture size for better image quality.

Did I understand you well this time?

horacio
11-26-2008, 07:31 PM
Yes, you undestood it perfectly. Sorry for my syntax and grammar, english is not my first language. The thing i still couldn't fix is the thing with the out of order textures. What else do you think could be the problem?
Let me refresh your memory, i am doing exactly as you posted earlier, however, the wrong texture is geting binded any how.