0
101 Aug 10, 2003 at 13:20

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?

#### 32 Replies

0
101 Aug 10, 2003 at 18:52

0
101 Aug 12, 2003 at 07:55

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)?

0
101 Aug 12, 2003 at 12:26

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 ;)

0
101 Aug 12, 2003 at 13:55

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:

0
101 Aug 12, 2003 at 15:02

try to find out about opengl vertex buffers. you might want to google for the “opengl red book”

0
101 Aug 14, 2003 at 12:48

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

0
101 Aug 24, 2003 at 09:00

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:

0
101 Aug 24, 2003 at 11:04

how “different”? mirrored or what?

 i don’t know. we never had such problems, it… just worked.. :
0
101 Aug 24, 2003 at 12:06

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:

0
101 Aug 24, 2003 at 17:27

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..

0
101 Aug 28, 2003 at 08:34

it works!!!!
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)

0
101 Aug 28, 2003 at 08:52

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…

0
101 Aug 29, 2003 at 07:34

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..)

0
101 Aug 29, 2003 at 08:17

hey… that might be the solution… why didn’t i think of that ???
i bet he’s using targas for textures…

0
101 Aug 31, 2003 at 10:03

the texture format is jpg , i dont know what is “targas”.
my loader is basically from gametutorials.com

0
101 Aug 31, 2003 at 10:09

The Targa image format is quite common. The file extension is generally .tga

0
101 Aug 31, 2003 at 10:27

and very often they are stored upside-down

0
101 Sep 01, 2003 at 08:00

nope, jpg

0
101 Sep 01, 2003 at 12:12

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..

0
101 Sep 04, 2003 at 15:05

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!

0
101 Sep 05, 2003 at 12:18

Can anyone help me ? :unsure:

0
158 Sep 05, 2003 at 15:30

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

0
101 Sep 05, 2003 at 15:45

@Vifani

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

0
101 Sep 05, 2003 at 16:09

@apex

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 ?

0
101 Sep 05, 2003 at 16:18

With BMP

With TGA

0
101 Sep 05, 2003 at 21:28

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

0
101 Sep 05, 2003 at 21:46

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).

0
158 Sep 06, 2003 at 05:16

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

0
101 Sep 06, 2003 at 09:22

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

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

// Read in the imageType (RLE, RGB, etc...)

// 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)

// 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

// 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

// 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;
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

// 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

// If we have a 4 channel 32-bit image, assign one more for the alpha
if(bits == 32)

// Increase the current pixels read, decrease the amount
// of pixels left, and increase the starting index for the next pixel.
i++;
rleID--;
}
}
// 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

// If we have a 4 channel 32-bit image, assign one more for the alpha
if(bits == 32)

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

}

}

// 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;
}

0
101 Sep 06, 2003 at 18:19

as apex said. with opengl you are only allowed to use pow 2 textures. if you use other resolutions the result is unpredictable

0
101 Sep 06, 2003 at 20:26

Thank you guys. I have already implemented also DXTC 1, 3 and 5 texture compression. :)

0
101 Sep 10, 2003 at 22:11

well, the pow2 will change with gl1.5.. can’t wait.. new drivers are not yet gl1.5 :(