| |
| Posted by nobody in reply to Emp | PermalinkReply |
|
nobody
| Emp wrote:
> I've written some code to load tga files for openGl use and wanted to donate
> it (somewhere?)
>
> Could you people check whether it is not totally faulty (not to my knowledge
> though).
> I've written it so that it will even take a textfile as long as it is big
> enough and the first 18 or so bytes are correct :)
>
> Any comments/improvements are more than welcome.
> Also if anyone knows how to do good openGL error handling...
I noticed your post yesterday. For sharing your code you might want to check dsource.org. I don't use OpenGL so I can't help with your error handling question. I did want to suggest a way to use names to refer to the array offsets you used in your code.
The following code should suggest a strategy I think will work for using meaningful names. I did not test the code so it might work but certainly won't be very robust. I mostly wanted to illustrate how a combination of structs and unions might help.
import std.file;
alias std.file.read read;
align(1)
struct TGAHeader
{
// raster stores BGRA
// size of ID field that follows 18 byte header (0 usually)
ubyte identsize;
// type of colour map 0=none, 1=has palette
ubyte colourmap;
// type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
ubyte type;
// first colour map entry in palette
ushort cmStart;
// number of colours in palette
ushort cmLength;
// number of bits per palette entry 15,16,24,32
ubyte cmBits;
// image x origin
ushort xStart;
// image y origin
ushort yStart;
// image width in pixels
ushort width;
// image height in pixels
ushort height;
// image bits per pixel 8,16,24,32
ubyte bits;
// image descriptor bits (vh flip bits)
ubyte descriptor;
enum
{
// greyscale image
typeGREY = 3,
// rgb image type (same as rgba)
typeRGB = 2,
// rgba image type (same as rgb)
typeRGBA = 2,
// no palette
colourmapRAW = 0,
// palette present
colourmapPAL = 1,
// grey
bitsGREY = 8,
// rgb
bitsRGB = 24,
// rgb w alpha
bitsRGBA = 32,
// alpha value bit mask
descriptorAM = 15,
// origin bit mask
descriptorOM = 48,
// ? img.pix[0] is at bottom left of scree
descriptorBL = 0,
// ? img.pix[0] is at bottom right of screen
descriptorBR = 16,
// ? img.pix[0] is at top left of screen
descriptorTL = 32,
// ? img.pix[0] is at top right of screen
descriptorTR = 48
};
}
align(1)
struct PixBGR
{
ubyte b;
ubyte g;
ubyte r;
alias r red;
alias g green;
alias b blue;
}
align(1)
struct PixRGB
{
ubyte r;
ubyte g;
ubyte b;
alias r red;
alias g green;
alias b blue;
PixRGB opAssign(PixBGR bgr) {
return *this;
}
}
struct PixArrayMeta
{
uint len;
void* ptr;
}
union PixArray
{
ubyte[] grey;
PixBGR[] bgr;
PixRGB[] rgb;
PixArrayMeta meta;
}
struct TGAImage
{
void[] buf;
PixArray raster;
TGAHeader* header;
bool loadTGA(char[] filename)
{
// dump file contents in buf
buf = read(filename);
// make header point to start of buffer
header = cast(TGAHeader*) &buf[0];
// make sure the TGA has 24 bpp
if( header.bits != header.bitsRGB ) return false;
/*
* more type checking & etc here
*/
// no colormap means raster follows header?
raster.meta.ptr = &buf[header.sizeof];
// raster.whatever.length; whatever is rgb, bgr, grey, ...
raster.meta.len = header.width * header.height;
// now swap BGR to RGB for OpenGL
ubyte tempR, tempG, tempB;
for(uint i = 0; i < raster.bgr.length; i++)
{
// using aliased names
tempR = raster.bgr[i].red;
tempG = raster.bgr[i].green;
tempB = raster.bgr[i].blue;
// using non-aliased names
raster.rgb[i].r = tempR;
raster.rgb[i].g = tempG;
raster.rgb[i].b = tempB;
}
// raster has now swapped from BGR to RGB
return true;
}
}
|