PDA

View Full Version : 3ds with max's texture coordinates


urika
08-10-2003, 07:20 AM
i loaded a 3ds object into my program , i managed to load the texture as well but not as i mapped it in 3d studio max 5
the "preserve max's texture coordinates" is checked but still it kinda puts the jpg on the object without mapping
can anyone help?

anubis
08-10-2003, 12:52 PM
well, without seeing any code it's hard to help you

urika
08-12-2003, 01:55 AM
its basicly the 3ds loader from gametutorials (that can also read jpeg)
i changed the 3ds object to mine.
i can post code but since i dont know where the problem is i dont really know what to post :blush:
while i m looking 4 a solution myself i came across glTexCoordPointer
does this have something to do with it (or something like it)?

anubis
08-12-2003, 06:26 AM
well, if you pass glTexCoordPointer the texture coordiantes from your max file i don't know why it doesn't work. it looks like some small bug in your code... which i can't fix for you ;)

urika
08-12-2003, 07:55 AM
i did not use glTexCoordPointer yet!
i just saw it in the msdn help as i was looking for a solution.
can anyone post some code with glTexCoordPointer?
or just tell me where i can find something helpful.. :nod:

anubis
08-12-2003, 09:02 AM
try to find out about opengl vertex buffers. you might want to google for the "opengl red book"

urika
08-14-2003, 06:48 AM
here is some code that i think should texture correctly but doesnt
if(pObject->bHasTexture)
{

// Make sure there was a UVW map applied to the object or else it won't have tex coords.
if(pObject->pTexVerts)
{
glTexCoord2f(pObject->pTexVerts[ index ].x, pObject->pTexVerts[ index ].y);
}
}


i assume the info in pTexVerts is correct but still it doesnt texturize correctly

urika
08-24-2003, 03:00 AM
after working on it and changing the order of things , the texture appears on the object but not as in 3d studio max, why ????? is there something in max that i need to change? :blink:

davepermen
08-24-2003, 05:04 AM
how "different"? mirrored or what?

i don't know. we never had such problems, it... just worked.. :|

urika
08-24-2003, 06:06 AM
first of all thanks for trying.
my object is a jet fighter, in max i put a texture using unwrap uvw so it would look lifelike.
when i use the object in opengl , it uses the same jpg allright but the coordinates have moved , for instance the back fin texture is smeared on the wing.
i don't know WHERE the problem is openGL? Max?(it looks good in max) :eek:

davepermen
08-24-2003, 11:27 AM
hm.. comparison pics (hint: my webspace for hosting), or actual loading code could help i guess.. difficult without any info on WHAT is wrong, or HOW its wrong..

urika
08-28-2003, 02:34 AM
it works!!!!
the problem was this:
there was glTexCoord2f(pObject->pTexVerts[ind].x, pObject->pTexVerts[ind].y);
and when i changed it to
glTexCoord2f(pObject->pTexVerts[ind].x, -pObject->pTexVerts[ind].y);
it works (the "-" made the differance).
i dont exactly understand why...
can any one enlighten me? B)

anubis
08-28-2003, 02:52 AM
max has strange ways of dealing with coordinates in general... y - z axis mixed up, etc. i wouldn't know y it should store negative texture coordinates. also i never had that problem...

davepermen
08-29-2003, 01:34 AM
hm... very weird.. what format is the texture? and what do you use to load it?

because some images are known to be stored "topdown" => you have to flip the y-coord (actually you have to calc 1-ycoord, but if you have GL_REPEAT, result is the same..)

anubis
08-29-2003, 02:17 AM
hey... that might be the solution... why didn't i think of that ???
i bet he's using targas for textures...

urika
08-31-2003, 04:03 AM
the texture format is jpg , i dont know what is "targas".
my loader is basically from gametutorials.com

baldurk
08-31-2003, 04:09 AM
The Targa image format is quite common. The file extension is generally .tga

