📄 targa.cpp
字号:
#include <windows.h>
#include <fstream>
#include <gl/gl.h>
#include "targa.h"
#include "tgaformat.h"
using namespace std;
///////////////////////////////////////////////////////////////////////////
GcTarga::GcTarga():
imageTypeCode(0),
imageWidth(0),
imageHeight(0),
bitCount(0),
imageData(NULL)
{
// Constructing the targa object
}
///////////////////////////////////////////////////////////////////////////
GcTarga::~GcTarga()
{
// Free memmory
Destroy();
}
///////////////////////////////////////////////////////////////////////////
bool GcTarga::Load(char *fileName)
{
TGAHeader header;
// Open the TGA file
ifstream file(fileName, ios::in | ios::binary);
// Check to see if opened
if(!file) {
MessageBox(NULL, "Failed to open TGA file.", "ERROR", MB_OK);
return false;
}
// Read the header
file.read((char*)&header, sizeof(TGAHeader));
// Sasve neccessary data
imageTypeCode = header.imageTypeCode;
imageWidth = header.imageWidth;
imageHeight = header.imageHeight;
bitCount = header.bitCount;
// Check that it's the corect type
if((imageTypeCode != 2) && (imageTypeCode != 3) && (imageTypeCode != 10)) {
file.close();
MessageBox(NULL, "The TGA file is not of a suported format", "ERROR", MB_OK);
return false;
}
if(imageTypeCode != 10)
{
// Load a normal, non compressed tga
if(!LoadNormal(file)) {
file.close();
return false;
}
}
else
{
// Load a RLE compressed tga
if(!LoadRLE(file)) {
file.close();
return false;
}
}
// Close the file
file.close();
return true;
}
///////////////////////////////////////////////////////////////////////////
bool GcTarga::Write(char *fileName, uint width, uint height, uint screenBpp)
{
TGAHeader header;
int colorMode;
byte colorSwap;
long imageSize;
// Create file ofr writing
ofstream file(fileName, ios::out | ios::binary);
// Check to make sure it's opened corectly
if(!file) {
file.close();
return false;
}
// Clear the header
memset(&header, 0, sizeof(TGAHeader));
// Fill the header with correct data
header.bitCount = screenBpp;
header.colorMapEntrySize = 0;
header.colorMapLenght = 0;
header.colorMapOrgin = 0;
header.colorMapType = 0;
header.imageDescriptor = 0;
header.imageHeight = height;
header.imageIDLenght = 0;
header.imageTypeCode = 2;
header.imageWidth = width;
header.imageXOrgin = 0;
header.imageYOrgin = 0;
// Get the color mode
colorMode = screenBpp / 8;
// Write the header data to the file
file.write((char*)&header, sizeof(TGAHeader));
// Calculate the image size
imageSize = width * height * colorMode;
// Change image data from RGB to BGR
for(int i = 0; i < imageSize; i += colorMode)
{
colorSwap = imageData[i];
imageData[i] = imageData[i + 2];
imageData[i + 2] = colorSwap;
}
// Write the image data
file.write((char*)imageData, imageSize);
// Close the file
file.close();
return true;
}
///////////////////////////////////////////////////////////////////////////
void GcTarga::Screenshot(char *fileName, uint winWidth, uint winHeight, uint screenBpp)
{
/* WARNING! DO NOT USE THIS IF THE BITMAP ARE TO BE USED FURTHER ON */
// Make sure that the memmory is freed
if(imageData != NULL) {
delete [] imageData;
imageData = NULL;
}
// Allocate and reset the memory
imageData = new byte[winWidth * winHeight * (screenBpp / 8)];
memset(imageData, 0, sizeof(winWidth * winHeight * (screenBpp / 8)));
// Check for format
if(screenBpp == 32)
{
// Read the image data from the window
glReadPixels(0, 0, winWidth, winHeight, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
}
else
{
// Read the image data from the window
glReadPixels(0, 0, winWidth, winHeight, GL_RGB, GL_UNSIGNED_BYTE, imageData);
}
// Write to TGA file
Write(fileName, winWidth, winHeight, screenBpp);
// Make sure that the memmory is freed
if(imageData != NULL) {
delete [] imageData;
imageData = NULL;
}
}
///////////////////////////////////////////////////////////////////////////
void GcTarga::Draw(uint xPos, uint yPos)
{
// Bind a null texture to "disable texturing
glBindTexture(GL_TEXTURE_2D, NULL);
// Set the correct drawing options
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
// Set the position
glRasterPos2i(xPos, yPos);
// Draw the TGA
if(bitCount == 32) {
glDrawPixels(imageWidth, imageHeight, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
}
else {
glDrawPixels(imageWidth, imageHeight, GL_RGB, GL_UNSIGNED_BYTE, imageData);
}
}
///////////////////////////////////////////////////////////////////////////
void GcTarga::Destroy()
{
if(imageData != NULL) {
delete [] imageData;
imageData = NULL;
}
}
///////////////////////////////////////////////////////////////////////////
bool GcTarga::LoadNormal(ifstream &file)
{
byte colorMode;
byte colorSwap;
// Check for depth
if((bitCount == 24) || (bitCount == 32))
{
// Get the color mode
colorMode = bitCount / 8;
// Calculate the size of the image
imageSize = imageWidth * imageHeight * colorMode;
// Allocate memory for image data
imageData = new byte[imageSize];
// Read image data
file.read((char*)imageData, imageSize);
// Change BGR to RGB (BGRA to RGBA)
for(int i = 0; i < imageSize; i += colorMode)
{
colorSwap = imageData[i];
imageData[i] = imageData[i + 2];
imageData[i + 2] = colorSwap;
}
}
else if(bitCount == 16)
{
ushort *pixels;
int r = 0, g = 0, b = 0;
// RGB color mode (after conversion)
imageSize = imageWidth * imageHeight * 3;
// Allocate memory for image data
imageData = new byte[imageSize];
byte *buffer = new byte[imageSize];
// Read the image data
file.read((char*)buffer, imageSize);
// Set pointer to first group of pixles
pixels = (ushort*)buffer;
// Convert to 24 bit RGB
for(int i = 0; i < imageWidth * imageHeight; i++)
{
// Change the pixel to 24 bit
b = (pixels[i] & 0x1f) << 3;
g = ((pixels[i] >> 5) & 0x1f) << 3;
r = ((pixels[i] >> 10) & 0x1f) << 3;
// Swap to RGB and save in array
imageData[i * 3 + 0] = r;
imageData[i * 3 + 1] = g;
imageData[i * 3 + 2] = b;
}
// Free upp the memory
delete [] buffer;
}
else
{
MessageBox(NULL, "TGA file of a not suported bpp", "Error", MB_OK);
return false;
}
return true;
}
///////////////////////////////////////////////////////////////////////////
bool GcTarga::LoadRLE(ifstream &file)
{
/* This code is based on gametutorials.com's tutorial */
/* on loading a RLE TGA file. */
byte rleID = 0;
byte colorCount = 0;
byte colorMode = bitCount / 8;
int colorsRead = 0;
int stride = colorMode * imageWidth;
int pixels = 0, j = 0;
int counter = 0;
int dataSize;
// Find the size of the image data
file.seekg(0, ios::end);
dataSize = file.tellg();
dataSize -= sizeof(TGAHeader);
// Set position for data reading
file.seekg(sizeof(TGAHeader), ios::beg);
// Allocate memory for image data
imageData = new byte[stride * imageHeight];
byte *color = new byte[colorMode];
byte *buffer = new byte[dataSize];
// Read all image data to the buffer
file.read((char*)buffer, dataSize);
// Read the image data
while(pixels < imageWidth * imageHeight)
{
// Read in the current color count + 1
rleID = buffer[counter++];
if(rleID < 128)
{
/* The colroCount number of colors are uniqe */
// Calculate the number of colors to be read
colorCount = rleID + 1;
// Go through and read all the unique colors found
while(colorCount)
{
// Read in the current color
for(j = 0; j < colorMode; j++) {
color[j] = buffer[counter++];
}
// Store the current pixel in our image array
imageData[colorsRead + 0] = color[2];
imageData[colorsRead + 1] = color[1];
imageData[colorsRead + 2] = color[0];
// Is this a RGBA file?
if(bitCount == 32) {
imageData[colorsRead + 3] = color[3];
}
pixels++;
colorCount--;
colorsRead += colorMode;
}
}
else
{
/* The colroCount number of colors are the same */
// Calculate the number of colors to be read
colorCount = rleID - 127;
// Read in the current color
for(j = 0; j < colorMode; j++) {
color[j] = buffer[counter++];
}
// Write colorCount pixels of the smae color to the imageData
while(colorCount)
{
// Swap to RGB form BGR
imageData[colorsRead + 0] = color[2];
imageData[colorsRead + 1] = color[1];
imageData[colorsRead + 2] = color[0];
// Is this a RGBA file?
if(bitCount == 32) {
imageData[colorsRead + 3] = color[3];
}
pixels++;
colorCount--;
colorsRead += colorMode;
}
}
}
// Free up the memory
delete [] color;
delete [] buffer;
return true;
}
///////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -