nv_dds.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 1,363 行 · 第 1/3 页
CPP
1,363 行
GLenum target;
// loop through cubemap faces and load them as 2D textures
for (unsigned int n = 0; n < 6; n++)
{
// specify cubemap face
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + n;
if (!upload_texture2D(n, target))
return false;
}
return true;
}
#endif // !BITMAP_NO_OPENGL
///////////////////////////////////////////////////////////////////////////////
// clamps input size to [1-size]
inline unsigned int CDDSImage::clamp_size(unsigned int size)
{
if (size <= 0)
size = 1;
return size;
}
///////////////////////////////////////////////////////////////////////////////
// CDDSImage private functions
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// calculates size of DXTC texture in bytes
inline unsigned int CDDSImage::size_dxtc(unsigned int width, unsigned int height)
{
return ((width+3)/4)*((height+3)/4)*
(m_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ? 8 : 16);
}
///////////////////////////////////////////////////////////////////////////////
// calculates size of uncompressed RGB texture in bytes
inline unsigned int CDDSImage::size_rgb(unsigned int width, unsigned int height)
{
return width*height*m_components;
}
///////////////////////////////////////////////////////////////////////////////
// flip image around X axis
void CDDSImage::flip(CSurface &surface)
{
unsigned int linesize;
unsigned int offset;
if (!is_compressed())
{
assert(surface.get_depth() > 0);
unsigned int imagesize = surface.get_size()/surface.get_depth();
linesize = imagesize / surface.get_height();
for (unsigned int n = 0; n < surface.get_depth(); n++)
{
offset = imagesize*n;
unsigned char *top = (unsigned char*)surface + offset;
unsigned char *bottom = top + (imagesize-linesize);
for (unsigned int i = 0; i < (surface.get_height() >> 1); i++)
{
swap(bottom, top, linesize);
top += linesize;
bottom -= linesize;
}
}
}
else
{
void (CDDSImage::*flipblocks)(DXTColBlock*, unsigned int);
unsigned int xblocks = surface.get_width() / 4;
unsigned int yblocks = surface.get_height() / 4;
unsigned int blocksize;
switch (m_format)
{
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
blocksize = 8;
flipblocks = &CDDSImage::flip_blocks_dxtc1;
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
blocksize = 16;
flipblocks = &CDDSImage::flip_blocks_dxtc3;
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
blocksize = 16;
flipblocks = &CDDSImage::flip_blocks_dxtc5;
break;
default:
return;
}
linesize = xblocks * blocksize;
DXTColBlock *top;
DXTColBlock *bottom;
for (unsigned int j = 0; j < (yblocks >> 1); j++)
{
top = (DXTColBlock*)((unsigned char*)surface+ j * linesize);
bottom = (DXTColBlock*)((unsigned char*)surface + (((yblocks-j)-1) * linesize));
(this->*flipblocks)(top, xblocks);
(this->*flipblocks)(bottom, xblocks);
swap(bottom, top, linesize);
}
}
}
void CDDSImage::flip_texture(CTexture &texture)
{
flip(texture);
for (unsigned int i = 0; i < texture.get_num_mipmaps(); i++)
{
flip(texture.get_mipmap(i));
}
}
///////////////////////////////////////////////////////////////////////////////
// swap to sections of memory
void CDDSImage::swap(void *byte1, void *byte2, unsigned int size)
{
unsigned char *tmp = SAFE_NEW unsigned char[size];
memcpy(tmp, byte1, size);
memcpy(byte1, byte2, size);
memcpy(byte2, tmp, size);
delete [] tmp;
}
///////////////////////////////////////////////////////////////////////////////
// flip a DXT1 color block
void CDDSImage::flip_blocks_dxtc1(DXTColBlock *line, unsigned int numBlocks)
{
DXTColBlock *curblock = line;
for (unsigned int i = 0; i < numBlocks; i++)
{
swap(&curblock->row[0], &curblock->row[3], sizeof(unsigned char));
swap(&curblock->row[1], &curblock->row[2], sizeof(unsigned char));
curblock++;
}
}
///////////////////////////////////////////////////////////////////////////////
// flip a DXT3 color block
void CDDSImage::flip_blocks_dxtc3(DXTColBlock *line, unsigned int numBlocks)
{
DXTColBlock *curblock = line;
DXT3AlphaBlock *alphablock;
for (unsigned int i = 0; i < numBlocks; i++)
{
alphablock = (DXT3AlphaBlock*)curblock;
swap(&alphablock->row[0], &alphablock->row[3], sizeof(unsigned short));
swap(&alphablock->row[1], &alphablock->row[2], sizeof(unsigned short));
curblock++;
swap(&curblock->row[0], &curblock->row[3], sizeof(unsigned char));
swap(&curblock->row[1], &curblock->row[2], sizeof(unsigned char));
curblock++;
}
}
///////////////////////////////////////////////////////////////////////////////
// flip a DXT5 alpha block
void CDDSImage::flip_dxt5_alpha(DXT5AlphaBlock *block)
{
unsigned char gBits[4][4];
const unsigned int mask = 0x00000007; // bits = 00 00 01 11
unsigned int bits = 0;
memcpy(&bits, &block->row[0], sizeof(unsigned char) * 3);
gBits[0][0] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[0][1] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[0][2] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[0][3] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[1][0] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[1][1] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[1][2] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[1][3] = (unsigned char)(bits & mask);
bits = 0;
memcpy(&bits, &block->row[3], sizeof(unsigned char) * 3);
gBits[2][0] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[2][1] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[2][2] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[2][3] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[3][0] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[3][1] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[3][2] = (unsigned char)(bits & mask);
bits >>= 3;
gBits[3][3] = (unsigned char)(bits & mask);
unsigned int *pBits = ((unsigned int*) &(block->row[0]));
*pBits = *pBits | (gBits[3][0] << 0);
*pBits = *pBits | (gBits[3][1] << 3);
*pBits = *pBits | (gBits[3][2] << 6);
*pBits = *pBits | (gBits[3][3] << 9);
*pBits = *pBits | (gBits[2][0] << 12);
*pBits = *pBits | (gBits[2][1] << 15);
*pBits = *pBits | (gBits[2][2] << 18);
*pBits = *pBits | (gBits[2][3] << 21);
pBits = ((unsigned int*) &(block->row[3]));
#ifdef MACOS
*pBits &= 0x000000ff;
#else
*pBits &= 0xff000000;
#endif
*pBits = *pBits | (gBits[1][0] << 0);
*pBits = *pBits | (gBits[1][1] << 3);
*pBits = *pBits | (gBits[1][2] << 6);
*pBits = *pBits | (gBits[1][3] << 9);
*pBits = *pBits | (gBits[0][0] << 12);
*pBits = *pBits | (gBits[0][1] << 15);
*pBits = *pBits | (gBits[0][2] << 18);
*pBits = *pBits | (gBits[0][3] << 21);
}
///////////////////////////////////////////////////////////////////////////////
// flip a DXT5 color block
void CDDSImage::flip_blocks_dxtc5(DXTColBlock *line, unsigned int numBlocks)
{
DXTColBlock *curblock = line;
DXT5AlphaBlock *alphablock;
for (unsigned int i = 0; i < numBlocks; i++)
{
alphablock = (DXT5AlphaBlock*)curblock;
flip_dxt5_alpha(alphablock);
curblock++;
swap(&curblock->row[0], &curblock->row[3], sizeof(unsigned char));
swap(&curblock->row[1], &curblock->row[2], sizeof(unsigned char));
curblock++;
}
}
///////////////////////////////////////////////////////////////////////////////
// CTexture implementation
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// default constructor
CTexture::CTexture()
: CSurface() // initialize base class part
{
}
///////////////////////////////////////////////////////////////////////////////
// creates an empty texture
CTexture::CTexture(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels)
: CSurface(w, h, d, imgsize, pixels) // initialize base class part
{
}
CTexture::~CTexture()
{
}
///////////////////////////////////////////////////////////////////////////////
// copy constructor
CTexture::CTexture(const CTexture ©)
: CSurface(copy)
{
for (unsigned int i = 0; i < copy.get_num_mipmaps(); i++)
m_mipmaps.push_back(copy.get_mipmap(i));
}
///////////////////////////////////////////////////////////////////////////////
// assignment operator
CTexture &CTexture::operator= (const CTexture &rhs)
{
if (this != &rhs)
{
CSurface::operator = (rhs);
m_mipmaps.clear();
for (unsigned int i = 0; i < rhs.get_num_mipmaps(); i++)
m_mipmaps.push_back(rhs.get_mipmap(i));
}
return *this;
}
void CTexture::create(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels)
{
CSurface::create(w, h, d, imgsize, pixels);
m_mipmaps.clear();
}
void CTexture::clear()
{
CSurface::clear();
m_mipmaps.clear();
}
///////////////////////////////////////////////////////////////////////////////
// CSurface implementation
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// default constructor
CSurface::CSurface()
: m_width(0),
m_height(0),
m_depth(0),
m_size(0),
m_pixels(NULL)
{
}
///////////////////////////////////////////////////////////////////////////////
// creates an empty image
CSurface::CSurface(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels)
: m_width(0),
m_height(0),
m_depth(0),
m_size(0),
m_pixels(NULL)
{
create(w, h, d, imgsize, pixels);
}
///////////////////////////////////////////////////////////////////////////////
// copy constructor
CSurface::CSurface(const CSurface ©)
: m_width(0),
m_height(0),
m_depth(0),
m_size(0),
m_pixels(NULL)
{
if (copy.get_size() != 0)
{
m_size = copy.get_size();
m_width = copy.get_width();
m_height = copy.get_height();
m_depth = copy.get_depth();
m_pixels = SAFE_NEW unsigned char[m_size];
memcpy(m_pixels, copy, m_size);
}
}
///////////////////////////////////////////////////////////////////////////////
// assignment operator
CSurface &CSurface::operator= (const CSurface &rhs)
{
if (this != &rhs)
{
clear();
if (rhs.get_size())
{
m_size = rhs.get_size();
m_width = rhs.get_width();
m_height = rhs.get_height();
m_depth = rhs.get_depth();
m_pixels = SAFE_NEW unsigned char[m_size];
memcpy(m_pixels, rhs, m_size);
}
}
return *this;
}
///////////////////////////////////////////////////////////////////////////////
// clean up image memory
CSurface::~CSurface()
{
clear();
}
///////////////////////////////////////////////////////////////////////////////
// returns a pointer to image
CSurface::operator unsigned char*() const
{
return m_pixels;
}
///////////////////////////////////////////////////////////////////////////////
// creates an empty image
void CSurface::create(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels)
{
assert(w != 0);
assert(h != 0);
assert(d != 0);
assert(imgsize != 0);
assert(pixels);
clear();
m_width = w;
m_height = h;
m_depth = d;
m_size = imgsize;
m_pixels = SAFE_NEW unsigned char[imgsize];
memcpy(m_pixels, pixels, imgsize);
}
///////////////////////////////////////////////////////////////////////////////
// free surface memory
void CSurface::clear()
{
if (m_pixels != NULL)
{
delete [] m_pixels;
m_pixels = NULL;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?