Hello,
I got my TGA class to properly load TARGA (TGA) image files. The program will work fine if I use TGA's I find on the Internet. But, I downloaded the program GIMP for Windows which was reccommended as an image editor on one of Gamedev.net's recent articles since I don't have enough spare $$ to buy Paint Shop Pro 7. When I save a TGA and attempt to display it, the picture is UPSIDE DOWN! You can imagine how painful this is
. It may have something to do with how I draw it one screen with the glTexCoord2f(). Anyways if you have any suggestions they would be very helpful.
Here is the code for the Image class (I'll add bitmap support later on):
#ifndef GLIMAGE
#define GLIMAGE
// Define the universal bitmap id
#define BITMAP_ID 0x4D42
#include <stdio.h> // Holds the file manipulation routines
#include <stdlib.h> // Holds other routines
#include <gl\gl.h> // Header file for the OpenGL32 library
// Structure that holds pertinent information about image formats
typedef struct
{
short int width; // Width of the image
short int height; // Height of the image
unsigned char *data; // Data of the image
} IMAGE;
// The definition fo the GLImage class
class GLImage
{
// Variables
private:
FILE *file; // The file pointer
// Texture format (GL_RGBA, GL_RGB, GL_ALPHA)
GLenum textureFormat;
// Windows Bitmap variables
// Targa image format variables
unsigned char tgaType[4]; // Holds colormap information and the image type - byte 0 ignored
unsigned char tgaInfo[7]; // Holds information such as the image width, height, and number of bits
unsigned char* tgaImageData; // Holds the image data
int tgaImageWidth; // Holds the image width
int tgaImageHeight; // Holds the image height
int tgaImageBits; // Holds the image number of bits
int tgaImageSize; // Holds the image size
// Functions
public:
// Loads a Windows bitmap file
int LoadBMPFile(char *filename, int idNum);
// Loads a Targa image format file - supports 8, 24, and 32 uncompressed images
// The texture to bind this image too is idNum
int LoadTGAFile(char *filename, int idNum);
// Utility functions
private:
// Reads in a RGBA for a 32bit tga image
int tgaRGBA();
// Reads in a RGB for a 24bit tga image
int tgaRGB();
// Reads in a grayscale 8bit tga image
int tgaGray();
// Gets the tga data based on the number of bits of the image
int tgaData();
};
#endif
Here is the function definitions for the GLImage class:
// Include neccessary header files
#include "stdafx.h" // Header file for Windows
#include "GLImage.h" // Header file for the GLImage class
// Loads a Windows bitmap file
int GLImage::LoadBMPFile(char *filename, int idNum)
{
return 1;
}
// Loads a Targa image format file - supports 8, 24, and 32 uncompressed images
// The texture to bind this image too is idNum
int GLImage::LoadTGAFile(char *filename, int idNum)
{
// Open the file and checked to see if it was a success
if((file = fopen(filename, "r+bt")) == NULL)
return 0;
fread(tgaType, sizeof(char), 3, file); // Read in the colormap information and the image type - byte 0 ignored
fseek(file, 12, SEEK_SET); // Seek past the tga header and the other useless information
fread(&tgaInfo, sizeof(char), 6, file); // Read in the vital information
// Load only the image types we support
if(tgaType[1] != 0 || (tgaType[2] != 2 && tgaType[2] != 3))
{
fclose(file);
return 0;
}
tgaImageWidth = tgaInfo[0] + tgaInfo[1] * 256; // Get the image width
tgaImageHeight = tgaInfo[2] + tgaInfo[3] * 256; // Get the image height
tgaImageBits = tgaInfo[4]; // Get the number of bits in the image
tgaImageSize = tgaImageWidth * tgaImageHeight * (tgaImageBits / 8); // Get the image size
// Make sure we are loading a supported type
if(tgaImageBits != 32 && tgaImageBits != 24 && tgaImageBits != 8)
{
fclose(file);
return 0;
}
// Get the image data and check for a success
if(tgaData() == NULL)
{
fclose(file);
return 0;
}
// If there was an error or there was no image data return 0
if(tgaImageData == NULL)
{
fclose(file);
return 0;
}
// Close the file
fclose(file);
// Set up texture with OpenGL
glBindTexture(GL_TEXTURE_2D, idNum);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, textureFormat, tgaImageWidth, tgaImageHeight, 0, textureFormat, GL_UNSIGNED_BYTE, tgaImageData);
// Free the tga image data since it was already uploaded
free(tgaImageData);
return 1;
}
// Reads in a RGBA for a 32bit tga image
int GLImage::tgaRGBA()
{
// Allocate memory for the image data
tgaImageData = (unsigned char*)malloc(tgaImageSize);
// Check to make sure the allocation of memory was a success
if(tgaImageData == NULL)
return 0;
// Make sure the number of bytes read is equal to the size of the image
if(fread(tgaImageData, sizeof(unsigned char), tgaImageSize, file) != (size_t)tgaImageSize)
{
free(tgaImageData);
return 0;
}
// A utility variable
unsigned char temp;
// Since the tga image is in BGR we need to change it to RGB so OpenGL can read it
for (int i = 0; i < tgaImageSize; i += 4)
{
// Swap the appropriate letters
temp = tgaImageData[i];
tgaImageData[i] = tgaImageData[i + 2];
tgaImageData[i + 2] = temp;
}
// Set the texture format to a 32bit RGBA image
textureFormat = GL_RGBA;
return 1;
}
// Reads in a RGB for a 24bit tga image
int GLImage::tgaRGB()
{
// Allocate memory for the image data
tgaImageData = (unsigned char*)malloc(tgaImageSize);
// Check to make sure the allocation of memory was a success
if(tgaImageData == NULL)
return 0;
// Make sure the number of bytes read is equal to the size of the image
if(fread(tgaImageData, sizeof(unsigned char), tgaImageSize, file) != (size_t)tgaImageSize)
{
free(tgaImageData);
return 0;
}
// A utility variable
unsigned char temp;
// Since the tga image is in BGR we need to change it to RGB so OpenGL can read it
for (int i = 0; i < tgaImageSize; i += 3)
{
// Swap the appropriate letters
temp = tgaImageData[i];
tgaImageData[i] = tgaImageData[i + 2];
tgaImageData[i + 2] = temp;
}
// Set the texture format to a 24bit RGB image
textureFormat = GL_RGB;
return 1;
}
// Reads in a grayscale 8bit tga image
int GLImage::tgaGray()
{
// Allocate memory for the image data
tgaImageData = (unsigned char*)malloc(tgaImageSize);
// Check to make sure the allocation of memory was a success
if(tgaImageData == NULL)
return 0;
// Make sure the number of bytes read is equal to the size of the image
if(fread(tgaImageData, sizeof(unsigned char), tgaImageSize, file) != (size_t)tgaImageSize)
{
free(tgaImageData);
return 0;
}
// Set the texture format to a 8bit grayscale image
textureFormat = GL_ALPHA;
return 1;
}
// Gets the tga data based on the number of bits of the image
int GLImage::tgaData()
{
if (tgaImageBits == 32)
return tgaRGBA();
else if (tgaImageBits == 24)
return tgaRGB();
else if (tgaImageBits == 8)
return tgaGray();
return 0;
}
Here is how I implemented it where image is an object of the GLImage class and these functions are a part of a seperate GLMain class:
// Initialize the OpenGL scene
void GLMain::Initialize(GLWindow* wnd)
{
// Initialze the variables
window = wnd; // Get the vital information about the window
angle = 0.0f;
// Enable OpenGL specific abilities
InitGLScene();
if(image.LoadTGAFile("texture.tga", 13) == NULL)
{
// Send an error message
MessageBox(HWND_DESKTOP, "Error loading textures", "Error", MB_OK | MB_ICONEXCLAMATION);
window->isDone = TRUE;
}
}
I'm skipping a few other irrelevant functions....
// Render the scene
void GLMain::Render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the screen
glLoadIdentity(); // Reset the origin back to the center
glTranslatef(0.0f, 0.0f, -30.0f);
glEnable (GL_TEXTURE_2D); // Enable texture mapping
glBindTexture (GL_TEXTURE_2D, 13); // Bind the texture 13 so we can use it
glBegin (GL_QUADS);
glTexCoord2f (0.0f,0.0f); // Lower left corner of image
glVertex3f (-10.0f, -10.0f, 0.0f);
glTexCoord2f (1.0f, 0.0f); // Lower right corner of image
glVertex3f (10.0f, -10.0f, 0.0f);
glTexCoord2f (1.0f, 1.0f); // Upper right corner of image
glVertex3f (10.0f, 10.0f, 0.0f);
glTexCoord2f (0.0f, 1.0f); // Upper left corner of image
glVertex3f (-10.0f, 10.0f, 0.0f);
glEnd ();
glDisable (GL_TEXTURE_2D); // Disable texture mapping
}
Thank you!!
Edited by - Viscous-Flow on October 18, 2001 6:39:57 PM