mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 13:56:48 +08:00
Added positioning code based on material origin, size, and scale. Fixed mirrored vertices and mirrored BGRA pixels. Added DXT3 support. Fixed DXT decompression segfault due to sizeof(long). Fixed RGBA packing order. Added texture dumping to file. Enabled PKGV0008 support. Disabled shader dumping to log.
This commit is contained in:
parent
39d3f4f1e0
commit
72831e1b2f
3
main.cpp
3
main.cpp
@ -2,7 +2,8 @@
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <sstream>
|
||||
#include <wallpaperengine/video/renderer.h>
|
||||
#include <wallpaperengine/video/material.h>
|
||||
// wp::video::material is currently not used
|
||||
//#include <wallpaperengine/video/material.h>
|
||||
#include <wallpaperengine/irr/CPkgReader.h>
|
||||
#include <getopt.h>
|
||||
#include <SDL_mixer.h>
|
||||
|
@ -68,21 +68,32 @@ namespace wp
|
||||
}
|
||||
|
||||
// initialize actual material properties
|
||||
irr::f32 xsize = this->m_parent->getSize ().X;
|
||||
irr::f32 ysize = this->m_parent->getSize ().Y;
|
||||
if (xsize == 0. || ysize == 0.)
|
||||
{
|
||||
xsize = 1920.;
|
||||
ysize = 1080.;
|
||||
wp::irrlicht::device->getLogger ()->log ("Initializing xsize and ysize as default values 1920 and 1080", this->m_file.c_str(), irr::ELL_INFORMATION);
|
||||
}
|
||||
irr::f32 xscale = this->m_parent->getScale ().X;
|
||||
irr::f32 yscale = this->m_parent->getScale ().Y;
|
||||
|
||||
irr::f32 xright = this->m_parent->getOrigin ().X;
|
||||
irr::f32 xleft = -this->m_parent->getOrigin ().X;
|
||||
irr::f32 ztop = this->m_parent->getOrigin ().Y;
|
||||
irr::f32 zbottom = -this->m_parent->getOrigin ().Y;
|
||||
irr::f32 xleft = this->m_parent->getOrigin ().X - xsize * xscale;
|
||||
irr::f32 ytop = this->m_parent->getOrigin ().Y;
|
||||
irr::f32 ybottom = this->m_parent->getOrigin ().Y - ysize * yscale;
|
||||
irr::f32 z = this->m_parent->getScene ()->getCamera ()->getEye ().Z;
|
||||
|
||||
m_vertices [0].Pos = irr::core::vector3df (xleft, ztop, z); // top left
|
||||
m_vertices [1].Pos = irr::core::vector3df (xright, ztop, z); // top right
|
||||
m_vertices [2].Pos = irr::core::vector3df (xright, zbottom, z); // bottom right
|
||||
m_vertices [3].Pos = irr::core::vector3df (xleft, zbottom, z); // bottom left
|
||||
m_vertices [0].Pos = irr::core::vector3df (xleft, ytop, z); // top left
|
||||
m_vertices [1].Pos = irr::core::vector3df (xright, ytop, z); // top right
|
||||
m_vertices [2].Pos = irr::core::vector3df (xright, ybottom, z); // bottom right
|
||||
m_vertices [3].Pos = irr::core::vector3df (xleft, ybottom, z); // bottom left
|
||||
|
||||
m_vertices [0].TCoords = irr::core::vector2df (1.0f, 0.0f);
|
||||
m_vertices [1].TCoords = irr::core::vector2df (0.0f, 0.0f);
|
||||
m_vertices [2].TCoords = irr::core::vector2df (0.0f, 1.0f);
|
||||
m_vertices [3].TCoords = irr::core::vector2df (1.0f, 1.0f);
|
||||
m_vertices [0].TCoords = irr::core::vector2df (0.0f, 0.0f);
|
||||
m_vertices [1].TCoords = irr::core::vector2df (1.0f, 0.0f);
|
||||
m_vertices [2].TCoords = irr::core::vector2df (1.0f, 1.0f);
|
||||
m_vertices [3].TCoords = irr::core::vector2df (0.0f, 1.0f);
|
||||
|
||||
m_vertices [0].Color = irr::video::SColor (255, 255, 255, 255);
|
||||
m_vertices [1].Color = irr::video::SColor (255, 255, 255, 255);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <lz4.h>
|
||||
#include <wallpaperengine/irrlicht.h>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
namespace irr {
|
||||
namespace video {
|
||||
@ -75,6 +76,14 @@ namespace irr {
|
||||
input->seek (4, true); // ignore bytes
|
||||
input->read (buffer, 9);
|
||||
|
||||
if (input->getFileName().find("materials/flowmask.tex") != std::string::npos ||
|
||||
input->getFileName().find("godrays_downsample2_mask") != std::string::npos ||
|
||||
input->getFileName().find("materials/util/white.tex") != std::string::npos)
|
||||
{
|
||||
// relevant shaders are currently drawing these masks opaque; return a transparent image instead
|
||||
wp::irrlicht::device->getLogger ()->log ("LOAD TEX: Skipping broken mask", input->getFileName ().c_str (), irr::ELL_INFORMATION);
|
||||
return wp::irrlicht::driver->createImage (ECF_A8R8G8B8, irr::core::dimension2d<u32> (width, height));
|
||||
}
|
||||
if (memcmp (buffer, "TEXB0003", 9) == 0)
|
||||
{
|
||||
containerVersion = 3;
|
||||
@ -179,18 +188,25 @@ namespace irr {
|
||||
switch (format)
|
||||
{
|
||||
case TextureFormat::ARGB8888:
|
||||
wp::irrlicht::device->getLogger ()->log ("LOAD TEX: This is an ARGB8", input->getFileName ().c_str (), irr::ELL_INFORMATION);
|
||||
this->loadImageFromARGB8Data (image, decompressedBuffer, width, height, mipmap_width);
|
||||
break;
|
||||
case TextureFormat::DXT5:
|
||||
this->loadImageFromDXT5 (image, decompressedBuffer, width, height, mipmap_width, mipmap_height);
|
||||
break;
|
||||
case TextureFormat::DXT1:
|
||||
wp::irrlicht::device->getLogger ()->log ("LOAD TEX: This is a DXT1", input->getFileName ().c_str (), irr::ELL_INFORMATION);
|
||||
this->loadImageFromDXT1 (image, decompressedBuffer, width, height, mipmap_width, mipmap_height);
|
||||
break;
|
||||
case TextureFormat::DXT3:
|
||||
wp::irrlicht::device->getLogger ()->log ("LOAD TEX: DXT3 textures not supported yet\n", input->getFileName ().c_str (), irr::ELL_ERROR);
|
||||
wp::irrlicht::device->getLogger ()->log ("LOAD TEX: This is a DXT3", input->getFileName ().c_str (), irr::ELL_INFORMATION);
|
||||
this->loadImageFromDXT3 (image, decompressedBuffer, width, height, mipmap_width, mipmap_height);
|
||||
break;
|
||||
case TextureFormat::DXT5:
|
||||
wp::irrlicht::device->getLogger ()->log ("LOAD TEX: This is a DXT5", input->getFileName ().c_str (), irr::ELL_INFORMATION);
|
||||
this->loadImageFromDXT5 (image, decompressedBuffer, width, height, mipmap_width, mipmap_height);
|
||||
break;
|
||||
default:
|
||||
delete [] decompressedBuffer;
|
||||
delete image;
|
||||
wp::irrlicht::device->getLogger ()->log ("LOAD TEX: Unknown texture format\n", input->getFileName ().c_str (), irr::ELL_ERROR);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -203,7 +219,7 @@ namespace irr {
|
||||
// copy file data to the final file buffer to be used
|
||||
memcpy (filebuffer, decompressedBuffer, mipmap_uncompressed_size);
|
||||
// generate temporal name
|
||||
std::tmpnam (tmpname);
|
||||
mkstemp (tmpname);
|
||||
// store it in a std::string
|
||||
std::string filename = tmpname;
|
||||
irr::io::IReadFile* file;
|
||||
@ -214,21 +230,25 @@ namespace irr {
|
||||
case FREE_IMAGE_FORMAT::FIF_BMP:
|
||||
// add extension to the file
|
||||
filename += ".bmp";
|
||||
wp::irrlicht::device->getLogger ()->log ("LOAD TEX: This is a BMP", input->getFileName ().c_str (), irr::ELL_INFORMATION);
|
||||
file = wp::irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
|
||||
break;
|
||||
case FREE_IMAGE_FORMAT::FIF_PNG:
|
||||
// add extension to the file
|
||||
filename += ".png";
|
||||
wp::irrlicht::device->getLogger ()->log ("LOAD TEX: This is a PNG", input->getFileName ().c_str (), irr::ELL_INFORMATION);
|
||||
file = wp::irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
|
||||
break;
|
||||
case FREE_IMAGE_FORMAT::FIF_JPEG:
|
||||
// add extension to the file
|
||||
filename += ".jpg";
|
||||
wp::irrlicht::device->getFileSystem ()->createAndWriteFile ("/tmp/test.jpg", false)->write (filebuffer, mipmap_uncompressed_size);
|
||||
wp::irrlicht::device->getLogger ()->log ("LOAD TEX: This is a JPG", input->getFileName ().c_str (), irr::ELL_INFORMATION);
|
||||
//wp::irrlicht::device->getFileSystem ()->createAndWriteFile ("/tmp/test.jpg", false)->write (filebuffer, mipmap_uncompressed_size);
|
||||
file = wp::irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
|
||||
break;
|
||||
case FREE_IMAGE_FORMAT::FIF_GIF:
|
||||
filename += ".gif";
|
||||
wp::irrlicht::device->getLogger ()->log ("LOAD TEX: This is a GIF", input->getFileName ().c_str (), irr::ELL_INFORMATION);
|
||||
file = wp::irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
|
||||
break;
|
||||
default:
|
||||
@ -253,6 +273,36 @@ namespace irr {
|
||||
|
||||
delete [] decompressedBuffer;
|
||||
|
||||
#if 0
|
||||
// dump image to a TGA file (adapted from maluoi's gist)
|
||||
u32 bytesPerPixel = image->getBytesPerPixel ();
|
||||
std::string fileName = input->getFileName ().c_str ();
|
||||
std::replace (fileName.begin (), fileName.end (), '/', '-');
|
||||
std::string path = std::string (getenv("HOME")) + "/stuff/wallpaperengine-dumps/";
|
||||
system(("mkdir -p " + path).c_str());
|
||||
path += fileName + ".tga";
|
||||
FILE *dumpFile = fopen (path.c_str (), "wb");
|
||||
uint8_t header[18] = { 0,0,2,0,0,0,0,0,0,0,0,0,
|
||||
(uint8_t)(width%256), (uint8_t)(width/256), (uint8_t)(height%256), (uint8_t)(height/256), 32, 32 };
|
||||
fwrite (&header, 18, 1, dumpFile);
|
||||
char *imagedata = (char *) image->lock ();
|
||||
for (u32 y = 0; y < image->getDimension ().Height; y ++)
|
||||
{
|
||||
u32 baseDestination = y * image->getPitch ();
|
||||
for (u32 x = 0; x < width; x ++)
|
||||
{
|
||||
static unsigned char color[4];
|
||||
color[0] = imagedata [baseDestination + (x * bytesPerPixel) + 0]; // b
|
||||
color[1] = imagedata [baseDestination + (x * bytesPerPixel) + 1]; // g
|
||||
color[2] = imagedata [baseDestination + (x * bytesPerPixel) + 2]; // r
|
||||
// this currently screws up JPG dumps
|
||||
color[3] = imagedata [baseDestination + (x * bytesPerPixel) + 3]; // a
|
||||
fwrite (color, 1, 4, dumpFile);
|
||||
}
|
||||
}
|
||||
image->unlock ();
|
||||
fclose (dumpFile);
|
||||
#endif
|
||||
return image;
|
||||
}
|
||||
|
||||
@ -268,10 +318,10 @@ namespace irr {
|
||||
|
||||
for (u32 x = 0; x < width; x ++)
|
||||
{
|
||||
imagedata [baseDestination + (x * bytesPerPixel) + 2] = input [baseOrigin + ((width - x) * 4) + 0]; // r
|
||||
imagedata [baseDestination + (x * bytesPerPixel) + 1] = input [baseOrigin + ((width - x) * 4) + 1]; // g
|
||||
imagedata [baseDestination + (x * bytesPerPixel) + 0] = input [baseOrigin + ((width - x) * 4) + 2]; // b
|
||||
imagedata [baseDestination + (x * bytesPerPixel) + 3] = input [baseOrigin + ((width - x) * 4) + 3]; // alpha
|
||||
imagedata [baseDestination + (x * bytesPerPixel) + 2] = input [baseOrigin + (x * 4) + 0]; // r
|
||||
imagedata [baseDestination + (x * bytesPerPixel) + 1] = input [baseOrigin + (x * 4) + 1]; // g
|
||||
imagedata [baseDestination + (x * bytesPerPixel) + 0] = input [baseOrigin + (x * 4) + 2]; // b
|
||||
imagedata [baseDestination + (x * bytesPerPixel) + 3] = input [baseOrigin + (x * 4) + 3]; // a
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,6 +338,16 @@ namespace irr {
|
||||
delete [] decompressedBuffer;
|
||||
}
|
||||
|
||||
void CImageLoaderTex::loadImageFromDXT3 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const
|
||||
{
|
||||
char* decompressedBuffer = new char [origin_width * origin_height * 4];
|
||||
|
||||
this->BlockDecompressImageDXT3 (origin_width, origin_height, (const unsigned char*) input, (unsigned long*) decompressedBuffer);
|
||||
this->loadImageFromARGB8Data (output, decompressedBuffer, destination_width, destination_height, origin_width);
|
||||
|
||||
delete [] decompressedBuffer;
|
||||
}
|
||||
|
||||
void CImageLoaderTex::loadImageFromDXT5 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const
|
||||
{
|
||||
char* decompressedBuffer = new char [origin_width * origin_height * 4];
|
||||
@ -310,9 +370,9 @@ namespace irr {
|
||||
// unsigned char b: blue channel.
|
||||
// unsigned char a: alpha channel.
|
||||
|
||||
unsigned long CImageLoaderTex::PackRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) const
|
||||
unsigned long CImageLoaderTex::PackRGBA (unsigned char r, unsigned char g, unsigned char b, unsigned char a) const
|
||||
{
|
||||
return ((r << 24) | (g << 16) | (b << 8) | a);
|
||||
return r | (g << 8) | (b << 16) | (a << 24);
|
||||
}
|
||||
|
||||
// void DecompressBlockDXT1(): Decompresses one block of a DXT1 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
@ -324,7 +384,7 @@ namespace irr {
|
||||
// const unsigned char *blockStorage: pointer to the block to decompress.
|
||||
// unsigned long *image: pointer to image where the decompressed pixel data should be stored.
|
||||
|
||||
void CImageLoaderTex::DecompressBlockDXT1(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const
|
||||
void CImageLoaderTex::DecompressBlockDXT1 (unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const
|
||||
{
|
||||
unsigned short color0 = *reinterpret_cast<const unsigned short *>(blockStorage);
|
||||
unsigned short color1 = *reinterpret_cast<const unsigned short *>(blockStorage + 2);
|
||||
@ -352,23 +412,23 @@ namespace irr {
|
||||
for (int i=0; i < 4; i++)
|
||||
{
|
||||
unsigned long finalColor = 0;
|
||||
unsigned char positionCode = (code >> 2*(4*j+i)) & 0x03;
|
||||
unsigned char positionCode = (code >> 2*(4*j+i)) & 0x03;
|
||||
|
||||
if (color0 > color1)
|
||||
{
|
||||
switch (positionCode)
|
||||
{
|
||||
case 0:
|
||||
finalColor = PackRGBA(r0, g0, b0, 255);
|
||||
finalColor = PackRGBA (r0, g0, b0, 255);
|
||||
break;
|
||||
case 1:
|
||||
finalColor = PackRGBA(r1, g1, b1, 255);
|
||||
finalColor = PackRGBA (r1, g1, b1, 255);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, 255);
|
||||
finalColor = PackRGBA ((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, 255);
|
||||
break;
|
||||
case 3:
|
||||
finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, 255);
|
||||
finalColor = PackRGBA ((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, 255);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -377,22 +437,21 @@ namespace irr {
|
||||
switch (positionCode)
|
||||
{
|
||||
case 0:
|
||||
finalColor = PackRGBA(r0, g0, b0, 255);
|
||||
finalColor = PackRGBA (r0, g0, b0, 255);
|
||||
break;
|
||||
case 1:
|
||||
finalColor = PackRGBA(r1, g1, b1, 255);
|
||||
finalColor = PackRGBA (r1, g1, b1, 255);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA((r0+r1)/2, (g0+g1)/2, (b0+b1)/2, 255);
|
||||
finalColor = PackRGBA ((r0+r1)/2, (g0+g1)/2, (b0+b1)/2, 255);
|
||||
break;
|
||||
case 3:
|
||||
finalColor = PackRGBA(0, 0, 0, 255);
|
||||
finalColor = PackRGBA (0, 0, 0, 255);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (x + i < width)
|
||||
image[(y + j)*width + (x + i)] = finalColor;
|
||||
reinterpret_cast<u32 *>(image)[(y + j)*width + x + i] = finalColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -413,11 +472,117 @@ namespace irr {
|
||||
|
||||
for (unsigned long j = 0; j < blockCountY; j++)
|
||||
{
|
||||
for (unsigned long i = 0; i < blockCountX; i++) DecompressBlockDXT1(i*4, j*4, width, blockStorage + i * 8, image);
|
||||
for (unsigned long i = 0; i < blockCountX; i++)
|
||||
DecompressBlockDXT1 (i*4, j*4, width, blockStorage + i * 8, image);
|
||||
blockStorage += blockCountX * 8;
|
||||
}
|
||||
}
|
||||
|
||||
// void DecompressBlockDXT3(): Decompresses one block of a DXT3 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
//
|
||||
// unsigned long x: x-coordinate of the first pixel in the block.
|
||||
// unsigned long y: y-coordinate of the first pixel in the block.
|
||||
// unsigned long width: width of the texture being decompressed.
|
||||
// unsigned long height: height of the texture being decompressed.
|
||||
// const unsigned char *blockStorage: pointer to the block to decompress.
|
||||
// unsigned long *image: pointer to image where the decompressed pixel data should be stored.
|
||||
|
||||
void CImageLoaderTex::DecompressBlockDXT3(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const
|
||||
{
|
||||
unsigned short color0 = *reinterpret_cast<const unsigned short *>(blockStorage + 8);
|
||||
unsigned short color1 = *reinterpret_cast<const unsigned short *>(blockStorage + 10);
|
||||
|
||||
unsigned long temp;
|
||||
|
||||
temp = (color0 >> 11) * 255 + 16;
|
||||
unsigned char r0 = (unsigned char)((temp/32 + temp)/32);
|
||||
temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
|
||||
unsigned char g0 = (unsigned char)((temp/64 + temp)/64);
|
||||
temp = (color0 & 0x001F) * 255 + 16;
|
||||
unsigned char b0 = (unsigned char)((temp/32 + temp)/32);
|
||||
|
||||
temp = (color1 >> 11) * 255 + 16;
|
||||
unsigned char r1 = (unsigned char)((temp/32 + temp)/32);
|
||||
temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
|
||||
unsigned char g1 = (unsigned char)((temp/64 + temp)/64);
|
||||
temp = (color1 & 0x001F) * 255 + 16;
|
||||
unsigned char b1 = (unsigned char)((temp/32 + temp)/32);
|
||||
|
||||
unsigned long code = *reinterpret_cast<const unsigned long *>(blockStorage + 12);
|
||||
unsigned long long alphaCode = *reinterpret_cast<const unsigned long long *>(blockStorage);
|
||||
|
||||
for (int j=0; j < 4; j++)
|
||||
{
|
||||
for (int i=0; i < 4; i++)
|
||||
{
|
||||
unsigned long finalColor = 0;
|
||||
unsigned char positionCode = (code >> 2*(4*j+i)) & 0x03;
|
||||
// per StackOverflow this creates an even distribution of alphas between 0 and 255
|
||||
unsigned char finalAlpha = 17 * (alphaCode >> 4*(4*j+i) & 0x0F);
|
||||
|
||||
if (color0 > color1)
|
||||
{
|
||||
switch (positionCode)
|
||||
{
|
||||
case 0:
|
||||
finalColor = PackRGBA (r0, g0, b0, finalAlpha);
|
||||
break;
|
||||
case 1:
|
||||
finalColor = PackRGBA (r1, g1, b1, finalAlpha);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA ((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, finalAlpha);
|
||||
break;
|
||||
case 3:
|
||||
finalColor = PackRGBA ((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, finalAlpha);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (positionCode)
|
||||
{
|
||||
case 0:
|
||||
finalColor = PackRGBA (r0, g0, b0, finalAlpha);
|
||||
break;
|
||||
case 1:
|
||||
finalColor = PackRGBA (r1, g1, b1, finalAlpha);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA ((r0+r1)/2, (g0+g1)/2, (b0+b1)/2, finalAlpha);
|
||||
break;
|
||||
case 3:
|
||||
finalColor = PackRGBA (0, 0, 0, finalAlpha);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
reinterpret_cast<u32 *>(image)[(y + j)*width + x + i] = finalColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// void BlockDecompressImageDXT3(): Decompresses all the blocks of a DXT3 compressed texture and stores the resulting pixels in 'image'.
|
||||
//
|
||||
// unsigned long width: Texture width.
|
||||
// unsigned long height: Texture height.
|
||||
// const unsigned char *blockStorage: pointer to compressed DXT3 blocks.
|
||||
// unsigned long *image: pointer to the image where the decompressed pixels will be stored.
|
||||
|
||||
void CImageLoaderTex::BlockDecompressImageDXT3(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const
|
||||
{
|
||||
unsigned long blockCountX = (width + 3) / 4;
|
||||
unsigned long blockCountY = (height + 3) / 4;
|
||||
unsigned long blockWidth = (width < 4) ? width : 4;
|
||||
unsigned long blockHeight = (height < 4) ? height : 4;
|
||||
for (unsigned long j = 0; j < blockCountY; j++)
|
||||
{
|
||||
for (unsigned long i = 0; i < blockCountX; i++)
|
||||
DecompressBlockDXT3 (i*4, j*4, width, blockStorage + i * 16, image);
|
||||
blockStorage += blockCountX * 16;
|
||||
}
|
||||
}
|
||||
|
||||
// void DecompressBlockDXT5(): Decompresses one block of a DXT5 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
//
|
||||
// unsigned long x: x-coordinate of the first pixel in the block.
|
||||
@ -503,27 +668,47 @@ namespace irr {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char colorCode = (code >> 2*(4*j+i)) & 0x03;
|
||||
unsigned long finalColor = 0;
|
||||
unsigned char positionCode = (code >> 2*(4*j+i)) & 0x03;
|
||||
|
||||
unsigned long finalColor;
|
||||
switch (colorCode)
|
||||
if (color0 > color1)
|
||||
{
|
||||
case 0:
|
||||
finalColor = PackRGBA(r0, g0, b0, finalAlpha);
|
||||
break;
|
||||
case 1:
|
||||
finalColor = PackRGBA(r1, g1, b1, finalAlpha);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, finalAlpha);
|
||||
break;
|
||||
case 3:
|
||||
finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, finalAlpha);
|
||||
break;
|
||||
switch (positionCode)
|
||||
{
|
||||
case 0:
|
||||
finalColor = PackRGBA (r0, g0, b0, finalAlpha);
|
||||
break;
|
||||
case 1:
|
||||
finalColor = PackRGBA (r1, g1, b1, finalAlpha);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA ((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, finalAlpha);
|
||||
break;
|
||||
case 3:
|
||||
finalColor = PackRGBA ((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, finalAlpha);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (positionCode)
|
||||
{
|
||||
case 0:
|
||||
finalColor = PackRGBA (r0, g0, b0, finalAlpha);
|
||||
break;
|
||||
case 1:
|
||||
finalColor = PackRGBA (r1, g1, b1, finalAlpha);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA ((r0+r1)/2, (g0+g1)/2, (b0+b1)/2, finalAlpha);
|
||||
break;
|
||||
case 3:
|
||||
finalColor = PackRGBA (0, 0, 0, finalAlpha);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (x + i < width)
|
||||
image[(y + j)*width + (x + i)] = finalColor;
|
||||
reinterpret_cast<u32 *>(image)[(y + j)*width + x + i] = finalColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -544,7 +729,8 @@ namespace irr {
|
||||
|
||||
for (unsigned long j = 0; j < blockCountY; j++)
|
||||
{
|
||||
for (unsigned long i = 0; i < blockCountX; i++) DecompressBlockDXT5(i*4, j*4, width, blockStorage + i * 16, image);
|
||||
for (unsigned long i = 0; i < blockCountX; i++)
|
||||
DecompressBlockDXT5 (i*4, j*4, width, blockStorage + i * 16, image);
|
||||
blockStorage += blockCountX * 16;
|
||||
}
|
||||
}
|
||||
|
@ -26,12 +26,15 @@ public:
|
||||
virtual void loadImageFromARGB8Data (IImage* output, const char* input, u32 width, u32 height, u32 mipmap_width) const;
|
||||
|
||||
virtual void loadImageFromDXT1 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const;
|
||||
virtual void loadImageFromDXT3 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const;
|
||||
virtual void loadImageFromDXT5 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const;
|
||||
|
||||
private:
|
||||
void BlockDecompressImageDXT1(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const;
|
||||
void DecompressBlockDXT1(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const;
|
||||
unsigned long PackRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) const;
|
||||
void BlockDecompressImageDXT3(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const;
|
||||
void DecompressBlockDXT3(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const;
|
||||
void BlockDecompressImageDXT5(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const;
|
||||
void DecompressBlockDXT5(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const;
|
||||
|
||||
@ -40,9 +43,9 @@ private:
|
||||
ARGB8888,
|
||||
RA88,
|
||||
A8,
|
||||
DXT5,
|
||||
DXT3,
|
||||
DXT1
|
||||
DXT1,
|
||||
DXT5 // most of the defaultprojects textures are DXT5 as indicated by their alpha data
|
||||
// DXT3 support seems to be missing from wallpaper engine
|
||||
};
|
||||
|
||||
// extracted from the free image library
|
||||
|
@ -73,7 +73,10 @@ bool CArchiveLoaderPkg::isALoadableFileFormat(irr::io::IReadFile* file) const
|
||||
|
||||
file->read (pointer, size - 1);
|
||||
|
||||
if (strcmp (pointer, "PKGV0002") != 0 && strcmp (pointer, "PKGV0001") != 0)
|
||||
if (strcmp (pointer, "PKGV0001") != 0 &&
|
||||
strcmp (pointer, "PKGV0002") != 0 &&
|
||||
strcmp (pointer, "PKGV0007") != 0 &&
|
||||
strcmp (pointer, "PKGV0008") != 0)
|
||||
{
|
||||
delete [] pointer;
|
||||
return false;
|
||||
@ -120,8 +123,11 @@ const irr::io::IFileList* CPkgReader::getFileList() const
|
||||
void CPkgReader::scanPkgHeader ()
|
||||
{
|
||||
char* headerVersion = this->readSizedString ();
|
||||
|
||||
if (strcmp ("PKGV0007", headerVersion) != 0 && strcmp ("PKGV0002", headerVersion) != 0 && strcmp ("PKGV0001", headerVersion) != 0)
|
||||
|
||||
if (strcmp ("PKGV0001", headerVersion) != 0 &&
|
||||
strcmp ("PKGV0002", headerVersion) != 0 &&
|
||||
strcmp ("PKGV0007", headerVersion) != 0 &&
|
||||
strcmp ("PKGV0008", headerVersion) != 0)
|
||||
{
|
||||
wp::irrlicht::device->getLogger ()->log ("Unexpected package header... Aborting load", this->mFile->getFileName ().c_str (), irr::ELL_ERROR);
|
||||
|
||||
|
@ -445,8 +445,8 @@ namespace wp
|
||||
|
||||
if (this->m_recursive == false)
|
||||
{
|
||||
wp::irrlicht::device->getLogger ()->log ("Compiled shader output for", this->m_file.c_str ());
|
||||
wp::irrlicht::device->getLogger ()->log (this->m_compiledContent.c_str ());
|
||||
//wp::irrlicht::device->getLogger ()->log ("Compiled shader output for", this->m_file.c_str ());
|
||||
//wp::irrlicht::device->getLogger ()->log (this->m_compiledContent.c_str ());
|
||||
}
|
||||
|
||||
return this->m_compiledContent;
|
||||
|
Loading…
Reference in New Issue
Block a user