mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
option to load dds with upper-left origin (currently disabled by default)
This commit is contained in:
@@ -626,6 +626,10 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
Parser.getTokens( 1 );
|
Parser.getTokens( 1 );
|
||||||
Parser >> loading_log;
|
Parser >> loading_log;
|
||||||
}
|
}
|
||||||
|
else if (token == "ddsupperorigin") {
|
||||||
|
Parser.getTokens( 1 );
|
||||||
|
Parser >> dds_upper_origin;
|
||||||
|
}
|
||||||
} while ((token != "") && (token != "endconfig")); //(!Parser->EndOfFile)
|
} while ((token != "") && (token != "endconfig")); //(!Parser->EndOfFile)
|
||||||
// na koniec trochę zależności
|
// na koniec trochę zależności
|
||||||
if (!bLoadTraction) // wczytywanie drutów i słupów
|
if (!bLoadTraction) // wczytywanie drutów i słupów
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ struct global_settings {
|
|||||||
motiontelemetry::conf_t motiontelemetry_conf;
|
motiontelemetry::conf_t motiontelemetry_conf;
|
||||||
std::string screenshot_dir;
|
std::string screenshot_dir;
|
||||||
bool loading_log = true;
|
bool loading_log = true;
|
||||||
|
bool dds_upper_origin = false;
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
void LoadIniFile( std::string asFileName );
|
void LoadIniFile( std::string asFileName );
|
||||||
|
|||||||
47
Texture.cpp
47
Texture.cpp
@@ -23,7 +23,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include "sn_utils.h"
|
#include "sn_utils.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
#include "flip-s3tc.h"
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
|
|
||||||
#define EU07_DEFERRED_TEXTURE_UPLOAD
|
#define EU07_DEFERRED_TEXTURE_UPLOAD
|
||||||
@@ -319,26 +319,7 @@ opengl_texture::load_DDS() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t datasize = filesize - offset;
|
size_t datasize = filesize - offset;
|
||||||
/*
|
|
||||||
// this approach loads only the first mipmap and relies on graphics card to fill the rest
|
|
||||||
data_mapcount = 1;
|
|
||||||
int datasize = ( ( data_width + 3 ) / 4 ) * ( ( data_height + 3 ) / 4 ) * blockSize;
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
// calculate size of accepted data
|
|
||||||
// NOTE: this is a fallback, as we should be able to just move the file caret by calculated offset and read the rest
|
|
||||||
int datasize = 0;
|
|
||||||
int mapcount = data_mapcount,
|
|
||||||
width = data_width,
|
|
||||||
height = data_height;
|
|
||||||
while( mapcount ) {
|
|
||||||
|
|
||||||
datasize += ( ( width + 3 ) / 4 ) * ( ( height + 3 ) / 4 ) * blockSize;
|
|
||||||
width = std::max( width / 2, 4 );
|
|
||||||
height = std::max( height / 2, 4 );
|
|
||||||
--mapcount;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if( datasize == 0 ) {
|
if( datasize == 0 ) {
|
||||||
// catch malformed .dds files
|
// catch malformed .dds files
|
||||||
WriteLog( "Bad texture: file \"" + name + "\" is malformed and holds no texture data.", logtype::texture );
|
WriteLog( "Bad texture: file \"" + name + "\" is malformed and holds no texture data.", logtype::texture );
|
||||||
@@ -347,6 +328,7 @@ opengl_texture::load_DDS() {
|
|||||||
}
|
}
|
||||||
// reserve space and load texture data
|
// reserve space and load texture data
|
||||||
data.resize( datasize );
|
data.resize( datasize );
|
||||||
|
|
||||||
if( offset != 0 ) {
|
if( offset != 0 ) {
|
||||||
// skip data for mipmaps we don't need
|
// skip data for mipmaps we don't need
|
||||||
file.seekg( offset, std::ios_base::cur );
|
file.seekg( offset, std::ios_base::cur );
|
||||||
@@ -355,8 +337,29 @@ opengl_texture::load_DDS() {
|
|||||||
file.read((char *)&data[0], datasize);
|
file.read((char *)&data[0], datasize);
|
||||||
filesize -= datasize;
|
filesize -= datasize;
|
||||||
|
|
||||||
// we're storing texture data internally with bottom-left origin
|
// we're storing texture data internally with bottom-left origin,
|
||||||
// ...and DDS stores it with top-left origin! bug here, needs flip!
|
// while DDS stores it with top-left origin. we need to flip it.
|
||||||
|
if (Global.dds_upper_origin)
|
||||||
|
{
|
||||||
|
char *mipmap = (char*)&data[0];
|
||||||
|
int mapcount = data_mapcount,
|
||||||
|
width = data_width,
|
||||||
|
height = data_height;
|
||||||
|
while (mapcount)
|
||||||
|
{
|
||||||
|
if (ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT1)
|
||||||
|
flip_s3tc::flip_dxt1_image(mipmap, width, height);
|
||||||
|
else if (ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT3)
|
||||||
|
flip_s3tc::flip_dxt23_image(mipmap, width, height);
|
||||||
|
else if (ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT5)
|
||||||
|
flip_s3tc::flip_dxt45_image(mipmap, width, height);
|
||||||
|
|
||||||
|
mipmap += ( ( width + 3 ) / 4 ) * ( ( height + 3 ) / 4 ) * blockSize;
|
||||||
|
width = std::max( width / 2, 4 );
|
||||||
|
height = std::max( height / 2, 4 );
|
||||||
|
--mapcount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data_components =
|
data_components =
|
||||||
( ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT1 ?
|
( ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT1 ?
|
||||||
|
|||||||
207
flip-s3tc.h
Normal file
207
flip-s3tc.h
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
// https://github.com/inequation/flip-s3tc
|
||||||
|
// Leszek Godlewski places this file in the public domain.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
namespace flip_s3tc
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
struct dxt1_block
|
||||||
|
{
|
||||||
|
uint16_t c0, c1;
|
||||||
|
uint8_t dcba,
|
||||||
|
hgfe,
|
||||||
|
lkji,
|
||||||
|
ponm;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dxt23_block
|
||||||
|
{
|
||||||
|
uint16_t adacabaa,
|
||||||
|
ahagafae,
|
||||||
|
alakajai,
|
||||||
|
apaoanam;
|
||||||
|
uint16_t c0, c1;
|
||||||
|
uint8_t dcba,
|
||||||
|
hgfe,
|
||||||
|
lkji,
|
||||||
|
ponm;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dxt45_block
|
||||||
|
{
|
||||||
|
uint8_t a0, a1;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8_t alpha[3];
|
||||||
|
} ahagafaeadacabaa,
|
||||||
|
apaoanamalakajai;
|
||||||
|
uint16_t c0, c1;
|
||||||
|
uint8_t dcba,
|
||||||
|
hgfe,
|
||||||
|
lkji,
|
||||||
|
ponm;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
/** Performs an Y-flip of the given DXT1 block in place. */
|
||||||
|
void flip_dxt1_block(struct dxt1_block *block)
|
||||||
|
{
|
||||||
|
uint8_t temp;
|
||||||
|
|
||||||
|
temp = block->dcba;
|
||||||
|
block->dcba = block->ponm;
|
||||||
|
block->ponm = temp;
|
||||||
|
temp = block->hgfe;
|
||||||
|
block->hgfe = block->lkji;
|
||||||
|
block->lkji = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Performs an Y-flip of the given DXT2/DXT3 block in place. */
|
||||||
|
void flip_dxt23_block(struct dxt23_block *block)
|
||||||
|
{
|
||||||
|
uint8_t temp8;
|
||||||
|
uint16_t temp16;
|
||||||
|
|
||||||
|
temp16 = block->adacabaa;
|
||||||
|
block->adacabaa = block->apaoanam;
|
||||||
|
block->apaoanam = temp16;
|
||||||
|
temp16 = block->ahagafae;
|
||||||
|
block->ahagafae = block->alakajai;
|
||||||
|
block->alakajai = temp16;
|
||||||
|
|
||||||
|
temp8 = block->dcba;
|
||||||
|
block->dcba = block->ponm;
|
||||||
|
block->ponm = temp8;
|
||||||
|
temp8 = block->hgfe;
|
||||||
|
block->hgfe = block->lkji;
|
||||||
|
block->lkji = temp8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Performs an Y-flip of the given DXT4/DXT5 block in place. */
|
||||||
|
void flip_dxt45_block(struct dxt45_block *block)
|
||||||
|
{
|
||||||
|
uint8_t temp8;
|
||||||
|
uint32_t temp32;
|
||||||
|
uint32_t *as_int[2];
|
||||||
|
|
||||||
|
as_int[0] = (uint32_t *)block->ahagafaeadacabaa.alpha;
|
||||||
|
as_int[1] = (uint32_t *)block->apaoanamalakajai.alpha;
|
||||||
|
// swap adacabaa with apaoanam
|
||||||
|
temp32 = *as_int[0] & ((1 << 12) - 1);
|
||||||
|
*as_int[0] &= ~((1 << 12) - 1);
|
||||||
|
*as_int[0] |= (*as_int[1] & (((1 << 12) - 1) << 12)) >> 12;
|
||||||
|
*as_int[1] &= ~(((1 << 12) - 1) << 12);
|
||||||
|
*as_int[1] |= temp32 << 12;
|
||||||
|
// swap ahagafae with alakajai
|
||||||
|
temp32 = *as_int[0] & (((1 << 12) - 1) << 12);
|
||||||
|
*as_int[0] &= ~(((1 << 12) - 1) << 12);
|
||||||
|
*as_int[0] |= (*as_int[1] & ((1 << 12) - 1)) << 12;
|
||||||
|
*as_int[1] &= ~((1 << 12) - 1);
|
||||||
|
*as_int[1] |= temp32 >> 12;
|
||||||
|
|
||||||
|
temp8 = block->dcba;
|
||||||
|
block->dcba = block->ponm;
|
||||||
|
block->ponm = temp8;
|
||||||
|
temp8 = block->hgfe;
|
||||||
|
block->hgfe = block->lkji;
|
||||||
|
block->lkji = temp8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs an Y-flip on the given DXT1 image in place.
|
||||||
|
* @param data buffer with image data (S3TC blocks)
|
||||||
|
* @param width image width in pixels
|
||||||
|
* @param height image height in pixels
|
||||||
|
*/
|
||||||
|
void flip_dxt1_image(void *data, int width, int height)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
struct dxt1_block temp1, temp2;
|
||||||
|
struct dxt1_block *blocks = (struct dxt1_block *)data;
|
||||||
|
|
||||||
|
width = (width + 3) / 4;
|
||||||
|
height = (height + 3) / 4;
|
||||||
|
|
||||||
|
for (y = 0; y < height / 2; ++y)
|
||||||
|
{
|
||||||
|
for (x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
temp1 = blocks[y * width + x];
|
||||||
|
temp2 = blocks[(height - y - 1) * width + x];
|
||||||
|
flip_dxt1_block(&temp1);
|
||||||
|
flip_dxt1_block(&temp2);
|
||||||
|
blocks[(height - y - 1) * width + x] = temp1;
|
||||||
|
blocks[y * width + x] = temp2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs an Y-flip on the given DXT2/DXT3 image in place.
|
||||||
|
* @param data buffer with image data (S3TC blocks)
|
||||||
|
* @param width image width in pixels
|
||||||
|
* @param height image height in pixels
|
||||||
|
*/
|
||||||
|
void flip_dxt23_image(void *data, int width, int height)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
struct dxt23_block temp1, temp2;
|
||||||
|
struct dxt23_block *blocks = (struct dxt23_block *)data;
|
||||||
|
|
||||||
|
width = (width + 3) / 4;
|
||||||
|
height = (height + 3) / 4;
|
||||||
|
|
||||||
|
for (y = 0; y < height / 2; ++y)
|
||||||
|
{
|
||||||
|
for (x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
temp1 = blocks[y * width + x];
|
||||||
|
temp2 = blocks[(height - y - 1) * width + x];
|
||||||
|
flip_dxt23_block(&temp1);
|
||||||
|
flip_dxt23_block(&temp2);
|
||||||
|
blocks[(height - y - 1) * width + x] = temp1;
|
||||||
|
blocks[y * width + x] = temp2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs an Y-flip on the given DXT1 image in place.
|
||||||
|
* @param data buffer with image data (S3TC blocks)
|
||||||
|
* @param width image width in pixels
|
||||||
|
* @param height image height in pixels
|
||||||
|
*/
|
||||||
|
void flip_dxt45_image(void *data, int width, int height)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
struct dxt45_block temp1, temp2;
|
||||||
|
struct dxt45_block *blocks = (struct dxt45_block *)data;
|
||||||
|
|
||||||
|
width = (width + 3) / 4;
|
||||||
|
height = (height + 3) / 4;
|
||||||
|
|
||||||
|
for (y = 0; y < height / 2; ++y)
|
||||||
|
{
|
||||||
|
for (x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
temp1 = blocks[y * width + x];
|
||||||
|
temp2 = blocks[(height - y - 1) * width + x];
|
||||||
|
flip_dxt45_block(&temp1);
|
||||||
|
flip_dxt45_block(&temp2);
|
||||||
|
blocks[(height - y - 1) * width + x] = temp1;
|
||||||
|
blocks[y * width + x] = temp2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
} // namespace flip_s3tc
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user