Use libsquish for skybox texture compression
This commit is contained in:
parent
9e70abb631
commit
bc311a445e
@ -18,15 +18,26 @@
|
|||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
|
|
||||||
#include "graphics/skybox.hpp"
|
#include "graphics/skybox.hpp"
|
||||||
|
#include "config/stk_config.hpp"
|
||||||
#include "graphics/central_settings.hpp"
|
#include "graphics/central_settings.hpp"
|
||||||
#include "graphics/irr_driver.hpp"
|
#include "graphics/irr_driver.hpp"
|
||||||
|
#include "graphics/sp/sp_base.hpp"
|
||||||
#include "graphics/texture_shader.hpp"
|
#include "graphics/texture_shader.hpp"
|
||||||
|
|
||||||
|
#include <ge_main.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <IImage.h>
|
#include <IImage.h>
|
||||||
|
|
||||||
|
#include <squish.h>
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include <mipmap/img.h>
|
||||||
|
#include <mipmap/imgresize.h>
|
||||||
|
}
|
||||||
|
|
||||||
using namespace irr;
|
using namespace irr;
|
||||||
|
|
||||||
|
|
||||||
@ -137,6 +148,9 @@ namespace {
|
|||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
extern "C" void squishCompressImage(uint8_t* rgba, int width, int height,
|
||||||
|
int pitch, void* blocks, unsigned flags);
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Generate an opengl cubemap texture from 6 2d textures */
|
/** Generate an opengl cubemap texture from 6 2d textures */
|
||||||
void Skybox::generateCubeMapFromTextures()
|
void Skybox::generateCubeMapFromTextures()
|
||||||
@ -160,16 +174,22 @@ void Skybox::generateCubeMapFromTextures()
|
|||||||
{
|
{
|
||||||
unsigned idx = texture_permutation[i];
|
unsigned idx = texture_permutation[i];
|
||||||
video::IImage* img = m_skybox_textures[idx];
|
video::IImage* img = m_skybox_textures[idx];
|
||||||
#if defined(USE_GLES2)
|
|
||||||
uint8_t* data = (uint8_t*)img->lock();
|
bool is_gles = false;
|
||||||
for (unsigned int j = 0; j <
|
#ifdef USE_GLES2
|
||||||
img->getDimension().Width * img->getDimension().Height; j++)
|
is_gles = true;
|
||||||
{
|
|
||||||
uint8_t tmp_val = data[j * 4];
|
|
||||||
data[j * 4] = data[j * 4 + 2];
|
|
||||||
data[j * 4 + 2] = tmp_val;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
if (CVS->isTextureCompressionEnabled() || is_gles)
|
||||||
|
{
|
||||||
|
uint8_t* data = (uint8_t*)img->lock();
|
||||||
|
for (unsigned int j = 0; j <
|
||||||
|
img->getDimension().Width * img->getDimension().Height; j++)
|
||||||
|
{
|
||||||
|
uint8_t tmp_val = data[j * 4];
|
||||||
|
data[j * 4] = data[j * 4 + 2];
|
||||||
|
data[j * 4 + 2] = tmp_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
img->copyToScaling(rgba[i], size, size);
|
img->copyToScaling(rgba[i], size, size);
|
||||||
|
|
||||||
@ -188,24 +208,80 @@ void Skybox::generateCubeMapFromTextures()
|
|||||||
}
|
}
|
||||||
img->drop();
|
img->drop();
|
||||||
|
|
||||||
|
bool needs_srgb_format = CVS->isDeferredEnabled();
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, m_cube_map);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, m_cube_map);
|
||||||
|
|
||||||
bool needs_srgb_format = CVS->isDeferredEnabled();
|
const unsigned tc_flag = squish::kDxt5 | stk_config->m_tc_quality;
|
||||||
|
|
||||||
GLint format = GL_RGBA;
|
|
||||||
GLint internal_format = needs_srgb_format ? GL_SRGB8_ALPHA8 : GL_RGBA8;
|
|
||||||
#if !defined(USE_GLES2)
|
|
||||||
if (CVS->isTextureCompressionEnabled())
|
if (CVS->isTextureCompressionEnabled())
|
||||||
internal_format = needs_srgb_format ? GL_COMPRESSED_SRGB_ALPHA
|
{
|
||||||
: GL_COMPRESSED_RGBA;
|
unsigned tex_size = GE::get4x4CompressedTextureSize(size, size);
|
||||||
format = GL_BGRA;
|
uint8_t* compressed = new uint8_t[tex_size];
|
||||||
#endif
|
squishCompressImage((uint8_t*)rgba[i], size, size, size * 4,
|
||||||
|
compressed, tc_flag);
|
||||||
|
GLint internal_format = needs_srgb_format ?
|
||||||
|
GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT :
|
||||||
|
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||||
|
glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
|
||||||
|
internal_format, size, size, 0, tex_size, compressed);
|
||||||
|
delete[] compressed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GLint format = GL_BGRA;
|
||||||
|
if (is_gles)
|
||||||
|
format = GL_RGBA;
|
||||||
|
GLint internal_format = needs_srgb_format ? GL_SRGB8_ALPHA8 : GL_RGBA8;
|
||||||
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
|
||||||
|
internal_format, size, size, 0, format,
|
||||||
|
GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
|
||||||
|
}
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
|
if (CVS->isTextureCompressionEnabled())
|
||||||
internal_format, size, size, 0, format,
|
{
|
||||||
GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
|
imMipmapCascade cascade;
|
||||||
|
imReduceOptions options;
|
||||||
|
imReduceSetOptions(&options, IM_REDUCE_FILTER_LINEAR/*filter*/,
|
||||||
|
2/*hopcount*/, 2.0f/*alpha*/, 1.0f/*amplifynormal*/,
|
||||||
|
0.0f/*normalsustainfactor*/);
|
||||||
|
#ifdef DEBUG
|
||||||
|
int ret = imBuildMipmapCascade(&cascade, rgba[i], size, size,
|
||||||
|
1/*layercount*/, 4, size * 4, &options, 0);
|
||||||
|
assert(ret == 1);
|
||||||
|
#else
|
||||||
|
imBuildMipmapCascade(&cascade, rgba[i], size, size,
|
||||||
|
1/*layercount*/, 4, size * 4, &options, 0);
|
||||||
|
#endif
|
||||||
|
std::vector<unsigned> mipmap_sizes;
|
||||||
|
unsigned width = size;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
width = width < 2 ? 1 : width >> 1;
|
||||||
|
mipmap_sizes.push_back(width);
|
||||||
|
if (width == 1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (unsigned mip = 0; mip < mipmap_sizes.size(); mip++)
|
||||||
|
{
|
||||||
|
unsigned cur_size = mipmap_sizes[mip];
|
||||||
|
unsigned tex_size = GE::get4x4CompressedTextureSize(cur_size,
|
||||||
|
cur_size);
|
||||||
|
uint8_t* compressed = new uint8_t[tex_size];
|
||||||
|
squishCompressImage((uint8_t*)cascade.mipmap[mip + 1],
|
||||||
|
cur_size, cur_size, cur_size * 4, compressed, tc_flag);
|
||||||
|
GLint internal_format = needs_srgb_format ?
|
||||||
|
GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT :
|
||||||
|
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||||
|
glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
|
||||||
|
mip + 1, internal_format, cur_size, cur_size, 0, tex_size,
|
||||||
|
compressed);
|
||||||
|
delete[] compressed;
|
||||||
|
}
|
||||||
|
imFreeMipmapCascade(&cascade);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
|
||||||
|
if (!CVS->isTextureCompressionEnabled())
|
||||||
|
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
||||||
for (unsigned i = 0; i < 6; i++)
|
for (unsigned i = 0; i < 6; i++)
|
||||||
delete[] rgba[i];
|
delete[] rgba[i];
|
||||||
} // generateCubeMapFromTextures
|
} // generateCubeMapFromTextures
|
||||||
|
Loading…
x
Reference in New Issue
Block a user