Skip to main content
GameDev.net gamedev.net
🔒 Locked

Texture problem

Started by Solano Apr 6, 2011 at 9:50 AM 7 replies 2.2k views
Original Post
Solano
Solano
Hello im writting a small opengl engine and am having lots of problems with texturing. Up close the texture looks kinda distorted and with random colors. I tried everything and nothing worked. Oh yeah I draw a cube and the texture got the same color as the cube but i don't want that.

Gl enable

glClearColor (0.0,0.0,0.0,1.0);
//set default viewport
glViewport(0, 0, (int)w, (int)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (float)640/(float)480, 1, 1000);//set default values for projection
//Default smooth shading
glShadeModel(GL_SMOOTH);
//Enable Z buffering
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);


This is how I load my texture I use freeimage for this

FREE_IMAGE_FORMAT format = FreeImage_GetFileType(path,0);
FIBITMAP* image = FreeImage_Load(format, path, 0);
if (!image) return false;

FIBITMAP* temp = image;
image = FreeImage_ConvertTo32Bits(temp);
FreeImage_Unload(temp);

int w = FreeImage_GetWidth(image);
int h = FreeImage_GetHeight(image);

BYTE *bits = (BYTE*)malloc( w * h * 3 );
BYTE *pixels = (BYTE*)FreeImage_GetBits(image);

//Free image stores data in BGR format so swap pixels
for(int pix=0; pix < w * h; pix++){
bits[pix*3+2]=pixels[pix*3+0];
bits[pix*3+1]=pixels[pix*3+1];
bits[pix*3+0]=pixels[pix*3+2];
}

GLuint textureID[1];

glGenTextures(1, &textureID[0]);
glBindTexture(GL_TEXTURE_2D, textureID[0]);

// Tried GL_MODULATE and GL_REPLACE none worked like i wanted them to
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR_MIPMAP_LINEAR );

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

//Generate the texture with mipmaps
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, w, h, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)bits );
free(bits);
free(pixels);
GLenum error = glGetError();
if(error)
return (double)error;
else
return (double)textureID[0];

And finally the render function

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(xf, yf, zf, xt, yt, zt, xu, yu, zu);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, (GLuint)textid);
glBegin(GL_QUADS);
glTexCoord2f(0.0,0.0f);glVertex3f(_x1, _z1, _y1);
glTexCoord2f(0.0f,1.0f * vrepeat);glVertex3f(_x1, _z2, _y2);
glTexCoord2f(1.0f * hrepeat,1.0f * vrepeat);glVertex3f(_x2, _z2, _y2);
glTexCoord2f(1.0f * hrepeat,0.0f);glVertex3f(_x2, _z1, _y1);
glEnd();
glDisable(GL_TEXTURE_2D);
SwapBuffers( ehDC );


Now this displays the texture like this:
89931c3e0918362db940089e02599084.jpg
The actual texture is:
f26743bc745e5addc5b3266df0760036.jpg
JackTheRapper
JackTheRapper
You seem to be converting the image to 32 bits then allocating memory for 24 bits. Have you tried treating it as a 32 bit image, adjusting your memory allocation, array addressing and GL tex params accordingly?
Solano
Solano

You seem to be converting the image to 32 bits then allocating memory for 24 bits. Have you tried treating it as a 32 bit image, adjusting your memory allocation, array addressing and GL tex params accordingly?


Good point changed code to

BYTE *bits = (BYTE*)malloc( w * h * 4 );
BYTE *pixels = (BYTE*)FreeImage_GetBits(image);

//Free image stores data in BGR format so swap pixels
for(int pix=0; pix < w * h; pix++){
bits[pix*4+2]=pixels[pix*4+0];
bits[pix*4+1]=pixels[pix*4+1];
bits[pix*4+0]=pixels[pix*4+2];
}

But still get incorrect results
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, w, h, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)bits );
The second parameter is the number of color components right 3 for r g b?
JackTheRapper
JackTheRapper

[quote name='JackTheRapper' timestamp='1302087862' post='4794985']
You seem to be converting the image to 32 bits then allocating memory for 24 bits. Have you tried treating it as a 32 bit image, adjusting your memory allocation, array addressing and GL tex params accordingly?


Good point changed code to

BYTE *bits = (BYTE*)malloc( w * h * 4 );
BYTE *pixels = (BYTE*)FreeImage_GetBits(image);

//Free image stores data in BGR format so swap pixels
for(int pix=0; pix < w * h; pix++){
bits[pix*4+2]=pixels[pix*4+0];
bits[pix*4+1]=pixels[pix*4+1];
bits[pix*4+0]=pixels[pix*4+2];
}

But still get incorrect results
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, w, h, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)bits );
The second parameter is the number of color components right 3 for r g b?
[/quote]
Should be something like:

gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bits );

you could also try:


gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bits );

In any case, it looks like a format problem as you can make out the basic shape of the texture.

You should also check out this link:
http://www.opengl.or...ld2DMipmaps.xml

Edit: forgot you were swapping R and B channels (fixed accordingly)
Solano
Solano
gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bits );

Solved it thank you very much. I just have one more question. Since I'm using GL_DECAL can I use lighting and will it illuminate the texture.
Second question if I use GL_MODULATE how can I make the texture not blend with colors set by glColor3f. In other words just get lighting color and no other colors.
I hope you can understand my question.

EDIT: If I use glColor3f(1.0f, 1.0f, 1.0f) before I draw my textured plane and then cast a blue light for example will the texture get blueish.
sprite_hound
sprite_hound
Your texture mag filter should be GL_LINEAR, not GL_LINEAR_MIPMAP_LINEAR (mipmap filter settings are only for the min filter).

Re: modulate - the idea behind modulate is that the texture is modulated by the color you set. If you want just the texture color, call glColor3f(1.0, 1.0, 1.0) (set it to white).

Also, your texture load function is very strange - it can return false, a GLenum cast to a double, or a GLuint cast to a double. How do you tell the difference between valid / invalid values?
Solano
Solano
Ok im having another problem >.<
Using the above code to load the texture but using glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)bits); instead of gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)bits );

Doesnt work. I don't get it, why doesn't it work.

export double drawTexture(double textid, double x, double y)
int w, h;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, (int)textid);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2i(0, 1);glVertex2f(x, y);
glTexCoord2i(0, 0);glVertex2f(x, y + h);
glTexCoord2i(1, 0);glVertex2f(x + w, y + h);
glTexCoord2i(1, 1);glVertex2f(x + w, y);
glEnd();
glDisable(GL_TEXTURE_2D);
}

This is how I draw it. I dont get it why isn't it drawing when its a mipmap.GL_INVALID_ENUM Is returned.

GL_INVALID_ENUM is generated if target is one of the six cube map 2D image targets and the width and height parameters are not equal.

GL_INVALID_ENUM is generated if type is not a type constant.

GL_INVALID_ENUM is generated if type is GL_BITMAP and format is not GL_COLOR_INDEX.
[/quote]
Its neither of the above reasons.
sprite_hound
sprite_hound
Perhaps because you don't define the other mip-levels using glTexImage2D, but still expect it to interpolate between them, whereas with gluBuild2DMipmaps, the other levels are filled in for you.
Solano
Solano
Oh yeah silly me xD

if (mip == true){
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR );//set the min filter
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR );//set the mag filter
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_RGB );//set up texture color properties
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );//repeat the texture
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );//repeat the texture
gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)bits ); //copy the internal buffer

}else {
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR );//set the min filter
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR );//set the mag filter
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)bits);
}

With the above code it works perfectly

Topic Locked

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

Sign in to reply to this topic.