Merge branch 'master' into vkdoom3-merge

This commit is contained in:
Robert Beckebans 2017-09-03 10:32:19 +02:00
commit c91f8f4338
15 changed files with 898 additions and 94 deletions

View file

@ -86,7 +86,7 @@ def object_to_entity( obj ):
#return json.dumps( obj.items(), indent = 4 )
#return { "items": obj.items() }
#return { "children":[{'name':key,"size":value} for key,value in sample.items()]}
#return { "children":[{'name':key,"size":value} for key,value in obj.items()]}
#return { obj.items() }
#return sample
@ -94,13 +94,26 @@ def object_to_entity( obj ):
#for key,value in obj.items():
# dict.insert( key, value )
print( "creating entity {0} of type {1}".format( obj.name, obj.type ) )
# make shallow copy without arrays of entries
ent = dict( obj )
#ent = dict( obj )
#ent = dict()
ignore_keys = [ '_RNA_UI', 'cycles_visibility', 'cycles' ]
ent = {}
for key,value in obj.items():# if key not in ignore_keys:
if key not in ignore_keys:
ent[ key] = value
print( "entity {0} key {1} has value {2}".format( obj.name, key, value ) )
# TODO quakeify name if necessary
ent['name'] = obj.name
ent['origin'] = "%f %f %f" % ( obj.location[0], obj.location[1], obj.location[2] )
ent['blender_object_type'] = obj.type
#ent['blender_object_type'] = obj.type
if obj.type == 'LAMP':
@ -172,4 +185,18 @@ def unregister():
bpy.types.INFO_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()
register()
"""
ignore_types = ['CAMERA','MESH','ARMATURE']
entities = [ obj for obj in bpy.context.selected_objects if obj.type not in ignore_types ]
data = {
"version": 3,
"authoring_tool": "Blender " + bpy.app.version_string,
"entities": [ object_to_entity( obj ) for obj in entities ] }
j = json.dumps( data, indent = 4 )
print( j )
"""

View file

