SDL - OGL texture

Started by
6 comments, last by Eskapade 15 years, 9 months ago
With this code I'm loading a .bmp with a magenta background, it's supposed to make the magenta background transparent, but it just makes it black. Is there something I have to enable to make this work, as in, to be able to have a quad with a transparent texture? GLuint loadTexture(const char filename[],bool mipmap){ GLuint texture; SDL_Surface* imgFile1 = IMG_Load(filename); if(imgFile1!=00000000){ SDL_SetColorKey(imgFile1,SDL_SRCCOLORKEY,SDL_MapRGB(imgFile1->format,255,0,255)); SDL_Surface* imgFile = SDL_DisplayFormatAlpha(imgFile1); SDL_PixelFormat format = {NULL,32,4,0,0,0,0,0,8,16,24,0x000000FF,0x0000FF00,0x00FF0000,0xFF000000,0,255}; SDL_Surface *temp = SDL_ConvertSurface(imgFile,&format,SDL_SWSURFACE); SDL_FreeSurface(imgFile); imgFile = temp; glGenTextures(1,&texture); glBindTexture(GL_TEXTURE_2D,texture); if(mipmap){ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D,3,imgFile->w,imgFile->h,GL_RGBA,GL_UNSIGNED_BYTE,imgFile->pixels); }else { glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexImage2D(GL_TEXTURE_2D,0,3,imgFile->w,imgFile->h,0,GL_RGBA,GL_UNSIGNED_BYTE,imgFile->pixels); } } return texture; } [Edited by - Wurzt on July 21, 2008 3:59:41 PM]
Advertisement
You can't use color keys for transparency in OpenGL... it's an SDL concept.

What probably be best for you to do would be to set the background color to anything with an alpha of 255 in your graphic editor, then load it normally as a texture.

Then make sure you included the line:

glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

When GL was initialised. Then use this code to load it into a GL_QUAD:

glEnable(GL_BLEND); glBegin( GL_QUADS );	//Top-left vertex (corner)    glColor4f(1.0f,1.0f,1.0f,1.0f);			glTexCoord2i( 0, 0 );	glVertex3f(x,y, 0.0f );		//Bottom-left vertex (corner)    glColor4f(1.0f,1.0f,1.0f,1.0f);		glTexCoord2i( 1, 0 );	glVertex3f(xe, y, 0 );		//Bottom-right vertex (corner)    glColor4f(1.0f,1.0f,1.0f,1.0f);		glTexCoord2i( 1, 1 );	glVertex3f(xe,ye, 0 );		//Top-right vertex (corner)    glColor4f(1.0f,1.0f,1.0f,1.0f);	    	glTexCoord2i( 0, 1 );	glVertex3f(x,ye, 0 );glEnd();glDisable(GL_BLEND);


Oh, and you might want to use the source tags when placing code: [ source ] and [ /source ] (without the spaces).
Ok so I'm going to use DevIL.
Once, a long time ago, I used DevIL and it worked great.
I found an example somewhere on the net, an example that wasn't filled with an extra 300 lines of error-checking..

Could some kind person give me an example of loading a bmp or png with DevIL, preferably it also loads transparency!
http://gpwiki.org/index.php/DevIL:Tutorials:Basics

[google]
Not that you necessarily want to load targas, but this lib(slightly modified by me to allow for 8 bit targas to use pure blue as transparent) is pretty easy to use, and what I use to load textures. It will load 8-bit or 32 bit RLE targas.


libtarga.h
#ifndef _libtarga_h_#define _libtarga_h_/************************************************************************** ** Simplified TARGA library for Intro to Graphics Classes ** ** This is a simple library for reading and writing image files in ** the TARGA file format (which is a simple format).  ** The routines are intentionally designed to be simple for use in ** into to graphics assignments - a more full-featured targa library ** also exists for other uses. ** ** This library was originally written by Alex Mohr who has assigned ** copyright to Michael Gleicher. The code is made available under an ** "MIT" Open Source license. **//** ** Copyright (c) 2005 Michael L. Gleicher ** ** Permission is hereby granted, free of charge, to any person ** obtaining a copy of this software and associated documentation ** files (the "Software"), to deal in the Software without ** restriction, including without limitation the rights to use, copy, ** modify, merge, publish, distribute, sublicense, and/or sell copies ** of the Software, and to permit persons to whom the Software is ** furnished to do so, subject to the following conditions: **  ** The above copyright notice and this permission notice shall be ** included in all copies or substantial portions of the Software. ** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ** HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ** DEALINGS IN THE SOFTWARE. **//* uncomment this line if you're compiling on a big-endian machine *//* #define WORDS_BIGENDIAN *//* make sure these types reflect your system's type sizes. */#define byte    char#define int32   int#define int16   short#define ubyte   unsigned byte#define uint32  unsigned int32#define uint16  unsigned int16/*      Truecolor images supported:    bits            breakdown   components    --------------------------------------    32              8-8-8-8     RGBA    24              8-8-8       RGB    16              5-6-5       RGB    15              5-5-5-1     RGB (ignore extra bit)    Paletted images supported:        index size      palette entry   breakdown   components    ------------------------------------------------------    8               <any of above>  <same as above> ..    16              <any of above>  <same as above> ..    24              <any of above>  <same as above> ..*//*   Targa files are read in and converted to   any of these three for you -- you choose which you want.   This is the 'format' argument to tga_create/load/write.      For create and load, format is what you want the data   converted to.   For write, format is what format the data you're writing   is in. (NOT the format you want written)   Only TGA_TRUECOLOR_32 supports an alpha channel.*/#define TGA_TRUECOLOR_32      (4)#define TGA_TRUECOLOR_24      (3)/*   Image data will start in the low-left corner   of the image.*/#ifdef __cplusplusextern "C" {#endif/* Error handling routines */int             tga_get_last_error();const char *    tga_error_string( int error_code );/* Creating/Loading images  --  a return of NULL indicates a fatal error */void * tga_create( int width, int height, unsigned int format );void * tga_load( const char * file, int * width, int * height, unsigned int format );/* Writing images to file  --  a return of 1 indicates success, 0 indicates error*/int tga_write_raw( const char * file, int width, int height, unsigned char * dat, unsigned int format );int tga_write_rle( const char * file, int width, int height, unsigned char * dat, unsigned int format );#ifdef __cplusplus}#endif#endif /* _libtarga_h_ */


