Texture/Image Binding crash.
OneSadCookie Wrote:um, if the image is 256x256, you should be passing 256, 256 to glTexImage2D..... where's 65536 come from?!
Well sonofa... I put in 256, 256 just for the heck of it, and it works... kinda it looks like a random collection of randomly colored pixels... as far as where 65536 came from, I put a printf statement in there and told it to give me the number being held in sizeX and then in sizeY. that's what I got. I guess it has something to do with the fread(&image->sizeX, 4, 1, file); and the same thing with &image->sizeY lines. they worked fine on a PC, I don't understand why all of a sudden the same code (for reading raw data mind you) would not work on my G5...
either way I'm sure the problem sits somewhere in the fread(); calls I have in there. Any idea what would cause this craziness?
endianness. search the boards, google, wikipedia, etc. you need to change the order of the bytes. 'course, 0x00 0x01 0x00 0x00 is a lot more than 256 whatever endianness you're looking at it in...
OneSadCookie Wrote:endianness. search the boards, google, wikipedia, etc. you need to change the order of the bytes. 'course, 0x00 0x01 0x00 0x00 is a lot more than 256 whatever endianness you're looking at it in...I saw a lot of that word when I was looking into this problem. I was afraid that might be ther problem

I did do a bit of research on it and I THINK I may have found something.
tell me, will this help me in any way?
http://chaoslizard.sourceforge.net/glbmp/
um, I was lying -- that number is 256 when you swap the bytes. I'm surprised nobody picked me up on that one...
that library looks like it should work, but then you'll be loading .bmps... ugh
I'd suggest, for learning purposes, you do the byte-swapping yourself. It's not difficult.
that library looks like it should work, but then you'll be loading .bmps... ugh

I'd suggest, for learning purposes, you do the byte-swapping yourself. It's not difficult.
well yeah, we were taught how to use bmps. and we don't really understand all the stuff about seeking past th eheader and extracting the width/height/data.
tho I WOULD like to be able to use other image types. perhaps you could point me in the direction of someplace that could teach me proper? I've done some googling and haven't found what I'm looking for. mayhaps I'm not doing the correct search terms?
tho I WOULD like to be able to use other image types. perhaps you could point me in the direction of someplace that could teach me proper? I've done some googling and haven't found what I'm looking for. mayhaps I'm not doing the correct search terms?
If you don't understand your bmp-reading code, loading other kinds of image in a cross-platform manner is probably beyond you