@ -551,19 +551,6 @@ void idCmdSystemLocal::ExecuteTokenizedString( const idCmdArgs& args )
return; // no tokens
}
// DEBUG: print commands executed by the console
/*
if(args.Argc() == 1) {
common->Printf("idCmdSystemLocal::ExecuteTokenizedString: '%s'\n", args.Argv( 0 ));
}
else if(args.Argc() == 2) {
common->Printf("idCmdSystemLocal::ExecuteTokenizedString: '%s' '%s'\n", args.Argv( 0 ), args.Argv( 1 ));
}
else if(args.Argc() == 3) {
common->Printf("idCmdSystemLocal::ExecuteTokenizedString: '%s' '%s' '%s'\n", args.Argv( 0 ), args.Argv( 1 ), args.Argv( 2 ));
}
*/
// check registered command functions
for( prev = &commands; *prev; prev = &cmd->next )
{

View file

@ -3,6 +3,8 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014-2016 Robert Beckebans
Copyright (C) 2014-2016 Kot in Action Creative Artel
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -128,8 +130,6 @@ typedef enum
EDITOR_MATERIAL = BIT( 11 )
} toolFlag_t;
extern int com_editors; // currently opened editor(s)
#define STRTABLE_ID "#str_"
#define STRTABLE_ID_LENGTH 5
@ -142,6 +142,7 @@ extern idCVar com_showMemoryUsage;
extern idCVar com_updateLoadSize;
extern idCVar com_productionMode;
extern int com_editors; // currently opened editor(s)
struct MemInfo_t
{
idStr filebase;
@ -222,7 +223,9 @@ public:
// DG end
virtual void UpdateLevelLoadPacifier() = 0;
//virtual void UpdateLevelLoadPacifier( int mProgress ) = 0;
//virtual void UpdateLevelLoadPacifier( bool updateSecondary ) = 0;
//virtual void UpdateLevelLoadPacifier( bool updateSecondary, int Progress ) = 0;
// Checks for and removes command line "+set var arg" constructs.
// If match is NULL, all set commands will be executed, otherwise

View file

@ -3,6 +3,8 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014-2016 Robert Beckebans
Copyright (C) 2014-2016 Kot in Action Creative Artel
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -786,6 +788,84 @@ void idCommonLocal::UpdateLevelLoadPacifier()
}
}
// foresthale 2014-05-30: loading progress pacifier for binarize operations only
void idCommonLocal::LoadPacifierBinarizeFilename( const char* filename, const char* reason )
{
idLib::Printf( "Binarize File: '%s' - reason '%s'\n", filename, reason );
// we won't actually show updates on very quick files (<16ms), so keep this false until the first progress
loadPacifierBinarizeActive = false;
loadPacifierBinarizeFilename = filename;
loadPacifierBinarizeInfo = "";
loadPacifierBinarizeProgress = 0.0f;
loadPacifierBinarizeStartTime = Sys_Milliseconds();
loadPacifierBinarizeMiplevel = 0;
loadPacifierBinarizeMiplevelTotal = 0;
}
void idCommonLocal::LoadPacifierBinarizeInfo( const char* info )
{
loadPacifierBinarizeInfo = info;
}
void idCommonLocal::LoadPacifierBinarizeMiplevel( int level, int maxLevel )
{
loadPacifierBinarizeMiplevel = level;
loadPacifierBinarizeMiplevelTotal = maxLevel;
}
// foresthale 2014-05-30: loading progress pacifier for binarize operations only
void idCommonLocal::LoadPacifierBinarizeProgress( float progress )
{
static int lastUpdateTime = 0;
int time = Sys_Milliseconds();
if( progress == 0.0f )
{
// restart the progress, so that if multiple images have to be
// binarized for one filename, we don't give bogus estimates...
loadPacifierBinarizeStartTime = Sys_Milliseconds();
}
loadPacifierBinarizeProgress = progress;
if( ( time - lastUpdateTime ) >= 16 )
{
lastUpdateTime = time;
loadPacifierBinarizeActive = true;
UpdateLevelLoadPacifier();
// TODO merge
//UpdateLevelLoadPacifier( true, progress );
}
}
// foresthale 2014-05-30: loading progress pacifier for binarize operations only
void idCommonLocal::LoadPacifierBinarizeEnd()
{
loadPacifierBinarizeActive = false;
loadPacifierBinarizeStartTime = 0;
loadPacifierBinarizeProgress = 0.0f;
loadPacifierBinarizeTimeLeft = 0.0f;
loadPacifierBinarizeFilename = "";
loadPacifierBinarizeProgressTotal = 0;
loadPacifierBinarizeProgressCurrent = 0;
loadPacifierBinarizeMiplevel = 0;
loadPacifierBinarizeMiplevelTotal = 0;
}
// foresthale 2014-05-30: loading progress pacifier for binarize operations only
void idCommonLocal::LoadPacifierBinarizeProgressTotal( int total )
{
loadPacifierBinarizeProgressTotal = total;
loadPacifierBinarizeProgressCurrent = 0;
}
// foresthale 2014-05-30: loading progress pacifier for binarize operations only
void idCommonLocal::LoadPacifierBinarizeProgressIncrement( int step )
{
loadPacifierBinarizeProgressCurrent += step;
LoadPacifierBinarizeProgress( ( float )loadPacifierBinarizeProgressCurrent / loadPacifierBinarizeProgressTotal );
}
/*
===============
idCommonLocal::ScrubSaveGameFileName

View file

@ -3,7 +3,8 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2012 Robert Beckebans
Copyright (C) 2014-2016 Robert Beckebans
Copyright (C) 2014-2016 Kot in Action Creative Artel
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -151,7 +152,10 @@ public:
// DG: added possibility to *not* release mouse in UpdateScreen(), it fucks up the view angle for screenshots
virtual void UpdateScreen( bool captureToImage, bool releaseMouse = true );
// DG end
virtual void UpdateLevelLoadPacifier();
virtual void UpdateLevelLoadPacifier(); // Indefinate
// virtual void UpdateLevelLoadPacifier( int mProgress );
// virtual void UpdateLevelLoadPacifier( bool Secondary );
// virtual void UpdateLevelLoadPacifier( bool updateSecondary, int mProgress );
virtual void StartupVariable( const char* match );
virtual void WriteConfigToFile( const char* filename );
virtual void BeginRedirect( char* buffer, int buffersize, void ( *flush )( const char* ) );
@ -282,6 +286,12 @@ public:
public:
void Draw(); // called by gameThread
// foresthale 2014-03-01: added WaitGameThread() method
void WaitGameThread()
{
gameThread.WaitForThread();
}
int GetGameThreadTotalTime() const
{
return gameThread.GetThreadTotalTime();
@ -310,6 +320,18 @@ public:
{
return time_gpu;
}
// foresthale 2014-05-30: a special binarize pacifier has to be shown in
// some cases, which includes filename and ETA information, note that
// the progress function takes 0-1 float, not 0-100, and can be called
// very quickly (it will check that enough time has passed when updating)
void LoadPacifierBinarizeFilename( const char* filename, const char* reason );
void LoadPacifierBinarizeInfo( const char* info );
void LoadPacifierBinarizeMiplevel( int level, int maxLevel );
void LoadPacifierBinarizeProgress( float progress );
void LoadPacifierBinarizeEnd();
// for images in particular we can measure more accurately this way (to deal with mipmaps)
void LoadPacifierBinarizeProgressTotal( int total );
void LoadPacifierBinarizeProgressIncrement( int step );
frameTiming_t frameTiming;
frameTiming_t mainFrameTiming;
@ -517,6 +539,18 @@ private:
int lastPacifierGuiTime;
bool lastPacifierDialogState;
// foresthale 2014-05-30: a special binarize pacifier has to be shown in some cases, which includes filename and ETA information
bool loadPacifierBinarizeActive;
int loadPacifierBinarizeStartTime;
float loadPacifierBinarizeProgress;
float loadPacifierBinarizeTimeLeft;
idStr loadPacifierBinarizeFilename;
idStr loadPacifierBinarizeInfo;
int loadPacifierBinarizeMiplevel;
int loadPacifierBinarizeMiplevelTotal;
int loadPacifierBinarizeProgressTotal;
int loadPacifierBinarizeProgressCurrent;
bool showShellRequested;
// RB begin

View file

@ -3,6 +3,8 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014-2016 Robert Beckebans
Copyright (C) 2014-2016 Kot in Action Creative Artel
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -27,6 +29,7 @@ If you have questions concerning this license or the applicable additional terms
*/
#pragma hdrstop
#include "precompiled.h"
#include "framework/Common_local.h"
/*
================================================================================================
@ -41,6 +44,7 @@ If you have questions concerning this license or the applicable additional terms
#include "Color/ColorSpace.h"
idCVar image_highQualityCompression( "image_highQualityCompression", "0", CVAR_BOOL, "Use high quality (slow) compression" );
idCVar r_useHighQualitySky( "r_useHighQualitySky", "0", CVAR_BOOL | CVAR_ARCHIVE, "Use high quality skyboxes" );
/*
========================
@ -56,6 +60,8 @@ void idBinaryImage::Load2DFromMemory( int width, int height, const byte* pic_con
fileData.height = height;
fileData.numLevels = numLevels;
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d)", width, height ) );
byte* pic = ( byte* )Mem_Alloc( width * height * 4, TAG_TEMP );
memcpy( pic, pic_const, width * height * 4 );
@ -95,6 +101,8 @@ void idBinaryImage::Load2DFromMemory( int width, int height, const byte* pic_con
{
idBinaryImageData& img = images[ level ];
commonLocal.LoadPacifierBinarizeMiplevel( level + 1, numLevels );
// Images that are going to be DXT compressed and aren't multiples of 4 need to be
// padded out before compressing.
byte* dxtPic = pic;
@ -132,10 +140,14 @@ void idBinaryImage::Load2DFromMemory( int width, int height, const byte* pic_con
img.Alloc( dxtWidth * dxtHeight / 2 );
if( image_highQualityCompression.GetBool() )
{
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d) - DXT1HQ", width, height ) );
dxt.CompressImageDXT1HQ( dxtPic, img.data, dxtWidth, dxtHeight );
}
else
{
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d) - DXT1Fast", width, height ) );
dxt.CompressImageDXT1Fast( dxtPic, img.data, dxtWidth, dxtHeight );
}
}
@ -147,10 +159,14 @@ void idBinaryImage::Load2DFromMemory( int width, int height, const byte* pic_con
{
if( image_highQualityCompression.GetBool() )
{
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d) - NormalMapDXT5HQ", width, height ) );
dxt.CompressNormalMapDXT5HQ( dxtPic, img.data, dxtWidth, dxtHeight );
}
else
{
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d) - NormalMapDXT5Fast", width, height ) );
dxt.CompressNormalMapDXT5Fast( dxtPic, img.data, dxtWidth, dxtHeight );
}
}
@ -158,10 +174,14 @@ void idBinaryImage::Load2DFromMemory( int width, int height, const byte* pic_con
{
if( image_highQualityCompression.GetBool() )
{
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d) - YCoCgDXT5HQ", width, height ) );
dxt.CompressYCoCgDXT5HQ( dxtPic, img.data, dxtWidth, dxtHeight );
}
else
{
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d) - YCoCgDXT5Fast", width, height ) );
dxt.CompressYCoCgDXT5Fast( dxtPic, img.data, dxtWidth, dxtHeight );
}
}
@ -170,10 +190,14 @@ void idBinaryImage::Load2DFromMemory( int width, int height, const byte* pic_con
fileData.colorFormat = colorFormat = CFM_DEFAULT;
if( image_highQualityCompression.GetBool() )
{
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d) - DXT5HQ", width, height ) );
dxt.CompressImageDXT5HQ( dxtPic, img.data, dxtWidth, dxtHeight );
}
else
{
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d) - DXT5Fast", width, height ) );
dxt.CompressImageDXT5Fast( dxtPic, img.data, dxtWidth, dxtHeight );
}
}
@ -289,6 +313,8 @@ idBinaryImage::LoadCubeFromMemory
*/
void idBinaryImage::LoadCubeFromMemory( int width, const byte* pics[6], int numLevels, textureFormat_t& textureFormat, bool gammaMips )
{
commonLocal.LoadPacifierBinarizeInfo( va( "cube (%d)", width ) );
fileData.textureType = TT_CUBIC;
fileData.format = textureFormat;
fileData.colorFormat = CFM_DEFAULT;
@ -302,11 +328,14 @@ void idBinaryImage::LoadCubeFromMemory( int width, const byte* pics[6], int numL
const byte* orig = pics[side];
const byte* pic = orig;
int scaledWidth = fileData.width;
for( int level = 0; level < fileData.numLevels; level++ )
{
// compress data or convert floats as necessary
idBinaryImageData& img = images[ level * 6 + side ];
commonLocal.LoadPacifierBinarizeMiplevel( level, fileData.numLevels );
// handle padding blocks less than 4x4 for the DXT compressors
ALIGN16( byte padBlock[64] );
int padSize;

View file

@ -3,7 +3,8 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013 Robert Beckebans
Copyright (C) 2014-2016 Robert Beckebans
Copyright (C) 2014-2016 Kot in Action Creative Artel
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -248,6 +249,16 @@ private:
int GetMinMaxNormalsDXT5HQ( const byte* normalBlock, byte* minColor, byte* maxColor, unsigned int& colorIndices, byte* alphaIndices ) const;
int GetMinMaxNormalsDXT5HQFast( const byte* normalBlock, byte* minColor, byte* maxColor, unsigned int& colorIndices, byte* alphaIndices ) const;
void ScaleYCoCg( byte* colorBlock ) const;
void ExtractBlockGimpDDS( const byte* src, int x, int y, int w, int h, byte* block );
void EncodeAlphaBlockBC3GimpDDS( byte* dst, const byte* block, const int offset );
void GetMinMaxYCoCgGimpDDS( const byte* block, byte* mincolor, byte* maxcolor );
void ScaleYCoCgGimpDDS( byte* block, byte* mincolor, byte* maxcolor );
void InsetBBoxYCoCgGimpDDS( byte* mincolor, byte* maxcolor );
void SelectDiagonalYCoCgGimpDDS( const byte* block, byte* mincolor, byte* maxcolor );
void LerpRGB13GimpDDS( byte* dst, byte* a, byte* b );
inline int Mul8BitGimpDDS( int a, int b );
inline unsigned short PackRGB565GimpDDS( const byte* c );
void EncodeYCoCgBlockGimpDDS( byte* dst, byte* block );
void BiasScaleNormalY( byte* colorBlock ) const;
void RotateNormalsDXT1( byte* block ) const;
void RotateNormalsDXT5( byte* block ) const;

View file

@ -3,6 +3,8 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014-2016 Robert Beckebans
Copyright (C) 2014-2016 Kot in Action Creative Artel
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -25,13 +27,9 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
/*
================================================================================================
Contains the DxtEncoder implementation.
================================================================================================
*/
#pragma hdrstop
#include "precompiled.h"
#include "framework/Common_local.h"
#include "DXTCodec_local.h"
#include "DXTCodec.h"
@ -46,6 +44,29 @@ Contains the DxtEncoder implementation.
typedef uint16 word;
typedef uint32 dword;
// macros required by gimp-dds code:
#ifndef MIN
# ifdef __GNUC__
# define MIN(a, b) ({typeof(a) _a=(a); typeof(b) _b=(b); _a < _b ? _a : _b;})
# else
# define MIN(a, b) ((a) < (b) ? (a) : (b))
# endif
#endif
#define PUTL16( buf, s ) \
( buf )[0] = ( ( s ) ) & 0xff; \
( buf )[1] = ( ( s ) >> 8 ) & 0xff;
#define PUTL32( buf, l ) \
( buf )[0] = ( ( l ) ) & 0xff; \
( buf )[1] = ( ( l ) >> 8 ) & 0xff; \
( buf )[2] = ( ( l ) >> 16 ) & 0xff; \
( buf )[3] = ( ( l ) >> 24 ) & 0xff;
#define INSET_SHIFT 4
#define BLOCK_OFFSET( x, y, w, bs ) ( ( ( y ) >> 2 ) * ( ( bs ) * ( ( ( w ) + 3 ) >> 2 ) ) + ( ( bs ) * ( ( x ) >> 2 ) ) )
/*
========================
idDxtEncoder::NV4XHardwareBugFix
@ -2154,7 +2175,8 @@ void idDxtEncoder::CompressImageDXT1HQ( const byte* inBuf, byte* outBuf, int wid
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
GetMinMaxColorsHQ( block, col1, col2, false );
@ -2235,7 +2257,8 @@ void idDxtEncoder::CompressImageDXT5HQ( const byte* inBuf, byte* outBuf, int wid
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
GetMinMaxColorsHQ( block, col1, col2, true );
@ -2334,7 +2357,8 @@ void idDxtEncoder::CompressImageCTX1HQ( const byte* inBuf, byte* outBuf, int wid
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
GetMinMaxCTX1HQ( block, col1, col2 );
@ -2413,6 +2437,335 @@ void idDxtEncoder::ScaleYCoCg( byte* colorBlock ) const
}
}
/*
========================
idDxtEncoder::ExtractBlockGimpDDS
Extract 4x4 BGRA block
========================
*/
void idDxtEncoder::ExtractBlockGimpDDS( const byte* src, int x, int y, int w, int h, byte* block )
{
int i, j;
int bw = MIN( w - x, 4 );
int bh = MIN( h - y, 4 );
int bx, by;
const int rem[] =
{
0, 0, 0, 0,
0, 1, 0, 1,
0, 1, 2, 0,
0, 1, 2, 3
};
for( i = 0; i < 4; i++ )
{
by = rem[( bh - 1 ) * 4 + i] + y;
for( j = 0; j < 4; j++ )
{
bx = rem[( bw - 1 ) * 4 + j] + x;
block[( i * 4 * 4 ) + ( j * 4 ) + 0] = src[( by * ( w * 4 ) ) + ( bx * 4 ) + 0];
block[( i * 4 * 4 ) + ( j * 4 ) + 1] = src[( by * ( w * 4 ) ) + ( bx * 4 ) + 1];
block[( i * 4 * 4 ) + ( j * 4 ) + 2] = src[( by * ( w * 4 ) ) + ( bx * 4 ) + 2];
block[( i * 4 * 4 ) + ( j * 4 ) + 3] = src[( by * ( w * 4 ) ) + ( bx * 4 ) + 3];
}
}
}
/*
========================
idDxtEncoder::EncodeAlphaBlockBC3GimpDDS
Write DXT5 alpha block
========================
*/
void idDxtEncoder::EncodeAlphaBlockBC3GimpDDS( byte* dst, const byte* block, const int offset )
{
int i, v, mn, mx;
int dist, bias, dist2, dist4, bits, mask;
int a, idx, t;
block += offset;
block += 3;
// find min/max alpha pair
mn = mx = block[0];
for( i = 0; i < 16; i++ )
{
v = block[4 * i];
if( v > mx ) mx = v;
if( v < mn ) mn = v;
}
// encode them
*dst++ = mx;
*dst++ = mn;
// determine bias and emit indices
// given the choice of mx/mn, these indices are optimal:
// http://fgiesen.wordpress.com/2009/12/15/dxt5-alpha-block-index-determination/
dist = mx - mn;
dist4 = dist * 4;
dist2 = dist * 2;
bias = ( dist < 8 ) ? ( dist - 1 ) : ( dist / 2 + 2 );
bias -= mn * 7;
bits = 0;
mask = 0;
for( i = 0; i < 16; i++ )
{
a = block[4 * i] * 7 + bias;
// Select index. This is a "linear scale" lerp factor between 0 (val=min) and 7 (val=max).
t = ( a >= dist4 ) ? -1 : 0;
idx = t & 4;
a -= dist4 & t;
t = ( a >= dist2 ) ? -1 : 0;
idx += t & 2;
a -= dist2 & t;
idx += ( a >= dist );
// turn linear scale into DXT index (0/1 are extremal pts)
idx = -idx & 7;
idx ^= ( 2 > idx );
// write index
mask |= idx << bits;
if( ( bits += 3 ) >= 8 )
{
*dst++ = mask;
mask >>= 8;
bits -= 8;
}
}
}
/*
========================
idDxtEncoder::GetMinMaxYCoCgGimpDDS
========================
*/
void idDxtEncoder::GetMinMaxYCoCgGimpDDS( const byte* block, byte* mincolor, byte* maxcolor )
{
int i;
mincolor[2] = mincolor[1] = 255;
maxcolor[2] = maxcolor[1] = 0;
for( i = 0; i < 16; i++ )
{
if( block[4 * i + 2] < mincolor[2] ) mincolor[2] = block[4 * i + 2];
if( block[4 * i + 1] < mincolor[1] ) mincolor[1] = block[4 * i + 1];
if( block[4 * i + 2] > maxcolor[2] ) maxcolor[2] = block[4 * i + 2];
if( block[4 * i + 1] > maxcolor[1] ) maxcolor[1] = block[4 * i + 1];
}
}
/*
========================
idDxtEncoder::ScaleYCoCgGimpDDS
========================
*/
void idDxtEncoder::ScaleYCoCgGimpDDS( byte* block, byte* mincolor, byte* maxcolor )
{
const int s0 = 128 / 2 - 1;
const int s1 = 128 / 4 - 1;
int m0, m1, m2, m3;
int mask0, mask1, scale;
int i;
m0 = abs( mincolor[2] - 128 );
m1 = abs( mincolor[1] - 128 );
m2 = abs( maxcolor[2] - 128 );
m3 = abs( maxcolor[1] - 128 );
if( m1 > m0 ) m0 = m1;
if( m3 > m2 ) m2 = m3;
if( m2 > m0 ) m0 = m2;
mask0 = -( m0 <= s0 );
mask1 = -( m0 <= s1 );
scale = 1 + ( 1 & mask0 ) + ( 2 & mask1 );
mincolor[2] = ( mincolor[2] - 128 ) * scale + 128;
mincolor[1] = ( mincolor[1] - 128 ) * scale + 128;
mincolor[0] = ( scale - 1 ) << 3;
maxcolor[2] = ( maxcolor[2] - 128 ) * scale + 128;
maxcolor[1] = ( maxcolor[1] - 128 ) * scale + 128;
maxcolor[0] = ( scale - 1 ) << 3;
for( i = 0; i < 16; i++ )
{
block[i * 4 + 2] = ( block[i * 4 + 2] - 128 ) * scale + 128;
block[i * 4 + 1] = ( block[i * 4 + 1] - 128 ) * scale + 128;
}
}
/*
========================
idDxtEncoder::InsetBBoxYCoCgGimpDDS
========================
*/
void idDxtEncoder::InsetBBoxYCoCgGimpDDS( byte* mincolor, byte* maxcolor )
{
int inset[4], mini[4], maxi[4];
inset[2] = ( maxcolor[2] - mincolor[2] ) - ( ( 1 << ( INSET_SHIFT - 1 ) ) - 1 );
inset[1] = ( maxcolor[1] - mincolor[1] ) - ( ( 1 << ( INSET_SHIFT - 1 ) ) - 1 );
mini[2] = ( ( mincolor[2] << INSET_SHIFT ) + inset[2] ) >> INSET_SHIFT;
mini[1] = ( ( mincolor[1] << INSET_SHIFT ) + inset[1] ) >> INSET_SHIFT;
maxi[2] = ( ( maxcolor[2] << INSET_SHIFT ) - inset[2] ) >> INSET_SHIFT;
maxi[1] = ( ( maxcolor[1] << INSET_SHIFT ) - inset[1] ) >> INSET_SHIFT;
mini[2] = ( mini[2] >= 0 ) ? mini[2] : 0;
mini[1] = ( mini[1] >= 0 ) ? mini[1] : 0;
maxi[2] = ( maxi[2] <= 255 ) ? maxi[2] : 255;
maxi[1] = ( maxi[1] <= 255 ) ? maxi[1] : 255;
mincolor[2] = ( mini[2] & 0xf8 ) | ( mini[2] >> 5 );
mincolor[1] = ( mini[1] & 0xfc ) | ( mini[1] >> 6 );
maxcolor[2] = ( maxi[2] & 0xf8 ) | ( maxi[2] >> 5 );
maxcolor[1] = ( maxi[1] & 0xfc ) | ( maxi[1] >> 6 );
}
/*
========================
idDxtEncoder::SelectDiagonalYCoCgGimpDDS
========================
*/
void idDxtEncoder::SelectDiagonalYCoCgGimpDDS( const byte* block, byte* mincolor, byte* maxcolor )
{
byte mid0, mid1, side, mask, b0, b1, c0, c1;
int i;
mid0 = ( ( int )mincolor[2] + maxcolor[2] + 1 ) >> 1;
mid1 = ( ( int )mincolor[1] + maxcolor[1] + 1 ) >> 1;
side = 0;
for( i = 0; i < 16; i++ )
{
b0 = block[i * 4 + 2] >= mid0;
b1 = block[i * 4 + 1] >= mid1;
side += ( b0 ^ b1 );
}
mask = -( side > 8 );
mask &= -( mincolor[2] != maxcolor[2] );
c0 = mincolor[1];
c1 = maxcolor[1];
c0 ^= c1;
c1 ^= c0 & mask;
c0 ^= c1;
mincolor[1] = c0;
maxcolor[1] = c1;
}
/*
========================
idDxtEncoder::LerpRGB13GimpDDS
Linear interpolation at 1/3 point between a and b
========================
*/
void idDxtEncoder::LerpRGB13GimpDDS( byte* dst, byte* a, byte* b )
{
#if 0
dst[0] = blerp( a[0], b[0], 0x55 );
dst[1] = blerp( a[1], b[1], 0x55 );
dst[2] = blerp( a[2], b[2], 0x55 );
#else
// according to the S3TC/DX10 specs, this is the correct way to do the
// interpolation (with no rounding bias)
//
// dst = ( 2 * a + b ) / 3;
dst[0] = ( 2 * a[0] + b[0] ) / 3;
dst[1] = ( 2 * a[1] + b[1] ) / 3;
dst[2] = ( 2 * a[2] + b[2] ) / 3;
#endif
}
/*
========================
idDxtEncoder::Mul8BitGimpDDS
========================
*/
inline int idDxtEncoder::Mul8BitGimpDDS( int a, int b )
{
int t = a * b + 128;
return ( ( t + ( t >> 8 ) ) >> 8 );
}
/*
========================
idDxtEncoder::PackRGB565GimpDDS
Pack BGR8 to RGB565
========================
*/
inline unsigned short idDxtEncoder::PackRGB565GimpDDS( const byte* c )
{
return( ( Mul8BitGimpDDS( c[2], 31 ) << 11 ) |
( Mul8BitGimpDDS( c[1], 63 ) << 5 ) |
( Mul8BitGimpDDS( c[0], 31 ) ) );
}
/*
========================
idDxtEncoder::EncodeYCoCgBlockGimpDDS
========================
*/
void idDxtEncoder::EncodeYCoCgBlockGimpDDS( byte* dst, byte* block )
{
byte colors[4][3], *maxcolor, *mincolor;
unsigned int mask;
int c0, c1, d0, d1, d2, d3;
int b0, b1, b2, b3, b4;
int x0, x1, x2;
int i, idx;
maxcolor = &colors[0][0];
mincolor = &colors[1][0];
GetMinMaxYCoCgGimpDDS( block, mincolor, maxcolor );
ScaleYCoCgGimpDDS( block, mincolor, maxcolor );
InsetBBoxYCoCgGimpDDS( mincolor, maxcolor );
SelectDiagonalYCoCgGimpDDS( block, mincolor, maxcolor );
LerpRGB13GimpDDS( &colors[2][0], maxcolor, mincolor );
LerpRGB13GimpDDS( &colors[3][0], mincolor, maxcolor );
mask = 0;
for( i = 0; i < 16; i++ )
{
c0 = block[4 * i + 2];
c1 = block[4 * i + 1];
d0 = abs( colors[0][2] - c0 ) + abs( colors[0][1] - c1 );
d1 = abs( colors[1][2] - c0 ) + abs( colors[1][1] - c1 );
d2 = abs( colors[2][2] - c0 ) + abs( colors[2][1] - c1 );
d3 = abs( colors[3][2] - c0 ) + abs( colors[3][1] - c1 );
b0 = d0 > d3;
b1 = d1 > d2;
b2 = d0 > d2;
b3 = d1 > d3;
b4 = d2 > d3;
x0 = b1 & b2;
x1 = b0 & b3;
x2 = b0 & b4;
idx = ( x2 | ( ( x0 | x1 ) << 1 ) );
mask |= idx << ( 2 * i );
}
PUTL16( dst + 0, PackRGB565GimpDDS( maxcolor ) );
PUTL16( dst + 2, PackRGB565GimpDDS( mincolor ) );
PUTL32( dst + 4, mask );
}
/*
========================
idDxtEncoder::CompressYCoCgDXT5HQ
@ -2459,7 +2812,8 @@ void idDxtEncoder::CompressYCoCgDXT5HQ( const byte* inBuf, byte* outBuf, int wid
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
ScaleYCoCg( block );
@ -2565,7 +2919,8 @@ void idDxtEncoder::CompressYCoCgCTX1DXT5AHQ( const byte* inBuf, byte* outBuf, in
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
GetMinMaxAlphaHQ( block, 3, col1, col2 );
@ -2713,7 +3068,8 @@ void idDxtEncoder::CompressNormalMapDXT1HQ( const byte* inBuf, byte* outBuf, int
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
for( int k = 0; k < 16; k++ )
@ -2782,7 +3138,8 @@ void idDxtEncoder::CompressNormalMapDXT1RenormalizeHQ( const byte* inBuf, byte*
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
// clear alpha channel
@ -3038,7 +3395,8 @@ void idDxtEncoder::CompressNormalMapDXT5HQ( const byte* inBuf, byte* outBuf, int
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
// swizzle components
@ -3149,7 +3507,8 @@ void idDxtEncoder::CompressNormalMapDXT5RenormalizeHQ( const byte* inBuf, byte*
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
// swizzle components
@ -3186,6 +3545,7 @@ void idDxtEncoder::CompressNormalMapDXT5RenormalizeHQ( const byte* inBuf, byte*
}
outData += dstPadding;
inBuf += srcPadding;
}
////idLib::Printf( "\r100%%\n" );
@ -3234,7 +3594,8 @@ void idDxtEncoder::CompressNormalMapDXN2HQ( const byte* inBuf, byte* outBuf, int
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
for( int k = 0; k < 2; k++ )
@ -3995,7 +4356,8 @@ void idDxtEncoder::CompressImageDXT1Fast_Generic( const byte* inBuf, byte* outBu
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
GetMinMaxBBox( block, minColor, maxColor );
@ -4039,7 +4401,8 @@ void idDxtEncoder::CompressImageDXT1AlphaFast_Generic( const byte* inBuf, byte*
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
GetMinMaxBBox( block, minColor, maxColor );
@ -4092,7 +4455,8 @@ void idDxtEncoder::CompressImageDXT5Fast_Generic( const byte* inBuf, byte* outBu
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
GetMinMaxBBox( block, minColor, maxColor );
@ -4415,7 +4779,8 @@ void idDxtEncoder::CompressYCoCgDXT5Fast_Generic( const byte* inBuf, byte* outBu
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
GetMinMaxBBox( block, minColor, maxColor );
@ -4469,7 +4834,8 @@ void idDxtEncoder::CompressYCoCgAlphaDXT5Fast( const byte* inBuf, byte* outBuf,
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
// scale down the chroma of texels that are close to gray with low luminance
@ -4536,7 +4902,8 @@ void idDxtEncoder::CompressYCoCgCTX1DXT5AFast_Generic( const byte* inBuf, byte*
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
GetMinMaxBBox( block, minColor, maxColor );
@ -4729,7 +5096,8 @@ void idDxtEncoder::CompressNormalMapDXT5Fast_Generic( const byte* inBuf, byte* o
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
GetMinMaxBBox( block, normal1, normal2 );
@ -4777,7 +5145,8 @@ void idDxtEncoder::CompressImageDXN1Fast_Generic( const byte* inBuf, byte* outBu
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
GetMinMaxBBox( block, min, max );
@ -4820,7 +5189,8 @@ void idDxtEncoder::CompressNormalMapDXN2Fast_Generic( const byte* inBuf, byte* o
{
for( int i = 0; i < width; i += 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
ExtractBlock( inBuf + i * 4, width, block );
GetMinMaxBBox( block, normal1, normal2 );
@ -4982,7 +5352,8 @@ void idDxtEncoder::ConvertNormalMapDXN2_DXT5( const byte* inBuf, byte* outBuf, i
{
for( int i = 0; i < width; i += 4, inBuf += 16, outBuf += 16 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
// decode normal Y stored as a DXT5 alpha channel
DecodeDXNAlphaValues( inBuf + 0, values );
@ -5133,7 +5504,8 @@ void idDxtEncoder::ConvertNormalMapDXT5_DXN2( const byte* inBuf, byte* outBuf, i
{
for( int i = 0; i < width; i += 4, inBuf += 16, outBuf += 16 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
// decode normal Y stored as a DXT5 alpha channel
DecodeNormalYValues( inBuf + 8, minNormalY, maxNormalY, values );
@ -5184,7 +5556,8 @@ void idDxtEncoder::ConvertImageDXN1_DXT1( const byte* inBuf, byte* outBuf, int w
{
for( int i = 0; i < width; i += 4, inBuf += 8, outBuf += 8 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( 16 );
// decode single channel stored as a DXT5 alpha channel
DecodeDXNAlphaValues( inBuf + 0, values );

View file

@ -3,6 +3,8 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014-2016 Robert Beckebans
Copyright (C) 2014-2016 Kot in Action Creative Artel
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -25,12 +27,9 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
/*
================================================================================================
Contains the DxtEncoder implementation for SSE2.
================================================================================================
*/
#pragma hdrstop
#include "precompiled.h"
#include "framework/Common_local.h"
#include "DXTCodec_local.h"
#include "DXTCodec.h"
@ -957,6 +956,8 @@ void idDxtEncoder::CompressImageDXT1Fast_SSE2( const byte* inBuf, byte* outBuf,
for( int j = 0; j < height; j += 4, inBuf += width * 4 * 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( width * 4 );
for( int i = 0; i < width; i += 4 )
{
ExtractBlock_SSE2( inBuf + i * 4, width, block );
@ -1018,6 +1019,7 @@ void idDxtEncoder::CompressImageDXT1AlphaFast_SSE2( const byte* inBuf, byte* out
for( int j = 0; j < height; j += 4, inBuf += width * 4 * 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( width * 4 );
for( int i = 0; i < width; i += 4 )
{
ExtractBlock_SSE2( inBuf + i * 4, width, block );
@ -1364,6 +1366,8 @@ void idDxtEncoder::CompressYCoCgDXT5Fast_SSE2( const byte* inBuf, byte* outBuf,
for( int j = 0; j < height; j += 4, inBuf += width * 4 * 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( width * 4 );
for( int i = 0; i < width; i += 4 )
{
ExtractBlock_SSE2( inBuf + i * 4, width, block );
@ -1587,6 +1591,8 @@ void idDxtEncoder::CompressNormalMapDXT5Fast_SSE2( const byte* inBuf, byte* outB
for( int j = 0; j < height; j += 4, inBuf += width * 4 * 4 )
{
commonLocal.LoadPacifierBinarizeProgressIncrement( width * 4 );
for( int i = 0; i < width; i += 4 )
{
ExtractBlock_SSE2( inBuf + i * 4, width, block );
@ -1628,4 +1634,4 @@ void idDxtEncoder::CompressNormalMapDXT5Fast_SSE2( const byte* inBuf, byte* outB
#endif
}
#endif // #if defined(USE_INTRINSICS)
#endif // #if defined(USE_INTRINSICS)

View file

@ -3,7 +3,8 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2015 Robert Beckebans
Copyright (C) 2013-2016 Robert Beckebans
Copyright (C) 2014-2016 Kot in Action Creative Artel
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -30,6 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "framework/Common_local.h"
#include "RenderCommon.h"
/*
@ -249,8 +251,23 @@ void idImage::GenerateImage( const byte* pic, int width, int height, textureFilt
else
{
idBinaryImage im( GetName() );
// foresthale 2014-05-30: give a nice progress display when binarizing
commonLocal.LoadPacifierBinarizeFilename( GetName() , "generated image" );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.height * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.height );
}
im.Load2DFromMemory( width, height, pic, opts.numLevels, opts.format, opts.colorFormat, opts.gammaMips );
commonLocal.LoadPacifierBinarizeEnd();
AllocImage();
for( int i = 0; i < im.NumImages(); i++ )
@ -295,8 +312,22 @@ void idImage::GenerateCubeImage( const byte* pic[6], int size, textureFilter_t f
}
idBinaryImage im( GetName() );
// foresthale 2014-05-30: give a nice progress display when binarizing
commonLocal.LoadPacifierBinarizeFilename( GetName(), "generated cube image" );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 );
}
im.LoadCubeFromMemory( size, pic, opts.numLevels, opts.format, opts.gammaMips );
commonLocal.LoadPacifierBinarizeEnd();
AllocImage();
for( int i = 0; i < im.NumImages(); i++ )
@ -498,6 +529,26 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
}
else
{
idStr binarizeReason = "binarize: unknown reason";
if( binaryFileTime == FILE_NOT_FOUND_TIMESTAMP )
{
binarizeReason = va( "binarize: binary file not found '%s'", generatedName.c_str() );
}
else if( header.colorFormat != opts.colorFormat )
{
binarizeReason = va( "binarize: mismatch color format '%s'", generatedName.c_str() );
}
else if( header.colorFormat != opts.colorFormat )
{
binarizeReason = va( "binarize: mismatched color format '%s'", generatedName.c_str() );
}
else if( header.textureType != opts.textureType )
{
binarizeReason = va( "binarize: mismatched texture type '%s'", generatedName.c_str() );
}
//else if( toolUsage )
// binarizeReason = va( "binarize: tool usage '%s'", generatedName.c_str() );
if( cubeFiles != CF_2D )
{
int size;
@ -509,13 +560,30 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
return;
}
opts.textureType = TT_CUBIC;
repeat = TR_CLAMP;
opts.textureType = TT_CUBIC;
opts.width = size;
opts.height = size;
opts.numLevels = 0;
DeriveOpts();
// foresthale 2014-05-30: give a nice progress display when binarizing
commonLocal.LoadPacifierBinarizeFilename( generatedName.c_str(), binarizeReason.c_str() );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 );
}
im.LoadCubeFromMemory( size, ( const byte** )pics, opts.numLevels, opts.format, opts.gammaMips );
commonLocal.LoadPacifierBinarizeEnd();
repeat = TR_CLAMP;
for( int i = 0; i < 6; i++ )
@ -559,7 +627,20 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
opts.height = height;
opts.numLevels = 0;
DeriveOpts();
// foresthale 2014-05-30: give a nice progress display when binarizing
commonLocal.LoadPacifierBinarizeFilename( generatedName.c_str(), binarizeReason.c_str() );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 );
}
im.Load2DFromMemory( opts.width, opts.height, pic, opts.numLevels, opts.format, opts.colorFormat, opts.gammaMips );
commonLocal.LoadPacifierBinarizeEnd();
Mem_Free( pic );
}

View file

@ -111,7 +111,7 @@ static const float negOne[4] = { -1, -1, -1, -1 };
RB_SetVertexColorParms
================
*/
static void RB_SetVertexColorParms( stageVertexColor_t svc )
void RB_SetVertexColorParms( stageVertexColor_t svc )
{
switch( svc )
{

View file

@ -861,6 +861,8 @@ public:
return frameCount;
};
void OnFrame();
public:
// renderer globals
bool registered; // cleared at shutdown, set at InitOpenGL
@ -1518,6 +1520,7 @@ void RB_ShowDestinationAlpha();
void RB_ShowOverdraw();
void RB_RenderDebugTools( drawSurf_t** drawSurfs, int numDrawSurfs );
void RB_ShutdownDebugTools();
void RB_SetVertexColorParms( stageVertexColor_t svc );
//=============================================

View file

@ -369,6 +369,8 @@ public:
// consoles switch stereo 3D eye views each 60 hz frame
virtual int GetFrameCount() const = 0;
virtual void OnFrame() = 0;
};
extern idRenderSystem* renderSystem;

View file

@ -1872,6 +1872,126 @@ void R_SampleCubeMap( const idVec3& dir, int size, byte* buffers[6], byte result
result[3] = buffers[axis][( y * size + x ) * 4 + 3];
}
class CommandlineProgressBar
{
private:
size_t tics = 0;
size_t nextTicCount = 0;
int count = 0;
int expectedCount = 0;
public:
CommandlineProgressBar( int _expectedCount )
{
expectedCount = _expectedCount;
common->Printf( "0%% 10 20 30 40 50 60 70 80 90 100%%\n" );
common->Printf( "|----|----|----|----|----|----|----|----|----|----|\n" );
common->UpdateScreen( false );
}
void Increment()
{
if( ( count + 1 ) >= nextTicCount )
{
size_t ticsNeeded = ( size_t )( ( ( double )( count + 1 ) / expectedCount ) * 50.0 );
do
{
common->Printf( "*" );
}
while( ++tics < ticsNeeded );
nextTicCount = ( size_t )( ( tics / 50.0 ) * expectedCount );
if( count == ( expectedCount - 1 ) )
{
if( tics < 51 )
{
common->Printf( "*" );
}
common->Printf( "\n" );
}
common->UpdateScreen( false );
}
count++;
}
};
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
// To implement the Hammersley point set we only need an efficent way to implement the Van der Corput radical inverse phi2(i).
// Since it is in base 2 we can use some basic bit operations to achieve this.
// The brilliant book Hacker's Delight [warren01] provides us a a simple way to reverse the bits in a given 32bit integer. Using this, the following code then implements phi2(i)
/*
GLSL version
float radicalInverse_VdC( uint bits )
{
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}
*/
// RB: radical inverse implementation from the Mitsuba PBR system
// Van der Corput radical inverse in base 2 with single precision
inline float RadicalInverse_VdC( uint32_t n, uint32_t scramble = 0U )
{
/* Efficiently reverse the bits in 'n' using binary operations */
#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))) || defined(__clang__)
n = __builtin_bswap32( n );
#else
n = ( n << 16 ) | ( n >> 16 );
n = ( ( n & 0x00ff00ff ) << 8 ) | ( ( n & 0xff00ff00 ) >> 8 );
#endif
n = ( ( n & 0x0f0f0f0f ) << 4 ) | ( ( n & 0xf0f0f0f0 ) >> 4 );
n = ( ( n & 0x33333333 ) << 2 ) | ( ( n & 0xcccccccc ) >> 2 );
n = ( ( n & 0x55555555 ) << 1 ) | ( ( n & 0xaaaaaaaa ) >> 1 );
// Account for the available precision and scramble
n = ( n >> ( 32 - 24 ) ) ^ ( scramble & ~ -( 1 << 24 ) );
return ( float ) n / ( float )( 1U << 24 );
}
// The ith point xi is then computed by
inline idVec2 Hammersley2D( uint i, uint N )
{
return idVec2( float( i ) / float( N ), RadicalInverse_VdC( i ) );
}
idVec3 ImportanceSampleGGX( const idVec2& Xi, float roughness, const idVec3& N )
{
float a = roughness * roughness;
// cosinus distributed direction (Z-up or tangent space) from the hammersley point xi
float Phi = 2 * idMath::PI * Xi.x;
float cosTheta = sqrt( ( 1 - Xi.y ) / ( 1 + ( a * a - 1 ) * Xi.y ) );
float sinTheta = sqrt( 1 - cosTheta * cosTheta );
idVec3 H;
H.x = sinTheta * cos( Phi );
H.y = sinTheta * sin( Phi );
H.z = cosTheta;
// rotate from tangent space to world space along N
idVec3 upVector = abs( N.z ) < 0.999f ? idVec3( 0, 0, 1 ) : idVec3( 1, 0, 0 );
idVec3 tangentX = upVector.Cross( N );
tangentX.Normalize();
idVec3 tangentY = N.Cross( tangentX );
return tangentX * H.x + tangentY * H.y + N * H.z;
}
/*
==================
R_MakeAmbientMap_f
@ -1954,6 +2074,8 @@ void R_MakeAmbientMap_f( const idCmdArgs& args )
}
}
bool pacifier = true;
// resample with hemispherical blending
int samples = 1000;
@ -1961,6 +2083,10 @@ void R_MakeAmbientMap_f( const idCmdArgs& args )
for( int map = 0 ; map < 2 ; map++ )
{
CommandlineProgressBar progressBar( outSize * outSize * 6 );
int start = Sys_Milliseconds();
for( i = 0 ; i < 6 ; i++ )
{
for( int x = 0 ; x < outSize ; x++ )
@ -1973,30 +2099,14 @@ void R_MakeAmbientMap_f( const idCmdArgs& args )
dir = cubeAxis[i][0] + -( -1 + 2.0 * x / ( outSize - 1 ) ) * cubeAxis[i][1] + -( -1 + 2.0 * y / ( outSize - 1 ) ) * cubeAxis[i][2];
dir.Normalize();
total[0] = total[1] = total[2] = 0;
//samples = 1;
float limit = map ? 0.95 : 0.25; // small for specular, almost hemisphere for ambient
float roughness = map ? 0.1 : 0.95; // small for specular, almost hemisphere for ambient
for( int s = 0 ; s < samples ; s++ )
{
// pick a random direction vector that is inside the unit sphere but not behind dir,
// which is a robust way to evenly sample a hemisphere
idVec3 test;
while( 1 )
{
for( int j = 0 ; j < 3 ; j++ )
{
test[j] = -1 + 2 * ( rand() & 0x7fff ) / ( float )0x7fff;
}
if( test.Length() > 1.0 )
{
continue;
}
test.Normalize();
if( test * dir > limit ) // don't do a complete hemisphere
{
break;
}
}
idVec2 Xi = Hammersley2D( s, samples );
idVec3 test = ImportanceSampleGGX( Xi, roughness, dir );
byte result[4];
//test = dir;
R_SampleCubeMap( test, width, buffers, result );
@ -2008,21 +2118,37 @@ void R_MakeAmbientMap_f( const idCmdArgs& args )
outBuffer[( y * outSize + x ) * 4 + 1] = total[1] / samples;
outBuffer[( y * outSize + x ) * 4 + 2] = total[2] / samples;
outBuffer[( y * outSize + x ) * 4 + 3] = 255;
progressBar.Increment();
}
}
if( map == 0 )
{
fullname.Format( "env/%s_amb%s.%s", baseName, envDirection[i], fileExten[TGA] );
fullname.Format( "env/%s_amb%s.%s", baseName, envDirection[i], fileExten[PNG] );
}
else
{
fullname.Format( "env/%s_spec%s.%s", baseName, envDirection[i], fileExten[TGA] );
fullname.Format( "env/%s_spec%s.%s", baseName, envDirection[i], fileExten[PNG] );
}
common->Printf( "writing %s\n", fullname.c_str() );
//common->Printf( "writing %s\n", fullname.c_str() );
const bool captureToImage = false;
common->UpdateScreen( captureToImage );
R_WriteTGA( fullname, outBuffer, outSize, outSize );
//R_WriteTGA( fullname, outBuffer, outSize, outSize, false, "fs_basepath" );
R_WritePNG( fullname, outBuffer, 4, outSize, outSize, true, "fs_basepath" );
}
int end = Sys_Milliseconds();
if( map == 0 )
{
common->Printf( "env/%s_amb convolved in %5.1f seconds\n\n", baseName, ( end - start ) * 0.001f );
}
else
{
common->Printf( "env/%s_spec convolved in %5.1f seconds\n\n", baseName, ( end - start ) * 0.001f );
}
}

View file

@ -3,7 +3,8 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
Copyright (C) 2014-2016 Robert Beckebans
Copyright (C) 2014-2016 Kot in Action Creative Artel
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -928,25 +929,66 @@ RB_ShowSurfaceInfo
Debugging tool
=====================
*/
static void RB_ShowSurfaceInfo( drawSurf_t** drawSurfs, int numDrawSurfs )
static idStr surfModelName, surfMatName;
static idVec3 surfPoint;
static bool surfTraced = false;
void idRenderSystemLocal::OnFrame()
{
// Do tracing at a safe time to avoid threading issues.
modelTrace_t mt;
idVec3 start, end;
surfTraced = false;
if( !r_showSurfaceInfo.GetBool() )
{
return;
}
if( tr.primaryView == NULL )
{
return;
}
// start far enough away that we don't hit the player model
start = tr.primaryView->renderView.vieworg + tr.primaryView->renderView.viewaxis[0] * 16;
start = tr.primaryView->renderView.vieworg + tr.primaryView->renderView.viewaxis[0] * 32;
end = start + tr.primaryView->renderView.viewaxis[0] * 1000.0f;
if( !tr.primaryWorld->Trace( mt, start, end, 0.0f, false ) )
{
return;
}
globalImages->BindNull();
surfPoint = mt.point;
surfModelName = mt.entity->hModel->Name();
surfMatName = mt.material->GetName();
surfTraced = true;
}
static void RB_ShowSurfaceInfo( drawSurf_t** drawSurfs, int numDrawSurfs )
{
if( !r_showSurfaceInfo.GetBool() || !surfTraced )
{
return;
}
// globalImages->BindNull();
// qglDisable( GL_TEXTURE_2D );
RB_SimpleWorldSetup();
// foresthale 2014-05-02: don't use a shader for tools
//renderProgManager.BindShader_TextureVertexColor();
GL_SelectTexture( 0 );
globalImages->whiteImage->Bind();
RB_SetVertexColorParms( SVC_MODULATE );
// foresthale 2014-05-02: don't use a shader for tools
//renderProgManager.CommitUniforms();
GL_Color( 1, 1, 1 );
@ -956,15 +998,15 @@ static void RB_ShowSurfaceInfo( drawSurf_t** drawSurfs, int numDrawSurfs )
GL_PolygonOffset( scale, bias );
GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE | GLS_POLYGON_OFFSET );
idVec3 trans[3];
float matrix[16];
// idVec3 trans[3];
// float matrix[16];
// transform the object verts into global space
R_AxisToModelMatrix( mt.entity->axis, mt.entity->origin, matrix );
// R_AxisToModelMatrix( mt.entity->axis, mt.entity->origin, matrix );
tr.primaryWorld->DrawText( mt.entity->hModel->Name(), mt.point + tr.primaryView->renderView.viewaxis[2] * 12,
tr.primaryWorld->DrawText( surfModelName, surfPoint + tr.primaryView->renderView.viewaxis[2] * 12,
0.35f, colorRed, tr.primaryView->renderView.viewaxis );
tr.primaryWorld->DrawText( mt.material->GetName(), mt.point,
tr.primaryWorld->DrawText( surfMatName, surfPoint,
0.35f, colorBlue, tr.primaryView->renderView.viewaxis );
}