-/**
- * \file texture.cxx
+/*
* Texture manipulation routines
*
* Copyright (c) Mark J. Kilgard, 1997.
* $Id$
*/
+#include <simgear/compiler.h>
+#ifdef WIN32
+# include <windows.h>
+#endif
#include <GL/glu.h>
#include <zlib.h>
#include "colours.h"
SGTexture::SGTexture()
+ : texture_id(0),
+ texture_data(0),
+ num_colors(3)
{
- texture_data = 0;
}
SGTexture::SGTexture(unsigned int width, unsigned int height)
+ : texture_id(0)
{
texture_data = new GLubyte[ width * height * 3 ];
}
SGTexture::~SGTexture()
{
- delete texture_data;
+ if ( texture_data ) {
+ delete texture_data;
+ }
+
+ if ( texture_id != 0 ) {
+ free_id();
+ }
}
void
SGTexture::bind()
{
- if (!texture_data) {
+ bool gen = false;
+ if (!texture_id) {
#ifdef GL_VERSION_1_1
glGenTextures(1, &texture_id);
#elif GL_EXT_texture_object
glGenTexturesEXT(1, &texture_id);
#endif
+ gen = true;
}
#ifdef GL_VERSION_1_1
glBindTextureEXT(GL_TEXTURE_2D, texture_id);
#endif
- if (!texture_data) {
+ if (gen) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
return;
}
- texture_data = new GLubyte[ image->xsize * image->ysize * 3];
+ texture_data = new GLubyte[ image->xsize * image->ysize * 3 ];
rbuf = new GLubyte[ image->xsize ];
gbuf = new GLubyte[ image->xsize ];
bbuf = new GLubyte[ image->xsize ];
ImageGetRow(image,rbuf,y,0);
ImageGetRow(image,gbuf,y,1);
ImageGetRow(image,bbuf,y,2);
- ImageGetRow(image,abuf,y,3); /* Discard. */
+ ImageGetRow(image,abuf,y,3); // discard
rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
ptr += (image->xsize * 3);
} else {
delete abuf;
}
+
+
+void
+SGTexture::read_rgba_texture(const char *name)
+{
+ GLubyte *ptr;
+ GLubyte *rbuf, *gbuf, *bbuf, *abuf;
+ SGTexture::ImageRec *image;
+ int y;
+
+ if (texture_data)
+ delete texture_data;
+
+ image = ImageOpen(name);
+ if(!image)
+ return;
+
+ texture_width = image->xsize;
+ texture_height = image->ysize;
+ if (image->zsize != 3 && image->zsize != 4) {
+ ImageClose(image);
+ return;
+ }
+
+ texture_data = new GLubyte[ image->xsize * image->ysize * 4 ];
+ rbuf = new GLubyte[ image->xsize ];
+ gbuf = new GLubyte[ image->xsize ];
+ bbuf = new GLubyte[ image->xsize ];
+ abuf = new GLubyte[ image->xsize ];
+ if(!texture_data || !rbuf || !gbuf || !bbuf || !abuf) {
+ delete texture_data;
+ delete rbuf;
+ delete gbuf;
+ delete bbuf;
+ delete abuf;
+ return;
+ }
+
+ ptr = texture_data;
+ memset(abuf, 255, image->xsize);
+ for(y=0; y<image->ysize; y++) {
+ if(image->zsize == 4) {
+ ImageGetRow(image,rbuf,y,0);
+ ImageGetRow(image,gbuf,y,1);
+ ImageGetRow(image,bbuf,y,2);
+ ImageGetRow(image,abuf,y,3);
+ rgbatorgba(rbuf,gbuf,bbuf,abuf,ptr,image->xsize);
+ ptr += (image->xsize * 4);
+ } else {
+ ImageGetRow(image,rbuf,y,0);
+ ImageGetRow(image,gbuf,y,1);
+ ImageGetRow(image,bbuf,y,2);
+ rgbatorgba(rbuf,gbuf,bbuf,abuf,ptr,image->xsize);
+ ptr += (image->xsize * 3);
+ }
+ }
+
+ ImageClose(image);
+ delete rbuf;
+ delete gbuf;
+ delete bbuf;
+ delete abuf;
+}
+
void
SGTexture::read_raw_texture(const char *name)
{
void
SGTexture::set_pixel(GLuint x, GLuint y, sgVec3 &c)
{
+ if (!texture_data)
+ return;
+
unsigned int pos = (x + y*texture_width)*3;
- texture_data[pos] = c[0];
- texture_data[pos+1] = c[1];
- texture_data[pos+2] = c[2];
+ texture_data[pos] = (unsigned char)(c[0] * 256);
+ texture_data[pos+1] = (unsigned char)(c[1] * 256);
+ texture_data[pos+2] = (unsigned char)(c[2] * 256);
}
-sgVec3 *
+float *
SGTexture::get_pixel(GLuint x, GLuint y)
{
static sgVec3 c;
+
+ sgSetVec3(c, 0, 0, 0);
+ if (!texture_data)
+ return c;
+
unsigned int pos = (x + y*texture_width)*3;
sgSetVec3(c, texture_data[pos], texture_data[pos+1], texture_data[pos+2]);
- return &c;
+ return c;
}
-
SGTexture::ImageRec *
SGTexture::ImageOpen(const char *fileName)
{
}
}
+void
+SGTexture::rgbatorgba(GLubyte *r, GLubyte *g, GLubyte *b, GLubyte *a,
+ GLubyte *l, int n) {
+ while(n--) {
+ l[0] = r[0];
+ l[1] = g[0];
+ l[2] = b[0];
+ l[3] = a[0];
+ l += 4; r++; g++; b++; a++;
+ }
+}
+
+
void
SGTexture::ConvertShort(unsigned short *array, unsigned int length) {
unsigned short b1, b2;