libtarga.cpp
/************************************************************************** ** Simplified TARGA library for Intro to Graphics Classes ** ** This is a simple library for reading and writing image files in ** the TARGA file format (which is a simple format). ** The routines are intentionally designed to be simple for use in ** into to graphics assignments - a more full-featured targa library ** also exists for other uses. ** ** This library was originally written by Alex Mohr who has assigned ** copyright to Michael Gleicher. The code is made available under an ** "MIT" Open Source license. **//** ** Copyright (c) 2005 Michael L. Gleicher ** ** Permission is hereby granted, free of charge, to any person ** obtaining a copy of this software and associated documentation ** files (the "Software"), to deal in the Software without ** restriction, including without limitation the rights to use, copy, ** modify, merge, publish, distribute, sublicense, and/or sell copies ** of the Software, and to permit persons to whom the Software is ** furnished to do so, subject to the following conditions: ** ** The above copyright notice and this permission notice shall be ** included in all copies or substantial portions of the Software. ** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ** HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ** DEALINGS IN THE SOFTWARE. **//*** libtarga.c -- routines for reading targa files.*//*  Modified by yu-chi because of initialization of variables at tga_load  09-16-2005*/#include <stdio.h>#include <malloc.h>#include "libtarga.h"#define TGA_IMG_NODATA             (0)#define TGA_IMG_UNC_PALETTED       (1)#define TGA_IMG_UNC_TRUECOLOR      (2)#define TGA_IMG_UNC_GRAYSCALE      (3)#define TGA_IMG_RLE_PALETTED       (9)#define TGA_IMG_RLE_TRUECOLOR      (10)#define TGA_IMG_RLE_GRAYSCALE      (11)#define TGA_LOWER_LEFT             (0)#define TGA_LOWER_RIGHT            (1)#define TGA_UPPER_LEFT             (2)#define TGA_UPPER_RIGHT            (3)#define HDR_LENGTH               (18)#define HDR_IDLEN                (0)#define HDR_CMAP_TYPE            (1)#define HDR_IMAGE_TYPE           (2)#define HDR_CMAP_FIRST           (3)#define HDR_CMAP_LENGTH          (5)#define HDR_CMAP_ENTRY_SIZE      (7)#define HDR_IMG_SPEC_XORIGIN     (8)#define HDR_IMG_SPEC_YORIGIN     (10)#define HDR_IMG_SPEC_WIDTH       (12)#define HDR_IMG_SPEC_HEIGHT      (14)#define HDR_IMG_SPEC_PIX_DEPTH   (16)#define HDR_IMG_SPEC_IMG_DESC    (17)#define TGA_ERR_NONE                    (0)#define TGA_ERR_BAD_HEADER              (1)#define TGA_ERR_OPEN_FAILS              (2)#define TGA_ERR_BAD_FORMAT              (3)#define TGA_ERR_UNEXPECTED_EOF          (4)#define TGA_ERR_NODATA_IMAGE            (5)#define TGA_ERR_COLORMAP_FOR_GRAY       (6)#define TGA_ERR_BAD_COLORMAP_ENTRY_SIZE (7)#define TGA_ERR_BAD_COLORMAP            (8)#define TGA_ERR_READ_FAILS              (9)#define TGA_ERR_BAD_IMAGE_TYPE          (10)#define TGA_ERR_BAD_DIMENSIONS          (11)static uint32 TargaError;static int16 ttohs( int16 val );static int16 htots( int16 val );static int32 ttohl( int32 val );static int32 htotl( int32 val );static uint32 tga_get_pixel( FILE * tga, ubyte bytes_per_pix,                            ubyte * colormap, ubyte cmap_bytes_entry );static uint32 tga_convert_color( uint32 pixel, uint32 bpp_in, ubyte alphabits, uint32 format_out );static void tga_write_pixel_to_mem( ubyte * dat, ubyte img_spec, uint32 number,                                   uint32 w, uint32 h, uint32 pixel, uint32 format );/* returns the last error encountered */int tga_get_last_error() {    return( TargaError );}/* returns a pointer to the string for an error code */const char * tga_error_string( int error_code ) {    switch( error_code ) {    case TGA_ERR_NONE:        return( "no error" );    case TGA_ERR_BAD_HEADER:        return( "bad image header" );    case TGA_ERR_OPEN_FAILS:        return( "cannot open file" );    case TGA_ERR_BAD_FORMAT:        return( "bad format argument" );    case TGA_ERR_UNEXPECTED_EOF:        return( "unexpected end-of-file" );    case TGA_ERR_NODATA_IMAGE:        return( "image contains no data" );    case TGA_ERR_COLORMAP_FOR_GRAY:        return( "found colormap for a grayscale image" );    case TGA_ERR_BAD_COLORMAP_ENTRY_SIZE:        return( "unsupported colormap entry size" );    case TGA_ERR_BAD_COLORMAP:        return( "bad colormap" );    case TGA_ERR_READ_FAILS:        return( "cannot read from file" );    case TGA_ERR_BAD_IMAGE_TYPE:        return( "unknown image type" );    case TGA_ERR_BAD_DIMENSIONS:        return( "image has size 0 width or height (or both)" );    default:        return( "unknown error" );    }    // shut up compiler..    return( NULL );}/* creates a targa image of the desired format */void * tga_create( int width, int height, unsigned int format ) {    switch( format ) {    case TGA_TRUECOLOR_32:        return( (void *)malloc( width * height * 4 ) );    case TGA_TRUECOLOR_24:        return( (void *)malloc( width * height * 3 ) );    default:        TargaError = TGA_ERR_BAD_FORMAT;        break;    }    return( NULL );}/* loads and converts a targa from disk */void * tga_load( const char * filename,                int * width, int * height, unsigned int format ) {    ubyte  idlen;               // length of the image_id string below.    ubyte  cmap_type;           // paletted image <=> cmap_type    ubyte  image_type;          // can be any of the IMG_TYPE constants above.    uint16 cmap_first;          //    uint16 cmap_length;         // how long the colormap is    ubyte  cmap_entry_size;     // how big a palette entry is.    uint16 img_spec_xorig;      // the x origin of the image in the image data.    uint16 img_spec_yorig;      // the y origin of the image in the image data.    uint16 img_spec_width;      // the width of the image.    uint16 img_spec_height;     // the height of the image.    ubyte  img_spec_pix_depth;  // the depth of a pixel in the image.    ubyte  img_spec_img_desc;   // the image descriptor.    FILE * targafile;    ubyte * tga_hdr = NULL;    ubyte * colormap = NULL;    //***********************************************************************    // Add by Yu-Chi because of variable initialization.    // Add all = 0 to all the following variables    //***********************************************************************    ubyte cmap_bytes_entry = 0;    uint32 cmap_bytes = 0;    uint32 tmp_col = 0;    uint32 tmp_int32 = 0;    ubyte  tmp_byte = 0;    ubyte alphabits = 0;    uint32 num_pixels = 0;    uint32 i = 0;    uint32 j = 0;    ubyte * image_data = 0;    uint32 img_dat_len = 0;    ubyte bytes_per_pix = 0;    ubyte true_bits_per_pixel = 0;    uint32 bytes_total = 0;    ubyte packet_header = 0;    ubyte repcount = 0;    switch( format ) {    case TGA_TRUECOLOR_24:    case TGA_TRUECOLOR_32:        break;    default:        TargaError = TGA_ERR_BAD_FORMAT;        return( NULL );    }    /* open binary image file */    targafile = fopen( filename, "rb" );    if( targafile == NULL ) {        TargaError = TGA_ERR_OPEN_FAILS;        return( NULL );    }    /* allocate memory for the header */    tga_hdr = (ubyte *)malloc( HDR_LENGTH );    /* read the header in. */    if( fread( (void *)tga_hdr, 1, HDR_LENGTH, targafile ) != HDR_LENGTH ) {        free( tga_hdr );        TargaError = TGA_ERR_BAD_HEADER;        return( NULL );    }    /* byte order is important here. */    idlen              = (ubyte)tga_hdr[HDR_IDLEN];    image_type         = (ubyte)tga_hdr[HDR_IMAGE_TYPE];    cmap_type          = (ubyte)tga_hdr[HDR_CMAP_TYPE];    cmap_first         = ttohs( *(uint16 *)(&tga_hdr[HDR_CMAP_FIRST]) );    cmap_length        = ttohs( *(uint16 *)(&tga_hdr[HDR_CMAP_LENGTH]) );    cmap_entry_size    = (ubyte)tga_hdr[HDR_CMAP_ENTRY_SIZE];    img_spec_xorig     = ttohs( *(uint16 *)(&tga_hdr[HDR_IMG_SPEC_XORIGIN]) );    img_spec_yorig     = ttohs( *(uint16 *)(&tga_hdr[HDR_IMG_SPEC_YORIGIN]) );    img_spec_width     = ttohs( *(uint16 *)(&tga_hdr[HDR_IMG_SPEC_WIDTH]) );    img_spec_height    = ttohs( *(uint16 *)(&tga_hdr[HDR_IMG_SPEC_HEIGHT]) );    img_spec_pix_depth = (ubyte)tga_hdr[HDR_IMG_SPEC_PIX_DEPTH];    img_spec_img_desc  = (ubyte)tga_hdr[HDR_IMG_SPEC_IMG_DESC];    free( tga_hdr );    num_pixels = img_spec_width * img_spec_height;    if( num_pixels == 0 ) {        TargaError = TGA_ERR_BAD_DIMENSIONS;        return( NULL );    }    alphabits = img_spec_img_desc & 0x0F;    /* seek past the image id, if there is one */    if( idlen ) {        if( fseek( targafile, idlen, SEEK_CUR ) ) {            TargaError = TGA_ERR_UNEXPECTED_EOF;            return( NULL );        }    }    /* if this is a 'nodata' image, just jump out. */    if( image_type == TGA_IMG_NODATA ) {        TargaError = TGA_ERR_NODATA_IMAGE;        return( NULL );    }    /* now we're starting to get into the meat of the matter. */    /* deal with the colormap, if there is one. */    if( cmap_type ) {        switch( image_type ) {        case TGA_IMG_UNC_PALETTED:        case TGA_IMG_RLE_PALETTED:            break;        case TGA_IMG_UNC_TRUECOLOR:        case TGA_IMG_RLE_TRUECOLOR:            // this should really be an error, but some really old            // crusty targas might actually be like this (created by TrueVision, no less!)            // so, we'll hack our way through it.            break;        case TGA_IMG_UNC_GRAYSCALE:        case TGA_IMG_RLE_GRAYSCALE:            TargaError = TGA_ERR_COLORMAP_FOR_GRAY;            return( NULL );        }        /* ensure colormap entry size is something we support */        if( !(cmap_entry_size == 15 ||            cmap_entry_size == 16 ||            cmap_entry_size == 24 ||            cmap_entry_size == 32) ) {            TargaError = TGA_ERR_BAD_COLORMAP_ENTRY_SIZE;            return( NULL );        }        /* allocate memory for a colormap */        if( cmap_entry_size & 0x07 ) {            cmap_bytes_entry = (((8 - (cmap_entry_size & 0x07)) + cmap_entry_size) >> 3);        } else {            cmap_bytes_entry = (cmap_entry_size >> 3);        }        cmap_bytes = cmap_bytes_entry * cmap_length;        colormap = (ubyte *)malloc( cmap_bytes );        for( i = 0; i < cmap_length; i++ ) {            /* seek ahead to first entry used */            if( cmap_first != 0 ) {                fseek( targafile, cmap_first * cmap_bytes_entry, SEEK_CUR );            }            tmp_int32 = 0;            for( j = 0; j < cmap_bytes_entry; j++ ) {                if( !fread( &tmp_byte, 1, 1, targafile ) ) {                    free( colormap );                    TargaError = TGA_ERR_BAD_COLORMAP;                    return( NULL );                }                tmp_int32 += tmp_byte << (j * 8);            }            // byte order correct.            tmp_int32 = ttohl( tmp_int32 );            for( j = 0; j < cmap_bytes_entry; j++ ) {                colormap = (tmp_int32 &gt;&gt; (<span class="cpp-number">8</span> * j)) &amp; 0xFF;<br>            }<br><br>        }<br><br>    }<br><br><br>    <span class="cpp-comment">// compute number of bytes in an image data unit (either index or BGR triple)</span><br>    <span class="cpp-keyword">if</span>( img_spec_pix_depth &amp; 0x07 ) {<br>        bytes_per_pix = (((<span class="cpp-number">8</span> - (img_spec_pix_depth &amp; 0x07)) + img_spec_pix_depth) &gt;&gt; <span class="cpp-number">3</span>);<br>    } <span class="cpp-keyword">else</span> {<br>        bytes_per_pix = (img_spec_pix_depth &gt;&gt; <span class="cpp-number">3</span>);<br>    }<br><br><br>    <span class="cpp-comment">/* assume that there's one byte per pixel */</span><br>    <span class="cpp-keyword">if</span>( bytes_per_pix == <span class="cpp-number">0</span> ) {<br>        bytes_per_pix = <span class="cpp-number">1</span>;<br>    }<br><br><br>    <span class="cpp-comment">/* compute how many bytes of storage we need for the image */</span><br>    bytes_total = img_spec_width * img_spec_height * format;<br><br>    image_data = (ubyte *)malloc( bytes_total );<br><br>    img_dat_len = img_spec_width * img_spec_height * bytes_per_pix;<br><br>    <span class="cpp-comment">// compute the true number of bits per pixel</span><br>    true_bits_per_pixel = cmap_type ? cmap_entry_size : img_spec_pix_depth;<br><br>    <span class="cpp-keyword">switch</span>( image_type ) {<br><br>    <span class="cpp-keyword">case</span> TGA_IMG_UNC_TRUECOLOR:<br>    <span class="cpp-keyword">case</span> TGA_IMG_UNC_GRAYSCALE:<br>    <span class="cpp-keyword">case</span> TGA_IMG_UNC_PALETTED:<br><br>        <span class="cpp-comment">/* FIXME: support grayscale */</span><br><br>        <span class="cpp-keyword">for</span>( i = <span class="cpp-number">0</span>; i &lt; num_pixels; i++ ) {<br><br>            <span class="cpp-comment">// get the color value.</span><br>            tmp_col = tga_get_pixel( targafile, bytes_per_pix, colormap, cmap_bytes_entry );<br>            tmp_col = tga_convert_color( tmp_col, true_bits_per_pixel, alphabits, format );<br><br>            <span class="cpp-comment">// now write the data out.</span><br>            tga_write_pixel_to_mem( image_data, img_spec_img_desc,<br>                i, img_spec_width, img_spec_height, tmp_col, format );<br><br>        }<br><br>        <span class="cpp-keyword">break</span>;<br><br><br>    <span class="cpp-keyword">case</span> TGA_IMG_RLE_TRUECOLOR:<br>    <span class="cpp-keyword">case</span> TGA_IMG_RLE_GRAYSCALE:<br>    <span class="cpp-keyword">case</span> TGA_IMG_RLE_PALETTED:<br><br>        <span class="cpp-comment">// FIXME: handle grayscale..</span><br><br>        <span class="cpp-keyword">for</span>( i = <span class="cpp-number">0</span>; i &lt; num_pixels; ) {<br><br>            <span class="cpp-comment">/* a bit of work to do to read the data.. */</span><br>            <span class="cpp-keyword">if</span>( fread( &amp;packet_header, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, targafile ) &lt; <span class="cpp-number">1</span> ) {<br>                <span class="cpp-comment">// well, just let them fill the rest with null pixels then…</span><br>                packet_header = <span class="cpp-number">1</span>;<br>            }<br><br>            <span class="cpp-keyword">if</span>( packet_header &amp; 0x80 ) {<br>                <span class="cpp-comment">/* run length packet */</span><br><br>                tmp_col = tga_get_pixel( targafile, bytes_per_pix, colormap, cmap_bytes_entry );<br>                tmp_col = tga_convert_color( tmp_col, true_bits_per_pixel, alphabits, format );<br><br>                repcount = (packet_header &amp; 0x7F) + <span class="cpp-number">1</span>;<br><br>                <span class="cpp-comment">/* write all the data out */</span><br>                <span class="cpp-keyword">for</span>( j = <span class="cpp-number">0</span>; j &lt; repcount; j++ ) {<br>                    tga_write_pixel_to_mem( image_data, img_spec_img_desc,<br>                        i + j, img_spec_width, img_spec_height, tmp_col, format );<br>                }<br><br>                i += repcount;<br><br>            } <span class="cpp-keyword">else</span> {<br>                <span class="cpp-comment">/* raw packet */</span><br>                <span class="cpp-comment">/* get pixel from file */</span><br><br>                repcount = (packet_header &amp; 0x7F) + <span class="cpp-number">1</span>;<br><br>                <span class="cpp-keyword">for</span>( j = <span class="cpp-number">0</span>; j &lt; repcount; j++ ) {<br><br>                    tmp_col = tga_get_pixel( targafile, bytes_per_pix, colormap, cmap_bytes_entry );<br>                    tmp_col = tga_convert_color( tmp_col, true_bits_per_pixel, alphabits, format );<br><br>                    tga_write_pixel_to_mem( image_data, img_spec_img_desc,<br>                        i + j, img_spec_width, img_spec_height, tmp_col, format );<br><br>                }<br><br>                i += repcount;<br><br>            }<br><br>        }<br><br>        <span class="cpp-keyword">break</span>;<br><br><br>    <span class="cpp-keyword">default</span>:<br><br>        TargaError = TGA_ERR_BAD_IMAGE_TYPE;<br>        <span class="cpp-keyword">return</span>( NULL );<br><br>    }<br><br>    fclose( targafile );<br><br>    *width  = img_spec_width;<br>    *height = img_spec_height;<br><br>    <span class="cpp-keyword">return</span>( (<span class="cpp-keyword">void</span> *)image_data );<br><br>}<br><br><br><br><br><br><span class="cpp-keyword">int</span> tga_write_raw( <span class="cpp-keyword">const</span> <span class="cpp-keyword">char</span> * file, <span class="cpp-keyword">int</span> width, <span class="cpp-keyword">int</span> height, <span class="cpp-keyword">unsigned</span> <span class="cpp-keyword">char</span> * dat, <span class="cpp-keyword">unsigned</span> <span class="cpp-keyword">int</span> format ) {<br><br>    FILE * tga;<br><br>    uint32 i, j;<br><br>    uint32 size = width * height;<br><br>    <span class="cpp-keyword">float</span> red, green, blue, alpha;<br><br>    <span class="cpp-keyword">char</span> id[] = <span class="cpp-literal">"written with libtarga"</span>;<br>    ubyte idlen = <span class="cpp-number">21</span>;<br>    ubyte zeroes[<span class="cpp-number">5</span>] = { <span class="cpp-number">0</span>, <span class="cpp-number">0</span>, <span class="cpp-number">0</span>, <span class="cpp-number">0</span>, <span class="cpp-number">0</span> };<br>    uint32 pixbuf;<br>    ubyte one = <span class="cpp-number">1</span>;<br>    ubyte cmap_type = <span class="cpp-number">0</span>;<br>    ubyte img_type  = <span class="cpp-number">2</span>;  <span class="cpp-comment">// 2 - uncompressed truecolor  10 - RLE truecolor</span><br>    uint16 xorigin  = <span class="cpp-number">0</span>;<br>    uint16 yorigin  = <span class="cpp-number">0</span>;<br>    ubyte  pixdepth = format * <span class="cpp-number">8</span>;  <span class="cpp-comment">// bpp</span><br>    ubyte img_desc;<br><br><br>    <span class="cpp-keyword">switch</span>( format ) {<br><br>    <span class="cpp-keyword">case</span> TGA_TRUECOLOR_24:<br>        img_desc = <span class="cpp-number">0</span>;<br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">case</span> TGA_TRUECOLOR_32:<br>        img_desc = <span class="cpp-number">8</span>;<br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">default</span>:<br>        TargaError = TGA_ERR_BAD_FORMAT;<br>        <span class="cpp-keyword">return</span>( <span class="cpp-number">0</span> );<br>        <span class="cpp-keyword">break</span>;<br><br>    }<br><br>    tga = fopen( file, <span class="cpp-literal">"wb"</span> );<br><br>    <span class="cpp-keyword">if</span>( tga == NULL ) {<br>        TargaError = TGA_ERR_OPEN_FAILS;<br>        <span class="cpp-keyword">return</span>( <span class="cpp-number">0</span> );<br>    }<br><br>    <span class="cpp-comment">// write id length</span><br>    fwrite( &amp;idlen, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><br>    <span class="cpp-comment">// write colormap type</span><br>    fwrite( &amp;cmap_type, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><br>    <span class="cpp-comment">// write image type</span><br>    fwrite( &amp;img_type, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><br>    <span class="cpp-comment">// write cmap spec.</span><br>    fwrite( &amp;zeroes, <span class="cpp-number">5</span>, <span class="cpp-number">1</span>, tga );<br><br>    <span class="cpp-comment">// write image spec.</span><br>    fwrite( &amp;xorigin, <span class="cpp-number">2</span>, <span class="cpp-number">1</span>, tga );<br>    fwrite( &amp;yorigin, <span class="cpp-number">2</span>, <span class="cpp-number">1</span>, tga );<br>    fwrite( &amp;width, <span class="cpp-number">2</span>, <span class="cpp-number">1</span>, tga );<br>    fwrite( &amp;height, <span class="cpp-number">2</span>, <span class="cpp-number">1</span>, tga );<br>    fwrite( &amp;pixdepth, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br>    fwrite( &amp;img_desc, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><br><br>    <span class="cpp-comment">// write image id.</span><br>    fwrite( &amp;id, idlen, <span class="cpp-number">1</span>, tga );<br><br>    <span class="cpp-comment">// color correction – data is in RGB, need BGR.</span><br>    <span class="cpp-keyword">for</span>( i = <span class="cpp-number">0</span>; i &lt; size; i++ ) {<br><br>        pixbuf = <span class="cpp-number">0</span>;<br>        <span class="cpp-keyword">for</span>( j = <span class="cpp-number">0</span>; j &lt; format; j++ ) {<br>            pixbuf += dat[i*format+j] &lt;&lt; (<span class="cpp-number">8</span> * j);<br>        }<br><br>        <span class="cpp-keyword">switch</span>( format ) {<br><br>        <span class="cpp-keyword">case</span> TGA_TRUECOLOR_24:<br><br>            pixbuf = ((pixbuf &amp; 0xFF) &lt;&lt; <span class="cpp-number">16</span>) +<br>                     (pixbuf &amp; 0xFF00) +<br>                     ((pixbuf &amp; 0xFF0000) &gt;&gt; <span class="cpp-number">16</span>);<br><br>            pixbuf = htotl( pixbuf );<br><br>            fwrite( &amp;pixbuf, <span class="cpp-number">3</span>, <span class="cpp-number">1</span>, tga );<br><br>            <span class="cpp-keyword">break</span>;<br><br>        <span class="cpp-keyword">case</span> TGA_TRUECOLOR_32:<br><br>            <span class="cpp-comment">/* need to un-premultiply alpha.. */</span><br><br>            red     = (pixbuf &amp; 0xFF) / <span class="cpp-number">255</span>.0f;<br>            green   = ((pixbuf &amp; 0xFF00) &gt;&gt; <span class="cpp-number">8</span>) / <span class="cpp-number">255</span>.0f;<br>            blue    = ((pixbuf &amp; 0xFF0000) &gt;&gt; <span class="cpp-number">16</span>) / <span class="cpp-number">255</span>.0f;<br>            alpha   = ((pixbuf &amp; 0xFF000000) &gt;&gt; <span class="cpp-number">24</span>) / <span class="cpp-number">255</span>.0f;<br><br>            <span class="cpp-keyword">if</span>( alpha &gt; <span class="cpp-number">0</span>.<span class="cpp-number">0001</span> ) {<br>                red /= alpha;<br>                green /= alpha;<br>                blue /= alpha;<br>            }<br><br>            <span class="cpp-comment">/* clamp to 1.0f */</span><br><br>            red = red &gt; <span class="cpp-number">1</span>.0f ? <span class="cpp-number">255</span>.0f : red * <span class="cpp-number">255</span>.0f;<br>            green = green &gt; <span class="cpp-number">1</span>.0f ? <span class="cpp-number">255</span>.0f : green * <span class="cpp-number">255</span>.0f;<br>            blue = blue &gt; <span class="cpp-number">1</span>.0f ? <span class="cpp-number">255</span>.0f : blue * <span class="cpp-number">255</span>.0f;<br>            alpha = alpha &gt; <span class="cpp-number">1</span>.0f ? <span class="cpp-number">255</span>.0f : alpha * <span class="cpp-number">255</span>.0f;<br><br>            pixbuf = (ubyte)blue + (((ubyte)green) &lt;&lt; <span class="cpp-number">8</span>) +<br>                (((ubyte)red) &lt;&lt; <span class="cpp-number">16</span>) + (((ubyte)alpha) &lt;&lt; <span class="cpp-number">24</span>);<br><br>            pixbuf = htotl( pixbuf );<br><br>            fwrite( &amp;pixbuf, <span class="cpp-number">4</span>, <span class="cpp-number">1</span>, tga );<br><br>            <span class="cpp-keyword">break</span>;<br><br>        }<br><br>    }<br><br>    fclose( tga );<br><br>    <span class="cpp-keyword">return</span>( <span class="cpp-number">1</span> );<br><br>}<br><br><br><br><br><br><span class="cpp-keyword">int</span> tga_write_rle( <span class="cpp-keyword">const</span> <span class="cpp-keyword">char</span> * file, <span class="cpp-keyword">int</span> width, <span class="cpp-keyword">int</span> height, <span class="cpp-keyword">unsigned</span> <span class="cpp-keyword">char</span> * dat, <span class="cpp-keyword">unsigned</span> <span class="cpp-keyword">int</span> format ) {<br><br>    FILE * tga;<br><br>    uint32 i, j;<br>    uint32 oc, nc;<br><br>    <span class="cpp-keyword">enum</span> RLE_STATE { INIT, NONE, RLP, RAWP };<br><br>    <span class="cpp-keyword">int</span> state = INIT;<br><br>    uint32 size = width * height;<br><br>    uint16 shortwidth = (uint16)width;<br>    uint16 shortheight = (uint16)height;<br><br>    ubyte repcount;<br><br>    <span class="cpp-keyword">float</span> red, green, blue, alpha;<br><br>    <span class="cpp-keyword">int</span> idx, row, column;<br><br>    <span class="cpp-comment">// have to buffer a whole line for raw packets.</span><br>    <span class="cpp-keyword">unsigned</span> <span class="cpp-keyword">char</span> * rawbuf = (<span class="cpp-keyword">unsigned</span> <span class="cpp-keyword">char</span> *)malloc( width * format );<br><br>    <span class="cpp-keyword">char</span> id[] = <span class="cpp-literal">"written with libtarga"</span>;<br>    ubyte idlen = <span class="cpp-number">21</span>;<br>    ubyte zeroes[<span class="cpp-number">5</span>] = { <span class="cpp-number">0</span>, <span class="cpp-number">0</span>, <span class="cpp-number">0</span>, <span class="cpp-number">0</span>, <span class="cpp-number">0</span> };<br>    uint32 pixbuf;<br>    ubyte one = <span class="cpp-number">1</span>;<br>    ubyte cmap_type = <span class="cpp-number">0</span>;<br>    ubyte img_type  = <span class="cpp-number">10</span>;  <span class="cpp-comment">// 2 - uncompressed truecolor  10 - RLE truecolor</span><br>    uint16 xorigin  = <span class="cpp-number">0</span>;<br>    uint16 yorigin  = <span class="cpp-number">0</span>;<br>    ubyte  pixdepth = format * <span class="cpp-number">8</span>;  <span class="cpp-comment">// bpp</span><br>    ubyte img_desc  = format == TGA_TRUECOLOR_32 ? <span class="cpp-number">8</span> : <span class="cpp-number">0</span>;<br><br><br>    <span class="cpp-keyword">switch</span>( format ) {<br>    <span class="cpp-keyword">case</span> TGA_TRUECOLOR_24:<br>    <span class="cpp-keyword">case</span> TGA_TRUECOLOR_32:<br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">default</span>:<br>        TargaError = TGA_ERR_BAD_FORMAT;<br>        <span class="cpp-keyword">return</span>( <span class="cpp-number">0</span> );<br>    }<br><br><br>    tga = fopen( file, <span class="cpp-literal">"wb"</span> );<br><br>    <span class="cpp-keyword">if</span>( tga == NULL ) {<br>        TargaError = TGA_ERR_OPEN_FAILS;<br>        <span class="cpp-keyword">return</span>( <span class="cpp-number">0</span> );<br>    }<br><br>    <span class="cpp-comment">// write id length</span><br>    fwrite( &amp;idlen, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><br>    <span class="cpp-comment">// write colormap type</span><br>    fwrite( &amp;cmap_type, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><br>    <span class="cpp-comment">// write image type</span><br>    fwrite( &amp;img_type, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><br>    <span class="cpp-comment">// write cmap spec.</span><br>    fwrite( &amp;zeroes, <span class="cpp-number">5</span>, <span class="cpp-number">1</span>, tga );<br><br>    <span class="cpp-comment">// write image spec.</span><br>    fwrite( &amp;xorigin, <span class="cpp-number">2</span>, <span class="cpp-number">1</span>, tga );<br>    fwrite( &amp;yorigin, <span class="cpp-number">2</span>, <span class="cpp-number">1</span>, tga );<br>    fwrite( &amp;shortwidth, <span class="cpp-number">2</span>, <span class="cpp-number">1</span>, tga );<br>    fwrite( &amp;shortheight, <span class="cpp-number">2</span>, <span class="cpp-number">1</span>, tga );<br>    fwrite( &amp;pixdepth, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br>    fwrite( &amp;img_desc, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><br><br>    <span class="cpp-comment">// write image id.</span><br>    fwrite( &amp;id, idlen, <span class="cpp-number">1</span>, tga );<br><br>    <span class="cpp-comment">// initial color values – just to shut up the compiler.</span><br>    nc = <span class="cpp-number">0</span>;<br><br>    <span class="cpp-comment">// color correction – data is in RGB, need BGR.</span><br>    <span class="cpp-comment">// also run-length-encoding.</span><br>    <span class="cpp-keyword">for</span>( i = <span class="cpp-number">0</span>; i &lt; size; i++ ) {<br><br>        idx = i * format;<br><br>        row = i / width;<br>        column = i % width;<br><br>        <span class="cpp-comment">//printf( "row: %d, col: %d\n", row, column );</span><br>        pixbuf = <span class="cpp-number">0</span>;<br>        <span class="cpp-keyword">for</span>( j = <span class="cpp-number">0</span>; j &lt; format; j++ ) {<br>            pixbuf += dat[idx+j] &lt;&lt; (<span class="cpp-number">8</span> * j);<br>        }<br><br>        <span class="cpp-keyword">switch</span>( format ) {<br><br>        <span class="cpp-keyword">case</span> TGA_TRUECOLOR_24:<br><br>            pixbuf = ((pixbuf &amp; 0xFF) &lt;&lt; <span class="cpp-number">16</span>) +<br>                     (pixbuf &amp; 0xFF00) +<br>                     ((pixbuf &amp; 0xFF0000) &gt;&gt; <span class="cpp-number">16</span>);<br><br>            pixbuf = htotl( pixbuf );<br>            <span class="cpp-keyword">break</span>;<br><br>        <span class="cpp-keyword">case</span> TGA_TRUECOLOR_32:<br><br>            <span class="cpp-comment">/* need to un-premultiply alpha.. */</span><br><br>            red     = (pixbuf &amp; 0xFF) / <span class="cpp-number">255</span>.0f;<br>            green   = ((pixbuf &amp; 0xFF00) &gt;&gt; <span class="cpp-number">8</span>) / <span class="cpp-number">255</span>.0f;<br>            blue    = ((pixbuf &amp; 0xFF0000) &gt;&gt; <span class="cpp-number">16</span>) / <span class="cpp-number">255</span>.0f;<br>            alpha   = ((pixbuf &amp; 0xFF000000) &gt;&gt; <span class="cpp-number">24</span>) / <span class="cpp-number">255</span>.0f;<br><br>            <span class="cpp-keyword">if</span>( alpha &gt; <span class="cpp-number">0</span>.<span class="cpp-number">0001</span> ) {<br>                red /= alpha;<br>                green /= alpha;<br>                blue /= alpha;<br>            }<br><br>            <span class="cpp-comment">/* clamp to 1.0f */</span><br><br>            red = red &gt; <span class="cpp-number">1</span>.0f ? <span class="cpp-number">255</span>.0f : red * <span class="cpp-number">255</span>.0f;<br>            green = green &gt; <span class="cpp-number">1</span>.0f ? <span class="cpp-number">255</span>.0f : green * <span class="cpp-number">255</span>.0f;<br>            blue = blue &gt; <span class="cpp-number">1</span>.0f ? <span class="cpp-number">255</span>.0f : blue * <span class="cpp-number">255</span>.0f;<br>            alpha = alpha &gt; <span class="cpp-number">1</span>.0f ? <span class="cpp-number">255</span>.0f : alpha * <span class="cpp-number">255</span>.0f;<br><br>            pixbuf = (ubyte)blue + (((ubyte)green) &lt;&lt; <span class="cpp-number">8</span>) +<br>                (((ubyte)red) &lt;&lt; <span class="cpp-number">16</span>) + (((ubyte)alpha) &lt;&lt; <span class="cpp-number">24</span>);<br><br>            pixbuf = htotl( pixbuf );<br>            <span class="cpp-keyword">break</span>;<br><br>        }<br><br><br>        oc = nc;<br><br>        nc = pixbuf;<br><br><br>        <span class="cpp-keyword">switch</span>( state ) {<br><br>        <span class="cpp-keyword">case</span> INIT:<br>            <span class="cpp-comment">// this is just used to make sure we have 2 pixel values to consider.</span><br>            state = NONE;<br>            <span class="cpp-keyword">break</span>;<br><br><br>        <span class="cpp-keyword">case</span> NONE:<br><br>            <span class="cpp-keyword">if</span>( column == <span class="cpp-number">0</span> ) {<br>                <span class="cpp-comment">// write a 1 pixel raw packet for the old pixel, then go thru again.</span><br>                repcount = <span class="cpp-number">0</span>;<br>                fwrite( &amp;repcount, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>                fwrite( (&amp;oc)+<span class="cpp-number">4</span>, format, <span class="cpp-number">1</span>, tga );  <span class="cpp-comment">// byte order..</span><br>#<span class="cpp-keyword">else</span><br>                fwrite( &amp;oc, format, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#endif</span><br>                state = NONE;<br>                <span class="cpp-keyword">break</span>;<br>            }<br><br>            <span class="cpp-keyword">if</span>( nc == oc ) {<br>                repcount = <span class="cpp-number">0</span>;<br>                state = RLP;<br>            } <span class="cpp-keyword">else</span> {<br>                repcount = <span class="cpp-number">0</span>;<br>                state = RAWP;<br>                <span class="cpp-keyword">for</span>( j = <span class="cpp-number">0</span>; j &lt; format; j++ ) {<br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>                    rawbuf[(repcount * format) + j] = (ubyte)(*((&amp;oc)+format-j-<span class="cpp-number">1</span>));<br>#<span class="cpp-keyword">else</span><br>                    rawbuf[(repcount * format) + j] = *(((ubyte *)(&amp;oc)) + j);<br><span class="cpp-directive">#endif</span><br>                }<br>            }<br>            <span class="cpp-keyword">break</span>;<br><br><br>        <span class="cpp-keyword">case</span> RLP:<br>            repcount++;<br><br>            <span class="cpp-keyword">if</span>( column == <span class="cpp-number">0</span> ) {<br>                <span class="cpp-comment">// finish off rlp.</span><br>                repcount |= 0x80;<br>                fwrite( &amp;repcount, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>                fwrite( (&amp;oc)+<span class="cpp-number">4</span>, format, <span class="cpp-number">1</span>, tga );  <span class="cpp-comment">// byte order..</span><br>#<span class="cpp-keyword">else</span><br>                fwrite( &amp;oc, format, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#endif</span><br>                state = NONE;<br>                <span class="cpp-keyword">break</span>;<br>            }<br><br>            <span class="cpp-keyword">if</span>( repcount == <span class="cpp-number">127</span> ) {<br>                <span class="cpp-comment">// finish off rlp.</span><br>                repcount |= 0x80;<br>                fwrite( &amp;repcount, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>                fwrite( (&amp;oc)+<span class="cpp-number">4</span>, format, <span class="cpp-number">1</span>, tga );  <span class="cpp-comment">// byte order..</span><br>#<span class="cpp-keyword">else</span><br>                fwrite( &amp;oc, format, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#endif</span><br>                state = NONE;<br>                <span class="cpp-keyword">break</span>;<br>            }<br><br>            <span class="cpp-keyword">if</span>( nc != oc ) {<br>                <span class="cpp-comment">// finish off rlp</span><br>                repcount |= 0x80;<br>                fwrite( &amp;repcount, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>                fwrite( (&amp;oc)+<span class="cpp-number">4</span>, format, <span class="cpp-number">1</span>, tga );  <span class="cpp-comment">// byte order..</span><br>#<span class="cpp-keyword">else</span><br>                fwrite( &amp;oc, format, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#endif</span><br>                state = NONE;<br>            }<br>            <span class="cpp-keyword">break</span>;<br><br><br>        <span class="cpp-keyword">case</span> RAWP:<br>            repcount++;<br><br>            <span class="cpp-keyword">if</span>( column == <span class="cpp-number">0</span> ) {<br>                <span class="cpp-comment">// finish off rawp.</span><br>                <span class="cpp-keyword">for</span>( j = <span class="cpp-number">0</span>; j &lt; format; j++ ) {<br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>                    rawbuf[(repcount * format) + j] = (ubyte)(*((&amp;oc)+format-j-<span class="cpp-number">1</span>));<br>#<span class="cpp-keyword">else</span><br>                    rawbuf[(repcount * format) + j] = *(((ubyte *)(&amp;oc)) + j);<br><span class="cpp-directive">#endif</span><br>                }<br>                fwrite( &amp;repcount, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br>                fwrite( rawbuf, (repcount + <span class="cpp-number">1</span>) * format, <span class="cpp-number">1</span>, tga );<br>                state = NONE;<br>                <span class="cpp-keyword">break</span>;<br>            }<br><br>            <span class="cpp-keyword">if</span>( repcount == <span class="cpp-number">127</span> ) {<br>                <span class="cpp-comment">// finish off rawp.</span><br>                <span class="cpp-keyword">for</span>( j = <span class="cpp-number">0</span>; j &lt; format; j++ ) {<br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>                    rawbuf[(repcount * format) + j] = (ubyte)(*((&amp;oc)+format-j-<span class="cpp-number">1</span>));<br>#<span class="cpp-keyword">else</span><br>                    rawbuf[(repcount * format) + j] = *(((ubyte *)(&amp;oc)) + j);<br><span class="cpp-directive">#endif</span><br>                }<br>                fwrite( &amp;repcount, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br>                fwrite( rawbuf, (repcount + <span class="cpp-number">1</span>) * format, <span class="cpp-number">1</span>, tga );<br>                state = NONE;<br>                <span class="cpp-keyword">break</span>;<br>            }<br><br>            <span class="cpp-keyword">if</span>( nc == oc ) {<br>                <span class="cpp-comment">// finish off rawp</span><br>                repcount–;<br>                fwrite( &amp;repcount, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br>                fwrite( rawbuf, (repcount + <span class="cpp-number">1</span>) * format, <span class="cpp-number">1</span>, tga );<br><br>                <span class="cpp-comment">// start new rlp</span><br>                repcount = <span class="cpp-number">0</span>;<br>                state = RLP;<br>                <span class="cpp-keyword">break</span>;<br>            }<br><br>            <span class="cpp-comment">// continue making rawp</span><br>            <span class="cpp-keyword">for</span>( j = <span class="cpp-number">0</span>; j &lt; format; j++ ) {<br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>                rawbuf[(repcount * format) + j] = (ubyte)(*((&amp;oc)+format-j-<span class="cpp-number">1</span>));<br>#<span class="cpp-keyword">else</span><br>                rawbuf[(repcount * format) + j] = *(((ubyte *)(&amp;oc)) + j);<br><span class="cpp-directive">#endif</span><br>            }<br><br>            <span class="cpp-keyword">break</span>;<br><br>        }<br><br><br>    }<br><br><br>    <span class="cpp-comment">// clean up state.</span><br><br>    <span class="cpp-keyword">switch</span>( state ) {<br><br>    <span class="cpp-keyword">case</span> INIT:<br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">case</span> NONE:<br>        <span class="cpp-comment">// write the last 2 pixels in a raw packet.</span><br>        fwrite( &amp;one, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>                fwrite( (&amp;oc)+<span class="cpp-number">4</span>, format, <span class="cpp-number">1</span>, tga );  <span class="cpp-comment">// byte order..</span><br>#<span class="cpp-keyword">else</span><br>                fwrite( &amp;oc, format, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#endif</span><br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>                fwrite( (&amp;nc)+<span class="cpp-number">4</span>, format, <span class="cpp-number">1</span>, tga );  <span class="cpp-comment">// byte order..</span><br>#<span class="cpp-keyword">else</span><br>                fwrite( &amp;nc, format, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#endif</span><br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">case</span> RLP:<br>        repcount++;<br>        repcount |= 0x80;<br>        fwrite( &amp;repcount, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>                fwrite( (&amp;oc)+<span class="cpp-number">4</span>, format, <span class="cpp-number">1</span>, tga );  <span class="cpp-comment">// byte order..</span><br>#<span class="cpp-keyword">else</span><br>                fwrite( &amp;oc, format, <span class="cpp-number">1</span>, tga );<br><span class="cpp-directive">#endif</span><br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">case</span> RAWP:<br>        repcount++;<br>        <span class="cpp-keyword">for</span>( j = <span class="cpp-number">0</span>; j &lt; format; j++ ) {<br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>            rawbuf[(repcount * format) + j] = (ubyte)(*((&amp;oc)+format-j-<span class="cpp-number">1</span>));<br>#<span class="cpp-keyword">else</span><br>            rawbuf[(repcount * format) + j] = *(((ubyte *)(&amp;oc)) + j);<br><span class="cpp-directive">#endif</span><br>        }<br>        fwrite( &amp;repcount, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga );<br>        fwrite( rawbuf, (repcount + <span class="cpp-number">1</span>) * <span class="cpp-number">3</span>, <span class="cpp-number">1</span>, tga );<br>        <span class="cpp-keyword">break</span>;<br><br>    }<br><br><br>    <span class="cpp-comment">// close the file.</span><br>    fclose( tga );<br><br>    free( rawbuf );<br><br>    <span class="cpp-keyword">return</span>( <span class="cpp-number">1</span> );<br><br>}<br><br><br><br><br><br><br><span class="cpp-comment">/*************************************************************************************************/</span><br><br><br><br><br><br><br><br><span class="cpp-keyword">static</span> <span class="cpp-keyword">void</span> tga_write_pixel_to_mem( ubyte * dat, ubyte img_spec, uint32 number,<br>                                   uint32 w, uint32 h, uint32 pixel, uint32 format ) {<br><br>    <span class="cpp-comment">// write the pixel to the data regarding how the</span><br>    <span class="cpp-comment">// header says the data is ordered.</span><br><br>    uint32 j;<br>    uint32 x, y;<br>    uint32 addy;<br><br>    <span class="cpp-keyword">switch</span>( (img_spec &amp; 0x30) &gt;&gt; <span class="cpp-number">4</span> ) {<br><br>    <span class="cpp-keyword">case</span> TGA_LOWER_RIGHT:<br>        x = w - <span class="cpp-number">1</span> - (number % w);<br>        y = number / h;<br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">case</span> TGA_UPPER_LEFT:<br>        x = number % w;<br>        y = h - <span class="cpp-number">1</span> - (number / w);<br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">case</span> TGA_UPPER_RIGHT:<br>        x = w - <span class="cpp-number">1</span> - (number % w);<br>        y = h - <span class="cpp-number">1</span> - (number / w);<br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">case</span> TGA_LOWER_LEFT:<br>    <span class="cpp-keyword">default</span>:<br>        x = number % w;<br>        y = number / w;<br>        <span class="cpp-keyword">break</span>;<br><br>    }<br><br>    addy = (y * w + x) * format;<br>    <span class="cpp-keyword">for</span>( j = <span class="cpp-number">0</span>; j &lt; format; j++ ) {<br>        dat[addy + j] = (ubyte)((pixel &gt;&gt; (j * <span class="cpp-number">8</span>)) &amp; 0xFF);<br>    }<br><br>}<br><br><br><br><br><br><span class="cpp-keyword">static</span> uint32 tga_get_pixel( FILE * tga, ubyte bytes_per_pix,<br>                            ubyte * colormap, ubyte cmap_bytes_entry ) {<br><br>    <span class="cpp-comment">/* get the image data value out */</span><br><br>    uint32 tmp_col;<br>    uint32 tmp_int32;<br>    ubyte tmp_byte;<br><br>    uint32 j;<br><br>    tmp_int32 = <span class="cpp-number">0</span>;<br>    <span class="cpp-keyword">for</span>( j = <span class="cpp-number">0</span>; j &lt; bytes_per_pix; j++ ) {<br>        <span class="cpp-keyword">if</span>( fread( &amp;tmp_byte, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, tga ) &lt; <span class="cpp-number">1</span> ) {<br>            tmp_int32 = <span class="cpp-number">0</span>;<br>        } <span class="cpp-keyword">else</span> {<br>            tmp_int32 += tmp_byte &lt;&lt; (j * <span class="cpp-number">8</span>);<br>        }<br>    }<br><br>    <span class="cpp-comment">/* byte-order correct the thing */</span><br>    <span class="cpp-keyword">switch</span>( bytes_per_pix ) {<br><br>    <span class="cpp-keyword">case</span> <span class="cpp-number">2</span>:<br>        tmp_int32 = ttohs( (uint16)tmp_int32 );<br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">case</span> <span class="cpp-number">3</span>: <span class="cpp-comment">/* intentional fall-thru */</span><br>    <span class="cpp-keyword">case</span> <span class="cpp-number">4</span>:<br>        tmp_int32 = ttohl( tmp_int32 );<br>        <span class="cpp-keyword">break</span>;<br><br>    }<br><br>    <span class="cpp-keyword">if</span>( colormap != NULL ) {<br>        <span class="cpp-comment">/* need to look up value to get real color */</span><br>        tmp_col = <span class="cpp-number">0</span>;<br>        <span class="cpp-keyword">for</span>( j = <span class="cpp-number">0</span>; j &lt; cmap_bytes_entry; j++ ) {<br>            tmp_col += colormap[cmap_bytes_entry * tmp_int32 + j] &lt;&lt; (<span class="cpp-number">8</span> * j);<br>        }<br>    } <span class="cpp-keyword">else</span> {<br>        tmp_col = tmp_int32;<br>    }<br><br>    <span class="cpp-keyword">return</span>( tmp_col );<br><br>}<br><br><br><br><br><br><span class="cpp-keyword">static</span> uint32 tga_convert_color( uint32 pixel, uint32 bpp_in, ubyte alphabits, uint32 format_out ) {<br><br>    <span class="cpp-comment">// this is not only responsible for converting from different depths</span><br>    <span class="cpp-comment">// to other depths, it also switches BGR to RGB.</span><br><br>    <span class="cpp-comment">// this thing will also premultiply alpha, on a pixel by pixel basis.</span><br><br>    ubyte r, g, b, a;<br><br>    <span class="cpp-keyword">switch</span>( bpp_in ) {<br><br>    <span class="cpp-keyword">case</span> <span class="cpp-number">32</span>:<br>        <span class="cpp-keyword">if</span>( alphabits == <span class="cpp-number">0</span> ) {<br>            <span class="cpp-keyword">goto</span> is_24_bit_in_disguise;<br>        }<br>        <span class="cpp-comment">// 32-bit to 32-bit – nop.</span><br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">case</span> <span class="cpp-number">24</span>:<br>is_24_bit_in_disguise:<br>        <span class="cpp-comment">// 24-bit to 32-bit; (only force alpha to full)</span><br>        pixel |= 0xFF000000;<br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">case</span> <span class="cpp-number">15</span>:<br>is_15_bit_in_disguise:<br>        r = (ubyte)(((<span class="cpp-keyword">float</span>)((pixel &amp; 0x7C00) &gt;&gt; <span class="cpp-number">10</span>)) * <span class="cpp-number">8</span>.2258f);<br>        g = (ubyte)(((<span class="cpp-keyword">float</span>)((pixel &amp; 0x03E0) &gt;&gt; <span class="cpp-number">5</span> )) * <span class="cpp-number">8</span>.2258f);<br>        b = (ubyte)(((<span class="cpp-keyword">float</span>)(pixel &amp; 0x001F)) * <span class="cpp-number">8</span>.2258f);<br>        <span class="cpp-comment">// 15-bit to 32-bit; (force alpha to full)</span><br>        pixel = 0xFF000000 + (r &lt;&lt; <span class="cpp-number">16</span>) + (g &lt;&lt; <span class="cpp-number">8</span>) + b;<br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">case</span> <span class="cpp-number">16</span>:<br>        <span class="cpp-keyword">if</span>( alphabits == <span class="cpp-number">1</span> ) {<br>            <span class="cpp-keyword">goto</span> is_15_bit_in_disguise;<br>        }<br>        <span class="cpp-comment">// 16-bit to 32-bit; (force alpha to full)</span><br>        r = (ubyte)(((<span class="cpp-keyword">float</span>)((pixel &amp; 0xF800) &gt;&gt; <span class="cpp-number">11</span>)) * <span class="cpp-number">8</span>.2258f);<br>        g = (ubyte)(((<span class="cpp-keyword">float</span>)((pixel &amp; 0x07E0) &gt;&gt; <span class="cpp-number">5</span> )) * <span class="cpp-number">4</span>.0476f);<br>        b = (ubyte)(((<span class="cpp-keyword">float</span>)(pixel &amp; 0x001F)) * <span class="cpp-number">8</span>.2258f);<br>        pixel = 0xFF000000 + (r &lt;&lt; <span class="cpp-number">16</span>) + (g &lt;&lt; <span class="cpp-number">8</span>) + b;<br>        <span class="cpp-keyword">break</span>;<br><br>    }<br><br>    <span class="cpp-comment">// convert the 32-bit pixel from BGR to RGB.</span><br>    pixel = (pixel &amp; 0xFF00FF00) + ((pixel &amp; 0xFF) &lt;&lt; <span class="cpp-number">16</span>) + ((pixel &amp; 0xFF0000) &gt;&gt; <span class="cpp-number">16</span>);<br><br>    r = pixel &amp; 0x000000FF;<br>    g = (pixel &amp; 0x0000FF00) &gt;&gt; <span class="cpp-number">8</span>;<br>    b = (pixel &amp; 0x00FF0000) &gt;&gt; <span class="cpp-number">16</span>;<br>    a = (pixel &amp; 0xFF000000) &gt;&gt; <span class="cpp-number">24</span>;<br><br>    <span class="cpp-comment">// not premultiplied alpha – multiply.</span><br>    <span class="cpp-comment">//r = (ubyte)(((float)r / 255.0f) * ((float)a / 255.0f) * 255.0f);</span><br>    <span class="cpp-comment">//g = (ubyte)(((float)g / 255.0f) * ((float)a / 255.0f) * 255.0f);</span><br>    <span class="cpp-comment">//b = (ubyte)(((float)b / 255.0f) * ((float)a / 255.0f) * 255.0f);</span><br><br>    pixel = r + (g &lt;&lt; <span class="cpp-number">8</span>) + (b &lt;&lt; <span class="cpp-number">16</span>) + (a &lt;&lt; <span class="cpp-number">24</span>);<br><br>    <span class="cpp-comment">/* now convert from 32-bit to whatever they want. */</span><br><br>    <span class="cpp-keyword">switch</span>( format_out ) {<br><br>    <span class="cpp-keyword">case</span> TGA_TRUECOLOR_32:<br>        <span class="cpp-comment">// 32 to 32 – nop.</span><br>        <span class="cpp-keyword">break</span>;<br><br>    <span class="cpp-keyword">case</span> TGA_TRUECOLOR_24:<br>        <span class="cpp-comment">// 32 to 24 – discard alpha.</span><br>        pixel &amp;= 0x00FFFFFF;<br>        <span class="cpp-keyword">break</span>;<br><br>    }<br><br>    <span class="cpp-keyword">return</span>( pixel );<br><br>}<br><br><br><br><br><span class="cpp-keyword">static</span> int16 ttohs( int16 val ) {<br><br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>    <span class="cpp-keyword">return</span>( ((val &amp; 0xFF) &lt;&lt; <span class="cpp-number">8</span>) + (val &gt;&gt; <span class="cpp-number">8</span>) );<br>#<span class="cpp-keyword">else</span><br>    <span class="cpp-keyword">return</span>( val );<br><span class="cpp-directive">#endif</span><br><br>}<br><br><br><span class="cpp-keyword">static</span> int16 htots( int16 val ) {<br><br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>    <span class="cpp-keyword">return</span>( ((val &amp; 0xFF) &lt;&lt; <span class="cpp-number">8</span>) + (val &gt;&gt; <span class="cpp-number">8</span>) );<br>#<span class="cpp-keyword">else</span><br>    <span class="cpp-keyword">return</span>( val );<br><span class="cpp-directive">#endif</span><br><br>}<br><br><br><span class="cpp-keyword">static</span> int32 ttohl( int32 val ) {<br><br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>    <span class="cpp-keyword">return</span>( ((val &amp; 0x000000FF) &lt;&lt; <span class="cpp-number">24</span>) +<br>            ((val &amp; 0x0000FF00) &lt;&lt; <span class="cpp-number">8</span>)  +<br>            ((val &amp; 0x00FF0000) &gt;&gt; <span class="cpp-number">8</span>)  +<br>            ((val &amp; 0xFF000000) &gt;&gt; <span class="cpp-number">24</span>) );<br>#<span class="cpp-keyword">else</span><br>    <span class="cpp-keyword">return</span>( val );<br><span class="cpp-directive">#endif</span><br><br>}<br><br><br><span class="cpp-keyword">static</span> int32 htotl( int32 val ) {<br><br><span class="cpp-directive">#ifdef</span> WORDS_BIGENDIAN<br>    <span class="cpp-keyword">return</span>( ((val &amp; 0x000000FF) &lt;&lt; <span class="cpp-number">24</span>) +<br>            ((val &amp; 0x0000FF00) &lt;&lt; <span class="cpp-number">8</span>)  +<br>            ((val &amp; 0x00FF0000) &gt;&gt; <span class="cpp-number">8</span>)  +<br>            ((val &amp; 0xFF000000) &gt;&gt; <span class="cpp-number">24</span>) );<br>#<span class="cpp-keyword">else</span><br>    <span class="cpp-keyword">return</span>( val );<br><span class="cpp-directive">#endif</span><br><br>}<br><br><br></pre></div><!–ENDSCRIPT–><br><br><br><br>my code to use library…<br><br><!–STARTSCRIPT–><!–source lang="cpp"–><div class="source"><pre><br><br><span class="cpp-keyword">typedef</span> <span class="cpp-keyword">struct</span> image{<br>   GLint sizeX, sizeY;<br>   GLuint type,bpp;<span class="cpp-comment">//GL_RGB,GL_RGBA</span><br>   <span class="cpp-keyword">unsigned</span> <span class="cpp-keyword">char</span> *data;<br>} image;<br><br><span class="cpp-keyword">typedef</span> <span class="cpp-keyword">struct</span> material{<br>   <span class="cpp-keyword">bool</span> loaded;<span class="cpp-comment">//1 = loaded/true</span><br>   <span class="cpp-keyword">bool</span> textured;<span class="cpp-comment">//1=textured</span><br>   <span class="cpp-keyword">bool</span> spheremap;<br>   GLuint type;<br>   GLuint tex;<br>	<span class="cpp-keyword">float</span> r,g,b,a;<br>} material;<br><br>image * loadtga(<span class="cpp-keyword">char</span> *filename){<br>	<span class="cpp-keyword">unsigned</span> <span class="cpp-keyword">char</span>* targaimage;<br>	<span class="cpp-keyword">int</span> wdt, hgt;<br>	targaimage = (<span class="cpp-keyword">unsigned</span> <span class="cpp-keyword">char</span>*)tga_load(filename, &amp;wdt, &amp;hgt, TGA_TRUECOLOR_32);<br><br>	<span class="cpp-keyword">if</span> (targaimage == NULL){<br>	   printf(<span class="cpp-literal">"Failed to read image!\n"</span>);<br>	   printf(tga_error_string(tga_get_last_error()));<br>	}<br><br>   image * teximage;<br>   teximage=(image *)malloc(<span class="cpp-keyword">sizeof</span>(image));<br><br><br>   <span class="cpp-keyword">for</span>(<span class="cpp-keyword">int</span> index=<span class="cpp-number">0</span>;index&lt;wdt*hgt;index++){<br>      <span class="cpp-keyword">if</span>(targaimage[index*<span class="cpp-number">4</span>]==<span class="cpp-number">0</span> &amp;&amp; targaimage[index*<span class="cpp-number">4</span>+<span class="cpp-number">1</span>]==<span class="cpp-number">0</span> &amp;&amp; targaimage[index*<span class="cpp-number">4</span>+<span class="cpp-number">2</span>]==<span class="cpp-number">255</span>){<br>         targaimage[index*<span class="cpp-number">4</span>]=<span class="cpp-number">0</span>;<br>         targaimage[index*<span class="cpp-number">4</span>+<span class="cpp-number">1</span>]=<span class="cpp-number">0</span>;<br>         targaimage[index*<span class="cpp-number">4</span>+<span class="cpp-number">2</span>]=<span class="cpp-number">0</span>;<br>         targaimage[index*<span class="cpp-number">4</span>+<span class="cpp-number">3</span>]=<span class="cpp-number">0</span>;<br>      }<br>   }<br><br><br>	teximage-&gt;sizeX=wdt;<br>  	teximage-&gt;sizeY=hgt;<br>	teximage-&gt;data=targaimage;<br>  	teximage-&gt;bpp=<span class="cpp-number">4</span>;<br>  	teximage-&gt;type=GL_RGBA;<br>}<br><br><br><span class="cpp-keyword">int</span> loadtex(<span class="cpp-keyword">char</span> *str1,material * mat){<br>	GLuint * tex=&amp;(mat-&gt;tex);<br>	image * tex2=NULL;<br>	<span class="cpp-keyword">if</span>(!(tex2=loadtga(str1)))<br>		<span class="cpp-keyword">return</span>(<span class="cpp-number">0</span>);<br>	glDeleteTextures(<span class="cpp-number">1</span>,tex);<br>	glGenTextures(<span class="cpp-number">1</span>,tex);<br>	glBindTexture(GL_TEXTURE_2D, *(tex));<br>	glTexImage2D(GL_TEXTURE_2D, <span class="cpp-number">0</span>, tex2-&gt;type, tex2-&gt;sizeX,<br>		tex2-&gt;sizeY, <span class="cpp-number">0</span>, tex2-&gt;type, GL_UNSIGNED_BYTE,<br>		tex2-&gt;data);<br><br>	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);<br>	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);<br><br>	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);<br>	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);<br><br>	gluBuild2DMipmaps(GL_TEXTURE_2D, tex2-&gt;type,tex2-&gt;sizeX,tex2-&gt;sizeY,tex2-&gt;type,GL_UNSIGNED_BYTE,tex2-&gt;data);<br><br>   mat-&gt;type=tex2-&gt;type;<br><br>	<span class="cpp-keyword">if</span>(tex2){<br>		<span class="cpp-keyword">if</span>(tex2-&gt;data){<br>			free(tex2-&gt;data);<br>		}<br>		free(tex2);<br>	}<br><br>	<span class="cpp-keyword">return</span>(<span class="cpp-number">1</span>);<br>}<br><br></pre></div><!–ENDSCRIPT–> 
_______________ Play my Game at neonswarm.com
Hey there, using DevIL with OpenGL aswell. I'll share some code with you.