did you created an opengl context before generating opengl texture ?
Aftershock6783 Wrote:well yeah, we were taught how to use bmps. and we don't really understand all the stuff about seeking past th eheader and extracting the width/height/data.
tho I WOULD like to be able to use other image types. perhaps you could point me in the direction of someplace that could teach me proper? I've done some googling and haven't found what I'm looking for. mayhaps I'm not doing the correct search terms?
you hsould try to found some TGA loader with google
or use SLD image loader (bmp/jpg/tga/png...)
There are actually many problems with the code presented. Some highlights include:
You should not trust a file based on its extension alone. Read all of the header and verify that the values are consistant, and that flags and features are implemented in your code. If you don't implement a feature that the file format supports you should report an error and abort processing the file.
If the header indicates compression, such as RLE, you must also decompress. See the MS documentation on BMP for information on run length encoding. It involves masking bytes and using a repeat count(if present) or bitshifting the input to assemble a pixel.
BMP scanlines are padded (I think to a multiple of 8), 256 is not a common multiple of 3 and 8; so you could be modifing undefined space. You should not parse or modify the data pixel by pixel, use a scanline buffer and calculate the correct padded size (or use a nested loop with stride). glTexImage2D defaults to 4 byte padding, unless you change it with glPixelStore. Verify the BMP pad value and sync with GL_UNPACK_ALIGNMENT.
You don't need to swap color channels, use GL_BGR for glTexImage2D.
The order of scanlines is correct for glTexImage2D (the first line starts the lower left corner, and the last line is the upper left corner -- this is the reverse of TGA)
If your BMP is not compressed, and padded to 4 byte alignment; you don't need to massage the pixel data at all. You might want to expand your Image structure to leverage information from the BMP header about the raw data, so that you can be more sophisticated in setting parameters to glTexImage2D, without writing lots of marshalling code.
Perhaps your function
meant to return an error but you return a constant and don't check the value. It would probablely be better to use:
If you are going to use Cocoa for this project, then you can also use:
architecture/byte_order.h to verify machine host endian and swap bytes
When using CPP in ObjectiveC, you should not use the file extension *.m. Use *.mm instead, the compiler will recognize this and switch to ObjectiveC++.
If you put CPP classes or headers, in your *.h, then only *.mm files can use that header. You can put void * in your @interface{data...} and add a conversion category to your *.mm file. Or use private subclasses in your *.mm file.
ObjectiveC exceptions use longjmp and are not compatible with CPP exceptions. Also, OC++ will not call custom constructors nor virtual destructors; therefore (in OC methods and objects) always use pointers to CPP objects to be safe (new and delete operators will handle ctor/dtor correctly). Use a wrapper around your CPP calls like this.
#include <stdexcept>
try {
// call cpp methods
} catch ( std::exception & ex ){
// clean up
[NSExecption
raise:@"CPP exception caught"
format:@"Message: %s\n",ex.what()];
}
Now you can use
NS_DURING, NS_HANDLER, and NS_ENDHANDLER
or
@try {
// call code (may include some statements that call CPP wrappers.
} @catch (NSException * ex) {
// clean up or handle error
}
depending on your compiler flags.
- BMP files are scanline oriented and padded
- BMP files may use RLE
- BMP files may use a colormap (8 bpp)
- You should verify ponter!=NULL before writing to it.
- You should check your return codes.
You should not trust a file based on its extension alone. Read all of the header and verify that the values are consistant, and that flags and features are implemented in your code. If you don't implement a feature that the file format supports you should report an error and abort processing the file.
If the header indicates compression, such as RLE, you must also decompress. See the MS documentation on BMP for information on run length encoding. It involves masking bytes and using a repeat count(if present) or bitshifting the input to assemble a pixel.
BMP scanlines are padded (I think to a multiple of 8), 256 is not a common multiple of 3 and 8; so you could be modifing undefined space. You should not parse or modify the data pixel by pixel, use a scanline buffer and calculate the correct padded size (or use a nested loop with stride). glTexImage2D defaults to 4 byte padding, unless you change it with glPixelStore. Verify the BMP pad value and sync with GL_UNPACK_ALIGNMENT.
You don't need to swap color channels, use GL_BGR for glTexImage2D.
The order of scanlines is correct for glTexImage2D (the first line starts the lower left corner, and the last line is the upper left corner -- this is the reverse of TGA)
If your BMP is not compressed, and padded to 4 byte alignment; you don't need to massage the pixel data at all. You might want to expand your Image structure to leverage information from the BMP header about the raw data, so that you can be more sophisticated in setting parameters to glTexImage2D, without writing lots of marshalling code.
Perhaps your function
Code:
int loadImage(char * filename, Image * image)
Code:
Image * loadImage(char * filename) {
// malloc Image * image here
if ( image != NULL ) {
// try to load data
{...}
// on error free image and set to NULL
}
return image
}
void loadTextures(){
Image * image = loadImage("image.bmp");
if ( image != NULL) {
//use image
//do you need to free(image)?
} else
reportError;
}
If you are going to use Cocoa for this project, then you can also use:
architecture/byte_order.h to verify machine host endian and swap bytes
When using CPP in ObjectiveC, you should not use the file extension *.m. Use *.mm instead, the compiler will recognize this and switch to ObjectiveC++.
If you put CPP classes or headers, in your *.h, then only *.mm files can use that header. You can put void * in your @interface{data...} and add a conversion category to your *.mm file. Or use private subclasses in your *.mm file.
ObjectiveC exceptions use longjmp and are not compatible with CPP exceptions. Also, OC++ will not call custom constructors nor virtual destructors; therefore (in OC methods and objects) always use pointers to CPP objects to be safe (new and delete operators will handle ctor/dtor correctly). Use a wrapper around your CPP calls like this.
#include <stdexcept>
try {
// call cpp methods
} catch ( std::exception & ex ){
// clean up
[NSExecption
raise:@"CPP exception caught"
format:@"Message: %s\n",ex.what()];
}
Now you can use
NS_DURING, NS_HANDLER, and NS_ENDHANDLER
or
@try {
// call code (may include some statements that call CPP wrappers.
} @catch (NSException * ex) {
// clean up or handle error
}
depending on your compiler flags.
Yeah, that would be the invalid value... No card would support 65536 by 65536
.

VolganPoet Wrote:Also, OC++ will not call custom constructors nor virtual destructors; therefore (in OC methods and objects) always use pointers to CPP objects to be safe (new and delete operators will handle ctor/dtor correctly).
IIRC, C++ classes created on the stack (ie normally) construct and destruct just fine; it's only when they're members of an Obj-C class that there's a problem, because their constructors don't automatically get called when the class is created (and likewise, with "destructors" and "destroyed").
Yes, some CPP instances could be useful in the context of a method where the object is no longer needed after the method returns, so thats a good point to add.
Perhaps 'not compatible' was a poor choice of words on my part. My point was that NS_HANDLER is expecting an NSException and won't see a std:exception and it would throw past the handler code. The converse could also happen and neither would unwind as expected. But the wrapper shows an approach for translation between them.
setjump/longjmp; std:exception and NSException can all be used in the same application, they just need to be used with care.
Perhaps 'not compatible' was a poor choice of words on my part. My point was that NS_HANDLER is expecting an NSException and won't see a std:exception and it would throw past the handler code. The converse could also happen and neither would unwind as expected. But the wrapper shows an approach for translation between them.
setjump/longjmp; std:exception and NSException can all be used in the same application, they just need to be used with care.
Aftershock6783,
when reading your image file you should also check the return value from fread, and be prepared to handle a short read. Since you calculated size from w*h and not file size, this could happen with compression or file truncation. w*h may produce an inaccurate value for the length of pixel data for some values of w, because that formula does not consider the scanline alignment pad bytes.
also if there is an error reading the file, fseek will not move the file pointer and return -1, so you need some error handling here too.
when reading your image file you should also check the return value from fread, and be prepared to handle a short read. Since you calculated size from w*h and not file size, this could happen with compression or file truncation. w*h may produce an inaccurate value for the length of pixel data for some values of w, because that formula does not consider the scanline alignment pad bytes.
also if there is an error reading the file, fseek will not move the file pointer and return -1, so you need some error handling here too.
Possibly Related Threads...
Thread: | Author | Replies: | Views: | Last Post | |
Suggestions for a physics library for java? Is there a chipmunk binding? | aqua_scummm | 6 | 7,714 |
Dec 12, 2008 12:40 PM Last Post: aqua_scummm |