rts_glTextureMap.cpp 5.97 KB
#include "rts_glTextureMap.h"

#define RTS_UNKNOWN				0

rts_glTextureMap::rts_glTextureMap()
{
	name = 0;
}

void rts_glTextureMap::get_type()
{
	if(size.y == 0)
		texture_type = GL_TEXTURE_1D;
	else if(size.z == 0)
		texture_type = GL_TEXTURE_2D;
	else
		texture_type = GL_TEXTURE_3D;
}

void rts_glTextureMap::set_wrapping()
{
	CHECK_OPENGL_ERROR
	switch(texture_type)
	{
	case GL_TEXTURE_3D:
		glTexParameteri(texture_type, GL_TEXTURE_WRAP_R_EXT, GL_REPEAT);
	case GL_TEXTURE_2D:
		glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, GL_REPEAT);
	case GL_TEXTURE_1D:
		glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, GL_REPEAT);
		break;
	case GL_TEXTURE_RECTANGLE_ARB:
		glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP);
		glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP);
		break;

	default:
		break;
	}
	CHECK_OPENGL_ERROR
}

void rts_glTextureMap::SetBits(GLvoid* bits)
{
	glEnable(texture_type);						//enable the texture map
	CHECK_OPENGL_ERROR
	glBindTexture(texture_type, name);
	CHECK_OPENGL_ERROR

	switch(texture_type)
	{
	case GL_TEXTURE_3D:
		glTexImage3D(texture_type, 0, internal_format, size.x, size.y, size.z, 0, pixel_format, data_type, bits);
		break;
	case GL_TEXTURE_2D:
	case GL_TEXTURE_RECTANGLE_ARB:
		glTexImage2D(texture_type, 0, internal_format, size.x, size.y, 0, pixel_format, data_type, bits);
		break;
	case GL_TEXTURE_1D:
		glTexImage1D(texture_type, 0, internal_format, size.x, 0, pixel_format, data_type, bits);
		break;
	default:
		//glTexImage2D(texture_type, 0, internal_format, size.x, size.y, 0, pixel_format, data_type, bits);
		break;
	}
	CHECK_OPENGL_ERROR
}

void* rts_glTextureMap::GetBits(GLenum format, GLenum type)
{
	//returns the texture data
	
	int components;
	switch(format)
	{
	case GL_RED:
	case GL_GREEN:
	case GL_BLUE:
	case GL_ALPHA:
	case GL_LUMINANCE:
		components = 1;
		break;
	case GL_LUMINANCE_ALPHA:
		components = 2;
		break;
	case GL_RGB:
	case GL_BGR:
		components = 3;
		break;
	case GL_RGBA:
	case GL_BGRA:
		components = 4;
		break;
	}

	int type_size;
	switch(type)
	{
	case GL_UNSIGNED_BYTE:
	case GL_BYTE:
		type_size = sizeof(char);
		break;
	case GL_UNSIGNED_SHORT:
	case GL_SHORT:
		type_size = sizeof(short);
		break;
	case GL_UNSIGNED_INT:
	case GL_INT:
		type_size = sizeof(int);
		break;
	case GL_FLOAT:
		type_size = sizeof(float);
		break;
	}

	//allocate memory for the texture
	void* result = malloc(components*type_size * size.x * size.y);

	BeginTexture();
	glGetTexImage(texture_type, 0, format, type, result);

	CHECK_OPENGL_ERROR
	EndTexture();


	return result;

}

void rts_glTextureMap::ResetBits(GLvoid *bits)
{
	glEnable(texture_type);						//enable the texture map
	CHECK_OPENGL_ERROR
	glBindTexture(texture_type, name);
	CHECK_OPENGL_ERROR

	switch(texture_type)
	{
	case GL_TEXTURE_3D:
		//glTexImage3D(texture_type, 0, internal_format, size.x, size.y, size.z, 0, pixel_format, data_type, bits);
		break;
	case GL_TEXTURE_2D:
	case GL_TEXTURE_RECTANGLE_ARB:
		glTexSubImage2D(texture_type, 0, 0, 0, size.x, size.y, pixel_format, data_type, bits);
		CHECK_OPENGL_ERROR
		break;
	case GL_TEXTURE_1D:
		//glTexImage1D(texture_type, 0, internal_format, size.x, 0, pixel_format, data_type, bits);
		break;
	default:
		//glTexImage2D(texture_type, 0, internal_format, size.x, size.y, 0, pixel_format, data_type, bits);
		break;
	}
	glDisable(texture_type);
	CHECK_OPENGL_ERROR
}

void rts_glTextureMap::BeginTexture()
{
	glEnable(texture_type);
	glBindTexture(texture_type, name);
	CHECK_OPENGL_ERROR
}

void rts_glTextureMap::EndTexture()
{
	glDisable(texture_type);
	CHECK_OPENGL_ERROR
}



void rts_glTextureMap::Init(GLvoid *bits,
						   GLenum type,
						   GLsizei width, 
						   GLsizei height, 
						   GLsizei depth, 
						   GLint internalformat, 
						   GLenum format, 
						   GLenum datatype,
						   GLint interpolation)
{
	if(name != 0)
		glDeleteTextures(1, &name);
	//see if the texture is supported using a proxy
	CHECK_OPENGL_ERROR
	//glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internalformat, width, height, 0, format, datatype, NULL);
	GLint p;
	CHECK_OPENGL_ERROR
	//glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &p);
	//if(p == 0)
	//	cout<<"cannot use a texture with these parameters."<<endl;
	CHECK_OPENGL_ERROR
	if(datatype == GL_FLOAT)
	{
		glPixelStorei(GL_PACK_ALIGNMENT, 4);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);				//I honestly don't know what this does but it fixes problems
	}
	else if(datatype == GL_UNSIGNED_BYTE)
	{
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		//glPixelStorei(GL_PACK_ALIGNMENT, 1);
	}
	else if(datatype == GL_UNSIGNED_SHORT)
	{
		//glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
		//glPixelStorei(GL_PACK_ALIGNMENT, 2);
	}
	CHECK_OPENGL_ERROR
	glGenTextures(1, &name);							//get the texture name from OpenGL
	cout<<"OpenGL Name: "<<name<<endl;
	CHECK_OPENGL_ERROR
	size = vector3D<GLuint>(width, height, depth);		//assign the texture size
	//get_type();											//guess the type based on the size
	texture_type = type;						//set the type of texture
	glEnable(texture_type);						//enable the texture map
	CHECK_OPENGL_ERROR
	glBindTexture(texture_type, name);							//bind the texture for editing
	CHECK_OPENGL_ERROR
	set_wrapping();										//set the texture wrapping parameters
	CHECK_OPENGL_ERROR
	glTexParameteri(texture_type, GL_TEXTURE_MAG_FILTER, interpolation);		//set filtering
	CHECK_OPENGL_ERROR
	glTexParameteri(texture_type, GL_TEXTURE_MIN_FILTER, interpolation);
	CHECK_OPENGL_ERROR
	internal_format = internalformat;					//set the number of components per pixel
	pixel_format = format;								//set the pixel format
	data_type = datatype;									//set the data type
	SetBits(bits);										//send the bits to the OpenGL driver
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);	//replace the specified vertex color
	CHECK_OPENGL_ERROR
	glDisable(texture_type);
}