// main.cpp#include "exception.hpp"#include "image.hpp"#include "texture.hpp"#include <memory>int main(){// ...// init opengl first// ...	std::auto_ptr<Texture> texture;	try	{		texture.reset(new Texture(Image("tanks.png"), Texture::TRILINEAR, Texture::CLAMPTOEDGE, Texture::CLAMPTOEDGE));	}	catch(const Exception& e)	{		std::cerr << e.error << std::endl;		return 1;	}	glEnable(GL_TEXTURE_2D);	// if you want bianry transparency (either visible or not)//	glAlphaFunc(GL_GREATER, 0.0f);//	glEnable(GL_ALPHA_TEST);	// if you want varying transparency	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 	glEnable(GL_BLEND);	glBindTexture(GL_TEXTURE_2D, texture->ID());	// ready for drawing!}


// image.hpp#ifndef IMAGE_HPP#define IMAGE_HPP#include <IL/il.h>#include <string>class Image{public:	Image(const std::string& filename);	~Image();	const unsigned short Width() const;	const unsigned short Height() const;	const unsigned char* Data() const;private:	static bool devilInitialized;	unsigned char* data;	unsigned short width;	unsigned short height;};#endif


// image.cpp#include "exception.hpp"#include "image.hpp"#include <IL/il.h>#include <string>bool Image::devilInitialized = false;Image::Image(const std::string& filename){	if(!devilInitialized)	{		ilInit();		ilOriginFunc(IL_ORIGIN_LOWER_LEFT);		ilEnable(IL_ORIGIN_SET);		devilInitialized = true;	}	unsigned int devilid;	ilGenImages(1, &devilid);	if(!ilLoadImage(filename.c_str()))		throw Exception(std::string("Image library DevIL was unable to load \"") + filename + std::string("\""));	if(!ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE))		throw Exception(std::string("Image library DevIL was unable to convert \"") + filename + std::string("\" to video format of the OpenGL context."));	width = ilGetInteger(IL_IMAGE_WIDTH);	height = ilGetInteger(IL_IMAGE_HEIGHT);	unsigned short bytesperpixel = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);	unsigned long size = width * height * bytesperpixel;	data = new unsigned char[size];	memcpy(data, ilGetData(), size);	ilDeleteImages(1, &devilid);}Image::~Image(){	delete [] data;}const unsigned short Image::Width() const{	return width;}const unsigned short Image::Height() const{	return height;}const unsigned char* Image::Data() const{	return data;}


