Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * tga.h
- *
- *
- */
- #include "config.h"
- #ifdef __APPLE__
- #include <GLUT/glut.h>
- #else
- #include <GL/glut.h>
- #endif
- GLuint
- loadTGATexture (const char *filename, GLuint texid = 0);
- /*
- * tga.cpp
- *
- */
- #include "tga.h"
- /*
- * tga.c -- tga texture loader
- * last modification: dec. 15, 2005
- *
- * Copyright (c) 2005 David HENRY
- *
- * 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.
- *
- * gcc -Wall -ansi -L/usr/X11R6/lib -lGL -lGLU -lglut tga.c -o tga
- */
- #include <stdio.h>
- #include <stdlib.h>
- /* OpenGL texture info */
- typedef struct
- {
- GLsizei width;
- GLsizei height;
- GLenum format;
- GLint internalFormat;
- GLuint id;
- GLubyte *texels;
- } gl_texture_t;
- #pragma pack(push, 1)
- /* tga header */
- typedef struct
- {
- GLubyte id_lenght; /* size of image id */
- GLubyte colormap_type; /* 1 is has a colormap */
- GLubyte image_type; /* compression type */
- short cm_first_entry; /* colormap origin */
- short cm_length; /* colormap length */
- GLubyte cm_size; /* colormap size */
- short x_origin; /* bottom left x coord origin */
- short y_origin; /* bottom left y coord origin */
- short width; /* picture width (in pixels) */
- short height; /* picture height (in pixels) */
- GLubyte pixel_depth; /* bits per pixel: 8, 16, 24 or 32 */
- GLubyte image_descriptor; /* 24 bits = 0x00; 32 bits = 0x80 */
- } tga_header_t;
- #pragma pack(pop)
- /* texture id for exemple */
- GLuint texId = 0;
- void
- GetTextureInfo (tga_header_t *header, gl_texture_t *texinfo)
- {
- texinfo->width = header->width;
- texinfo->height = header->height;
- switch (header->image_type)
- {
- case 3: /* grayscale 8 bits */
- case 11: /* grayscale 8 bits (RLE) */
- {
- if (header->pixel_depth == 8)
- {
- texinfo->format = GL_LUMINANCE;
- texinfo->internalFormat = 1;
- }
- else /* 16 bits */
- {
- texinfo->format = GL_LUMINANCE_ALPHA;
- texinfo->internalFormat = 2;
- }
- break;
- }
- case 1: /* 8 bits color index */
- case 2: /* BGR 16-24-32 bits */
- case 9: /* 8 bits color index (RLE) */
- case 10: /* BGR 16-24-32 bits (RLE) */
- {
- /* 8 bits and 16 bits images will be converted to 24 bits */
- if (header->pixel_depth <= 24)
- {
- texinfo->format = GL_RGB;
- texinfo->internalFormat = 3;
- }
- else /* 32 bits */
- {
- texinfo->format = GL_RGBA;
- texinfo->internalFormat = 4;
- }
- break;
- }
- }
- }
- void
- ReadTGA8bits (FILE *fp, GLubyte *colormap, gl_texture_t *texinfo)
- {
- int i;
- GLubyte color;
- for (i = 0; i < texinfo->width * texinfo->height; ++i)
- {
- /* read index color byte */
- color = (GLubyte)fgetc (fp);
- /* convert to RGB 24 bits */
- texinfo->texels[(i * 3) + 2] = colormap[(color * 3) + 0];
- texinfo->texels[(i * 3) + 1] = colormap[(color * 3) + 1];
- texinfo->texels[(i * 3) + 0] = colormap[(color * 3) + 2];
- }
- }
- void
- ReadTGA16bits (FILE *fp, gl_texture_t *texinfo)
- {
- int i;
- unsigned short color;
- for (i = 0; i < texinfo->width * texinfo->height; ++i)
- {
- /* read color word */
- color = fgetc (fp) + (fgetc (fp) << 8);
- /* convert BGR to RGB */
- texinfo->texels[(i * 3) + 0] = (GLubyte)(((color & 0x7C00) >> 10) << 3);
- texinfo->texels[(i * 3) + 1] = (GLubyte)(((color & 0x03E0) >> 5) << 3);
- texinfo->texels[(i * 3) + 2] = (GLubyte)(((color & 0x001F) >> 0) << 3);
- }
- }
- void
- ReadTGA24bits (FILE *fp, gl_texture_t *texinfo)
- {
- int i;
- for (i = 0; i < texinfo->width * texinfo->height; ++i)
- {
- /* read and convert BGR to RGB */
- texinfo->texels[(i * 3) + 2] = (GLubyte)fgetc (fp);
- texinfo->texels[(i * 3) + 1] = (GLubyte)fgetc (fp);
- texinfo->texels[(i * 3) + 0] = (GLubyte)fgetc (fp);
- }
- }
- void
- ReadTGA32bits (FILE *fp, gl_texture_t *texinfo)
- {
- int i;
- for (i = 0; i < texinfo->width * texinfo->height; ++i)
- {
- /* read and convert BGRA to RGBA */
- texinfo->texels[(i * 4) + 2] = (GLubyte)fgetc (fp);
- texinfo->texels[(i * 4) + 1] = (GLubyte)fgetc (fp);
- texinfo->texels[(i * 4) + 0] = (GLubyte)fgetc (fp);
- texinfo->texels[(i * 4) + 3] = (GLubyte)fgetc (fp);
- }
- }
- void
- ReadTGAgray8bits (FILE *fp, gl_texture_t *texinfo)
- {
- int i;
- for (i = 0; i < texinfo->width * texinfo->height; ++i)
- {
- /* read grayscale color byte */
- texinfo->texels[i] = (GLubyte)fgetc (fp);
- }
- }
- void
- ReadTGAgray16bits (FILE *fp, gl_texture_t *texinfo)
- {
- int i;
- for (i = 0; i < texinfo->width * texinfo->height; ++i)
- {
- /* read grayscale color + alpha channel bytes */
- texinfo->texels[(i * 2) + 0] = (GLubyte)fgetc (fp);
- texinfo->texels[(i * 2) + 1] = (GLubyte)fgetc (fp);
- }
- }
- void
- ReadTGA8bitsRLE (FILE *fp, GLubyte *colormap, gl_texture_t *texinfo)
- {
- int i, size;
- GLubyte color;
- GLubyte packet_header;
- GLubyte *ptr = texinfo->texels;
- while (ptr < texinfo->texels + (texinfo->width * texinfo->height) * 3)
- {
- /* read first byte */
- packet_header = (GLubyte)fgetc (fp);
- size = 1 + (packet_header & 0x7f);
- if (packet_header & 0x80)
- {
- /* run-length packet */
- color = (GLubyte)fgetc (fp);
- for (i = 0; i < size; ++i, ptr += 3)
- {
- ptr[0] = colormap[(color * 3) + 2];
- ptr[1] = colormap[(color * 3) + 1];
- ptr[2] = colormap[(color * 3) + 0];
- }
- }
- else
- {
- /* non run-length packet */
- for (i = 0; i < size; ++i, ptr += 3)
- {
- color = (GLubyte)fgetc (fp);
- ptr[0] = colormap[(color * 3) + 2];
- ptr[1] = colormap[(color * 3) + 1];
- ptr[2] = colormap[(color * 3) + 0];
- }
- }
- }
- }
- void
- ReadTGA16bitsRLE (FILE *fp, gl_texture_t *texinfo)
- {
- int i, size;
- unsigned short color;
- GLubyte packet_header;
- GLubyte *ptr = texinfo->texels;
- while (ptr < texinfo->texels + (texinfo->width * texinfo->height) * 3)
- {
- /* read first byte */
- packet_header = fgetc (fp);
- size = 1 + (packet_header & 0x7f);
- if (packet_header & 0x80)
- {
- /* run-length packet */
- color = fgetc (fp) + (fgetc (fp) << 8);
- for (i = 0; i < size; ++i, ptr += 3)
- {
- ptr[0] = (GLubyte)(((color & 0x7C00) >> 10) << 3);
- ptr[1] = (GLubyte)(((color & 0x03E0) >> 5) << 3);
- ptr[2] = (GLubyte)(((color & 0x001F) >> 0) << 3);
- }
- }
- else
- {
- /* non run-length packet */
- for (i = 0; i < size; ++i, ptr += 3)
- {
- color = fgetc (fp) + (fgetc (fp) << 8);
- ptr[0] = (GLubyte)(((color & 0x7C00) >> 10) << 3);
- ptr[1] = (GLubyte)(((color & 0x03E0) >> 5) << 3);
- ptr[2] = (GLubyte)(((color & 0x001F) >> 0) << 3);
- }
- }
- }
- }
- void
- ReadTGA24bitsRLE (FILE *fp, gl_texture_t *texinfo)
- {
- int i, size;
- GLubyte rgb[3];
- GLubyte packet_header;
- GLubyte *ptr = texinfo->texels;
- while (ptr < texinfo->texels + (texinfo->width * texinfo->height) * 3)
- {
- /* read first byte */
- packet_header = (GLubyte)fgetc (fp);
- size = 1 + (packet_header & 0x7f);
- if (packet_header & 0x80)
- {
- /* run-length packet */
- fread (rgb, sizeof (GLubyte), 3, fp);
- for (i = 0; i < size; ++i, ptr += 3)
- {
- ptr[0] = rgb[2];
- ptr[1] = rgb[1];
- ptr[2] = rgb[0];
- }
- }
- else
- {
- /* non run-length packet */
- for (i = 0; i < size; ++i, ptr += 3)
- {
- ptr[2] = (GLubyte)fgetc (fp);
- ptr[1] = (GLubyte)fgetc (fp);
- ptr[0] = (GLubyte)fgetc (fp);
- }
- }
- }
- }
- void
- ReadTGA32bitsRLE (FILE *fp, gl_texture_t *texinfo)
- {
- int i, size;
- GLubyte rgba[4];
- GLubyte packet_header;
- GLubyte *ptr = texinfo->texels;
- while (ptr < texinfo->texels + (texinfo->width * texinfo->height) * 4)
- {
- /* read first byte */
- packet_header = (GLubyte)fgetc (fp);
- size = 1 + (packet_header & 0x7f);
- if (packet_header & 0x80)
- {
- /* run-length packet */
- fread (rgba, sizeof (GLubyte), 4, fp);
- for (i = 0; i < size; ++i, ptr += 4)
- {
- ptr[0] = rgba[2];
- ptr[1] = rgba[1];
- ptr[2] = rgba[0];
- ptr[3] = rgba[3];
- }
- }
- else
- {
- /* non run-length packet */
- for (i = 0; i < size; ++i, ptr += 4)
- {
- ptr[2] = (GLubyte)fgetc (fp);
- ptr[1] = (GLubyte)fgetc (fp);
- ptr[0] = (GLubyte)fgetc (fp);
- ptr[3] = (GLubyte)fgetc (fp);
- }
- }
- }
- }
- void
- ReadTGAgray8bitsRLE (FILE *fp, gl_texture_t *texinfo)
- {
- int i, size;
- GLubyte color;
- GLubyte packet_header;
- GLubyte *ptr = texinfo->texels;
- while (ptr < texinfo->texels + (texinfo->width * texinfo->height))
- {
- /* read first byte */
- packet_header = (GLubyte)fgetc (fp);
- size = 1 + (packet_header & 0x7f);
- if (packet_header & 0x80)
- {
- /* run-length packet */
- color = (GLubyte)fgetc (fp);
- for (i = 0; i < size; ++i, ptr++)
- *ptr = color;
- }
- else
- {
- /* non run-length packet */
- for (i = 0; i < size; ++i, ptr++)
- *ptr = (GLubyte)fgetc (fp);
- }
- }
- }
- void
- ReadTGAgray16bitsRLE (FILE *fp, gl_texture_t *texinfo)
- {
- int i, size;
- GLubyte color, alpha;
- GLubyte packet_header;
- GLubyte *ptr = texinfo->texels;
- while (ptr < texinfo->texels + (texinfo->width * texinfo->height) * 2)
- {
- /* read first byte */
- packet_header = (GLubyte)fgetc (fp);
- size = 1 + (packet_header & 0x7f);
- if (packet_header & 0x80)
- {
- /* run-length packet */
- color = (GLubyte)fgetc (fp);
- alpha = (GLubyte)fgetc (fp);
- for (i = 0; i < size; ++i, ptr += 2)
- {
- ptr[0] = color;
- ptr[1] = alpha;
- }
- }
- else
- {
- /* non run-length packet */
- for (i = 0; i < size; ++i, ptr += 2)
- {
- ptr[0] = (GLubyte)fgetc (fp);
- ptr[1] = (GLubyte)fgetc (fp);
- }
- }
- }
- }
- gl_texture_t *
- ReadTGAFile (const char *filename)
- {
- FILE *fp;
- gl_texture_t *texinfo;
- tga_header_t header;
- GLubyte *colormap = NULL;
- fp = fopen (filename, "rb");
- if (!fp)
- {
- fprintf (stderr, "error: couldn't open \"%s\"!\n", filename);
- return NULL;
- }
- /* read header */
- fread (&header, sizeof (tga_header_t), 1, fp);
- texinfo = (gl_texture_t *)malloc (sizeof (gl_texture_t));
- GetTextureInfo (&header, texinfo);
- fseek (fp, header.id_lenght, SEEK_CUR);
- /* memory allocation */
- texinfo->texels = (GLubyte *)malloc (sizeof (GLubyte) *
- texinfo->width * texinfo->height * texinfo->internalFormat);
- if (!texinfo->texels)
- {
- free (texinfo);
- return NULL;
- }
- /* read color map */
- if (header.colormap_type)
- {
- /* NOTE: color map is stored in BGR format */
- colormap = (GLubyte *)malloc (sizeof (GLubyte)
- * header.cm_length * (header.cm_size >> 3));
- fread (colormap, sizeof (GLubyte), header.cm_length
- * (header.cm_size >> 3), fp);
- }
- /* read image data */
- switch (header.image_type)
- {
- case 0:
- /* no data */
- break;
- case 1:
- /* uncompressed 8 bits color index */
- ReadTGA8bits (fp, colormap, texinfo);
- break;
- case 2:
- /* uncompressed 16-24-32 bits */
- switch (header.pixel_depth)
- {
- case 16:
- ReadTGA16bits (fp, texinfo);
- break;
- case 24:
- ReadTGA24bits (fp, texinfo);
- break;
- case 32:
- ReadTGA32bits (fp, texinfo);
- break;
- }
- break;
- case 3:
- /* uncompressed 8 or 16 bits grayscale */
- if (header.pixel_depth == 8)
- ReadTGAgray8bits (fp, texinfo);
- else /* 16 */
- ReadTGAgray16bits (fp, texinfo);
- break;
- case 9:
- /* RLE compressed 8 bits color index */
- ReadTGA8bitsRLE (fp, colormap, texinfo);
- break;
- case 10:
- /* RLE compressed 16-24-32 bits */
- switch (header.pixel_depth)
- {
- case 16:
- ReadTGA16bitsRLE (fp, texinfo);
- break;
- case 24:
- ReadTGA24bitsRLE (fp, texinfo);
- break;
- case 32:
- ReadTGA32bitsRLE (fp, texinfo);
- break;
- }
- break;
- case 11:
- /* RLE compressed 8 or 16 bits grayscale */
- if (header.pixel_depth == 8)
- ReadTGAgray8bitsRLE (fp, texinfo);
- else /* 16 */
- ReadTGAgray16bitsRLE (fp, texinfo);
- break;
- default:
- /* image type is not correct */
- fprintf (stderr, "error: unknown TGA image type %i!\n", header.image_type);
- free (texinfo->texels);
- free (texinfo);
- texinfo = NULL;
- break;
- }
- /* no longer need colormap data */
- if (colormap)
- free (colormap);
- fclose (fp);
- return texinfo;
- }
- GLuint
- loadTGATexture (const char *filename, GLuint texid)
- {
- gl_texture_t *tga_tex = NULL;
- GLuint tex_id = 0;
- tga_tex = ReadTGAFile (filename);
- if (tga_tex && tga_tex->texels)
- {
- /* generate texture */
- if(!texid)
- glGenTextures (1, &tga_tex->id);
- else
- tga_tex->id = texid;
- glBindTexture (GL_TEXTURE_2D, tga_tex->id);
- /* setup some parameters for texture filters and mipmapping */
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_LINEAR*/);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexImage2D (GL_TEXTURE_2D, 0, tga_tex->internalFormat,
- tga_tex->width, tga_tex->height, 0, tga_tex->format,
- GL_UNSIGNED_BYTE, tga_tex->texels);
- /*
- gluBuild2DMipmaps (GL_TEXTURE_2D, tga_tex->internalFormat,
- tga_tex->width, tga_tex->height,
- tga_tex->format, GL_UNSIGNED_BYTE, tga_tex->texels);
- */
- tex_id = tga_tex->id;
- /* OpenGL has its own copy of texture data */
- free (tga_tex->texels);
- free (tga_tex);
- }
- return tex_id;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement