Sign in to follow this  

TGA Resource Texture Problem

This topic is 4835 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I recently spent some time writing a TGA loader, and then trying to write a resource TGA loader. I accomplished this by creating a class that could accept either a string representing the TGA file location or an unsigned integer representing the resource ID. However, I have run into some problems with it. I can load the resource texture and even draw it, but the colors are a little bit lighter than they are supposed to be. I've tried running various different ways, and have come to the conclusion that it must be the texture class code as opposed to the implementation settings (blending, alpha testing, etc.). Could anyone point out what I messed up? (Loading a resource from a file is also currently broken). Note that the class can only load a 32 bit uncompressed TGA image, that will hopefully be fixed in the future.
// CTexture.h

#ifndef __TEXTURE_H__
#define __TEXTURE_H__

struct PIXEL
{
	unsigned char red;
	unsigned char green;
	unsigned char blue;
	unsigned char alpha;

	PIXEL( unsigned char _red = 0, unsigned char _green = 0, unsigned char _blue = 0, unsigned
		char _alpha = 0 ) :	red(_red), green(_green), blue(_blue), alpha(_alpha)
	{
		// Nothing else to do
	}
};

#pragma pack(push,1)
struct _TARGA 
{
	unsigned char  idlength;
	unsigned char  colourmaptype;
	unsigned char datatypecode;
	short int colourmaporigin;
	short int colourmaplength;
	unsigned char  colourmapdepth;
	short int x_origin;
	short int y_origin;
	short width;
	short height;
	unsigned char  bitsperpixel;
	unsigned char  imagedescriptor;
	PIXEL data;
};
#pragma pack(pop,1)

class CTexture
{
public:

	static unsigned int numTextures;

	CTexture();
	CTexture( unsigned int resourceID );
	CTexture( const char* fileName );
	~CTexture();

	void Bind() const;
	bool Initialize( const char* fileName );
	bool Initialize( unsigned int resourceID );

private:
	unsigned int id;

	bool LoadResourceTGA( _TARGA* targa, PIXEL* data, unsigned int resourceID );
	bool LoadFileTGA( const char* fileName );
};


#endif



#include "CTexture.h"

#include <windows.h>
#include <gl/gl.h>
#include <stdio.h>

unsigned int CTexture::numTextures = 0;

CTexture::CTexture()
{
	// Nothing else to do
}

CTexture::CTexture( unsigned int resourceID )
{
	_TARGA* tga = (_TARGA*)LockResource( LoadResource(NULL, 
		FindResource(NULL, MAKEINTRESOURCE(resourceID), "TGA") ) );

	if ( tga )
	{
		glGenTextures(1, &numTextures);
		id = numTextures;
		LoadResourceTGA( tga, &tga->data, id );
	}
}

CTexture::CTexture( const char* fileName )
{	
	glGenTextures(1, &numTextures);
	id = numTextures;

	LoadFileTGA( fileName );
}

CTexture::~CTexture()
{
	glDeleteTextures(1, &id);
}

void CTexture::Bind() const
{
	glBindTexture(GL_TEXTURE_2D, id);
}

bool CTexture::Initialize( const char* fileName )
{
	glGenTextures(1, &numTextures);
	id = numTextures;

	if ( ! LoadFileTGA( fileName ) )
	{
		return false;
	}

	return true;
}

bool CTexture::Initialize( unsigned int resourceID )
{
	_TARGA* tga = (_TARGA*)LockResource( LoadResource(NULL, 
		FindResource(NULL, MAKEINTRESOURCE(resourceID), "TGA") ) );

	if ( tga )
	{	
		glGenTextures(1, &numTextures);
		id = numTextures;
		
		if ( ! LoadResourceTGA( tga, &tga->data, id ) )
		{
			return false;
		}
	}
	
	return true;
}

bool CTexture::LoadResourceTGA( _TARGA* targa, PIXEL* data,  unsigned int resourceID )
{
	PIXEL* pixels = new PIXEL[targa->height*targa->width];

	for ( int height = 0; height < targa->height; ++height )
	{
		for ( int width = 0; width < targa->width; ++width )
		{
			pixels[(targa->height - height - 1) * targa->width + width].blue  = data->red;
			pixels[(targa->height - height - 1) * targa->width + width].green = data->green;
			pixels[(targa->height - height - 1) * targa->width + width].red   = data->blue;
			pixels[(targa->height - height - 1) * targa->width + width].alpha = data->alpha;

			data++;
		}
	}

	glBindTexture(GL_TEXTURE_2D, resourceID);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, targa->width, targa->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
	
	delete[] pixels;

	return true;
}

bool CTexture::LoadFileTGA( const char *fileName )
{
	_TARGA* tga = new _TARGA;
	FILE* file = NULL;
	PIXEL* pixels;

	if ( ! fileName )
	{
		return false;
	}
	
	file = fopen(fileName,"rb");

	if ( ! file )
	{
		return false;
	}
	
	fread(tga, 1, sizeof(_TARGA) - sizeof(PIXEL), file);

	pixels = new PIXEL[tga->width * tga->height];

	fread(pixels, 1, tga->width * tga->height * sizeof(PIXEL), file);

	if ( ! LoadResourceTGA(tga, pixels, id))
	{
		return false;
	}

	delete tga;
	fclose(file);

	return true;
}




[Edited by - Cypher777 on September 17, 2004 3:17:10 PM]

Share this post


Link to post
Share on other sites
Hmmm... the only reasonable expenation for the difference must be that you have some kind of blending turned on, what blendfunk are you using?

The difference in the images could be the alpha channel.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Depth Testing is on (tried off too), blending enabled with GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA, alpha testing enabled with GL_GREATER and 0.1f. I made a small testing program based off NeHe's framework, and the initialization and drawing functions are shown below. Included are the expected and actual results of the image.

TGA Image in PSP 8.0 (Expected Result)

TGA Image in During Program Execution (Actual Result)




CTexture tex;

int InitGL(GLvoid)
{
tex.Initialize(IDR_TGA1);
glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
return TRUE;
}

int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.1f);

glTranslatef(-0.4f,-0.4f,-2.0f);
glColor4f(1.0f,1.0f,1.0f,1.0f);

tex.Bind();
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.0f,0.0f,0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,0.0f,0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,1.0f,0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f (0.0f,1.0f,0.0f);
glEnd();

return TRUE;
}


Share this post


Link to post
Share on other sites
I think you have an alpha problem, with that blendfunc it's supposed to look like that(given that you have a correct alphamap), you could perhaps try to reduce the alpha values in the tga file to next to nothing.
Remember, PSP8 has a somewhat "wonky" alpha map support.
I normaly use PSP8 for most of my texturing and graphics needs, but when i need an alphamapped texture, i do that in photoshop.

Share this post


Link to post
Share on other sites

This topic is 4835 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this