anubis
08-31-2003, 04:27 AM
and very often they are stored upside-down

urika
09-01-2003, 02:00 AM
nope, jpg

davepermen
09-01-2003, 06:12 AM
well, all i know is jpg and bmp are upsidedown with relation to eachother.. i always "loved" that in DevIL.. but you could set there a mode to lode in the correct orientation..

i guess its that.. flip your jpgs..

Vifani
09-04-2003, 09:05 AM
Hi guys,

can you tell me how to flip y coords ? have you some code?

I have a problem with TGA and JPG file, while with BMP file all looks great!

Vifani
09-05-2003, 06:18 AM
Can anyone help me ? :unsure:

Dia Kharrat
09-05-2003, 09:30 AM
Try this:


unsigned char *temp = new unsigned char[width * height * 4];
memcpy(temp, data, width * height * 4);
for(j = 0; j < height; j++)
{
* *memcpy(&data[((height-1) - j)*4*width], &temp[j*4*width], 4*width);
}
delete[] temp;


I didn't check if it works though :D

davepermen
09-05-2003, 09:45 AM
Hi guys,

can you tell me how to flip y coords ? have you some code?

I have a problem with TGA and JPG file, while with BMP file all looks great!
hm.. statistically, this rather means you have a problem with your bmp files, and in your code another problem wich makes your bmp problem dissapear:D

Vifani
09-05-2003, 10:09 AM
Try this:

unsigned char *temp = new unsigned char[width * height * 4];memcpy(temp, data, width * height * 4);for(j = 0; j < height; j++){ * *memcpy(&data[((height-1) - j)*4*width], &temp[j*4*width], 4*width);}delete[] temp;

I didn't check if it works though :D
Thank you for this code but the result is the same :sigh:

davepermen the problem is caused by the different data order stored in JPG and TGA. The texture coords are generated by 3D Studio Max so that are surely exact (with BMP all works fine!).

Have anyone ideas to solve this problem ?

Vifani
09-05-2003, 10:18 AM
With BMP
http://www.hardware4you.sm/img/bmp.jpg

With TGA
http://www.hardware4you.sm/img/tga.jpg

anubis
09-05-2003, 03:28 PM
this looks like some tga loading error... check your loader... it might be a cast error... this kind of error might be induced by some really small bug in your code... double check everything

Vifani
09-05-2003, 03:46 PM
The problem is the texture resolution. When I use a resolution such as 510x1001 the problem is present. if I use a texture 512x1024 all look fine!

This is normal for you ?

With BMP I can use all texture that I need without any limits (2048x2048 is the hardware limit).

Dia Kharrat
09-05-2003, 11:16 PM
It doesn't look to me that your y-coords is flipped; It seems to me that you loaded the file incorrectly.

Could you show some code as to how you're loading the image?

Oh, btw, I think you're only supposed to load images in power of 2's

Vifani
09-06-2003, 03:22 AM
The code is the same of GameTutorials.com


