fix issues with texture compression of small, L8 textures

This commit is contained in:
David Rose 2009-01-14 01:33:14 +00:00
parent 06c855c7d2
commit c44da02cee
5 changed files with 91 additions and 9 deletions

View File

@ -377,6 +377,15 @@ create_texture(DXScreenData &scrn) {
}
}
// We can't compress for some reason, so ensure the uncompressed
// image is ready to load.
if (texture_stored_compressed) {
tex->get_uncompressed_ram_image();
compression_mode = tex->get_ram_image_compression();
texture_stored_compressed = compression_mode != Texture::CM_off;
compress_texture = false;
}
// handle each target bitdepth separately. might be less confusing
// to reorg by num_color_channels (input type)
switch (target_bpp) {
@ -1001,11 +1010,37 @@ extract_texture_data() {
return false;
}
int x_size = tex->get_expected_mipmap_x_size(n);
int y_size = tex->get_expected_mipmap_y_size(n);
int size = rect.Pitch * (y_size / div);
size = min(size, (int)tex->get_expected_ram_mipmap_image_size(n));
PTA_uchar image = PTA_uchar::empty_array(size);
memcpy(image.p(), rect.pBits, size);
PTA_uchar image;
if (compression == Texture::CM_off) {
// Uncompressed, but we have to respect the pitch.
int pitch = x_size * tex->get_num_components() * tex->get_component_width();
pitch = min(pitch, (int)rect.Pitch);
int size = pitch * y_size;
image = PTA_uchar::empty_array(size);
if (pitch == rect.Pitch) {
// Easy copy.
memcpy(image.p(), rect.pBits, size);
} else {
// Harder copy: we have to de-interleave DirectX's extra bytes
// on the end of each row.
unsigned char *dest = image.p();
unsigned char *source = (unsigned char *)rect.pBits;
for (int yi = 0; yi < y_size; ++yi) {
memcpy(dest, source, pitch);
dest += pitch;
source += rect.Pitch;
}
}
} else {
// Compressed; just copy the data verbatim.
int size = rect.Pitch * (y_size / div);
image = PTA_uchar::empty_array(size);
memcpy(image.p(), rect.pBits, size);
}
_d3d_2d_texture->UnlockRect(n);
if (n == 0) {

View File

@ -405,6 +405,15 @@ create_texture(DXScreenData &scrn) {
}
}
// We can't compress for some reason, so ensure the uncompressed
// image is ready to load.
if (texture_stored_compressed) {
tex->get_uncompressed_ram_image();
compression_mode = tex->get_ram_image_compression();
texture_stored_compressed = compression_mode != Texture::CM_off;
compress_texture = false;
}
// handle each target bitdepth separately. might be less confusing
// to reorg by num_color_channels (input type, rather than desired
// 1st target)
@ -1236,12 +1245,38 @@ extract_texture_data(DXScreenData &screen) {
<< "Texture::LockRect() failed! level = " << n << " " << D3DERRORSTRING(hr);
return state;
}
int x_size = tex->get_expected_mipmap_x_size(n);
int y_size = tex->get_expected_mipmap_y_size(n);
int size = rect.Pitch * (y_size / div);
size = min(size, (int)tex->get_expected_ram_mipmap_image_size(n));
PTA_uchar image = PTA_uchar::empty_array(size);
memcpy(image.p(), rect.pBits, size);
PTA_uchar image;
if (compression == Texture::CM_off) {
// Uncompressed, but we have to respect the pitch.
int pitch = x_size * tex->get_num_components() * tex->get_component_width();
pitch = min(pitch, (int)rect.Pitch);
int size = pitch * y_size;
image = PTA_uchar::empty_array(size);
if (pitch == rect.Pitch) {
// Easy copy.
memcpy(image.p(), rect.pBits, size);
} else {
// Harder copy: we have to de-interleave DirectX's extra bytes
// on the end of each row.
unsigned char *dest = image.p();
unsigned char *source = (unsigned char *)rect.pBits;
for (int yi = 0; yi < y_size; ++yi) {
memcpy(dest, source, pitch);
dest += pitch;
source += rect.Pitch;
}
}
} else {
// Compressed; just copy the data verbatim.
int size = rect.Pitch * (y_size / div);
image = PTA_uchar::empty_array(size);
memcpy(image.p(), rect.pBits, size);
}
_d3d_2d_texture->UnlockRect(n);
if (n == 0) {

View File

@ -82,6 +82,12 @@ ConfigVariableDouble texture_scale
"scale factor is applied before textures-power-2 or "
"max-texture-dimension."));
ConfigVariableInt texture_scale_limit
("texture-scale-limit", 4,
PRC_DESC("This specifies the limit below which texture-scale will not "
"reduce a texture image. This is a single dimension which applies "
"to both X and Y."));
ConfigVariableList exclude_texture_scale
("exclude-texture-scale",
PRC_DESC("This is a list of glob patterns for texture filenames "

View File

@ -49,6 +49,7 @@ EXPCL_PANDA_GOBJ istream &operator >> (istream &in, ShaderUtilization &sut);
// Configure variables for gobj package.
extern EXPCL_PANDA_GOBJ ConfigVariableInt max_texture_dimension;
extern EXPCL_PANDA_GOBJ ConfigVariableDouble texture_scale;
extern EXPCL_PANDA_GOBJ ConfigVariableInt texture_scale_limit;
extern EXPCL_PANDA_GOBJ ConfigVariableList exclude_texture_scale;

View File

@ -1817,6 +1817,11 @@ adjust_size(int &x_size, int &y_size, const string &name) {
if (!exclude) {
new_x_size = (int)cfloor(new_x_size * texture_scale + 0.5);
new_y_size = (int)cfloor(new_y_size * texture_scale + 0.5);
// Don't auto-scale below 4 in either dimension. This causes
// problems for DirectX and texture compression.
new_x_size = min(max(new_x_size, (int)texture_scale_limit), x_size);
new_y_size = min(max(new_y_size, (int)texture_scale_limit), y_size);
}
switch (get_textures_power_2()) {