// texture.hpp#ifndef TEXTURE_HPP#define TEXTURE_HPPclass Image;	class Texture{public:	enum textureFilter	{		NONE,     // GL_NEAREST               GL_NEAREST		LINEAR,   // GL_LINEAR                GL_LINEAR		BILINEAR, // GL_LINEAR_MIPMAP_NEAREST GL_LINEAR		TRILINEAR // GL_LINEAR_MIPMAP_LINEAR  GL_LINEAR	};	enum textureWrap	{		CLAMP,		CLAMPTOEDGE,		REPEAT	};	Texture(const Image& image, textureFilter filter = TRILINEAR, textureWrap wrap_s = REPEAT, textureWrap wrap_t = REPEAT);	~Texture();	const unsigned long ID() const;private:	unsigned long textureid;};#endif


// texture.cpp#include "exception.hpp"#include "image.hpp"#include "texture.hpp"#include <OpenGL/gl.h>Texture::Texture(const Image& image, textureFilter filter, textureWrap wrap_s, textureWrap wrap_t){	GLenum minify, magnify;	bool createmipmaps = false;	switch(filter)	{		case NONE:		minify = GL_NEAREST;		magnify = GL_NEAREST;		break;		case LINEAR:		minify = GL_LINEAR;		magnify = GL_LINEAR;		break;		case BILINEAR:		minify = GL_LINEAR_MIPMAP_NEAREST;		magnify = GL_LINEAR;		createmipmaps = true;		break;		case TRILINEAR:		minify = GL_LINEAR_MIPMAP_LINEAR;		magnify = GL_LINEAR;		createmipmaps = true;		break;		default:		throw Exception("Unknown texture filter.");	}	GLenum glwrap_s;	switch(wrap_s)	{		case CLAMP:		glwrap_s = GL_CLAMP;		break;		case CLAMPTOEDGE:		glwrap_s = GL_CLAMP_TO_EDGE;		break;		case REPEAT:		glwrap_s = GL_REPEAT;		break;		default:		throw Exception("Unknown texture wrap mode for side S.");	}	GLenum glwrap_t;	switch(wrap_t)	{		case CLAMP:		glwrap_t = GL_CLAMP;		break;		case CLAMPTOEDGE:		glwrap_t = GL_CLAMP_TO_EDGE;		break;		case REPEAT:		glwrap_t = GL_REPEAT;		break;		default:		throw Exception("Unknown texture wrap mode for side T.");	}	glGenTextures(1, reinterpret_cast<GLuint*>(&textureid));	glBindTexture(GL_TEXTURE_2D, textureid);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magnify);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minify);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glwrap_s);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glwrap_t);	if(createmipmaps)		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.Width(), image.Height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.Data());}Texture::~Texture(){	if(textureid)		glDeleteTextures(1, reinterpret_cast<GLuint*>(&textureid));}const unsigned long Texture::ID() const{	return textureid;}


