Thread: OpenGL Textures and TGAs

  1. #1
    Hi ay_okay's Avatar
    Join Date
    Dec 2004
    Location
    Here
    Posts
    69

    OpenGL Textures and TGAs

    Hello, I am a newbie at OpenGL, as you will probably figure out yourself once you read my question. I am reading a book called "Beginning OpenGL Game Programming" and it is pretty useful, but I don't entirely get there examples. Can anyone post some code of how to load a Targa file. If you could cut out the stuff about conversions between RGBA and RGB and stuff like that, I would appreciate it. This will help me to focus on the main part of loading a Targa image into memory. Oh and please don't use linked lists becaus eI don't get them either and I already tried the tutorial on this site. Thanks guys and gals!!!

  2. #2
    ---
    Join Date
    May 2004
    Posts
    1,379
    here is a small tutorial for writing a tga loader for a height map.

  3. #3
    Hi ay_okay's Avatar
    Join Date
    Dec 2004
    Location
    Here
    Posts
    69
    Thanks that should do it. But could you send me a link to a tutorial that explains linked lists well(not the one on this site) that would be really nice

  4. #4

    Join Date
    May 2005
    Posts
    1,042
    I learned the .TGA image format from NEHE tutorials and wrote this loader. This is from my texture manager class...enjoy

    Code:
    UINT	TextureManager::LoadTGA(char	*FileName)
    {
    	int	i; 
    	WORD	width, height;
    	byte	*data	=	NULL;
    	byte	type, bits, length;
    
    	int		rowlength, channels, filesize;
    	byte	*pBuffer = NULL;
    	byte	*ptr = NULL;
    	FILE	*pFile = fopen(FileName, "rb");
    
    	if(!pFile)
    	{
    		TextureData	<<	"TextureManager::LoadTGA: could not load tga file: " << FileName << "\n";
    		return	NULL;	
    	}
    
    	fseek(pFile, 0, SEEK_END);
    	filesize = ftell(pFile);
    	fseek(pFile, 0, SEEK_SET);
    	pBuffer = new byte[filesize];
    	fread(pBuffer, 1, filesize, pFile);
    	fclose(pFile);
    	
    	ptr = pBuffer;
    	length	=	*(byte*)ptr;
    	ptr+=2;
    
    	type	=	*(byte*)ptr;
    	ptr += 10;
    
    	width	=	*(WORD*)ptr;
    	ptr += sizeof(WORD);
    
    	height	=	*(WORD*)ptr;
    	ptr	+= sizeof(WORD);
    
    	bits	=	*(byte*)ptr;
    	ptr++;
    	ptr += length+1;
    	
    	if(bits == 16)
    	{
    		MessageBox(NULL, "LoadTGA: Doesn't support 16bit","ERROR", MB_OK);
    		return NULL;
    	}
    
    	channels = bits / 8;
    	rowlength = channels * width;//length of a row in bytes
    	data = new byte[rowlength * height];
    	unsigned	int y;
    if(type != TGA_RLE)
    {
    	if(channels == 3)
    	{
    		for(i = 0; i < height; i++)
    		{
    			for(y = 0; y < rowlength; y++)
    			{
    				data[(i*rowlength)+y] = *(byte*)ptr;
    				ptr++;
    			}	
    		}
    		GLenum	GLtype = GL_BGR_EXT;
    		return	GenerateInternalTexture(data, channels, width, height, GLtype);
    	}
    	else
    	{
    		if(channels == 4)
    		{
    			for(i = 0; i < height; i++)
    			{
    				for(y = 0; y < rowlength; y++)
    				{
    					data[(i*rowlength)+y] = *(byte*)ptr;
    					ptr++;
    				}
    			}	
    		}
    		GLenum	GLtype	=	GL_BGRA_EXT;
    		
    		ptr = NULL;
    		delete	[]	pBuffer;
    		delete	ptr;
    
    		return	GenerateInternalTexture(data, channels, width, height, GLtype);
    	}
    	//FIXME: make sure all of the data is cleaned up! 
    }
    else	if(type == TGA_RLE) //NOTE: LoadTGA_RLE must delete data when done!
    	return	LoadTGA_RLE(pBuffer, ptr, bits, channels, width, height, data);
    }
    
    UINT	TextureManager::LoadTGA_RLE(byte*pBuffer, byte*ptr, byte	bits, byte	channels, WORD width, WORD height, byte	*data)
    {
    		byte *pColor = new byte[channels];
    		int	pixelsleft = 0;
    		int	colorsread = 0;
    		int	pixelsread = 0;
    		int	totalpixels = width * height;
    		unsigned	int	y; //counter 
    		
    		//FIXME: must have an error logging system! 
    		if(!ptr)
    			return	NULL;
    		if(!pBuffer)
    			return	NULL;
    		while(pixelsread < totalpixels)
    		{
    			pixelsleft = *(byte*)ptr;
    			ptr++;
    
    			if(pixelsleft < 128)
    			{
    				pixelsleft++;
    
    			if(channels == 4)
    			{
    					while(pixelsleft)
    					{
    						for(y = 0; y < channels; y++)
    						{
    							pColor[y] = *(byte*)ptr;
    							ptr++;
    						}
    						data[colorsread + 0] = pColor[0];	
    						data[colorsread + 1] = pColor[1];
    						data[colorsread + 2] = pColor[2];	
    						data[colorsread + 3] = pColor[3];
    
    						pixelsread++;
    						pixelsleft--;
    						colorsread += channels;
    					}
    				}
    				else	if(channels == 3)
    				{
    						while(pixelsleft)
    						{
    							for(y = 0; y < channels; y++)
    							{
    								pColor[y] = *(byte*)ptr;
    								ptr++;
    							}
    							data[colorsread + 0] = pColor[0];	
    							data[colorsread + 1] = pColor[1];
    							data[colorsread + 2] = pColor[2];	
    
    							pixelsread++;
    							pixelsleft--;
    							colorsread += channels;
    						}
    				}
    			}
    			else
    			{
    				pixelsleft -= 127;
    				for(y = 0; y < channels; y++)
    				{
    					pColor[y] = *(byte*)ptr;
    					ptr++;
    				}
    
    				if(channels == 4)
    				{
    					while(pixelsleft)
    					{
    						data[colorsread + 0] = pColor[0];
    						data[colorsread + 1] = pColor[1];
    						data[colorsread + 2] = pColor[2];
    						data[colorsread + 3] = pColor[3];
    						pixelsread++;
    						pixelsleft--;
    						colorsread += channels;
    					}
    				}
    				else	if(channels == 3)
    				{
    					while(pixelsleft)
    					{
    						data[colorsread + 0] = pColor[0];
    						data[colorsread + 1] = pColor[1];
    						data[colorsread + 2] = pColor[2];
    						pixelsread++;
    						pixelsleft--;
    						colorsread += channels;
    					}
    				}
    				
    			}
    		}
    		
    		ptr=NULL;
    		delete	[]	pBuffer;
    		delete	ptr;
    		
    		GLenum	GLtype;
    		if(channels == 4)
    			GLtype = GL_BGRA_EXT;
    		if(channels == 3)
    			GLtype = GL_BGR_EXT;
    		return	GenerateInternalTexture(data, channels, width, height, GLtype);
    	}
    
    UINT	TextureManager::GenerateInternalTexture(byte * data, int channels, int width, int height, GLenum type)
    {
    	UINT	texture;
    	gpNTGLAPI->ntglGenTextures(1, &texture);
    	gpNTGLAPI->ntglPixelStorei (GL_UNPACK_ALIGNMENT, 1);
    	gpNTGLAPI->ntglBindTexture(GL_TEXTURE_2D, texture);
    
    	gluBuild2DMipmaps(GL_TEXTURE_2D, channels,width,height, type, GL_UNSIGNED_BYTE, data);
    
    	gpNTGLAPI->ntglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); //GL_LINEAR_MIPMAP_NEAREST is faster than GL_LINEAR_MIPMAP_LINEAR
    	gpNTGLAPI->ntglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    	gpNTGLAPI->ntglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    	return texture;
    }

Popular pages Recent additions subscribe to a feed