2012-10-24 06:57:34 +00:00
|
|
|
//
|
|
|
|
|
// KRTextureTGA.cpp
|
|
|
|
|
// KREngine
|
|
|
|
|
//
|
|
|
|
|
// Created by Kearwood Gilbert on 2012-10-23.
|
|
|
|
|
// Copyright (c) 2012 Kearwood Software. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#include "KRTextureTGA.h"
|
2012-10-25 03:15:28 +00:00
|
|
|
#include "KREngine-common.h"
|
2012-11-17 00:15:52 +00:00
|
|
|
#include "KRContext.h"
|
2012-10-25 03:15:28 +00:00
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
char idlength;
|
|
|
|
|
char colourmaptype;
|
|
|
|
|
char imagetype;
|
|
|
|
|
short int colourmaporigin;
|
|
|
|
|
short int colourmaplength;
|
|
|
|
|
char colourmapdepth;
|
|
|
|
|
short int x_origin;
|
|
|
|
|
short int y_origin;
|
|
|
|
|
short width;
|
|
|
|
|
short height;
|
|
|
|
|
char bitsperpixel;
|
|
|
|
|
char imagedescriptor;
|
|
|
|
|
} __attribute__((packed)) TGA_HEADER;
|
|
|
|
|
|
|
|
|
|
|
2012-12-20 01:23:57 +00:00
|
|
|
KRTextureTGA::KRTextureTGA(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name)
|
2012-10-25 03:15:28 +00:00
|
|
|
{
|
2013-10-06 18:56:23 -07:00
|
|
|
data->lock();
|
2012-10-25 03:15:28 +00:00
|
|
|
TGA_HEADER *pHeader = (TGA_HEADER *)data->getStart();
|
|
|
|
|
|
|
|
|
|
m_max_lod_max_dim = pHeader->width > pHeader->height ? pHeader->width : pHeader->height;
|
|
|
|
|
m_min_lod_max_dim = m_max_lod_max_dim; // Mipmaps not yet supported for TGA images
|
2013-11-16 02:34:18 -08:00
|
|
|
switch(pHeader->imagetype) {
|
|
|
|
|
case 2: // rgb
|
|
|
|
|
switch(pHeader->bitsperpixel) {
|
|
|
|
|
case 24:
|
|
|
|
|
{
|
|
|
|
|
m_imageSize = pHeader->width * pHeader->height * 4;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 32:
|
|
|
|
|
{
|
|
|
|
|
m_imageSize = pHeader->width * pHeader->height * 4;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
assert(false);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
assert(false);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-06 18:56:23 -07:00
|
|
|
data->unlock();
|
2012-10-25 03:15:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
KRTextureTGA::~KRTextureTGA()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-16 02:34:18 -08:00
|
|
|
bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim)
|
2013-11-01 23:17:04 -07:00
|
|
|
{
|
|
|
|
|
m_pData->lock();
|
2012-10-25 03:15:28 +00:00
|
|
|
TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart();
|
2012-11-17 00:15:52 +00:00
|
|
|
unsigned char *pData = (unsigned char *)pHeader + (long)pHeader->idlength + (long)pHeader->colourmaplength * (long)pHeader->colourmaptype + sizeof(TGA_HEADER);
|
2012-10-25 03:15:28 +00:00
|
|
|
|
|
|
|
|
if(pHeader->colourmaptype != 0) {
|
2013-11-01 23:17:04 -07:00
|
|
|
m_pData->unlock();
|
2012-10-25 03:15:28 +00:00
|
|
|
return false; // Mapped colors not supported
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GLenum err;
|
|
|
|
|
|
|
|
|
|
switch(pHeader->imagetype) {
|
|
|
|
|
case 2: // rgb
|
|
|
|
|
switch(pHeader->bitsperpixel) {
|
|
|
|
|
case 24:
|
|
|
|
|
{
|
|
|
|
|
unsigned char *converted_image = (unsigned char *)malloc(pHeader->width * pHeader->height * 4);
|
|
|
|
|
//#ifdef __APPLE__
|
|
|
|
|
// vImage_Buffer source_image = { pData, pHeader->height, pHeader->width, pHeader->width*3 };
|
|
|
|
|
// vImage_Buffer dest_image = { converted_image, pHeader->height, pHeader->width, pHeader->width*4 };
|
|
|
|
|
// vImageConvert_RGB888toRGBA8888(&source_image, NULL, 0xff, &dest_image, false, kvImageDoNotTile);
|
|
|
|
|
//#else
|
|
|
|
|
unsigned char *pSource = pData;
|
|
|
|
|
unsigned char *pDest = converted_image;
|
|
|
|
|
unsigned char *pEnd = pData + pHeader->height * pHeader->width * 3;
|
|
|
|
|
while(pSource < pEnd) {
|
|
|
|
|
*pDest++ = pSource[0];
|
|
|
|
|
*pDest++ = pSource[1];
|
|
|
|
|
*pDest++ = pSource[2];
|
|
|
|
|
*pDest++ = 0xff;
|
|
|
|
|
pSource += 3;
|
|
|
|
|
}
|
|
|
|
|
//#endif
|
|
|
|
|
glTexImage2D(target, 0, GL_RGBA, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)converted_image);
|
2013-10-06 18:56:23 -07:00
|
|
|
free(converted_image);
|
2012-10-25 03:15:28 +00:00
|
|
|
err = glGetError();
|
2012-11-17 00:15:52 +00:00
|
|
|
if (err != GL_NO_ERROR) {
|
2013-11-01 23:17:04 -07:00
|
|
|
m_pData->unlock();
|
2012-11-17 00:15:52 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2012-10-25 03:15:28 +00:00
|
|
|
current_lod_max_dim = m_max_lod_max_dim;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 32:
|
|
|
|
|
{
|
|
|
|
|
glTexImage2D(target, 0, GL_RGBA, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)pData);
|
|
|
|
|
err = glGetError();
|
2012-11-17 00:15:52 +00:00
|
|
|
if (err != GL_NO_ERROR) {
|
2013-11-01 23:17:04 -07:00
|
|
|
m_pData->unlock();
|
2012-11-17 00:15:52 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2012-10-25 03:15:28 +00:00
|
|
|
current_lod_max_dim = m_max_lod_max_dim;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2013-11-01 23:17:04 -07:00
|
|
|
m_pData->unlock();
|
2012-10-25 03:15:28 +00:00
|
|
|
return false; // 16-bit images not yet supported
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2013-11-01 23:17:04 -07:00
|
|
|
m_pData->unlock();
|
2012-10-25 03:15:28 +00:00
|
|
|
return false; // Image type not yet supported
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-01 23:17:04 -07:00
|
|
|
m_pData->unlock();
|
2012-10-25 03:15:28 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2012-11-17 00:15:52 +00:00
|
|
|
|
|
|
|
|
long KRTextureTGA::getMemRequiredForSize(int max_dim)
|
|
|
|
|
{
|
2013-11-16 02:34:18 -08:00
|
|
|
return m_imageSize;
|
2012-11-17 00:15:52 +00:00
|
|
|
}
|
2012-12-20 01:23:57 +00:00
|
|
|
|
|
|
|
|
std::string KRTextureTGA::getExtension()
|
|
|
|
|
{
|
|
|
|
|
return "tga";
|
|
|
|
|
}
|