I'm using a custom exception class, if you don't want that, replace it with std::runtime_error!
// exception.hpp#ifndef EXCEPTION_HPP#define EXCEPTION_HPP#include <string>struct Exception{	Exception(const std::string& error) : error(error) {};	std::string error;};#endif


If you find any errors or improvements, please let me know. I just finished this today for my first game I want to make. :)

EDIT: Oh, I'm sorry. I forgot that <OpenGL/gl.h> is platform specific code for Apple! You'll want to put #ifs around it and include the headers depending on your platform. Sadly I don't know these constants for the varying compilers, so I'm kind of lost here. Help appreciated. :)
Alright, I got a loader thingy going, it works good, but the textures that I load are flipped and mirrored, should I just apply the texture in a way that makes it look right or should I flip it in the loading function?

Edit: Actually nevermind, it all worked out :D Thanks a lot all you who helped me!
Quote:Original post by Wurzt
Alright, I got a loader thingy going, it works good, but the textures that I load are flipped and mirrored, should I just apply the texture in a way that makes it look right or should I flip it in the loading function?


That's why I use this:
Image::Image(const std::string& filename){	if(!devilInitialized)	{		ilInit();		ilOriginFunc(IL_ORIGIN_LOWER_LEFT);		ilEnable(IL_ORIGIN_SET);		devilInitialized = true;	}// ...}


Devil's coordinate system is different to OpenGL's.

This topic is closed to new replies.

Advertisement