tImageTGA *t3DModel::LoadTGA(const char *filename)
{
tImageTGA *pImageData = NULL; // This stores our important image data
WORD width = 0, height = 0; // The dimensions of the image
byte length = 0; // The length in bytes to the pixels
byte imageType = 0; // The image type (RLE, RGB, Alpha...)
byte bits = 0; // The bits per pixel for the image (16, 24, 32)
FILE *pFile = NULL; // The file pointer
int channels = 0; // The channels of the image (3 = RGA : 4 = RGBA)
int stride = 0; // The stride (channels * width)
int i = 0; // A counter

// This function loads in a TARGA (.TGA) file and returns its data to be
// used as a texture or what have you. This currently loads in a 16, 24
// and 32-bit targa file, along with RLE compressed files. Eventually you
// will want to do more error checking to make it more robust. This is
// also a perfect start to go into a modular class for an engine.
// Basically, how it works is, you read in the header information, then
// move your file pointer to the pixel data. Before reading in the pixel
// data, we check to see the if it's an RLE compressed image. This is because
// we will handle it different. If it isn't compressed, then we need another
// check to see if we need to convert it from 16-bit to 24 bit. 24-bit and
// 32-bit textures are very similar, so there's no need to do anything special.
// We do, however, read in an extra bit for each color.

// Open a file pointer to the targa file and check if it was found and opened
if((pFile = fopen(filename, "rb")) == NULL)
{
// Display an error message saying the file was not found, then return NULL
MessageBox(istanza.hWnd, "Unable to load TGA File!", "Error", MB_OK);
return NULL;
}

// Allocate the structure that will hold our eventual image data (must free it!)
pImageData = (tImageTGA*)malloc(sizeof(tImageTGA));

// Read in the length in bytes from the header to the pixel data
fread(&length, sizeof(byte), 1, pFile);

// Jump over one byte
fseek(pFile,1,SEEK_CUR);

// Read in the imageType (RLE, RGB, etc...)
fread(&imageType, sizeof(byte), 1, pFile);

// Skip past general information we don't care about
fseek(pFile, 9, SEEK_CUR);

// Read the width, height and bits per pixel (16, 24 or 32)
fread(&width, sizeof(WORD), 1, pFile);
fread(&height, sizeof(WORD), 1, pFile);
fread(&bits, sizeof(byte), 1, pFile);

// Now we move the file pointer to the pixel data
fseek(pFile, length + 1, SEEK_CUR);

// Check if the image is RLE compressed or not
if(imageType != TGA_RLE)
{
// Check if the image is a 24 or 32-bit image
if(bits == 24 || bits == 32)
{
// Calculate the channels (3 or 4) - (use bits >> 3 for more speed).
// Next, we calculate the stride and allocate enough memory for the pixels.
channels = bits / 8;
stride = channels * width;
pImageData->data = new unsigned char[stride * height];

// Load in all the pixel data line by line
for(int y = 0; y < height; y++)
{
// Store a pointer to the current line of pixels
unsigned char *pLine = &(pImageData->data[stride * y]);

// Read in the current line of pixels
fread(pLine, stride, 1, pFile);

// Go through all of the pixels and swap the B and R values since TGA
// files are stored as BGR instead of RGB (or use GL_BGR_EXT verses GL_RGB)
for(i = 0; i < stride; i += channels)
{
int temp = pLine[i];
pLine[i] = pLine[i + 2];
pLine[i + 2] = temp;
}
}
}
// Check if the image is a 16 bit image (RGB stored in 1 unsigned short)
else if(bits == 16)
{
unsigned short pixels = 0;
int r=0, g=0, b=0;

// Since we convert 16-bit images to 24 bit, we hardcode the channels to 3.
// We then calculate the stride and allocate memory for the pixels.
channels = 3;
stride = channels * width;
pImageData->data = new unsigned char[stride * height];

// Load in all the pixel data pixel by pixel
for(int i = 0; i < width*height; i++)
{
// Read in the current pixel
fread(&pixels, sizeof(unsigned short), 1, pFile);

// To convert a 16-bit pixel into an R, G, B, we need to
// do some masking and such to isolate each color value.
// 0x1f = 11111 in binary, so since 5 bits are reserved in
// each unsigned short for the R, G and B, we bit shift and mask
// to find each value. We then bit shift up by 3 to get the full color.
b = (pixels & 0x1f) << 3;
g = ((pixels >> 5) & 0x1f) << 3;
r = ((pixels >> 10) & 0x1f) << 3;

// This essentially assigns the color to our array and swaps the
// B and R values at the same time.
pImageData->data[i * 3 + 0] = r;
pImageData->data[i * 3 + 1] = g;
pImageData->data[i * 3 + 2] = b;
}
}
// Else return a NULL for a bad or unsupported pixel format
else
return NULL;
}
// Else, it must be Run-Length Encoded (RLE)
else
{
// First, let me explain real quickly what RLE is.
// For further information, check out Paul Bourke's intro article at:
// http://astronomy.swin.edu.au/~pbourke/dataformats/rle/
//
// Anyway, we know that RLE is a basic type compression. It takes
// colors that are next to each other and then shrinks that info down
// into the color and a integer that tells how much of that color is used.
// For instance:
// aaaaabbcccccccc would turn into a5b2c8
// Well, that's fine and dandy and all, but how is it down with RGB colors?
// Simple, you read in an color count (rleID), and if that number is less than 128,
// it does NOT have any optimization for those colors, so we just read the next
// pixels normally. Say, the color count was 28, we read in 28 colors like normal.
// If the color count is over 128, that means that the next color is optimized and
// we want to read in the same pixel color for a count of (colorCount - 127).
// It's 127 because we add 1 to the color count, as you'll notice in the code.

// Create some variables to hold the rleID, current colors read, channels, & stride.
byte rleID = 0;
int colorsRead = 0;
channels = bits / 8;
stride = channels * width;

// Next we want to allocate the memory for the pixels and create an array,
// depending on the channel count, to read in for each pixel.
pImageData->data = new unsigned char[stride * height];
byte *pColors = new byte [channels];

// Load in all the pixel data
while(i < width*height)
{
// Read in the current color count + 1
fread(&rleID, sizeof(byte), 1, pFile);

// Check if we don't have an encoded string of colors
if(rleID < 128)
{
// Increase the count by 1
rleID++;

// Go through and read all the unique colors found
while(rleID)
{
// Read in the current color
fread(pColors, sizeof(byte) * channels, 1, pFile);

// Store the current pixel in our image array
pImageData->data[colorsRead + 0] = pColors[2];
pImageData->data[colorsRead + 1] = pColors[1];
pImageData->data[colorsRead + 2] = pColors[0];

// If we have a 4 channel 32-bit image, assign one more for the alpha
if(bits == 32)
pImageData->data[colorsRead + 3] = pColors[3];

// Increase the current pixels read, decrease the amount
// of pixels left, and increase the starting index for the next pixel.
i++;
rleID--;
colorsRead += channels;
}
}
// Else, let's read in a string of the same character
else
{
// Minus the 128 ID + 1 (127) to get the color count that needs to be read
rleID -= 127;

// Read in the current color, which is the same for a while
fread(pColors, sizeof(byte) * channels, 1, pFile);

// Go and read as many pixels as are the same
while(rleID)
{
// Assign the current pixel to the current index in our pixel array
pImageData->data[colorsRead + 0] = pColors[2];
pImageData->data[colorsRead + 1] = pColors[1];
pImageData->data[colorsRead + 2] = pColors[0];

// If we have a 4 channel 32-bit image, assign one more for the alpha
if(bits == 32)
pImageData->data[colorsRead + 3] = pColors[3];

// Increase the current pixels read, decrease the amount
// of pixels left, and increase the starting index for the next pixel.
i++;
rleID--;
colorsRead += channels;
}

}

}

// Free up pColors
delete[] pColors;
}

// Close the file pointer that opened the file
fclose(pFile);

// Fill in our tImageTGA structure to pass back
pImageData->channels = channels;
pImageData->sizeX = width;
pImageData->sizeY = height;

// Return the TGA data (remember, you must free this data after you are done)
return pImageData;
}

anubis
09-06-2003, 12:19 PM
as apex said. with opengl you are only allowed to use pow 2 textures. if you use other resolutions the result is unpredictable

Vifani
09-06-2003, 02:26 PM
Thank you guys. I have already implemented also DXTC 1, 3 and 5 texture compression. :)

davepermen
09-10-2003, 04:11 PM
well, the pow2 will change with gl1.5.. can't wait.. new drivers are not yet gl1.5 :(