digitalmars.D.learn - LoadTGA example
- Emp (58/58) Aug 03 2006 I've written some code to load tga files for openGl use and wanted to do...
- Emp (3/3) Aug 05 2006 Anybody knows a good place to send the code, or is it not really worth
- Bruno Medeiros (8/13) Aug 08 2006 I use SDL_Image for purposes as this. If there was a D homologue of
- nobody mailinator.com (146/154) Aug 06 2006 to my knowledge
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... struct Texture { GLuint width; GLuint height; GLuint id; } bool LoadTGA(inout Texture tex, char[] filename) { GLubyte[] TGAfile; GLubyte temp; GLuint mode=GL_RGBA; GLuint bpp; int imageSize; const GLubyte[] TGAheader= [0,0,2,0,0,0,0,0,0,0,0,0]; try{ TGAfile=cast(GLubyte[])read(filename); } catch{ return false; } if (TGAfile[].length<18) return false; if (TGAfile[0..12] != TGAheader) return false; tex.width = TGAfile[12+1] * 256 + TGAfile[12+0]; tex.height = TGAfile[12+3] * 256 + TGAfile[12+2]; if( tex.width <=0 || tex.width&(tex.width-1) !=0 ||tex.width >512|| tex.height<=0 || tex.height&(tex.height-1)!=0 ||tex.height>512|| (TGAfile[12+4]!=24 && TGAfile[12+4]!=32)){ return false; } bpp = TGAfile[12+4]/8; if (bpp==3) mode=GL_RGB; imageSize = tex.width * tex.height * bpp; if (TGAfile[].length<(18+imageSize)) return false; for(int i=0; i<imageSize; i+=bpp){ temp=TGAfile[(12+6)+i]; TGAfile[(12+6)+i] = TGAfile[(12+6)+i+2]; TGAfile[(12+6)+i+2] = temp; } //error handling! glGenTextures(1, &tex.id); //error handling! glBindTexture(GL_TEXTURE_2D, tex.id); //error handling! glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //error handling! glTexImage2D(GL_TEXTURE_2D, 0, mode, tex.width, tex.height, 0, mode, GL_UNSIGNED_BYTE, TGAfile[(12+6)..(imageSize+12+6)]); return true; }
Aug 03 2006
Anybody knows a good place to send the code, or is it not really worth sending? (Don't worry, I won't be offended)
Aug 05 2006
Emp wrote:Anybody knows a good place to send the code, or is it not really worth sending? (Don't worry, I won't be offended)I use SDL_Image for purposes as this. If there was a D homologue of SDL_Image, your function could belong there. (but it is very little code, and your function should have abstracted the openGL texture setup, from the TGA loading.) -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Aug 08 2006
Emp wrote:I've written some code to load tga files for openGl use andwanted to donateit (somewhere?) Could you people check whether it is not totally faulty (notto my knowledgethough). I've written it so that it will even take a textfile as longas it is bigenough 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; } }
Aug 06 2006