Advertisement

transparent TGAs

Started by December 11, 2004 11:29 PM
22 comments, last by clint8565 19 years, 11 months ago
png won't work I only know how to load TGAs... unless you want to tell me
I'm using DevC++ and I have a devpak that's supposed to include stuff for loading pngs (libpng or something like that) but I don't know how
If the "layers" option is available (not grayed-out), it means you have more than one layer in your image. Make sure to have only one (you can merge them together by pressing CTRL+SHIFT+E)
Advertisement
there is only one layer CTRL+SHIFT+E(Merge Layers) is grayed out because there is only one layer but the layers box is checked when I go to save as
I bet the alpha is there, after you save look at the color tab and see if you have a R G B A channel.

For some reasion they thought it would be cool if you didnt see the alpha unless you do some manipulation.
You have to create a layer mask, not an alpha channel. When you save the image (as TGA) you'll be prompted to specify how many bits - choose 32.
In the color tab there is never an alpha channel skow, but it's still there in the channel tab if that's what you mean. I have been saving in 32 bits/pixel form and the layer mask makes no difference, sure it shows that it's transparent before you save, but after you save it's bye bye. Same with the alpha channel, except it is still a channel but for some reason it has no effect. Can anybody else manage to save transparent TGAs? If so please post how.
Advertisement
Can you post your image somewhere?
I always have used Paint Shop Pro, but this may help. In PSP, you can take the image and create a mask, then save that mask to the alpha channel. It sounds like you are doing right in your program. Are you sure that the problem is the image itself. Post the rendering code, maybe that's where you are wrong.




You should be able to see the pic above, I want the white transparent... It could be the render code, but I don't think so because when I save and reload the image in Photoshop the transparency is gone.

