Files
simgear/simgear/scene/sky/clouds3d/SkyTextureManager.cpp
2002-09-13 20:29:04 +00:00

883 lines
28 KiB
C++

//------------------------------------------------------------------------------
// File : SkyTextureManager.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
/**
* @file SkyTextureManager.cpp
*
* Implementation of a manager that keeps track of texture resource locations and sharing.
*/
#pragma warning( disable : 4786)
#include "SkyTextureManager.hpp"
#include "SkyContext.hpp"
//#include "glvu.hpp"
//#include "ppm.hpp"
//#include "tga.hpp"
//#include "fileutils.hpp"
bool SkyTextureManager::s_bSlice3DTextures = false;
//------------------------------------------------------------------------------
// Function : SkyTextureManager::SkyTextureManager
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::SkyTextureManager(bool bSlice3DTextures)
* @brief Constructor.
*
*/
SkyTextureManager::SkyTextureManager(bool bSlice3DTextures /* = false */)
{
s_bSlice3DTextures = bSlice3DTextures;
// this should be put somewhere more safe -- like done once in the functions that actually
// use these extensions.
/*GraphicsContext::InstancePtr()->InitializeExtensions("GL_ARB_texture_cube_map "
"GL_VERSION_1_2");*/
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::~SkyTextureManager
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::~SkyTextureManager()
* @brief destructor.
*
* @todo <WRITE EXTENDED SkyTextureManager::~SkyTextureManager FUNCTION DOCUMENTATION>
*/
SkyTextureManager::~SkyTextureManager()
{
_texturePaths.clear();
for ( TextureIterator iter = _textures.begin();
iter != _textures.end();
++iter)
{
DestroyTextureObject(iter->second);
}
_textures.clear();
for ( TextureList::iterator uncachedIter = _uncachedTextures.begin();
uncachedIter != _uncachedTextures.end();
++uncachedIter)
{
DestroyTextureObject(*uncachedIter);
}
_uncachedTextures.clear();
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::AddPath
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::AddPath(const string &path)
* @brief Adds a texture path to the list of active search paths.
*
*/
void SkyTextureManager::AddPath(const string &path)
{
_texturePaths.push_back(path);
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::Get2DTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::Get2DTexture(const string& filename, SkyTexture& texture, bool bMipmap)
* @brief Returns a 2D texture object from the texture set.
*
* If the texture is already loaded, it is returned. If it is not, the texture is loaded from
* file, added to the texture set, and returned.
*
* If the image cannot be loaded, returns an error. Otherwise returns success.
*/
SKYRESULT SkyTextureManager::Get2DTexture(const string& filename,
SkyTexture& texture,
bool bMipmap /* = false */)
{
TextureIterator iter = _textures.find(filename);
if (iter != _textures.end())
{ // the texture is already loaded, just return it.
texture = iter->second;
}
else
{ // the texture is being requested for the first time, load and return it
FAIL_RETURN(Clone2DTexture(filename, texture, bMipmap));
_textures.insert(make_pair(filename, texture));
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::Get3DTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::Get3DTexture(const string& filename, SkyTexture& texture, unsigned int iDepth, bool bMipmap, bool bLoadFromSliceFiles)
* @brief Returns a 3D texture object from the texture set.
*
* If the texture is already loaded, it is returned. If it is not, the texture is loaded from
* file, added to the texture set, and returned. If the image cannot be loaded, returns an error.
* Otherwise returns success.
*
* For 3D textures, this simply loads a 2D image file, and duplicates it across each slice. The
* parameter iDepth must be set in order to use a 2D texture image for a 3D texture.
*/
SKYRESULT SkyTextureManager::Get3DTexture(const string& filename,
SkyTexture& texture,
unsigned int iDepth,
bool bMipmap /* = false */,
bool bLoadFromSliceFiles /* = false */)
{
TextureIterator iter = _textures.find(filename);
if (iter != _textures.end())
{ // the texture is already loaded, just return it.
texture = iter->second;
}
else
{ // the texture is being requested for the first time, load and return it
FAIL_RETURN(Clone3DTexture(filename, texture, iDepth, bMipmap, bLoadFromSliceFiles));
_textures.insert(make_pair(filename, texture));
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : roundPowerOf2
// Description :
//------------------------------------------------------------------------------
static int roundPowerOf2(int n)
{
int m;
for (m = 1; m < n; m *= 2);
// m >= n
if (m - n <= n - m/2)
return m;
else
return m/2;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::Clone2DTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::Clone2DTexture( const string &filename, SkyTexture& texture, bool bMipmap)
* @brief Returns a 2D texture object.
*
* Ignores texture set. This always loads the file, if it exists, and creates and returns the texture.
*
* If the image cannot be loaded, returns an error. Otherwise returns success.
*/
SKYRESULT SkyTextureManager::Clone2DTexture(const string &filename,
SkyTexture& texture,
bool bMipmap /* = false */)
{
string pathFilename;
unsigned char *pImageData = NULL;
int iWidth = 0;
int iHeight = 0;
int iChannels = 0;
enum ImageType
{
IMAGE_PPM,
IMAGE_TGA
};
ImageType eType;
/****
// first get the image type from its extension.
if (filename.find(".tga") != string.npos || filename.find(".TGA") != string.npos)
eType = IMAGE_TGA;
else if (filename.find(".ppm") != string.npos || filename.find(".PPM") != string.npos)
eType = IMAGE_PPM;
else
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyTextureManager error: invalid image format");
****/
// first try the filename sent in in case it includes a path.
//if (FileUtils::FileExists(filename.c_str()))
//{
// printf("Filename is %s\n", filename.c_str() );
//eType = IMAGE_TGA;
/* switch (eType)
{
case IMAGE_PPM:
LoadPPM(filename.c_str(), pImageData, iWidth, iHeight);
iChannels = 3;
break;
case IMAGE_TGA:
LoadTGA(filename.c_str(), pImageData, iWidth, iHeight, iChannels);
break;
default:
break;
}
*/
//}
if (!pImageData) // image not found in current directory. Check the paths...
{
for ( StringList::iterator iter = _texturePaths.begin();
iter != _texturePaths.end();
++iter)
{ // loop over all texture paths, looking for the filename
// get just the filename without path.
int iPos = filename.find_last_of("/");
if (iPos == filename.npos)
iPos = filename.find_last_of("/");
// tack on the paths from the texture path list.
if (iPos != filename.npos)
pathFilename = (*iter) + "/" + filename.substr(iPos+1);
else
pathFilename = (*iter) + "/" + filename;
//if (FileUtils::FileExists(pathFilename.c_str()))
//{
/* switch (eType)
{
case IMAGE_PPM:
LoadPPM(pathFilename.c_str(), pImageData, iWidth, iHeight);
break;
case IMAGE_TGA:
LoadTGA(pathFilename.c_str(), pImageData, iWidth, iHeight, iChannels);
break;
default:
break;
}
*/
//if (pImageData)
//break;
//}
}
}
if (!pImageData)
{
char buffer[256];
sprintf(buffer, "SkyTextureManager::Clone2DTexture(): Could not load image. %s.\n", filename);
FAIL_RETURN_MSG(SKYRESULT_OK, buffer);
}
// make sure it is power of 2 resolution.
int iNewWidth = roundPowerOf2(iWidth);
int iNewHeight = roundPowerOf2(iHeight);
int iMaxsize;
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &iMaxsize );
if (iNewWidth > iMaxsize)
{
iNewWidth = iMaxsize;
}
if (iNewHeight> iMaxsize)
{
iNewHeight = iMaxsize;
}
GLenum eFormat = (4 == iChannels) ? GL_RGBA : GL_RGB;
if (iNewWidth != iWidth || iNewHeight != iHeight)
{
unsigned char *pScaledImageData = new unsigned char[iChannels * iNewWidth * iNewHeight];
gluScaleImage(eFormat, iWidth, iHeight, GL_UNSIGNED_BYTE, pImageData,
iNewWidth, iNewHeight, GL_UNSIGNED_BYTE, pScaledImageData);
SAFE_DELETE_ARRAY(pImageData);
pImageData = pScaledImageData;
}
_Create2DTextureObject( texture, iNewWidth, iNewHeight, eFormat, pImageData);
SAFE_DELETE_ARRAY(pImageData);
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::Clone3DTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::Clone3DTexture( const string &filename, SkyTexture& texture, unsigned int iDepth, bool bMipmap, bool bLoadFromSliceFiles)
* @brief Returns a 3D texture object.
*
* Ignores texture set. This always loads the file, if it exists, and creates and returns the texture.
* If the image cannot be loaded, returns an error. Otherwise returns success.
*/
SKYRESULT SkyTextureManager::Clone3DTexture(const string &filename,
SkyTexture& texture,
unsigned int iDepth,
bool bMipmap /* = false */,
bool bLoadFromSliceFiles /* = false */)
{
string pathFilename;
/*QImage image;
QDir dir;
unsigned char *pBits = NULL;
if (!bLoadFromSliceFiles)
{
// first try the filename sent in in case it includes a path.
if (image.load(filename))
{
image = QGLWidget::convertToGLFormat(image);
}
else
{
image.reset();
for ( QStringList::Iterator iter = _texturePaths.begin();
iter != _texturePaths.end();
iter++)
{ // loop over all texture paths, looking for the filename
pathFilename = (*iter) + "\\" + filename;
if (image.load(pathFilename))
{
image = QGLWidget::convertToGLFormat(image);
break;
}
else
image.reset();
}
}
if (image.isNull())
{
qWarning("SkyTextureManager::GetTexture(): Could not load image "
"%s.\n", filename);
return false;
}
// make sure it is power of 2 resolutions.
int iWidth = roundPowerOf2(image.width());
int iHeight = roundPowerOf2(image.height());
int iMaxsize;
if (s_bSlice3DTextures)
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &iMaxsize );
else
glGetIntegerv( GL_MAX_3D_TEXTURE_SIZE, &iMaxsize );
if (iWidth > iMaxsize)
{
iWidth = iMaxsize;
}
if (iHeight> iMaxsize)
{
iHeight = iMaxsize;
}
if (iWidth != image.width() || iHeight != image.height())
image = image.smoothScale(iWidth, iHeight);
// first build an array of repeated 2D textures...
QImage inverted(image.mirror());
pBits = new unsigned char[image.numBytes() * iDepth];
unsigned int iSliceSize = image.numBytes();
int bInverted = false;
int iInvertedCount = 8;
for (unsigned int iSlice = 0; iSlice < iDepth; ++iSlice)
{
memcpy(&(pBits[iSlice * iSliceSize]),
(bInverted) ? inverted.bits() : image.bits(),
image.numBytes());
if (--iInvertedCount <= 0)
{
iInvertedCount = 8;
bInverted = !bInverted;
}
}
}
else /// Load from a set of files matching the file pattern
{
QFileInfo fi(filename);
fi.refresh();
QString baseFilename = fi.baseName();
int truncPos = baseFilename.find(QRegExp("[0-9]"));
if (truncPos >= 0)
baseFilename.truncate(truncPos);
dir.setFilter(QDir::Files);
dir.setNameFilter(baseFilename + "*." + fi.extension());
dir.setSorting(QDir::Name);
QStringList files = dir.entryList();
bool bFound = true;
if (files.count() < iDepth)
{
bFound = false;
for ( QStringList::Iterator iter = _texturePaths.begin();
iter != _texturePaths.end();
iter++)
{
dir.setCurrent(*iter);
files = dir.entryList();
if (files.count() >= iDepth)
{
bFound = true;
break;
}
}
}
if (!bFound)
{
qWarning("SkyTextureManager::Clone3DTexture: ERROR: could not find %d files matching "
"%s", iDepth, filename.latin1());
return false;
}
else
{
unsigned int iSlice = 0;
unsigned int iSliceSize = 0;
for ( QStringList::Iterator iter = files.begin();
iter != files.end() && iSlice < iDepth;
iter++)
{
if (image.load(*iter))
{
image = QGLWidget::convertToGLFormat(image);
// make sure it is power of 2 resolution.
int iWidth = roundPowerOf2(image.width());
int iHeight = roundPowerOf2(image.height());
int iMaxsize;
if (s_bSlice3DTextures)
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &iMaxsize );
else
glGetIntegerv( GL_MAX_3D_TEXTURE_SIZE, &iMaxsize );
if (iWidth > iMaxsize)
{
iWidth = iMaxsize;
}
if (iHeight> iMaxsize)
{
iHeight = iMaxsize;
}
if (iWidth != image.width() || iHeight != image.height())
image = image.smoothScale(iWidth, iHeight);
if (0 == iSlice)
{
pBits = new unsigned char[image.numBytes() * iDepth];
iSliceSize = image.numBytes();
}
memcpy(&(pBits[iSlice * iSliceSize]), image.bits(), image.numBytes());
++iSlice;
}
else
{
qWarning("SkyTextureManager::Clone3DTexture: ERROR: could not find %d files matching "
"%s", iDepth, filename);
return false;
}
}
}
}
_Create3DTextureObject(texture,
image.width(),
image.height(),
iDepth,
GL_RGBA,
pBits);
*/
return SKYRESULT_FAIL;
}
//!
/*! */
//------------------------------------------------------------------------------
// Function : SkyTextureManager::GetCubeMapTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::GetCubeMapTexture(const string& filename, SkyTexture& texture, bool bMipmap)
* @brief Returns a cube map texture object from the texture set
*
* If the texture is already loaded, it is returned. If it is not, the texture is loaded from file,
* added to the texture set, and returned. If any of the 6 images cannot be loaded, returns an error.
* Otherwise returns success.
*/
SKYRESULT SkyTextureManager::GetCubeMapTexture( const string& filename,
SkyTexture& texture,
bool bMipmap)
{
TextureIterator iter = _textures.find(filename);
if (iter != _textures.end())
{ // the texture is already loaded, just return it.
texture = iter->second;
}
else
{ // the texture is being requested for the first time, load and return it
if (!CloneCubeMapTexture(filename, texture, bMipmap))
return false;
_textures.insert(make_pair(filename, texture));
}
return true;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::CloneCubeMapTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::CloneCubeMapTexture(const string& filename, SkyTexture& texture, bool bMipmap)
* @brief Returns a cube map texture object.
*
* Ignores the texture set. This always loads the cube map texture, if all 6 face images exist,
* creates the texture, and returns it. If any of the 6 images cannot be loaded, returns an error.
* Otherwise returns success.
*/
SKYRESULT SkyTextureManager::CloneCubeMapTexture( const string& filename,
SkyTexture& texture,
bool bMipmap)
{
string pathFilename;
/*QImage images[6];
GLenum faces [] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB };
char* faceNames[] = {"posx", "negx", "posy", "negy", "posz", "negz" };
for ( QStringList::Iterator iter = _texturePaths.begin();
iter != _texturePaths.end();
iter++)
{ // loop over all texture paths, looking for the filename
for (int i = 0; i < 6; i++)
{
char buffer[FILENAME_MAX];
sprintf(buffer, filename.ascii(), faceNames[i]);
pathFilename = (*iter) + "\\" + buffer;
if (images[i].load(pathFilename))
{
images[i] = QGLWidget::convertToGLFormat(images[i]);
}
else
images[i].reset();
}
}
for (int i = 0; i < 6; i++)
{
if (images[i].isNull())
{
char buffer[FILENAME_MAX];
sprintf(buffer, filename.ascii(), faceNames[i]);
qWarning("SkyTextureManager::GetTexture(): Could not load image "
"%s.\n", buffer);
return false;
}
}
glGenTextures(1, &(texture.iTextureID));
texture.iWidth = images[0].width();
texture.iHeight = images[0].height();
// create and bind a cubemap texture object
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, texture.iTextureID);
// enable automipmap generation if needed.
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_GENERATE_MIPMAP_SGIS, bMipmap);
if (bMipmap)
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
else
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
for (i = 0; i < 6; i++)
{
glTexImage2D(faces[i],
0,
GL_RGBA8,
images[i].width(),
images[i].height(),
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
images[i].bits());
}*/
return true;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::_Create2DTextureObject
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::_Create2DTextureObject(SkyTexture &texture, unsigned int iWidth, unsigned int iHeight, unsigned int iFormat, unsigned char *pData)
* @brief Creates a 2D texture.
*
* Creates an OpenGL texture object and returns its ID and dimensions in a SkyTexture structure.
*/
SKYRESULT SkyTextureManager::_Create2DTextureObject(SkyTexture &texture,
unsigned int iWidth,
unsigned int iHeight,
unsigned int iFormat,
unsigned char *pData)
{
bool bNew = false;
unsigned int iTextureID;
if (!texture.GetID())
{
glGenTextures(1, &iTextureID);
texture.SetID(iTextureID);
bNew = true;
}
texture.SetWidth(iWidth);
texture.SetHeight(iHeight);
glBindTexture(GL_TEXTURE_2D, texture.GetID());
if (bNew)
{
unsigned int iInternalFormat;
switch (iFormat)
{
case GL_LUMINANCE:
iInternalFormat = GL_LUMINANCE;
break;
case GL_LUMINANCE_ALPHA:
iInternalFormat = GL_LUMINANCE_ALPHA;
break;
default:
iInternalFormat = GL_RGBA8;
break;
}
glTexImage2D( GL_TEXTURE_2D,
0,
iInternalFormat,
iWidth, iHeight,
0,
iFormat,
GL_UNSIGNED_BYTE,
pData);
}
else
{
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0,
iWidth, iHeight,
iFormat,
GL_UNSIGNED_BYTE,
pData);
}
// set default filtering.
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::_Create3DTextureObject
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::_Create3DTextureObject(SkyTexture &texture, unsigned int iWidth, unsigned int iHeight, unsigned int iDepth, unsigned int iFormat, unsigned char *pData)
* @brief Creates a 3D texture
*
* Creates an OpenGL 3D texture object (or a set of 2D slices) and returns its ID and dimensions
* in a SkyTexture structure.
*/
SKYRESULT SkyTextureManager::_Create3DTextureObject(SkyTexture &texture,
unsigned int iWidth,
unsigned int iHeight,
unsigned int iDepth,
unsigned int iFormat,
unsigned char *pData)
{
/* bool bNew = false;
if (s_bSlice3DTextures) // create one 2D texture per slice!
{
if (!texture.pSliceIDs)
{
texture.pSliceIDs = new unsigned int[iDepth];
glGenTextures(iDepth, texture.pSliceIDs);
bNew = true;
}
}
else if (!texture.iTextureID)
{
glGenTextures(1, &(texture.iTextureID));
bNew = true;
}
texture.iWidth = iWidth;
texture.iHeight = iHeight;
texture.iDepth = iDepth;
texture.bSliced3D = s_bSlice3DTextures;
if (!s_bSlice3DTextures)
{
glBindTexture(GL_TEXTURE_3D, texture.iTextureID);
if (bNew)
{
unsigned int iInternalFormat;
switch (iFormat)
{
case GL_LUMINANCE:
iInternalFormat = GL_LUMINANCE;
break;
case GL_LUMINANCE_ALPHA:
iInternalFormat = GL_LUMINANCE_ALPHA;
break;
default:
iInternalFormat = GL_RGBA;
break;
}
glTexImage3D( GL_TEXTURE_3D,
0,
iInternalFormat,
iWidth, iHeight, iDepth,
0,
iFormat,
GL_UNSIGNED_BYTE,
pData);
}
else
{
glTexSubImage3D(GL_TEXTURE_3D,
0, 0, 0, 0,
iWidth, iHeight, iDepth,
iFormat,
GL_UNSIGNED_BYTE,
pData);
}
// set default filtering.
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
else
{
unsigned int iInternalFormat = 0;
unsigned int iBytesPerPixel = 0;
switch (iFormat)
{
case GL_LUMINANCE:
iInternalFormat = GL_LUMINANCE;
iBytesPerPixel = 1;
break;
case GL_LUMINANCE_ALPHA:
iInternalFormat = GL_LUMINANCE_ALPHA;
iBytesPerPixel = 2;
break;
case GL_RGBA:
default:
iInternalFormat = GL_RGBA;
iBytesPerPixel = 4;
break;
}
unsigned int iSliceSize = iWidth * iHeight * iBytesPerPixel;
// create iDepth 2D texture slices...
for (unsigned int iSlice = 0; iSlice < iDepth; ++iSlice)
{
glBindTexture(GL_TEXTURE_2D, texture.pSliceIDs[iSlice]);
if (bNew)
{
glTexImage2D( GL_TEXTURE_2D,
0,
iInternalFormat,
iWidth, iHeight,
0,
iFormat,
GL_UNSIGNED_BYTE,
(pData + iSlice * iSliceSize));
}
else
{
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0,
iWidth, iHeight,
iFormat,
GL_UNSIGNED_BYTE,
(pData + iSlice * iSliceSize));
}
// set default filtering.
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
}
GLVU::CheckForGLError("SkyTextureManager::_Create3DTextureObject()");
return SKYRESULT_OK;*/
return SKYRESULT_FAIL;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::DestroyTextureObject
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::DestroyTextureObject(SkyTexture &texture)
* @brief destroys a SkyTexture object.
*
* Deletes the data as well as the OpenGL texture ID(s).
*/
void SkyTextureManager::DestroyTextureObject(SkyTexture &texture)
{
/*if (texture.GetID)
glDeleteTextures(1, &(texture.iTextureID));
if (texture.bSliced3D && texture.pSliceIDs)
{
glDeleteTextures(texture.iDepth, texture.pSliceIDs);
delete [] texture.pSliceIDs;
}*/
}