Skip to content

Commit

Permalink
Use new libfo76utils code for image based lighting
Browse files Browse the repository at this point in the history
  • Loading branch information
fo76utils committed Mar 31, 2024
1 parent a145a19 commit aed7689
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 3,470 deletions.
7 changes: 3 additions & 4 deletions NifSkope.pro
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@ SOURCES += \
src/gl/gltex.cpp \
src/gl/gltexloaders.cpp \
src/gl/gltools.cpp \
src/gl/pbr_lut_data.cpp \
src/gl/renderer.cpp \
src/io/materialfile.cpp \
src/io/MeshFile.cpp \
Expand Down Expand Up @@ -403,7 +402,7 @@ libfo76utils {
SOURCES += $$PWD/lib/libfo76utils/src/bsrefl.cpp
SOURCES += $$PWD/lib/libfo76utils/src/common.cpp
# SOURCES += $$PWD/lib/libfo76utils/src/courb24.cpp
SOURCES += $$PWD/lib/libfo76utils/src/ddstxt.cpp
SOURCES += $$PWD/lib/libfo76utils/src/ddstxt16.cpp
# SOURCES += $$PWD/lib/libfo76utils/src/downsamp.cpp
# SOURCES += $$PWD/lib/libfo76utils/src/esmfile.cpp
SOURCES += $$PWD/lib/libfo76utils/src/filebuf.cpp
Expand All @@ -414,9 +413,9 @@ libfo76utils {
SOURCES += $$PWD/lib/libfo76utils/src/mat_dump.cpp
SOURCES += $$PWD/lib/libfo76utils/src/mat_json.cpp
SOURCES += $$PWD/lib/libfo76utils/src/mat_list.cpp
# SOURCES += $$PWD/lib/libfo76utils/src/pbr_lut.cpp
SOURCES += $$PWD/lib/libfo76utils/src/pbr_lut.cpp
# SOURCES += $$PWD/lib/libfo76utils/src/sdlvideo.cpp
SOURCES += $$PWD/lib/libfo76utils/src/sfcube.cpp
SOURCES += $$PWD/lib/libfo76utils/src/sfcube2.cpp
# SOURCES += $$PWD/lib/libfo76utils/src/stringdb.cpp
# SOURCES += $$PWD/lib/libfo76utils/src/viewrtbl.cpp
SOURCES += $$PWD/lib/libfo76utils/src/zlib.cpp
Expand Down
4 changes: 2 additions & 2 deletions src/gl/gltex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ int TexCache::bind( const QModelIndex & iSource, Game::GameMode game )
glGenTextures( 1, tx->id );
glBindTexture( GL_TEXTURE_2D, tx->id[0] );
embedTextures.insert( iData, tx );
texLoad( game, iData, tx->format, tx->target, tx->width, tx->height, tx->mipmaps, tx->id );
texLoad( iData, tx->format, tx->target, tx->width, tx->height, tx->mipmaps, tx->id );
}
catch ( QString & e ) {
tx->status = e;
Expand Down Expand Up @@ -429,7 +429,7 @@ void TexCache::Tex::load()

bool TexCache::Tex::saveAsFile( const QModelIndex & index, QString & savepath )
{
texLoad( game, index, format, target, width, height, mipmaps, id );
texLoad( index, format, target, width, height, mipmaps, id );

if ( savepath.toLower().endsWith( ".tga" ) ) {
return texSaveTGA( index, savepath, width, height );
Expand Down
69 changes: 44 additions & 25 deletions src/gl/gltexloaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "model/nifmodel.h"

#include "dds.h"
#include "libfo76utils/src/sfcube.hpp"
#include "libfo76utils/src/pbr_lut.hpp"
#include "libfo76utils/src/sfcube2.hpp"

#include <QBuffer>
#include <QByteArray>
Expand Down Expand Up @@ -74,18 +75,19 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

bool extInitialized = false;
bool extSupported = true;
bool extStorageSupported = true;

static bool extInitialized = false;

#ifndef __APPLE__
// OpenGL 4.2
PFNGLTEXSTORAGE2DPROC glTexStorage2D = nullptr;
#ifdef _WIN32
PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D = nullptr;
PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D = nullptr;
static PFNGLTEXSTORAGE2DPROC glTexStorage2D = nullptr;
static bool extStorageSupported = true;
#else
static bool extStorageSupported = false;
#endif

#ifdef Q_OS_WIN32
static PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D = nullptr;
static PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D = nullptr;
#endif

#define FOURCC_DXT1 MAKEFOURCC( 'D', 'X', 'T', '1' )
Expand Down Expand Up @@ -625,7 +627,7 @@ GLuint texLoadBMP( QIODevice & f, QString & texformat, GLenum & target, GLuint &
return 0;
}

GLuint texLoadDDS( const Game::GameMode game, const QString & filepath, GLenum & target, GLuint & mipmaps, QByteArray & data, GLuint * id )
GLuint texLoadDDS( const QString & filepath, GLenum & target, GLuint & mipmaps, QByteArray & data, GLuint * id )
{
if ( data.size() < 128 )
return 0;
Expand All @@ -636,7 +638,11 @@ GLuint texLoadDDS( const Game::GameMode game, const QString & filepath, GLenum &
texture = load_if_valid( data.constData(), data.size() );
if ( !texture.empty() )
result = GLI_create_texture( texture, target, id );
#ifdef Q_OS_WIN32
} else if ( glCompressedTexImage2D ) {
#else
} else {
#endif
texture = load_if_valid( data.constData(), data.size() );
if ( !texture.empty() )
result = GLI_create_texture_fallback( texture, target, id );
Expand Down Expand Up @@ -703,6 +709,7 @@ GLuint texLoadPBRCubeMap( const Game::GameMode game, const QString & filepath, G
if ( data.size() < qsizetype(spaceRequired) )
data.resize( spaceRequired );
sfCubeMapCache.setRoughnessTable( nullptr, 7 );
sfCubeMapCache.setImportanceSamplingThreshold( 0.125f );
size_t newSize = sfCubeMapCache.convertImage( reinterpret_cast< unsigned char * >(data.data()), dataSize, true, spaceRequired, width );
data.resize( newSize );
}
Expand All @@ -720,10 +727,10 @@ GLuint texLoadPBRCubeMap( const Game::GameMode game, const QString & filepath, G
size_t newSize = sfCubeMapCache.convertImage( reinterpret_cast< unsigned char * >(tmpData.data()), dataSize, true, spaceRequired, width );
tmpData.resize( newSize );
GLuint tmpMipmaps = 0;
(void) texLoadDDS( game, filepath, target, tmpMipmaps, tmpData, id + 1 );
(void) texLoadDDS( filepath, target, tmpMipmaps, tmpData, id + 1 );
}

return texLoadDDS( game, filepath, target, mipmaps, data, id );
return texLoadDDS( filepath, target, mipmaps, data, id );
}

bool texLoadColor( const Game::GameMode game, const QString & filepath, GLenum & target, GLuint & width, GLuint & height, GLuint & mipmaps, QByteArray & data, GLuint * id )
Expand Down Expand Up @@ -757,11 +764,11 @@ bool texLoadColor( const Game::GameMode game, const QString & filepath, GLenum &

if ( isCubeMap && ( game == Game::FALLOUT_76 || game == Game::STARFIELD ) )
return bool( texLoadPBRCubeMap( game, filepath, target, mipmaps, data, id ) );
return bool( texLoadDDS( game, filepath, target, mipmaps, data, id ) );
return bool( texLoadDDS( filepath, target, mipmaps, data, id ) );
}

// (public function, documented in gltexloaders.h)
bool texLoad( const Game::GameMode game, const QModelIndex & iData, QString & texformat, GLenum & target, GLuint & width, GLuint & height, GLuint & mipmaps, GLuint * id )
bool texLoad( const QModelIndex & iData, QString & texformat, GLenum & target, GLuint & width, GLuint & height, GLuint & mipmaps, GLuint * id )
{
bool ok = false;

Expand Down Expand Up @@ -912,7 +919,7 @@ bool texLoad( const Game::GameMode game, const QModelIndex & iData, QString & te
buf.buffer().prepend( QByteArray::fromRawData( dds, sizeof( hdr ) ) );
buf.buffer().prepend( QByteArray::fromStdString( "DDS " ) );

mipmaps = texLoadDDS( game, QString( "[%1] NiPixelData" ).arg( nif->getBlockNumber( iData ) ),
mipmaps = texLoadDDS( QString( "[%1] NiPixelData" ).arg( nif->getBlockNumber( iData ) ),
target, mipmaps, buf.buffer(), id );

ok = (mipmaps > 0);
Expand All @@ -923,7 +930,7 @@ bool texLoad( const Game::GameMode game, const QModelIndex & iData, QString & te
}

//! Load NiPixelData or NiPersistentSrcTextureRendererData from a NifModel
GLuint texLoadNIF( const Game::GameMode game, QIODevice & f, QString & texformat, GLenum & target, GLuint & width, GLuint & height, GLuint * id )
GLuint texLoadNIF( QIODevice & f, QString & texformat, GLenum & target, GLuint & width, GLuint & height, GLuint * id )
{
GLuint mipmaps = 0;
target = GL_TEXTURE_2D;
Expand All @@ -943,7 +950,7 @@ GLuint texLoadNIF( const Game::GameMode game, QIODevice & f, QString & texformat
if ( !iData.isValid() || iData == QModelIndex() )
throw QString( "this is not a normal .nif file; there should be only pixel data as root blocks" );

texLoad( game, iData, texformat, target, width, height, mipmaps, id );
texLoad( iData, texformat, target, width, height, mipmaps, id );
}

return mipmaps;
Expand All @@ -955,13 +962,15 @@ void initializeTextureLoaders( const QOpenGLContext * context )
if ( !extInitialized ) {
#ifndef __APPLE__
glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)context->getProcAddress( "glTexStorage2D" );
#ifdef _WIN32
if ( !glTexStorage2D )
extStorageSupported = false;
#endif
#ifdef Q_OS_WIN32
glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)context->getProcAddress( "glCompressedTexSubImage2D" );
glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)context->getProcAddress( "glCompressedTexImage2D" );
#endif
#endif
if ( !glTexStorage2D || !glCompressedTexSubImage2D )
if ( !glCompressedTexSubImage2D )
extStorageSupported = false;
#endif

extInitialized = true;
}
Expand Down Expand Up @@ -1234,10 +1243,20 @@ gli::texture load_if_valid( const char * data, unsigned int size )

bool texLoad( const Game::GameMode game, const QString & filepath, QString & format, GLenum & target, GLuint & width, GLuint & height, GLuint & mipmaps, GLuint * id)
{
return texLoad( game, filepath, format, target, width, height, mipmaps, *(new QByteArray()), id );
QByteArray tmp;
return texLoad( game, filepath, format, target, width, height, mipmaps, tmp, id );
}

extern void extract_pbr_lut_data( QByteArray& data );
static void extract_pbr_lut_data( QByteArray & data )
{
static QByteArray pbrLUTData;
if ( pbrLUTData.isEmpty() ) {
SF_PBR_Tables pbrLUT( 512, 4096 );
pbrLUTData.resize( qsizetype( pbrLUT.getImageData().size() ) );
std::memcpy( pbrLUTData.data(), pbrLUT.getImageData().data(), pbrLUT.getImageData().size() );
}
data = pbrLUTData;
}

bool texLoad( const Game::GameMode game, const QString & filepath, QString & format, GLenum & target, GLuint & width, GLuint & height, GLuint & mipmaps, QByteArray & data, GLuint * id )
{
Expand Down Expand Up @@ -1274,7 +1293,7 @@ bool texLoad( const Game::GameMode game, const QString & filepath, QString & for
if ( isCubeMap && ( game == Game::FALLOUT_76 || game == Game::STARFIELD ) ) {
mipmaps = texLoadPBRCubeMap( game, filepath, target, mipmaps, data, id );
} else {
mipmaps = texLoadDDS( game, filepath, target, mipmaps, data, id );
mipmaps = texLoadDDS( filepath, target, mipmaps, data, id );
}
} else {
QBuffer f( &data );
Expand All @@ -1286,7 +1305,7 @@ bool texLoad( const Game::GameMode game, const QString & filepath, QString & for
else if ( filepath.endsWith( ".bmp", Qt::CaseInsensitive ) )
mipmaps = texLoadBMP( f, format, target, width, height, id );
else if ( filepath.endsWith( ".nif", Qt::CaseInsensitive ) || filepath.endsWith( ".texcache", Qt::CaseInsensitive ) )
mipmaps = texLoadNIF( game, f, format, target, width, height, id );
mipmaps = texLoadNIF( f, format, target, width, height, id );
else
isSupported = false;

Expand Down
2 changes: 1 addition & 1 deletion src/gl/gltexloaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ extern bool texLoad( const Game::GameMode game, const QString & filepath, QStrin
* @param mipmaps Contains the number of mipmaps on successful load.
* @return True if the load was successful, false otherwise.
*/
extern bool texLoad( const Game::GameMode game, const QModelIndex & iData, QString & format, GLenum & target, GLuint & width, GLuint & height, GLuint & mipmaps, GLuint * id );
extern bool texLoad( const QModelIndex & iData, QString & format, GLenum & target, GLuint & width, GLuint & height, GLuint & mipmaps, GLuint * id );

/*! A function which checks whether the given file can be loaded.
*
Expand Down
Loading

0 comments on commit aed7689

Please sign in to comment.