/*  Name: OpenGL Test  Author: Clint Dramnitzke  Start Date: 18/11/04 12:43*///include stuff#include <windows.h>#include <gl/gl.h>#include <gl/glu.h>#include <time.h>#include <math.h>#pragma comment(lib, "Glu32.lib")#include <stdlib.h>										// Header File For Windows#include <stdio.h>												// Header File For Standard Input/Output#include "texture.h"/************************** * Function Declarations * **************************/LRESULT CALLBACK WndProc (HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam);void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC);void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC);bool LoadTGA(Texture *, char *);Texture tex[2];int LoadGLTextures()											// Load Bitmaps And Convert To Textures{	int Status=FALSE;											// Status Indicator	// Load The Bitmap, Check For Errors.	if (LoadTGA(&tex[0], "shot.tga") && LoadTGA(&tex[1],"back.tga"))	{		Status=TRUE;											// Set The Status To TRUE    glGenTextures(1, &tex[0].texID);				// Create The Texture ( CHANGE )    glBindTexture(GL_TEXTURE_2D, tex[0].texID);    glTexImage2D(GL_TEXTURE_2D, 0, 4, tex[0].width, tex[0].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex[0].imageData);    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);    if (tex[0].imageData)						// If Texture Image Exists ( CHANGE )    {      free(tex[0].imageData);					// Free The Texture Image Memory ( CHANGE )    }        glGenTextures(1, &tex[1].texID);				// Create The Texture ( CHANGE )    glBindTexture(GL_TEXTURE_2D, tex[1].texID);    glTexImage2D(GL_TEXTURE_2D, 0, 4, tex[1].width, tex[1].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex[1].imageData);    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);    if (tex[1].imageData)						// If Texture Image Exists ( CHANGE )    {      free(tex[1].imageData);					// Free The Texture Image Memory ( CHANGE )    }	}	return Status;												// Return The Status}//draw everythingvoid Render(){  glClearColor (0.0f, 0.0f, 0.0f, 0.0f);  glClear (GL_COLOR_BUFFER_BIT);    glBindTexture(GL_TEXTURE_2D, tex[1].texID);  glBegin(GL_QUADS);  glTexCoord2f(0.0f, 0.0f); glVertex2f(4.0f, 4.0f);  glTexCoord2f(0.0f, 1.0f); glVertex2f(4.0f, 20.0f);  glTexCoord2f(1.0f, 1.0f); glVertex2f(20.0f, 20.0f);  glTexCoord2f(1.0f, 0.0f); glVertex2f(20.0f, 4.0f);  glEnd();    glBindTexture(GL_TEXTURE_2D, tex[0].texID);  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);  glBegin(GL_QUADS);  glTexCoord2f(1.0f, 1.0f); glVertex2f(0.0f, 0.0f);  glTexCoord2f(1.0f, 0.0f); glVertex2f(0.0f, 16.0f);  glTexCoord2f(0.0f, 0.0f); glVertex2f(16.0f, 16.0f);  glTexCoord2f(0.0f, 1.0f); glVertex2f(16.0f, 0.0f);  glEnd();	    glFlush();}/************************** * WinMain * **************************/int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow){  WNDCLASS wc;  HWND hWnd;  HDC hDC;  HGLRC hRC;          MSG msg;  BOOL bQuit = FALSE;  int t, ct;  /* register window class */  wc.style = CS_OWNDC;  wc.lpfnWndProc = WndProc;  wc.cbClsExtra = 0;  wc.cbWndExtra = 0;  wc.hInstance = hInstance;  wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);  wc.hCursor = LoadCursor (NULL, IDC_ARROW);  wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);  wc.lpszMenuName = NULL;  wc.lpszClassName = "GLTest";  RegisterClass (&wc);  /* create main window */  hWnd = CreateWindow ("GLTest", "OpenGL Test", WS_BORDER | WS_POPUPWINDOW | WS_VISIBLE,                        32, 32, 800, 600, NULL, NULL, hInstance, NULL);  /* enable OpenGL for the window */  EnableOpenGL (hWnd, &hDC, &hRC);  glMatrixMode(GL_PROJECTION);  glLoadIdentity();  glMatrixMode(GL_MODELVIEW);  glEnable(GL_TEXTURE_2D);  glDisable(GL_DEPTH_TEST);  glTranslatef(-1.0f,-1.0f,0.0f);  glScalef(0.0025f,0.0033f,0.0f);    //seed random # generator  srand(static_cast<unsigned>(time(0)));    if(!LoadGLTextures())    bQuit=true;    /* program main loop */  while (!bQuit)  {    /* check for messages */    if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))    {      /* handle or dispatch messages */      if (msg.message == WM_QUIT)      {        bQuit = TRUE;      }      else      {        TranslateMessage (&msg);        DispatchMessage (&msg);      }    }    else    {      //draw everything      Render();            SwapBuffers (hDC);    }  }  /* shutdown OpenGL */  DisableOpenGL (hWnd, hDC, hRC);  /* destroy the window explicitly */  DestroyWindow (hWnd);  return msg.wParam;}/******************** * Window Procedure * ********************/LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){  switch (message)  {    case WM_CREATE:      return 0;    case WM_CLOSE:      PostQuitMessage (0);      return 0;    case WM_DESTROY:      return 0;    case WM_KEYDOWN:      switch (wParam)      {      case VK_ESCAPE:        PostQuitMessage(0);        return 0;      }      return 0;    default:    return DefWindowProc (hWnd, message, wParam, lParam);  }}/******************* * Enable OpenGL * *******************/void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC){  PIXELFORMATDESCRIPTOR pfd;  int iFormat;/* get the device context (DC) */  *hDC = GetDC (hWnd);/* set the pixel format for the DC */  ZeroMemory (&pfd, sizeof (pfd));  pfd.nSize = sizeof (pfd);  pfd.nVersion = 1;  pfd.dwFlags = PFD_DRAW_TO_WINDOW |     PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;  pfd.iPixelType = PFD_TYPE_RGBA;  pfd.cColorBits = 24;  pfd.cDepthBits = 16;  pfd.iLayerType = PFD_MAIN_PLANE;  iFormat = ChoosePixelFormat (*hDC, &pfd);  SetPixelFormat (*hDC, iFormat, &pfd);  /* create and enable the render context (RC) */  *hRC = wglCreateContext( *hDC );  wglMakeCurrent( *hDC, *hRC );}/****************** * Disable OpenGL * ******************/void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC){  wglMakeCurrent (NULL, NULL);  wglDeleteContext (hRC);  ReleaseDC (hWnd, hDC);}
that's main.cpp
/********************************************************************************/Name:		TGA.cpp																*/Header:	tga.h																*/Purpose:	Load Compressed and Uncompressed TGA files							*/Functions:	LoadTGA(Texture * texture, char * filename)							*/			LoadCompressedTGA(Texture * texture, char * filename, FILE * fTGA)	*/			LoadUncompressedTGA(Texture * texture, char * filename, FILE * fTGA)*	/*******************************************************************************/#include "tga.h"/********************************************************************************/name :		LoadTGA(Texture * texture, char * filename)							*/function:  Open and test the file to make sure it is a valid TGA file			*	/parems:	texture, pointer to a Texture structure								*/			filename, string pointing to file to open							*/********************************************************************************/bool LoadTGA(Texture * texture, char * filename)				// Load a TGA file{	FILE * fTGA;												// File pointer to texture file	fTGA = fopen(filename, "rb");								// Open file for reading	if(fTGA == NULL)											// If it didn't open....	{		MessageBox(NULL, "Could not open texture file", "ERROR", MB_OK);	// Display an error message		return false;														// Exit function	}	if(fread(&tgaheader, 12, 1, fTGA) == 0)					// Attempt to read 12 byte header from file	{		MessageBox(NULL, "Could not read file header", "ERROR", MB_OK);		// If it fails, display an error message 		if(fTGA != NULL)													// Check to seeiffile is still open		{			fclose(fTGA);													// If it is, close it		}		return false;														// Exit function	}	if(tgaheader[2]==2)				// See if header matches the predefined header of 	{	// an Uncompressed TGA image		LoadUncompressedTGA(texture, filename, fTGA);						// If so, jump to Uncompressed TGA loading code	}	else if(tgaheader[2]==10)		// See if header matches the predefined header of	{																		// an RLE compressed TGA image		LoadCompressedTGA(texture, filename, fTGA);							// If so, jump to Compressed TGA loading code	}	else																	// If header matches neither type	{		MessageBox(NULL, "TGA file be type 2 or type 10 ", "Invalid Image", MB_OK);	// Display an error		fclose(fTGA);		return false;																// Exit function	}	return true;															// All went well, continue on}bool LoadUncompressedTGA(Texture * texture, char * filename, FILE * fTGA)	// Load an uncompressed TGA (note, much of this code is based on NeHe's {																			// TGA Loading code nehe.gamedev.net)	if(fread(tga.header, sizeof(tga.header), 1, fTGA) == 0)					// Read TGA header	{												MessageBox(NULL, "Could not read info header", "ERROR", MB_OK);		// Display error		if(fTGA != NULL)													// if file is still open		{			fclose(fTGA);													// Close it		}		return false;														// Return failular	}		texture->width  = tga.header[1] * 256 + tga.header[0];					// Determine The TGA Width	(highbyte*256+lowbyte)	texture->height = tga.header[3] * 256 + tga.header[2];					// Determine The TGA Height	(highbyte*256+lowbyte)	texture->bpp	= tga.header[4];										// Determine the bits per pixel	tga.Width		= texture->width;										// Copy width into local structure							tga.Height		= texture->height;										// Copy height into local structure	tga.Bpp			= texture->bpp;											// Copy BPP into local structure	if((texture->width <= 0) || (texture->height <= 0) || ((texture->bpp != 24) && (texture->bpp !=32)))	// Make sure all information is valid	{		MessageBox(NULL, "Invalid texture information", "ERROR", MB_OK);	// Display Error		if(fTGA != NULL)													// Check if file is still open		{			fclose(fTGA);													// If so, close it		}		return false;														// Return failed	}	if(tgaheader[0]!=0)	{		if(fread(&tgaID, tgaheader[0], 1, fTGA) == 0)						// Read TGA Id tag		{				MessageBox(NULL, "Could not read tga ID", "ERROR", MB_OK);				// Display Error			if(fTGA != NULL)												// if file is still open			{				fclose(fTGA);												// Close it			}			return false;													// Return fail		}	}	if(texture->bpp == 24)													//If the BPP of the image is 24...	{		texture->type	= GL_RGB;											// Set Image type to GL_RGB	}	else																	// Else if its 32 BPP	{		texture->type	= GL_RGBA;											// Set image type to GL_RGBA	}	tga.bytesPerPixel	= (tga.Bpp / 8);									// Compute the number of BYTES per pixel	tga.imageSize		= (tga.bytesPerPixel * tga.Width * tga.Height);		// Compute the total amout ofmemory needed to store data	texture->imageData	= (GLubyte *)malloc(tga.imageSize);					// Allocate that much memory	if(texture->imageData == NULL)											// If no space was allocated	{		MessageBox(NULL, "Could not allocate memory for image", "ERROR", MB_OK);	// Display Error		fclose(fTGA);														// Close the file		return false;														// Return failed	}	if(fread(texture->imageData, 1, tga.imageSize, fTGA) != tga.imageSize)	// Attempt to read image data	{		MessageBox(NULL, "Could not read image data", "ERROR", MB_OK);		// Display Error		if(texture->imageData != NULL)										// If imagedata has data in it		{			free(texture->imageData);										// Delete data from memory		}		fclose(fTGA);														// Close file		return false;														// Return failed	}	// Byte Swapping Optimized By Steve Thomas	for(GLuint cswap = 0; cswap < (int)tga.imageSize; cswap += tga.bytesPerPixel)	{		texture->imageData[cswap] ^= texture->imageData[cswap+2] ^=		texture->imageData[cswap] ^= texture->imageData[cswap+2];	}	fclose(fTGA);															// Close file	return true;															// Return success}bool LoadCompressedTGA(Texture * texture, char * filename, FILE * fTGA)		// Load COMPRESSED TGAs{ 	if(fread(tga.header, sizeof(tga.header), 1, fTGA) == 0)					// Attempt to read header	{		MessageBox(NULL, "Could not read info header", "ERROR", MB_OK);		// Display Error		if(fTGA != NULL)													// If file is open		{			fclose(fTGA);													// Close it		}		return false;														// Return failed	}	texture->width  = tga.header[1] * 256 + tga.header[0];					// Determine The TGA Width	(highbyte*256+lowbyte)	texture->height = tga.header[3] * 256 + tga.header[2];					// Determine The TGA Height	(highbyte*256+lowbyte)	texture->bpp	= tga.header[4];										// Determine Bits Per Pixel	tga.Width		= texture->width;										// Copy width to local structure	tga.Height		= texture->height;										// Copy width to local structure	tga.Bpp			= texture->bpp;											// Copy width to local structure	if((texture->width <= 0) || (texture->height <= 0) || ((texture->bpp != 24) && (texture->bpp !=32)))	//Make sure all texture info is ok	{		MessageBox(NULL, "Invalid texture information", "ERROR", MB_OK);	// If it isnt...Display error		if(fTGA != NULL)													// Check if file is open		{			fclose(fTGA);													// Ifit is, close it		}		return false;														// Return failed	}		if(tgaheader[0]!=0)	{		if(fread(&tgaID, tgaheader[0], 1, fTGA) == 0)						// Read TGA Id tag		{				MessageBox(NULL, "Could not read tga ID", "ERROR", MB_OK);				// Display Error			if(fTGA != NULL)												// if file is still open			{				fclose(fTGA);												// Close it			}			return false;													// Return fail		}	}	tga.bytesPerPixel	= (tga.Bpp / 8);									// Compute BYTES per pixel	tga.imageSize		= (tga.bytesPerPixel * tga.Width * tga.Height);		// Compute amout of memory needed to store image	texture->imageData	= (GLubyte *)malloc(tga.imageSize);					// Allocate that much memory	if(texture->imageData == NULL)											// If it wasnt allocated correctly..	{		MessageBox(NULL, "Could not allocate memory for image", "ERROR", MB_OK);	// Display Error		fclose(fTGA);														// Close file		return false;														// Return failed	}	GLuint pixelcount	= tga.Height * tga.Width;							// Nuber of pixels in the image	GLuint currentpixel	= 0;												// Current pixel being read	GLuint currentbyte	= 0;												// Current byte 	GLubyte * colorbuffer = (GLubyte *)malloc(tga.bytesPerPixel);			// Storage for 1 pixel	do	{		GLubyte chunkheader = 0;											// Storage for "chunk" header		if(fread(&chunkheader, sizeof(GLubyte), 1, fTGA) == 0)				// Read in the 1 byte header		{			MessageBox(NULL, "Could not read RLE header", "ERROR", MB_OK);	// Display Error			if(fTGA != NULL)												// If file is open			{				fclose(fTGA);												// Close file			}			if(texture->imageData != NULL)									// If there is stored image data			{				free(texture->imageData);									// Delete image data			}			return false;													// Return failed		}		if(chunkheader < 128)												// If the ehader is < 128, it means the that is the number of RAW color packets minus 1		{																	// that follow the header			chunkheader++;													// add 1 to get number of following color values			for(short counter = 0; counter < chunkheader; counter++)		// Read RAW color values			{				if(fread(colorbuffer, 1, tga.bytesPerPixel, fTGA) != tga.bytesPerPixel) // Try to read 1 pixel				{					MessageBox(NULL, "Could not read image data", "ERROR", MB_OK);		// IF we cant, display an error					if(fTGA != NULL)													// See if file is open					{						fclose(fTGA);													// If so, close file					}					if(colorbuffer != NULL)												// See if colorbuffer has data in it					{						free(colorbuffer);												// If so, delete it					}					if(texture->imageData != NULL)										// See if there is stored Image data					{						free(texture->imageData);										// If so, delete it too					}					return false;														// Return failed				}																						// write to memory				texture->imageData[currentbyte		] = colorbuffer[2];				    // Flip R and B vcolor values around in the process 				texture->imageData[currentbyte + 1	] = colorbuffer[1];				texture->imageData[currentbyte + 2	] = colorbuffer[0];				if(tga.bytesPerPixel == 4)												// if its a 32 bpp image				{					texture->imageData[currentbyte + 3] = colorbuffer[3];				// copy the 4th byte				}				currentbyte += tga.bytesPerPixel;										// Increase thecurrent byte by the number of bytes per pixel				currentpixel++;															// Increase current pixel by 1				if(currentpixel > pixelcount)											// Make sure we havent read too many pixels				{					MessageBox(NULL, "Too many pixels read", "ERROR", NULL);			// if there is too many... Display an error!					if(fTGA != NULL)													// If there is a file open					{						fclose(fTGA);													// Close file					}						if(colorbuffer != NULL)												// If there is data in colorbuffer					{						free(colorbuffer);												// Delete it					}					if(texture->imageData != NULL)										// If there is Image data					{						free(texture->imageData);										// delete it					}					return false;														// Return failed				}			}		}		else																			// chunkheader > 128 RLE data, next color reapeated chunkheader - 127 times		{			chunkheader -= 127;															// Subteact 127 to get rid of the ID bit			if(fread(colorbuffer, 1, tga.bytesPerPixel, fTGA) != tga.bytesPerPixel)		// Attempt to read following color values			{					MessageBox(NULL, "Could not read from file", "ERROR", MB_OK);			// If attempt fails.. Display error (again)				if(fTGA != NULL)														// If thereis a file open				{					fclose(fTGA);														// Close it				}				if(colorbuffer != NULL)													// If there is data in the colorbuffer				{					free(colorbuffer);													// delete it				}				if(texture->imageData != NULL)											// If thereis image data				{					free(texture->imageData);											// delete it				}				return false;															// return failed			}			for(short counter = 0; counter < chunkheader; counter++)					// copy the color into the image data as many times as dictated 			{																			// by the header				texture->imageData[currentbyte		] = colorbuffer[2];					// switch R and B bytes areound while copying				texture->imageData[currentbyte + 1	] = colorbuffer[1];				texture->imageData[currentbyte + 2	] = colorbuffer[0];				if(tga.bytesPerPixel == 4)												// If TGA images is 32 bpp				{					texture->imageData[currentbyte + 3] = colorbuffer[3];				// Copy 4th byte				}				currentbyte += tga.bytesPerPixel;										// Increase current byte by the number of bytes per pixel				currentpixel++;															// Increase pixel count by 1				if(currentpixel > pixelcount)											// Make sure we havent written too many pixels				{					MessageBox(NULL, "Too many pixels read", "ERROR", NULL);			// if there is too many... Display an error!					if(fTGA != NULL)													// If there is a file open					{						fclose(fTGA);													// Close file					}						if(colorbuffer != NULL)												// If there is data in colorbuffer					{						free(colorbuffer);												// Delete it					}					if(texture->imageData != NULL)										// If there is Image data					{						free(texture->imageData);										// delete it					}					return false;														// Return failed				}			}		}	}	while(currentpixel < pixelcount);													// Loop while there are still pixels left	fclose(fTGA);																		// Close the file	return true;																		// return success}
TGALoadder.cpp
#ifndef __TEXTURE_H__#define __TEXTURE_H__#pragma comment(lib, "Opengl32.lib")					//Link to OpenGL32.lib so we can use OpenGL stuff#include <windows.h>									// Standard windows header#include <stdio.h>										// Standard I/O header #include <gl\gl.h>										// Header for OpenGL32 librarytypedef	struct									{	GLubyte	* imageData;									// Image Data (Up To 32 Bits)	GLuint	bpp;											// Image Color Depth In Bits Per Pixel	GLuint	width;											// Image Width	GLuint	height;											// Image Height	GLuint	texID;											// Texture ID Used To Select A Texture	GLuint	type;											// Image Type (GL_RGB, GL_RGBA)} Texture;	#endif
Texture.h
#ifndef __TGA_H__#define __TGA_H__#pragma comment(lib, "Opengl32.lib")					//Link to OpenGL32.lib so we can use OpenGL stuff#include <windows.h>									// Standard windows header#include <stdio.h>										// Standard I/O header #include <gl\gl.h>										// Header for OpenGL32 library#include "texture.h"typedef struct{	GLubyte		header[6];								// First 6 Useful Bytes From The Header	GLuint		bytesPerPixel;							// Holds Number Of Bytes Per Pixel Used In The TGA File	GLuint		imageSize;								// Used To Store The Image Size When Setting Aside Ram	GLuint		temp;									// Temporary Variable	GLuint		type;		GLuint		Height;									//Height of Image	GLuint		Width;									//Width ofImage	GLuint		Bpp;									// Bits Per Pixel} TGA;char tgaheader[12];									// TGA headerchar tgaID[256];									// TGA headerTGA tga;												// TGA image databool LoadUncompressedTGA(Texture *, char *, FILE *);	// Load an Uncompressed filebool LoadCompressedTGA(Texture *, char *, FILE *);		// Load a Compressed file#endif
Tga.h
It's basically lesson 33 with slight modifications

edit: I don't know why it's so huge sideways, and the image didn't work. All the image is, is a white rectangle with a small red circle in the middle and the circle doesn't touch the edges. I just want the white transparent. I see I flipped the image in main.cpp, but that doesn't make a difference, I've tried it every way and that must have been the last way.
I couldn't see a call to glEnable(GL_BLEND); anywhere. You need to enable blending for alpha transparency to work.

Enigma

This topic is closed to new replies.

Advertisement