Merge of QAR-1267 to trunk. This was a combo merge of QAR-1175 (maint-render-9) and QAR-1236 (dll-msvcrt-2)
svn merge -r 109838:112264 svn+ssh://svn.lindenlab.com/svn/linden/branches/maint-render/maint-render-9-merge-r109833master
parent
34412f0530
commit
abdc99f21b
|
|
@ -108,6 +108,9 @@ Carjay McGinnis
|
|||
Catherine Pfeffer
|
||||
VWR-1282
|
||||
VWR-8624
|
||||
Celierra Darling
|
||||
VWR-1274
|
||||
VWR-6975
|
||||
Dale Glass
|
||||
VWR-120
|
||||
VWR-560
|
||||
|
|
@ -375,6 +378,7 @@ Renault Clio
|
|||
VWR-1976
|
||||
Robin Cornelius
|
||||
VWR-2488
|
||||
VWR-9557
|
||||
Ryozu Kojima
|
||||
VWR-287
|
||||
Sammy Frederix
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ include(Variables)
|
|||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -DLL_SEND_CRASH_REPORTS=1 -DNDEBUG")
|
||||
"-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=1 -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"-DLL_RELEASE=1 -DLL_SEND_CRASH_REPORTS=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
|
||||
"-DLL_RELEASE=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
|
||||
|
||||
|
||||
# Don't bother with a MinSizeRel build.
|
||||
|
|
@ -26,15 +26,18 @@ if (WINDOWS)
|
|||
# Don't build DLLs.
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MTd"
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd"
|
||||
CACHE STRING "C++ compiler debug options" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MT"
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD"
|
||||
CACHE STRING "C++ compiler release-with-debug options" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MT"
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD"
|
||||
CACHE STRING "C++ compiler release options" FORCE)
|
||||
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES "")
|
||||
set(CMAKE_C_STANDARD_LIBRARIES "")
|
||||
|
||||
add_definitions(
|
||||
/DLL_WINDOWS=1
|
||||
/DUNICODE
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
include(BerkeleyDB)
|
||||
include(Linking)
|
||||
include(Prebuilt)
|
||||
|
|
@ -19,12 +17,14 @@ else (STANDALONE)
|
|||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/apr-1.lib
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/apr-1.lib
|
||||
)
|
||||
set(APRUTIL_LIBRARIES
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/aprutil-1.lib
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/aprutil-1.lib
|
||||
set(APRICONV_LIBRARIES
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/apriconv-1.lib
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/apriconv-1.lib
|
||||
)
|
||||
set(APRUTIL_LIBRARIES
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/aprutil-1.lib ${APRICONV_LIBRARIES}
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/aprutil-1.lib ${APRICONV_LIBRARIES}
|
||||
)
|
||||
# Doesn't need to link with iconv.dll
|
||||
set(APRICONV_LIBRARIES "")
|
||||
elseif (DARWIN)
|
||||
set(APR_LIBRARIES
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapr-1.a
|
||||
|
|
|
|||
|
|
@ -14,10 +14,18 @@ else (STANDALONE)
|
|||
set(VORBISFILE_INCLUDE_DIRS ${VORBIS_INCLUDE_DIRS})
|
||||
|
||||
if (WINDOWS)
|
||||
set(OGG_LIBRARIES ogg_static_mt)
|
||||
set(VORBIS_LIBRARIES vorbis_static_mt)
|
||||
set(VORBISENC_LIBRARIES vorbisenc_static_mt)
|
||||
set(VORBISFILE_LIBRARIES vorbisfile_static_mt)
|
||||
set(OGG_LIBRARIES
|
||||
optimized ogg_static
|
||||
debug ogg_static_d)
|
||||
set(VORBIS_LIBRARIES
|
||||
optimized vorbis_static
|
||||
debug vorbis_static_d)
|
||||
set(VORBISENC_LIBRARIES
|
||||
optimized vorbisenc_static
|
||||
debug vorbisenc_static_d)
|
||||
set(VORBISFILE_LIBRARIES
|
||||
optimized vorbisfile_static
|
||||
debug vorbisfile_static_d)
|
||||
else (WINDOWS)
|
||||
set(OGG_LIBRARIES ogg)
|
||||
set(VORBIS_LIBRARIES vorbis)
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ else (STANDALONE)
|
|||
debug libboost_signals-vc71-mt-sgd-${BOOST_VERSION})
|
||||
else (MSVC71)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY
|
||||
optimized libboost_program_options-vc80-mt-s-${BOOST_VERSION}
|
||||
debug libboost_program_options-vc80-mt-sgd-${BOOST_VERSION})
|
||||
optimized libboost_program_options-vc80-mt-${BOOST_VERSION}
|
||||
debug libboost_program_options-vc80-mt-gd-${BOOST_VERSION})
|
||||
set(BOOST_REGEX_LIBRARY
|
||||
optimized libboost_regex-vc80-mt-s-${BOOST_VERSION}
|
||||
debug libboost_regex-vc80-mt-sgd-${BOOST_VERSION})
|
||||
optimized libboost_regex-vc80-mt-${BOOST_VERSION}
|
||||
debug libboost_regex-vc80-mt-gd-${BOOST_VERSION})
|
||||
set(BOOST_SIGNALS_LIBRARY
|
||||
optimized libboost_signals-vc80-mt-s-${BOOST_VERSION}
|
||||
debug libboost_signals-vc80-mt-sgd-${BOOST_VERSION})
|
||||
optimized libboost_signals-vc80-mt-${BOOST_VERSION}
|
||||
debug libboost_signals-vc80-mt-gd-${BOOST_VERSION})
|
||||
endif (MSVC71)
|
||||
elseif (DARWIN)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@ if (STANDALONE)
|
|||
include(FindGooglePerfTools)
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(google)
|
||||
if (WINDOWS)
|
||||
set(TCMALLOC_LIBRARIES
|
||||
debug libtcmalloc_minimal-debug
|
||||
optimized libtcmalloc_minimal-debug)
|
||||
endif (WINDOWS)
|
||||
if (LINUX)
|
||||
set(TCMALLOC_LIBRARIES tcmalloc)
|
||||
set(STACKTRACE_LIBRARIES stacktrace)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ else (STANDALONE)
|
|||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/liblljpeg.a
|
||||
)
|
||||
elseif (WINDOWS)
|
||||
set(JPEG_LIBRARIES jpeglib_6b)
|
||||
set(JPEG_LIBRARIES jpeglib)
|
||||
endif (LINUX)
|
||||
set(JPEG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ endif (SERVER AND LINUX)
|
|||
|
||||
# mapserver requires certain files to be copied so LL_MESA_HEADLESS can be set
|
||||
# differently for different object files.
|
||||
macro (copy_server_sources _copied_SOURCES)
|
||||
foreach (PREFIX ${_copied_SOURCES})
|
||||
macro (copy_server_sources )
|
||||
foreach (PREFIX ${ARGV})
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
|
|
|
|||
|
|
@ -40,4 +40,9 @@ else (SERVER AND LINUX)
|
|||
set(LLWINDOW_LIBRARIES
|
||||
llwindow
|
||||
)
|
||||
if (WINDOWS)
|
||||
list(APPEND LLWINDOW_LIBRARIES
|
||||
comdlg32
|
||||
)
|
||||
endif (WINDOWS)
|
||||
endif (SERVER AND LINUX)
|
||||
|
|
|
|||
|
|
@ -32,11 +32,16 @@ endif (LINUX)
|
|||
|
||||
if (WINDOWS)
|
||||
set(WINDOWS_LIBRARIES
|
||||
advapi32
|
||||
shell32
|
||||
ws2_32
|
||||
mswsock
|
||||
psapi
|
||||
winmm
|
||||
netapi32
|
||||
wldap32
|
||||
gdi32
|
||||
user32
|
||||
)
|
||||
else (WINDOWS)
|
||||
set(WINDOWS_LIBRARIES "")
|
||||
|
|
|
|||
|
|
@ -8,6 +8,12 @@ if (STANDALONE)
|
|||
include(FindPNG)
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(libpng)
|
||||
set(PNG_LIBRARIES png12)
|
||||
if (WINDOWS)
|
||||
set(PNG_LIBRARIES
|
||||
debug libpngd
|
||||
optimized libpng)
|
||||
else (WINDOWS)
|
||||
set(PNG_LIBRARIES png12)
|
||||
endif (WINDOWS)
|
||||
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ if (STANDALONE)
|
|||
else (STANDALONE)
|
||||
use_prebuilt_binary(zlib)
|
||||
if (WINDOWS)
|
||||
set(ZLIB_LIBRARIES zlib)
|
||||
set(ZLIB_LIBRARIES
|
||||
debug zlibd
|
||||
optimized zlib)
|
||||
else (WINDOWS)
|
||||
set(ZLIB_LIBRARIES z)
|
||||
endif (WINDOWS)
|
||||
|
|
|
|||
|
|
@ -178,7 +178,9 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
|
|||
//--------------------------------------------------------------------
|
||||
std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName);
|
||||
|
||||
apr_file_t *fp = ll_apr_file_open(path, LL_APR_R);
|
||||
LLAPRFile infile ;
|
||||
infile.open(path, LL_APR_R);
|
||||
apr_file_t *fp = infile.getFileHandle();
|
||||
if (!fp)
|
||||
return ST_NO_XLT_FILE;
|
||||
|
||||
|
|
@ -187,8 +189,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
|
|||
//--------------------------------------------------------------------
|
||||
// register file to be closed on function exit
|
||||
//--------------------------------------------------------------------
|
||||
FileCloser fileCloser(fp);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// load header
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -618,6 +619,8 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
infile.close() ;
|
||||
return ST_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -354,7 +354,9 @@ BOOL LLKeyframeMotionParam::loadMotions()
|
|||
// open the file
|
||||
//-------------------------------------------------------------------------
|
||||
S32 fileSize = 0;
|
||||
apr_file_t* fp = ll_apr_file_open(path, LL_APR_R, &fileSize);
|
||||
LLAPRFile infile ;
|
||||
infile.open(path, LL_APR_R, NULL, &fileSize);
|
||||
apr_file_t* fp = infile.getFileHandle() ;
|
||||
if (!fp || fileSize == 0)
|
||||
{
|
||||
llinfos << "ERROR: can't open: " << path << llendl;
|
||||
|
|
@ -366,7 +368,6 @@ BOOL LLKeyframeMotionParam::loadMotions()
|
|||
if ( !text )
|
||||
{
|
||||
llinfos << "ERROR: can't allocated keyframe text buffer." << llendl;
|
||||
apr_file_close(fp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -393,7 +394,7 @@ BOOL LLKeyframeMotionParam::loadMotions()
|
|||
//-------------------------------------------------------------------------
|
||||
// close the file
|
||||
//-------------------------------------------------------------------------
|
||||
apr_file_close( fp );
|
||||
infile.close();
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// check for error
|
||||
|
|
|
|||
|
|
@ -209,7 +209,9 @@ LLFSMState* LLStateDiagram::getState(U32 state_id)
|
|||
|
||||
BOOL LLStateDiagram::saveDotFile(const std::string& filename)
|
||||
{
|
||||
apr_file_t* dot_file = ll_apr_file_open(filename, LL_APR_W);
|
||||
LLAPRFile outfile ;
|
||||
outfile.open(filename, LL_APR_W);
|
||||
apr_file_t* dot_file = outfile.getFileHandle() ;
|
||||
|
||||
if (!dot_file)
|
||||
{
|
||||
|
|
@ -258,8 +260,6 @@ BOOL LLStateDiagram::saveDotFile(const std::string& filename)
|
|||
|
||||
apr_file_printf(dot_file, "}\n");
|
||||
|
||||
apr_file_close(dot_file);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,8 +36,10 @@
|
|||
#include "llapr.h"
|
||||
|
||||
apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
|
||||
LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
|
||||
apr_thread_mutex_t *gLogMutexp = NULL;
|
||||
|
||||
const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool
|
||||
|
||||
void ll_init_apr()
|
||||
{
|
||||
|
|
@ -46,10 +48,15 @@ void ll_init_apr()
|
|||
// Initialize APR and create the global pool
|
||||
apr_initialize();
|
||||
apr_pool_create(&gAPRPoolp, NULL);
|
||||
|
||||
|
||||
// Initialize the logging mutex
|
||||
apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
|
||||
}
|
||||
|
||||
if(!LLAPRFile::sAPRFilePoolp)
|
||||
{
|
||||
LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool() ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -70,31 +77,127 @@ void ll_cleanup_apr()
|
|||
apr_pool_destroy(gAPRPoolp);
|
||||
gAPRPoolp = NULL;
|
||||
}
|
||||
if (LLAPRFile::sAPRFilePoolp)
|
||||
{
|
||||
delete LLAPRFile::sAPRFilePoolp ;
|
||||
LLAPRFile::sAPRFilePoolp = NULL ;
|
||||
}
|
||||
apr_terminate();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//LLAPRPool
|
||||
//
|
||||
LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size)
|
||||
LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
|
||||
{
|
||||
mStatus = apr_pool_create(&mPool, parent);
|
||||
mParent = parent ;
|
||||
mReleasePoolFlag = releasePoolFlag ;
|
||||
mMaxSize = size ;
|
||||
mPool = NULL ;
|
||||
|
||||
if(size > 0) //size is the number of blocks (which is usually 4K), NOT bytes.
|
||||
{
|
||||
apr_allocator_t *allocator = apr_pool_allocator_get(mPool);
|
||||
if (allocator)
|
||||
{
|
||||
apr_allocator_max_free_set(allocator, size) ;
|
||||
}
|
||||
}
|
||||
createAPRPool() ;
|
||||
}
|
||||
|
||||
LLAPRPool::~LLAPRPool()
|
||||
{
|
||||
apr_pool_destroy(mPool) ;
|
||||
releaseAPRPool() ;
|
||||
}
|
||||
|
||||
void LLAPRPool::createAPRPool()
|
||||
{
|
||||
if(mPool)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
mStatus = apr_pool_create(&mPool, mParent);
|
||||
ll_apr_warn_status(mStatus) ;
|
||||
|
||||
if(mMaxSize > 0) //size is the number of blocks (which is usually 4K), NOT bytes.
|
||||
{
|
||||
apr_allocator_t *allocator = apr_pool_allocator_get(mPool);
|
||||
if (allocator)
|
||||
{
|
||||
apr_allocator_max_free_set(allocator, mMaxSize) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLAPRPool::releaseAPRPool()
|
||||
{
|
||||
if(!mPool)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
if(!mParent || mReleasePoolFlag)
|
||||
{
|
||||
apr_pool_destroy(mPool) ;
|
||||
mPool = NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
apr_pool_t* LLAPRPool::getAPRPool()
|
||||
{
|
||||
if(!mPool)
|
||||
{
|
||||
createAPRPool() ;
|
||||
}
|
||||
|
||||
return mPool ;
|
||||
}
|
||||
LLVolatileAPRPool::LLVolatileAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
|
||||
: LLAPRPool(parent, size, releasePoolFlag)
|
||||
{
|
||||
mNumActiveRef = 0 ;
|
||||
mNumTotalRef = 0 ;
|
||||
}
|
||||
|
||||
apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool()
|
||||
{
|
||||
mNumTotalRef++ ;
|
||||
mNumActiveRef++ ;
|
||||
return getAPRPool() ;
|
||||
}
|
||||
|
||||
void LLVolatileAPRPool::clearVolatileAPRPool()
|
||||
{
|
||||
if(mNumActiveRef > 0)
|
||||
{
|
||||
mNumActiveRef--;
|
||||
if(mNumActiveRef < 1)
|
||||
{
|
||||
if(isFull())
|
||||
{
|
||||
mNumTotalRef = 0 ;
|
||||
|
||||
//destroy the apr_pool.
|
||||
releaseAPRPool() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
//This does not actually free the memory,
|
||||
//it just allows the pool to re-use this memory for the next allocation.
|
||||
apr_pool_clear(mPool) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert_always(mNumActiveRef > 0) ;
|
||||
}
|
||||
|
||||
//paranoia check if the pool is jammed.
|
||||
//will remove the check before going to release.
|
||||
llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
|
||||
}
|
||||
|
||||
BOOL LLVolatileAPRPool::isFull()
|
||||
{
|
||||
return mNumTotalRef > FULL_VOLATILE_APR_POOL ;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// LLScopedLock
|
||||
//
|
||||
|
|
@ -133,9 +236,8 @@ void LLScopedLock::unlock()
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Misc functions
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
bool ll_apr_warn_status(apr_status_t status)
|
||||
{
|
||||
if(APR_SUCCESS == status) return false;
|
||||
|
|
@ -151,55 +253,110 @@ void ll_apr_assert_status(apr_status_t status)
|
|||
llassert(ll_apr_warn_status(status) == false);
|
||||
}
|
||||
|
||||
// File I/O
|
||||
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, S32* sizep, apr_pool_t* pool)
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// LLAPRFile functions
|
||||
//
|
||||
LLAPRFile::LLAPRFile()
|
||||
{
|
||||
apr_file_t* apr_file;
|
||||
apr_status_t s;
|
||||
if (pool == NULL) pool = gAPRPoolp;
|
||||
s = apr_file_open(&apr_file, filename.c_str(), flags, APR_OS_DEFAULT, pool);
|
||||
if (s != APR_SUCCESS)
|
||||
mFile = NULL ;
|
||||
mCurrentFilePoolp = NULL ;
|
||||
}
|
||||
LLAPRFile::~LLAPRFile()
|
||||
{
|
||||
close() ;
|
||||
}
|
||||
|
||||
apr_status_t LLAPRFile::close()
|
||||
{
|
||||
apr_status_t ret = APR_SUCCESS ;
|
||||
if(mFile)
|
||||
{
|
||||
ret = apr_file_close(mFile);
|
||||
mFile = NULL ;
|
||||
}
|
||||
|
||||
if(mCurrentFilePoolp)
|
||||
{
|
||||
mCurrentFilePoolp->clearVolatileAPRPool() ;
|
||||
mCurrentFilePoolp = NULL ;
|
||||
}
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
apr_status_t LLAPRFile::open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep)
|
||||
{
|
||||
apr_status_t s ;
|
||||
s = open(filename, flags, pool ? pool->getVolatileAPRPool() : NULL, sizep) ;
|
||||
|
||||
if(!mCurrentFilePoolp)
|
||||
{
|
||||
mCurrentFilePoolp = pool ;
|
||||
|
||||
if(!mFile)
|
||||
{
|
||||
close() ;
|
||||
}
|
||||
}
|
||||
|
||||
return s ;
|
||||
}
|
||||
apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool, S32* sizep)
|
||||
{
|
||||
apr_status_t s;
|
||||
|
||||
//check if already open some file
|
||||
llassert_always(!mFile) ;
|
||||
llassert_always(!mCurrentFilePoolp) ;
|
||||
|
||||
s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, getAPRFilePool(pool));
|
||||
if (s != APR_SUCCESS || !mFile)
|
||||
{
|
||||
mFile = NULL ;
|
||||
close() ;
|
||||
if (sizep)
|
||||
{
|
||||
*sizep = 0;
|
||||
}
|
||||
return NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
if (sizep)
|
||||
{
|
||||
S32 file_size = 0;
|
||||
apr_off_t offset = 0;
|
||||
if (apr_file_seek(apr_file, APR_END, &offset) == APR_SUCCESS)
|
||||
if (apr_file_seek(mFile, APR_END, &offset) == APR_SUCCESS)
|
||||
{
|
||||
llassert_always(offset <= 0x7fffffff);
|
||||
file_size = (S32)offset;
|
||||
offset = 0;
|
||||
apr_file_seek(apr_file, APR_SET, &offset);
|
||||
apr_file_seek(mFile, APR_SET, &offset);
|
||||
}
|
||||
*sizep = file_size;
|
||||
}
|
||||
|
||||
return apr_file;
|
||||
}
|
||||
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, S32* sizep)
|
||||
{
|
||||
return ll_apr_file_open(filename, flags, sizep, NULL);
|
||||
}
|
||||
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool)
|
||||
{
|
||||
return ll_apr_file_open(filename, flags, NULL, pool);
|
||||
}
|
||||
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags)
|
||||
{
|
||||
return ll_apr_file_open(filename, flags, NULL, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
S32 ll_apr_file_read(apr_file_t* apr_file, void *buf, S32 nbytes)
|
||||
apr_pool_t* LLAPRFile::getAPRFilePool(apr_pool_t* pool)
|
||||
{
|
||||
if(!pool)
|
||||
{
|
||||
mCurrentFilePoolp = sAPRFilePoolp ;
|
||||
return mCurrentFilePoolp->getVolatileAPRPool() ;
|
||||
}
|
||||
|
||||
return pool ;
|
||||
}
|
||||
|
||||
// File I/O
|
||||
S32 LLAPRFile::read(void *buf, S32 nbytes)
|
||||
{
|
||||
llassert_always(mFile) ;
|
||||
|
||||
apr_size_t sz = nbytes;
|
||||
apr_status_t s = apr_file_read(apr_file, buf, &sz);
|
||||
apr_status_t s = apr_file_read(mFile, buf, &sz);
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
return 0;
|
||||
|
|
@ -211,37 +368,12 @@ S32 ll_apr_file_read(apr_file_t* apr_file, void *buf, S32 nbytes)
|
|||
}
|
||||
}
|
||||
|
||||
S32 ll_apr_file_read_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes)
|
||||
{
|
||||
if (pool == NULL) pool = gAPRPoolp;
|
||||
apr_file_t* filep = ll_apr_file_open(filename, APR_READ|APR_BINARY, pool);
|
||||
if (!filep)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
S32 off;
|
||||
if (offset < 0)
|
||||
off = ll_apr_file_seek(filep, APR_END, 0);
|
||||
else
|
||||
off = ll_apr_file_seek(filep, APR_SET, offset);
|
||||
S32 bytes_read;
|
||||
if (off < 0)
|
||||
{
|
||||
bytes_read = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_read = ll_apr_file_read(filep, buf, nbytes );
|
||||
}
|
||||
apr_file_close(filep);
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
S32 ll_apr_file_write(apr_file_t* apr_file, const void *buf, S32 nbytes)
|
||||
S32 LLAPRFile::write(const void *buf, S32 nbytes)
|
||||
{
|
||||
llassert_always(mFile) ;
|
||||
|
||||
apr_size_t sz = nbytes;
|
||||
apr_status_t s = apr_file_write(apr_file, buf, &sz);
|
||||
apr_status_t s = apr_file_write(mFile, buf, &sz);
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
return 0;
|
||||
|
|
@ -253,51 +385,72 @@ S32 ll_apr_file_write(apr_file_t* apr_file, const void *buf, S32 nbytes)
|
|||
}
|
||||
}
|
||||
|
||||
S32 ll_apr_file_write_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes)
|
||||
S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset)
|
||||
{
|
||||
if (pool == NULL) pool = gAPRPoolp;
|
||||
apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
|
||||
if (offset < 0)
|
||||
{
|
||||
flags |= APR_APPEND;
|
||||
offset = 0;
|
||||
}
|
||||
apr_file_t* filep = ll_apr_file_open(filename, flags, pool);
|
||||
if (!filep)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (offset > 0)
|
||||
{
|
||||
offset = ll_apr_file_seek(filep, APR_SET, offset);
|
||||
}
|
||||
S32 bytes_written;
|
||||
if (offset < 0)
|
||||
{
|
||||
bytes_written = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_written = ll_apr_file_write(filep, buf, nbytes );
|
||||
}
|
||||
apr_file_close(filep);
|
||||
|
||||
return bytes_written;
|
||||
return LLAPRFile::seek(mFile, where, offset) ;
|
||||
}
|
||||
|
||||
S32 ll_apr_file_seek(apr_file_t* apr_file, apr_seek_where_t where, S32 offset)
|
||||
//
|
||||
//*******************************************************************************************************************************
|
||||
//static components of LLAPRFile
|
||||
//
|
||||
|
||||
//static
|
||||
apr_status_t LLAPRFile::close(apr_file_t* file_handle, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_status_t ret = APR_SUCCESS ;
|
||||
if(file_handle)
|
||||
{
|
||||
ret = apr_file_close(file_handle);
|
||||
file_handle = NULL ;
|
||||
}
|
||||
|
||||
if(pool)
|
||||
{
|
||||
pool->clearVolatileAPRPool() ;
|
||||
}
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
//static
|
||||
apr_file_t* LLAPRFile::open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags)
|
||||
{
|
||||
apr_status_t s;
|
||||
apr_file_t* file_handle ;
|
||||
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
|
||||
s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool());
|
||||
if (s != APR_SUCCESS || !file_handle)
|
||||
{
|
||||
file_handle = NULL ;
|
||||
close(file_handle, pool) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return file_handle ;
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
|
||||
{
|
||||
if(!file_handle)
|
||||
{
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
apr_status_t s;
|
||||
apr_off_t apr_offset;
|
||||
if (offset >= 0)
|
||||
{
|
||||
apr_offset = (apr_off_t)offset;
|
||||
s = apr_file_seek(apr_file, where, &apr_offset);
|
||||
s = apr_file_seek(file_handle, where, &apr_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
apr_offset = 0;
|
||||
s = apr_file_seek(apr_file, APR_END, &apr_offset);
|
||||
s = apr_file_seek(file_handle, APR_END, &apr_offset);
|
||||
}
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
|
|
@ -310,66 +463,178 @@ S32 ll_apr_file_seek(apr_file_t* apr_file, apr_seek_where_t where, S32 offset)
|
|||
}
|
||||
}
|
||||
|
||||
bool ll_apr_file_remove(const std::string& filename, apr_pool_t* pool)
|
||||
//static
|
||||
S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
|
||||
{
|
||||
//*****************************************
|
||||
apr_file_t* file_handle = open(filename, pool, APR_READ|APR_BINARY);
|
||||
//*****************************************
|
||||
if (!file_handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
S32 off;
|
||||
if (offset < 0)
|
||||
off = LLAPRFile::seek(file_handle, APR_END, 0);
|
||||
else
|
||||
off = LLAPRFile::seek(file_handle, APR_SET, offset);
|
||||
|
||||
apr_size_t bytes_read;
|
||||
if (off < 0)
|
||||
{
|
||||
bytes_read = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_read = nbytes ;
|
||||
apr_status_t s = apr_file_read(file_handle, buf, &bytes_read);
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
bytes_read = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert_always(bytes_read <= 0x7fffffff);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
close(file_handle, pool) ;
|
||||
//*****************************************
|
||||
return (S32)bytes_read;
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
|
||||
if (offset < 0)
|
||||
{
|
||||
flags |= APR_APPEND;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
apr_file_t* file_handle = open(filename, pool, flags);
|
||||
//*****************************************
|
||||
if (!file_handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (offset > 0)
|
||||
{
|
||||
offset = LLAPRFile::seek(file_handle, APR_SET, offset);
|
||||
}
|
||||
|
||||
apr_size_t bytes_written;
|
||||
if (offset < 0)
|
||||
{
|
||||
bytes_written = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_written = nbytes ;
|
||||
apr_status_t s = apr_file_write(file_handle, buf, &bytes_written);
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
bytes_written = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert_always(bytes_written <= 0x7fffffff);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
LLAPRFile::close(file_handle, pool);
|
||||
//*****************************************
|
||||
|
||||
return (S32)bytes_written;
|
||||
}
|
||||
|
||||
//static
|
||||
bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_status_t s;
|
||||
if (pool == NULL) pool = gAPRPoolp;
|
||||
s = apr_file_remove(filename.c_str(), pool);
|
||||
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
s = apr_file_remove(filename.c_str(), pool->getVolatileAPRPool());
|
||||
pool->clearVolatileAPRPool() ;
|
||||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
LL_DEBUGS("APR") << "ll_apr_file_remove failed on file: " << filename << LL_ENDL;
|
||||
LL_DEBUGS("APR") << "LLAPRFile::remove failed on file: " << filename << LL_ENDL;
|
||||
ll_apr_warn_status(s);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ll_apr_file_rename(const std::string& filename, const std::string& newname, apr_pool_t* pool)
|
||||
//static
|
||||
bool LLAPRFile::rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_status_t s;
|
||||
if (pool == NULL) pool = gAPRPoolp;
|
||||
s = apr_file_rename(filename.c_str(), newname.c_str(), pool);
|
||||
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
s = apr_file_rename(filename.c_str(), newname.c_str(), pool->getVolatileAPRPool());
|
||||
pool->clearVolatileAPRPool() ;
|
||||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
LL_DEBUGS("APR") << "ll_apr_file_rename failed on file: " << filename << LL_ENDL;
|
||||
LL_DEBUGS("APR") << "LLAPRFile::rename failed on file: " << filename << LL_ENDL;
|
||||
ll_apr_warn_status(s);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ll_apr_file_exists(const std::string& filename, apr_pool_t* pool)
|
||||
//static
|
||||
bool LLAPRFile::isExist(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags)
|
||||
{
|
||||
apr_file_t* apr_file;
|
||||
apr_status_t s;
|
||||
if (pool == NULL) pool = gAPRPoolp;
|
||||
s = apr_file_open(&apr_file, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool);
|
||||
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
s = apr_file_open(&apr_file, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool());
|
||||
|
||||
if (s != APR_SUCCESS || !apr_file)
|
||||
{
|
||||
pool->clearVolatileAPRPool() ;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
apr_file_close(apr_file);
|
||||
apr_file_close(apr_file) ;
|
||||
pool->clearVolatileAPRPool() ;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
S32 ll_apr_file_size(const std::string& filename, apr_pool_t* pool)
|
||||
//static
|
||||
S32 LLAPRFile::size(const std::string& filename, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_file_t* apr_file;
|
||||
apr_finfo_t info;
|
||||
apr_status_t s;
|
||||
if (pool == NULL) pool = gAPRPoolp;
|
||||
s = apr_file_open(&apr_file, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool);
|
||||
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
s = apr_file_open(&apr_file, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool->getVolatileAPRPool());
|
||||
|
||||
if (s != APR_SUCCESS || !apr_file)
|
||||
{
|
||||
{
|
||||
pool->clearVolatileAPRPool() ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file);
|
||||
apr_file_close(apr_file);
|
||||
apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file);
|
||||
|
||||
apr_file_close(apr_file) ;
|
||||
pool->clearVolatileAPRPool() ;
|
||||
|
||||
if (s == APR_SUCCESS)
|
||||
{
|
||||
return (S32)info.size;
|
||||
|
|
@ -381,31 +646,42 @@ S32 ll_apr_file_size(const std::string& filename, apr_pool_t* pool)
|
|||
}
|
||||
}
|
||||
|
||||
bool ll_apr_dir_make(const std::string& dirname, apr_pool_t* pool)
|
||||
//static
|
||||
bool LLAPRFile::makeDir(const std::string& dirname, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_status_t s;
|
||||
if (pool == NULL) pool = gAPRPoolp;
|
||||
s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool);
|
||||
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool->getVolatileAPRPool());
|
||||
pool->clearVolatileAPRPool() ;
|
||||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
LL_DEBUGS("APR") << "ll_apr_dir_make failed on file: " << dirname << LL_ENDL;
|
||||
LL_DEBUGS("APR") << "LLAPRFile::makeDir failed on file: " << dirname << LL_ENDL;
|
||||
ll_apr_warn_status(s);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ll_apr_dir_remove(const std::string& dirname, apr_pool_t* pool)
|
||||
//static
|
||||
bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_status_t s;
|
||||
if (pool == NULL) pool = gAPRPoolp;
|
||||
s = apr_file_remove(dirname.c_str(), pool);
|
||||
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
s = apr_file_remove(dirname.c_str(), pool->getVolatileAPRPool());
|
||||
pool->clearVolatileAPRPool() ;
|
||||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
LL_DEBUGS("APR") << "ll_apr_dir_remove failed on file: " << dirname << LL_ENDL;
|
||||
LL_DEBUGS("APR") << "LLAPRFile::removeDir failed on file: " << dirname << LL_ENDL;
|
||||
ll_apr_warn_status(s);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
//end of static components of LLAPRFile
|
||||
//*******************************************************************************************************************************
|
||||
//
|
||||
|
|
|
|||
|
|
@ -61,18 +61,51 @@ void ll_init_apr();
|
|||
*/
|
||||
void ll_cleanup_apr();
|
||||
|
||||
//
|
||||
//LL apr_pool
|
||||
//manage apr_pool_t, destroy allocated apr_pool in the destruction function.
|
||||
//
|
||||
class LLAPRPool
|
||||
{
|
||||
public:
|
||||
LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0) ;
|
||||
LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ;
|
||||
~LLAPRPool() ;
|
||||
|
||||
apr_pool_t* getAPRPool() {return mPool ; }
|
||||
apr_pool_t* getAPRPool() ;
|
||||
apr_status_t getStatus() {return mStatus ; }
|
||||
|
||||
protected:
|
||||
void releaseAPRPool() ;
|
||||
void createAPRPool() ;
|
||||
|
||||
protected:
|
||||
apr_pool_t* mPool ; //pointing to an apr_pool
|
||||
apr_pool_t* mParent ; //parent pool
|
||||
apr_size_t mMaxSize ; //max size of mPool, mPool should return memory to system if allocated memory beyond this limit. However it seems not to work.
|
||||
apr_status_t mStatus ; //status when creating the pool
|
||||
BOOL mReleasePoolFlag ; //if set, mPool is destroyed when LLAPRPool is deleted. default value is true.
|
||||
};
|
||||
|
||||
//
|
||||
//volatile LL apr_pool
|
||||
//which clears memory automatically.
|
||||
//so it can not hold static data or data after memory is cleared
|
||||
//
|
||||
class LLVolatileAPRPool : public LLAPRPool
|
||||
{
|
||||
public:
|
||||
LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE);
|
||||
~LLVolatileAPRPool(){}
|
||||
|
||||
apr_pool_t* getVolatileAPRPool() ;
|
||||
|
||||
void clearVolatileAPRPool() ;
|
||||
|
||||
BOOL isFull() ;
|
||||
BOOL isEmpty() {return !mNumActiveRef ;}
|
||||
private:
|
||||
apr_pool_t* mPool ;
|
||||
apr_status_t mStatus ;
|
||||
S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool.
|
||||
S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating.
|
||||
} ;
|
||||
|
||||
/**
|
||||
|
|
@ -145,24 +178,71 @@ typedef LLAtomic32<S32> LLAtomicS32;
|
|||
#define LL_APR_WB (APR_CREATE|APR_TRUNCATE|APR_WRITE|APR_BINARY) // "wb"
|
||||
#define LL_APR_RPB (APR_READ|APR_WRITE|APR_BINARY) // "r+b"
|
||||
#define LL_APR_WPB (APR_CREATE|APR_TRUNCATE|APR_READ|APR_WRITE|APR_BINARY) // "w+b"
|
||||
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, S32* sizep, apr_pool_t* pool);
|
||||
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, S32* sizep);
|
||||
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool);
|
||||
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags);
|
||||
// Returns actual offset, -1 if seek fails
|
||||
S32 ll_apr_file_seek(apr_file_t* apr_file, apr_seek_where_t where, S32 offset);
|
||||
// Returns bytes read/written, 0 if read/write fails:
|
||||
S32 ll_apr_file_read(apr_file_t* apr_file, void* buf, S32 nbytes);
|
||||
S32 ll_apr_file_read_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes);
|
||||
S32 ll_apr_file_write(apr_file_t* apr_file, const void* buf, S32 nbytes);
|
||||
S32 ll_apr_file_write_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes);
|
||||
// returns false if failure:
|
||||
bool ll_apr_file_remove(const std::string& filename, apr_pool_t* pool = NULL);
|
||||
bool ll_apr_file_rename(const std::string& filename, const std::string& newname, apr_pool_t* pool = NULL);
|
||||
bool ll_apr_file_exists(const std::string& filename, apr_pool_t* pool = NULL);
|
||||
S32 ll_apr_file_size(const std::string& filename, apr_pool_t* pool = NULL);
|
||||
bool ll_apr_dir_make(const std::string& dirname, apr_pool_t* pool = NULL);
|
||||
bool ll_apr_dir_remove(const std::string& dirname, apr_pool_t* pool = NULL);
|
||||
|
||||
//
|
||||
//apr_file manager
|
||||
//which: 1)only keeps one file open;
|
||||
// 2)closes the open file in the destruction function
|
||||
// 3)informs the apr_pool to clean the memory when the file is closed.
|
||||
//Note: please close an open file at the earliest convenience.
|
||||
// especially do not put some time-costly operations between open() and close().
|
||||
// otherwise it might lock the APRFilePool.
|
||||
//there are two different apr_pools the APRFile can use:
|
||||
// 1, a temperary pool passed to an APRFile function, which is used within this function and only once.
|
||||
// 2, a global pool.
|
||||
//
|
||||
class LLAPRFile
|
||||
{
|
||||
private:
|
||||
apr_file_t* mFile ;
|
||||
LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool.
|
||||
|
||||
public:
|
||||
LLAPRFile() ;
|
||||
~LLAPRFile() ;
|
||||
|
||||
apr_status_t open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep = NULL);
|
||||
apr_status_t open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool = NULL, S32* sizep = NULL);
|
||||
apr_status_t close() ;
|
||||
|
||||
// Returns actual offset, -1 if seek fails
|
||||
S32 seek(apr_seek_where_t where, S32 offset);
|
||||
apr_status_t eof() { return apr_file_eof(mFile);}
|
||||
|
||||
// Returns bytes read/written, 0 if read/write fails:
|
||||
S32 read(void* buf, S32 nbytes);
|
||||
S32 write(const void* buf, S32 nbytes);
|
||||
|
||||
apr_file_t* getFileHandle() {return mFile;}
|
||||
|
||||
private:
|
||||
apr_pool_t* getAPRFilePool(apr_pool_t* pool) ;
|
||||
|
||||
//
|
||||
//*******************************************************************************************************************************
|
||||
//static components
|
||||
//
|
||||
public:
|
||||
static LLVolatileAPRPool *sAPRFilePoolp ; //a global apr_pool for APRFile, which is used only when local pool does not exist.
|
||||
|
||||
private:
|
||||
static apr_file_t* open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags);
|
||||
static apr_status_t close(apr_file_t* file, LLVolatileAPRPool* pool) ;
|
||||
static S32 seek(apr_file_t* file, apr_seek_where_t where, S32 offset);
|
||||
public:
|
||||
// returns false if failure:
|
||||
static bool remove(const std::string& filename, LLVolatileAPRPool* pool = NULL);
|
||||
static bool rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool = NULL);
|
||||
static bool isExist(const std::string& filename, LLVolatileAPRPool* pool = NULL, apr_int32_t flags = APR_READ);
|
||||
static S32 size(const std::string& filename, LLVolatileAPRPool* pool = NULL);
|
||||
static bool makeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL);
|
||||
static bool removeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL);
|
||||
|
||||
// Returns bytes read/written, 0 if read/write fails:
|
||||
static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL);
|
||||
static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL);
|
||||
//*******************************************************************************************************************************
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Function which approprately logs error or remains quiet on
|
||||
|
|
|
|||
|
|
@ -197,6 +197,10 @@ void LLCRC::update(const std::string& filename)
|
|||
update(data, nread);
|
||||
delete[] data;
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -990,6 +990,38 @@ namespace LLError
|
|||
|
||||
return new std::ostringstream;
|
||||
}
|
||||
|
||||
void Log::flush(std::ostringstream* out, char* message)
|
||||
{
|
||||
LogLock lock;
|
||||
if (!lock.ok())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen(out->str().c_str()) < 128)
|
||||
{
|
||||
strcpy(message, out->str().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(message, out->str().c_str(), 127);
|
||||
message[127] = '\0' ;
|
||||
}
|
||||
|
||||
Globals& g = Globals::get();
|
||||
if (out == &g.messageStream)
|
||||
{
|
||||
g.messageStream.clear();
|
||||
g.messageStream.str("");
|
||||
g.messageStreamInUse = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete out;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
void Log::flush(std::ostringstream* out, const CallSite& site)
|
||||
{
|
||||
|
|
@ -1205,3 +1237,94 @@ namespace LLError
|
|||
}
|
||||
}
|
||||
|
||||
namespace LLError
|
||||
{
|
||||
char** LLCallStacks::sBuffer = NULL ;
|
||||
S32 LLCallStacks::sIndex = 0 ;
|
||||
|
||||
//static
|
||||
void LLCallStacks::push(const char* function, const int line)
|
||||
{
|
||||
if(!sBuffer)
|
||||
{
|
||||
sBuffer = new char*[512] ;
|
||||
sBuffer[0] = new char[512 * 128] ;
|
||||
for(S32 i = 1 ; i < 512 ; i++)
|
||||
{
|
||||
sBuffer[i] = sBuffer[i-1] + 128 ;
|
||||
}
|
||||
sIndex = 0 ;
|
||||
}
|
||||
|
||||
if(sIndex > 511)
|
||||
{
|
||||
clear() ;
|
||||
}
|
||||
|
||||
strcpy(sBuffer[sIndex], function) ;
|
||||
sprintf(sBuffer[sIndex] + strlen(function), " line: %d ", line) ;
|
||||
sIndex++ ;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
//static
|
||||
std::ostringstream* LLCallStacks::insert(const char* function, const int line)
|
||||
{
|
||||
std::ostringstream* _out = LLError::Log::out();
|
||||
*_out << function << " line " << line << " " ;
|
||||
|
||||
return _out ;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLCallStacks::end(std::ostringstream* _out)
|
||||
{
|
||||
if(!sBuffer)
|
||||
{
|
||||
sBuffer = new char*[512] ;
|
||||
sBuffer[0] = new char[512 * 128] ;
|
||||
for(S32 i = 1 ; i < 512 ; i++)
|
||||
{
|
||||
sBuffer[i] = sBuffer[i-1] + 128 ;
|
||||
}
|
||||
sIndex = 0 ;
|
||||
}
|
||||
|
||||
if(sIndex > 511)
|
||||
{
|
||||
clear() ;
|
||||
}
|
||||
|
||||
LLError::Log::flush(_out, sBuffer[sIndex++]) ;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLCallStacks::print()
|
||||
{
|
||||
if(sIndex > 0)
|
||||
{
|
||||
llinfos << " ************* PRINT OUT LL CALL STACKS ************* " << llendl ;
|
||||
while(sIndex > 0)
|
||||
{
|
||||
sIndex-- ;
|
||||
llinfos << sBuffer[sIndex] << llendl ;
|
||||
}
|
||||
llinfos << " *************** END OF LL CALL STACKS *************** " << llendl ;
|
||||
}
|
||||
|
||||
if(sBuffer)
|
||||
{
|
||||
delete[] sBuffer[0] ;
|
||||
delete[] sBuffer ;
|
||||
sBuffer = NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLCallStacks::clear()
|
||||
{
|
||||
sIndex = 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include <typeinfo>
|
||||
|
||||
#include "llerrorlegacy.h"
|
||||
#include "stdtypes.h"
|
||||
|
||||
|
||||
/* Error Logging Facility
|
||||
|
|
@ -135,6 +136,7 @@ namespace LLError
|
|||
public:
|
||||
static bool shouldLog(CallSite&);
|
||||
static std::ostringstream* out();
|
||||
static void flush(std::ostringstream* out, char* message) ;
|
||||
static void flush(std::ostringstream*, const CallSite&);
|
||||
};
|
||||
|
||||
|
|
@ -179,9 +181,41 @@ namespace LLError
|
|||
|
||||
class NoClassInfo { };
|
||||
// used to indicate no class info known for logging
|
||||
|
||||
//LLCallStacks keeps track of call stacks and output the call stacks to log file
|
||||
//when LLAppViewer::handleViewerCrash() is triggered.
|
||||
//
|
||||
//Note: to be simple, efficient and necessary to keep track of correct call stacks,
|
||||
//LLCallStacks is designed not to be thread-safe.
|
||||
//so try not to use it in multiple parallel threads at same time.
|
||||
//Used in a single thread at a time is fine.
|
||||
class LLCallStacks
|
||||
{
|
||||
private:
|
||||
static char** sBuffer ;
|
||||
static S32 sIndex ;
|
||||
|
||||
public:
|
||||
static void push(const char* function, const int line) ;
|
||||
static std::ostringstream* insert(const char* function, const int line) ;
|
||||
static void print() ;
|
||||
static void clear() ;
|
||||
static void end(std::ostringstream* _out) ;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//this is cheaper than llcallstacks if no need to output other variables to call stacks.
|
||||
#define llpushcallstacks LLError::LLCallStacks::push(__FUNCTION__, __LINE__)
|
||||
#define llcallstacks \
|
||||
{\
|
||||
std::ostringstream* _out = LLError::LLCallStacks::insert(__FUNCTION__, __LINE__) ; \
|
||||
(*_out)
|
||||
#define llcallstacksendl \
|
||||
LLError::End(); \
|
||||
LLError::LLCallStacks::end(_out) ; \
|
||||
}
|
||||
#define llclearcallstacks LLError::LLCallStacks::clear()
|
||||
#define llprintcallstacks LLError::LLCallStacks::print()
|
||||
|
||||
/*
|
||||
Class type information for logging
|
||||
|
|
|
|||
|
|
@ -71,6 +71,14 @@ public:
|
|||
FTM_UPDATE_AVATAR,
|
||||
|
||||
// common render components
|
||||
FTM_SHADOW_GEOMETRY,
|
||||
FTM_SHADOW_RENDER,
|
||||
FTM_SHADOW_TERRAIN,
|
||||
FTM_SHADOW_AVATAR,
|
||||
FTM_SHADOW_SIMPLE,
|
||||
FTM_SHADOW_ALPHA,
|
||||
FTM_SHADOW_TREE,
|
||||
|
||||
FTM_RENDER_GEOMETRY,
|
||||
FTM_RENDER_TERRAIN,
|
||||
FTM_RENDER_SIMPLE,
|
||||
|
|
@ -186,11 +194,13 @@ public:
|
|||
enum { FTM_MAX_DEPTH = 64 };
|
||||
|
||||
public:
|
||||
static LLFastTimer::EFastTimerType sCurType;
|
||||
|
||||
LLFastTimer(EFastTimerType type)
|
||||
{
|
||||
#if FAST_TIMER_ON
|
||||
mType = type;
|
||||
|
||||
sCurType = type;
|
||||
// These don't get counted, because they use CPU clockticks
|
||||
//gTimerBins[gCurTimerBin]++;
|
||||
//LLTimer::sNumTimerCalls++;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "llfixedbuffer.h"
|
||||
|
||||
LLFixedBuffer::LLFixedBuffer(const U32 max_lines)
|
||||
: mMutex(NULL)
|
||||
{
|
||||
mMaxLines = max_lines;
|
||||
mTimer.reset();
|
||||
|
|
@ -47,9 +48,11 @@ LLFixedBuffer::~LLFixedBuffer()
|
|||
|
||||
void LLFixedBuffer::clear()
|
||||
{
|
||||
mMutex.lock() ;
|
||||
mLines.clear();
|
||||
mAddTimes.clear();
|
||||
mLineLengths.clear();
|
||||
mMutex.unlock() ;
|
||||
|
||||
mTimer.reset();
|
||||
}
|
||||
|
|
@ -70,9 +73,11 @@ void LLFixedBuffer::addLine(const LLWString& line)
|
|||
|
||||
removeExtraLines();
|
||||
|
||||
mMutex.lock() ;
|
||||
mLines.push_back(line);
|
||||
mLineLengths.push_back((S32)line.length());
|
||||
mAddTimes.push_back(mTimer.getElapsedTimeF32());
|
||||
mMutex.unlock() ;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -86,10 +91,12 @@ void LLFixedBuffer::setMaxLines(S32 max_lines)
|
|||
|
||||
void LLFixedBuffer::removeExtraLines()
|
||||
{
|
||||
mMutex.lock() ;
|
||||
while ((S32)mLines.size() > llmax((S32)0, (S32)(mMaxLines - 1)))
|
||||
{
|
||||
mLines.pop_front();
|
||||
mAddTimes.pop_front();
|
||||
mLineLengths.pop_front();
|
||||
}
|
||||
mMutex.unlock() ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include <deque>
|
||||
#include <string>
|
||||
#include "llstring.h"
|
||||
#include "llthread.h"
|
||||
|
||||
// Fixed size buffer for console output and other things.
|
||||
|
||||
|
|
@ -53,14 +54,19 @@ public:
|
|||
std::deque<S32> mLineLengths;
|
||||
|
||||
void clear(); // Clear the buffer, and reset it.
|
||||
virtual void addLine(const std::string& utf8line);
|
||||
virtual void addLine(const LLWString& line);
|
||||
|
||||
//do not make these two "virtual"
|
||||
void addLine(const std::string& utf8line);
|
||||
void addLine(const LLWString& line);
|
||||
|
||||
// Get lines currently in the buffer, up to max_size chars, max_length lines
|
||||
char *getLines(U32 max_size = 0, U32 max_length = 0);
|
||||
void setMaxLines(S32 max_lines);
|
||||
protected:
|
||||
virtual void removeExtraLines();
|
||||
|
||||
protected:
|
||||
LLMutex mMutex ;
|
||||
};
|
||||
|
||||
const U32 FIXED_BUF_MAX_LINE_LEN = 255; // Not including termnating 0
|
||||
|
|
|
|||
|
|
@ -102,12 +102,20 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
|
|||
apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
|
||||
}
|
||||
mRunCondition = new LLCondition(mAPRPoolp);
|
||||
|
||||
mLocalAPRFilePoolp = NULL ;
|
||||
}
|
||||
|
||||
|
||||
LLThread::~LLThread()
|
||||
{
|
||||
shutdown();
|
||||
|
||||
if(mLocalAPRFilePoolp)
|
||||
{
|
||||
delete mLocalAPRFilePoolp ;
|
||||
mLocalAPRFilePoolp = NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
void LLThread::shutdown()
|
||||
|
|
|
|||
|
|
@ -83,7 +83,8 @@ public:
|
|||
void start(void);
|
||||
|
||||
apr_pool_t *getAPRPool() { return mAPRPoolp; }
|
||||
|
||||
LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; }
|
||||
|
||||
private:
|
||||
BOOL mPaused;
|
||||
|
||||
|
|
@ -99,6 +100,11 @@ protected:
|
|||
BOOL mIsLocalPool;
|
||||
EThreadStatus mStatus;
|
||||
|
||||
//a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.
|
||||
//Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.
|
||||
// otherwise it will cause severe memory leaking!!! --bao
|
||||
LLVolatileAPRPool *mLocalAPRFilePoolp ;
|
||||
|
||||
void setQuitting();
|
||||
|
||||
// virtual function overridden by subclass -- this will be called when the thread runs
|
||||
|
|
|
|||
|
|
@ -37,16 +37,18 @@
|
|||
#include "llframecallbackmanager.h"
|
||||
#endif
|
||||
|
||||
BOOL LLWorkerClass::sDeleteLock = FALSE ;
|
||||
//============================================================================
|
||||
// Run on MAIN thread
|
||||
|
||||
LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) :
|
||||
LLQueuedThread(name, threaded),
|
||||
mWorkerAPRPoolp(NULL)
|
||||
LLQueuedThread(name, threaded)
|
||||
{
|
||||
apr_pool_create(&mWorkerAPRPoolp, NULL);
|
||||
mDeleteMutex = new LLMutex(getAPRPool());
|
||||
mDeleteMutex = new LLMutex(NULL);
|
||||
|
||||
if(!mLocalAPRFilePoolp)
|
||||
{
|
||||
mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
|
||||
}
|
||||
}
|
||||
|
||||
LLWorkerThread::~LLWorkerThread()
|
||||
|
|
@ -96,7 +98,6 @@ S32 LLWorkerThread::update(U32 max_time_ms)
|
|||
{
|
||||
(*iter)->abortWork(false);
|
||||
}
|
||||
LLWorkerClass::sDeleteLock = TRUE ;
|
||||
for (std::vector<LLWorkerClass*>::iterator iter = delete_list.begin();
|
||||
iter != delete_list.end(); ++iter)
|
||||
{
|
||||
|
|
@ -110,8 +111,7 @@ S32 LLWorkerThread::update(U32 max_time_ms)
|
|||
}
|
||||
delete *iter;
|
||||
}
|
||||
LLWorkerClass::sDeleteLock = FALSE ;
|
||||
// delete and aborted entries mean there's still work to do
|
||||
// delete and aborted entries mean there's still work to do
|
||||
res += delete_list.size() + abort_list.size();
|
||||
return res;
|
||||
}
|
||||
|
|
@ -188,7 +188,7 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na
|
|||
: mWorkerThread(workerthread),
|
||||
mWorkerClassName(name),
|
||||
mRequestHandle(LLWorkerThread::nullHandle()),
|
||||
mMutex(workerthread->getWorkerAPRPool()),
|
||||
mMutex(NULL),
|
||||
mWorkFlags(0)
|
||||
{
|
||||
if (!mWorkerThread)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include <set>
|
||||
|
||||
#include "llqueuedthread.h"
|
||||
#include "llapr.h"
|
||||
|
||||
#define USE_FRAME_CALLBACK_MANAGER 0
|
||||
|
||||
|
|
@ -82,14 +83,11 @@ private:
|
|||
typedef std::list<LLWorkerClass*> delete_list_t;
|
||||
delete_list_t mDeleteList;
|
||||
LLMutex* mDeleteMutex;
|
||||
apr_pool_t* mWorkerAPRPoolp;
|
||||
|
||||
public:
|
||||
LLWorkerThread(const std::string& name, bool threaded = true);
|
||||
~LLWorkerThread();
|
||||
|
||||
apr_pool_t* getWorkerAPRPool() { return mWorkerAPRPoolp; }
|
||||
|
||||
/*virtual*/ S32 update(U32 max_time_ms);
|
||||
|
||||
handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL);
|
||||
|
|
@ -120,8 +118,6 @@ class LLWorkerClass
|
|||
friend class LLWorkerThread;
|
||||
friend class LLWorkerThread::WorkRequest;
|
||||
|
||||
public:
|
||||
static BOOL sDeleteLock ;
|
||||
public:
|
||||
typedef LLWorkerThread::handle_t handle_t;
|
||||
enum FLAGS
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ bool LLCrashLogger::init()
|
|||
if( gDirUtilp )
|
||||
{
|
||||
std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker");
|
||||
ll_apr_file_remove( marker_file );
|
||||
LLAPRFile::remove( marker_file );
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1513,7 +1513,9 @@ BOOL LLImageFormatted::load(const std::string &filename)
|
|||
resetLastError();
|
||||
|
||||
S32 file_size = 0;
|
||||
apr_file_t* apr_file = ll_apr_file_open(filename, LL_APR_RB, &file_size);
|
||||
LLAPRFile infile ;
|
||||
infile.open(filename, LL_APR_RB, NULL, &file_size);
|
||||
apr_file_t* apr_file = infile.getFileHandle();
|
||||
if (!apr_file)
|
||||
{
|
||||
setLastError("Unable to open file for reading", filename);
|
||||
|
|
@ -1522,7 +1524,6 @@ BOOL LLImageFormatted::load(const std::string &filename)
|
|||
if (file_size == 0)
|
||||
{
|
||||
setLastError("File is empty",filename);
|
||||
apr_file_close(apr_file);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -1540,8 +1541,7 @@ BOOL LLImageFormatted::load(const std::string &filename)
|
|||
{
|
||||
res = updateData();
|
||||
}
|
||||
apr_file_close(apr_file);
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1549,16 +1549,16 @@ BOOL LLImageFormatted::save(const std::string &filename)
|
|||
{
|
||||
resetLastError();
|
||||
|
||||
apr_file_t* apr_file = ll_apr_file_open(filename, LL_APR_WB);
|
||||
if (!apr_file)
|
||||
LLAPRFile outfile ;
|
||||
outfile.open(filename, LL_APR_WB);
|
||||
if (!outfile.getFileHandle())
|
||||
{
|
||||
setLastError("Unable to open file for writing", filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ll_apr_file_write(apr_file, getData(), getDataSize());
|
||||
apr_file_close(apr_file);
|
||||
|
||||
outfile.write(getData(), getDataSize());
|
||||
outfile.close() ;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -419,7 +419,9 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
|
|||
resetLastError();
|
||||
|
||||
S32 file_size = 0;
|
||||
apr_file_t* apr_file = ll_apr_file_open(filename, LL_APR_RB, &file_size);
|
||||
LLAPRFile infile ;
|
||||
infile.open(filename, LL_APR_RB, NULL, &file_size);
|
||||
apr_file_t* apr_file = infile.getFileHandle() ;
|
||||
if (!apr_file)
|
||||
{
|
||||
setLastError("Unable to open file for reading", filename);
|
||||
|
|
@ -428,7 +430,6 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
|
|||
else if (file_size == 0)
|
||||
{
|
||||
setLastError("File is empty",filename);
|
||||
apr_file_close(apr_file);
|
||||
res = FALSE;
|
||||
}
|
||||
else
|
||||
|
|
@ -436,7 +437,8 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
|
|||
U8 *data = new U8[file_size];
|
||||
apr_size_t bytes_read = file_size;
|
||||
apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read
|
||||
apr_file_close(apr_file);
|
||||
infile.close() ;
|
||||
|
||||
if (s != APR_SUCCESS || (S32)bytes_read != file_size)
|
||||
{
|
||||
delete[] data;
|
||||
|
|
@ -448,7 +450,7 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
|
|||
res = validate(data, file_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!mLastError.empty())
|
||||
{
|
||||
LLImage::setLastError(mLastError);
|
||||
|
|
|
|||
|
|
@ -178,28 +178,95 @@ S32 LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius)
|
|||
U8 mask = 0;
|
||||
S32 result = 2;
|
||||
|
||||
for (U32 i = 0; i < mPlaneCount; i++)
|
||||
{
|
||||
mask = mAgentPlanes[i].mask;
|
||||
LLPlane p = mAgentPlanes[i].p;
|
||||
LLVector3 n = LLVector3(p);
|
||||
float d = p.mV[3];
|
||||
LLVector3 rscale = radius.scaledVec(scaler[mask]);
|
||||
if (radius.magVecSquared() > mFrustumCornerDist * mFrustumCornerDist)
|
||||
{ //box is larger than frustum, check frustum quads against box planes
|
||||
|
||||
LLVector3 minp = center - rscale;
|
||||
LLVector3 maxp = center + rscale;
|
||||
|
||||
if (n * minp > -d)
|
||||
static const LLVector3 dir[] =
|
||||
{
|
||||
return 0;
|
||||
LLVector3(1, 0, 0),
|
||||
LLVector3(-1, 0, 0),
|
||||
LLVector3(0, 1, 0),
|
||||
LLVector3(0, -1, 0),
|
||||
LLVector3(0, 0, 1),
|
||||
LLVector3(0, 0, -1)
|
||||
};
|
||||
|
||||
U32 quads[] =
|
||||
{
|
||||
0, 1, 2, 3,
|
||||
0, 1, 5, 4,
|
||||
2, 3, 7, 6,
|
||||
3, 0, 7, 4,
|
||||
1, 2, 6, 4,
|
||||
4, 5, 6, 7
|
||||
};
|
||||
|
||||
result = 0;
|
||||
|
||||
BOOL total_inside = TRUE;
|
||||
for (U32 i = 0; i < 6; i++)
|
||||
{
|
||||
LLVector3 p = center + radius.scaledVec(dir[i]);
|
||||
F32 d = -p*dir[i];
|
||||
|
||||
for (U32 j = 0; j < 6; j++)
|
||||
{ //for each quad
|
||||
F32 dist = mAgentFrustum[quads[j*4+0]]*dir[i] + d;
|
||||
if (dist > 0)
|
||||
{ //at least one frustum point is outside the AABB
|
||||
total_inside = FALSE;
|
||||
for (U32 k = 1; k < 4; k++)
|
||||
{ //for each other point on quad
|
||||
if ( mAgentFrustum[quads[j*4+k]]*dir[i]+d <= 0.f)
|
||||
{ //quad is straddling some plane of AABB
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (U32 k = 1; k < 4; k++)
|
||||
{
|
||||
if (mAgentFrustum[quads[j*4+k]]*dir[i]+d > 0.f)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (n * maxp > -d)
|
||||
|
||||
if (total_inside)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (U32 i = 0; i < mPlaneCount; i++)
|
||||
{
|
||||
mask = mAgentPlanes[i].mask;
|
||||
LLPlane p = mAgentPlanes[i].p;
|
||||
LLVector3 n = LLVector3(p);
|
||||
float d = p.mV[3];
|
||||
LLVector3 rscale = radius.scaledVec(scaler[mask]);
|
||||
|
||||
LLVector3 minp = center - rscale;
|
||||
LLVector3 maxp = center + rscale;
|
||||
|
||||
if (n * minp > -d)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (n * maxp > -d)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ const F32 GRAVITY = -9.8f;
|
|||
const F32 F_PI = 3.1415926535897932384626433832795f;
|
||||
const F32 F_TWO_PI = 6.283185307179586476925286766559f;
|
||||
const F32 F_PI_BY_TWO = 1.5707963267948966192313216916398f;
|
||||
const F32 F_SQRT_TWO_PI = 2.506628274631000502415765284811f;
|
||||
const F32 F_E = 2.71828182845904523536f;
|
||||
const F32 F_SQRT2 = 1.4142135623730950488016887242097f;
|
||||
const F32 F_SQRT3 = 1.73205080756888288657986402541f;
|
||||
const F32 OO_SQRT2 = 0.7071067811865475244008443621049f;
|
||||
|
|
@ -548,4 +550,10 @@ inline U32 get_next_power_two(U32 val, U32 max_power_two)
|
|||
return val;
|
||||
}
|
||||
|
||||
//get the gaussian value given the linear distance from axis x and guassian value o
|
||||
inline F32 llgaussian(F32 x, F32 o)
|
||||
{
|
||||
return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2*o*o));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -470,9 +470,7 @@ bool LLAres::process(U64 timeout)
|
|||
|
||||
int socks[ARES_GETSOCK_MAXNUM];
|
||||
apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM];
|
||||
apr_int32_t nsds = 0;
|
||||
apr_status_t status;
|
||||
apr_pool_t *pool;
|
||||
apr_int32_t nsds = 0;
|
||||
int nactive = 0;
|
||||
int bitmask;
|
||||
|
||||
|
|
@ -480,10 +478,12 @@ bool LLAres::process(U64 timeout)
|
|||
|
||||
if (bitmask == 0)
|
||||
{
|
||||
goto bail;
|
||||
return nsds > 0;
|
||||
}
|
||||
|
||||
status = apr_pool_create(&pool, gAPRPoolp);
|
||||
apr_status_t status;
|
||||
LLAPRPool pool;
|
||||
status = pool.getStatus() ;
|
||||
ll_apr_assert_status(status);
|
||||
|
||||
for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++)
|
||||
|
|
@ -501,16 +501,16 @@ bool LLAres::process(U64 timeout)
|
|||
|
||||
apr_socket_t *aprSock = NULL;
|
||||
|
||||
status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool);
|
||||
status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool());
|
||||
if (status != APR_SUCCESS)
|
||||
{
|
||||
ll_apr_warn_status(status);
|
||||
goto bail_pool;
|
||||
return nsds > 0;
|
||||
}
|
||||
|
||||
aprFds[nactive].desc.s = aprSock;
|
||||
aprFds[nactive].desc_type = APR_POLL_SOCKET;
|
||||
aprFds[nactive].p = pool;
|
||||
aprFds[nactive].p = pool.getAPRPool();
|
||||
aprFds[nactive].rtnevents = 0;
|
||||
aprFds[nactive].client_data = &socks[i];
|
||||
|
||||
|
|
@ -538,10 +538,6 @@ bool LLAres::process(U64 timeout)
|
|||
}
|
||||
}
|
||||
|
||||
bail_pool:
|
||||
apr_pool_destroy(pool);
|
||||
|
||||
bail:
|
||||
return nsds > 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
#include "llsd.h"
|
||||
#include "llstring.h"
|
||||
#include "apr_env.h"
|
||||
|
||||
#include "llapr.h"
|
||||
static const U32 HTTP_STATUS_PIPE_ERROR = 499;
|
||||
|
||||
/**
|
||||
|
|
@ -166,18 +166,16 @@ void LLURLRequest::useProxy(bool use_proxy)
|
|||
if (use_proxy && (env_proxy == NULL))
|
||||
{
|
||||
apr_status_t status;
|
||||
apr_pool_t* pool;
|
||||
apr_pool_create(&pool, NULL);
|
||||
status = apr_env_get(&env_proxy, "ALL_PROXY", pool);
|
||||
LLAPRPool pool;
|
||||
status = apr_env_get(&env_proxy, "ALL_PROXY", pool.getAPRPool());
|
||||
if (status != APR_SUCCESS)
|
||||
{
|
||||
status = apr_env_get(&env_proxy, "http_proxy", pool);
|
||||
status = apr_env_get(&env_proxy, "http_proxy", pool.getAPRPool());
|
||||
}
|
||||
if (status != APR_SUCCESS)
|
||||
{
|
||||
use_proxy = FALSE;
|
||||
}
|
||||
apr_pool_destroy(pool);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,9 +27,7 @@ set(llrender_SOURCE_FILES
|
|||
llglslshader.cpp
|
||||
llimagegl.cpp
|
||||
llpostprocess.cpp
|
||||
llrender.cpp
|
||||
llrendersphere.cpp
|
||||
llrendertarget.cpp
|
||||
llshadermgr.cpp
|
||||
llvertexbuffer.cpp
|
||||
)
|
||||
|
|
@ -50,7 +48,6 @@ set(llrender_HEADER_FILES
|
|||
llpostprocess.h
|
||||
llrender.h
|
||||
llrendersphere.h
|
||||
llrendertarget.h
|
||||
llshadermgr.h
|
||||
llvertexbuffer.h
|
||||
)
|
||||
|
|
@ -63,6 +60,7 @@ list(APPEND llrender_SOURCE_FILES ${llrender_HEADER_FILES})
|
|||
if (SERVER AND NOT WINDOWS AND NOT DARWIN)
|
||||
copy_server_sources(
|
||||
llgl
|
||||
llrender
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -78,6 +76,8 @@ if (SERVER AND NOT WINDOWS AND NOT DARWIN)
|
|||
else (SERVER AND NOT WINDOWS AND NOT DARWIN)
|
||||
list(APPEND llrender_SOURCE_FILES
|
||||
llgl.cpp
|
||||
llrender.cpp
|
||||
llrendertarget.cpp
|
||||
)
|
||||
endif (SERVER AND NOT WINDOWS AND NOT DARWIN)
|
||||
add_library (llrender ${llrender_SOURCE_FILES})
|
||||
|
|
|
|||
|
|
@ -85,9 +85,9 @@ void LLCubeMap::initGL()
|
|||
// Not initialized, do stuff.
|
||||
if (mImages[0].isNull())
|
||||
{
|
||||
GLuint texname = 0;
|
||||
U32 texname = 0;
|
||||
|
||||
glGenTextures(1, &texname);
|
||||
LLImageGL::generateTextures(1, &texname);
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
|
|
@ -97,9 +97,10 @@ void LLCubeMap::initGL()
|
|||
mImages[i]->createGLTexture(0, mRawImages[i], texname);
|
||||
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
|
||||
mImages[i]->setClampCubemap (TRUE, TRUE, TRUE);
|
||||
mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
stop_glerror();
|
||||
}
|
||||
gGL.getTexUnit(0)->disable();
|
||||
}
|
||||
disable();
|
||||
}
|
||||
|
|
@ -311,8 +312,8 @@ void LLCubeMap::restoreMatrix()
|
|||
void LLCubeMap::setReflection (void)
|
||||
{
|
||||
gGL.getTexUnit(mTextureStage)->bindManual(LLTexUnit::TT_CUBE_MAP, getGLName());
|
||||
mImages[0]->setMipFilterNearest (FALSE, FALSE);
|
||||
mImages[0]->setClampCubemap (TRUE, TRUE);
|
||||
mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
|
||||
mImages[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
}
|
||||
|
||||
LLVector3 LLCubeMap::map(U8 side, U16 v_val, U16 h_val) const
|
||||
|
|
|
|||
|
|
@ -535,7 +535,7 @@ BOOL LLFontGL::loadFace(const std::string& filename,
|
|||
}
|
||||
mImageGLp->createGLTexture(0, mRawImageGLp);
|
||||
gGL.getTexUnit(0)->bind(mImageGLp);
|
||||
mImageGLp->setMipFilterNearest(TRUE, TRUE);
|
||||
mImageGLp->setFilteringOption(LLTexUnit::TFO_POINT);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -549,7 +549,7 @@ BOOL LLFontGL::addChar(const llwchar wch)
|
|||
stop_glerror();
|
||||
mImageGLp->setSubImage(mRawImageGLp, 0, 0, mImageGLp->getWidth(), mImageGLp->getHeight());
|
||||
gGL.getTexUnit(0)->bind(mImageGLp);
|
||||
mImageGLp->setMipFilterNearest(TRUE, TRUE);
|
||||
mImageGLp->setFilteringOption(LLTexUnit::TFO_POINT);
|
||||
stop_glerror();
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -565,7 +565,7 @@ S32 LLFontGL::renderUTF8(const std::string &text, const S32 offset,
|
|||
BOOL use_ellipses) const
|
||||
{
|
||||
LLWString wstr = utf8str_to_wstring(text);
|
||||
return render(wstr, offset, x, y, color, halign, valign, style, max_chars, max_pixels, right_x, use_ellipses);
|
||||
return render(wstr, offset, x, y, color, halign, valign, style, max_chars, max_pixels, right_x, FALSE, use_ellipses);
|
||||
}
|
||||
|
||||
S32 LLFontGL::render(const LLWString &wstr,
|
||||
|
|
@ -1104,59 +1104,32 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
|
|||
llwchar wch = wchars[i];
|
||||
|
||||
const embedded_data_t* ext_data = getEmbeddedCharData(wch);
|
||||
if (ext_data)
|
||||
F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : getXAdvance(wch);
|
||||
|
||||
if( scaled_max_pixels < (total_width + char_width) )
|
||||
{
|
||||
F32 char_width = getEmbeddedCharAdvance(ext_data);
|
||||
|
||||
if( scaled_max_pixels < (total_width + char_width) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
total_width += char_width;
|
||||
|
||||
drawable_chars++;
|
||||
if( max_chars >= 0 && drawable_chars >= max_chars )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( i > 0 )
|
||||
{
|
||||
total_width += EXT_KERNING * sScaleX;
|
||||
}
|
||||
|
||||
// Round after kerning.
|
||||
total_width = (F32)llfloor(total_width + 0.5f);
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
||||
total_width += char_width;
|
||||
drawable_chars++;
|
||||
|
||||
if( max_chars >= 0 && drawable_chars >= max_chars )
|
||||
{
|
||||
F32 char_width = getXAdvance(wch);
|
||||
if( scaled_max_pixels < (total_width + char_width) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
total_width += char_width;
|
||||
|
||||
drawable_chars++;
|
||||
if( max_chars >= 0 && drawable_chars >= max_chars )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( i > 0 )
|
||||
{
|
||||
// Kerning
|
||||
total_width += getXKerning(wchars[i-1], wch);
|
||||
}
|
||||
|
||||
// Round after kerning.
|
||||
total_width = (F32)llfloor(total_width + 0.5f);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( i > 0 )
|
||||
{
|
||||
// kerning
|
||||
total_width += ext_data ? (EXT_KERNING * sScaleX) : getXKerning(wchars[i-1], wch);
|
||||
}
|
||||
|
||||
// Round after kerning.
|
||||
total_width = llround(total_width);
|
||||
}
|
||||
|
||||
return text_len - drawable_chars;
|
||||
return start_pos - drawable_chars;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ public:
|
|||
F32* drawn_pixels = NULL) const;
|
||||
|
||||
// Returns the index of the first complete characters from text that can be drawn in max_pixels
|
||||
// starting on the right side (at character start_pos).
|
||||
// given that the character at start_pos should be the last character (or as close to last as possible).
|
||||
virtual S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const;
|
||||
|
||||
// Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars)
|
||||
|
|
|
|||
|
|
@ -133,6 +133,15 @@ PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL;
|
|||
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL;
|
||||
PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL;
|
||||
|
||||
// GL_EXT_framebuffer_multisample
|
||||
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT = NULL;
|
||||
|
||||
// GL_EXT_framebuffer_blit
|
||||
PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT = NULL;
|
||||
|
||||
// GL_ARB_draw_buffers
|
||||
PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB = NULL;
|
||||
|
||||
//shader object prototypes
|
||||
PFNGLDELETEOBJECTARBPROC glDeleteObjectARB = NULL;
|
||||
PFNGLGETHANDLEARBPROC glGetHandleARB = NULL;
|
||||
|
|
@ -249,6 +258,12 @@ PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL;
|
|||
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
|
||||
#endif
|
||||
|
||||
#if LL_LINUX_NV_GL_HEADERS
|
||||
// linux nvidia headers. these define these differently to mesa's. ugh.
|
||||
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;
|
||||
PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL;
|
||||
PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements = NULL;
|
||||
#endif // LL_LINUX_NV_GL_HEADERS
|
||||
#endif
|
||||
|
||||
LLGLManager gGLManager;
|
||||
|
|
@ -262,6 +277,7 @@ LLGLManager::LLGLManager() :
|
|||
mHasMipMapGeneration(FALSE),
|
||||
mHasCompressedTextures(FALSE),
|
||||
mHasFramebufferObject(FALSE),
|
||||
mHasFramebufferMultisample(FALSE),
|
||||
|
||||
mHasVertexBufferObject(FALSE),
|
||||
mHasPBuffer(FALSE),
|
||||
|
|
@ -560,6 +576,16 @@ void LLGLManager::initExtensions()
|
|||
mHasFramebufferObject = TRUE;
|
||||
# else
|
||||
mHasFramebufferObject = FALSE;
|
||||
# endif
|
||||
# if GL_EXT_framebuffer_multisample
|
||||
mHasFramebufferMultisample = TRUE;
|
||||
# else
|
||||
mHasFramebufferMultisample = FALSE;
|
||||
# endif
|
||||
# if GL_ARB_draw_buffers
|
||||
mHasDrawBuffers = TRUE;
|
||||
#else
|
||||
mHasDrawBuffers = FALSE;
|
||||
# endif
|
||||
mHasMipMapGeneration = FALSE;
|
||||
mHasSeparateSpecularColor = FALSE;
|
||||
|
|
@ -584,6 +610,8 @@ void LLGLManager::initExtensions()
|
|||
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
|
||||
mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts)
|
||||
&& ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
|
||||
mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts);
|
||||
mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
|
||||
#if !LL_DARWIN
|
||||
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
|
||||
#endif
|
||||
|
|
@ -604,6 +632,8 @@ void LLGLManager::initExtensions()
|
|||
mHasCompressedTextures = FALSE;
|
||||
mHasVertexBufferObject = FALSE;
|
||||
mHasFramebufferObject = FALSE;
|
||||
mHasFramebufferMultisample = FALSE;
|
||||
mHasDrawBuffers = FALSE;
|
||||
mHasMipMapGeneration = FALSE;
|
||||
mHasSeparateSpecularColor = FALSE;
|
||||
mHasAnisotropic = FALSE;
|
||||
|
|
@ -653,6 +683,9 @@ void LLGLManager::initExtensions()
|
|||
if (strchr(blacklist,'o')) mHasFragmentShader = FALSE;//S
|
||||
if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S
|
||||
if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S
|
||||
if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S
|
||||
if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE;
|
||||
|
||||
}
|
||||
#endif // LL_LINUX || LL_SOLARIS
|
||||
|
||||
|
|
@ -761,15 +794,29 @@ void LLGLManager::initExtensions()
|
|||
glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameterivEXT");
|
||||
glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmapEXT");
|
||||
}
|
||||
#if !LL_LINUX && !LL_SOLARIS
|
||||
// This is expected to be a static symbol on Linux GL implementations
|
||||
if (mHasFramebufferMultisample)
|
||||
{
|
||||
glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageMultisampleEXT");
|
||||
glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlitFramebufferEXT");
|
||||
}
|
||||
if (mHasDrawBuffers)
|
||||
{
|
||||
glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDrawBuffersARB");
|
||||
}
|
||||
#if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS
|
||||
// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah
|
||||
glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
|
||||
if (!glDrawRangeElements)
|
||||
{
|
||||
mGLMaxVertexRange = 0;
|
||||
mGLMaxIndexRange = 0;
|
||||
}
|
||||
#endif // !LL_LINUX
|
||||
#endif // !LL_LINUX || LL_LINUX_NV_GL_HEADERS
|
||||
#if LL_LINUX_NV_GL_HEADERS
|
||||
// nvidia headers are critically different from mesa-esque
|
||||
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)GLH_EXT_GET_PROC_ADDRESS("glActiveTextureARB");
|
||||
glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)GLH_EXT_GET_PROC_ADDRESS("glClientActiveTextureARB");
|
||||
#endif // LL_LINUX_NV_GL_HEADERS
|
||||
|
||||
if (mHasOcclusionQuery)
|
||||
{
|
||||
|
|
@ -946,7 +993,7 @@ void assert_glerror()
|
|||
{
|
||||
// gluErrorString returns NULL for some extensions' error codes.
|
||||
// you'll probably have to grep for the number in glext.h.
|
||||
LL_WARNS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << LL_ENDL;
|
||||
LL_WARNS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
|
||||
}
|
||||
error = glGetError();
|
||||
#endif
|
||||
|
|
@ -986,6 +1033,11 @@ void LLGLState::initClass()
|
|||
//make sure multisample defaults to disabled
|
||||
sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
|
||||
glDisable(GL_MULTISAMPLE_ARB);
|
||||
|
||||
sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
|
||||
glDisable(GL_MULTISAMPLE_ARB);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -1037,7 +1089,7 @@ void LLGLState::checkStates(const std::string& msg)
|
|||
|
||||
if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
|
||||
{
|
||||
LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << LL_ENDL;
|
||||
LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL;
|
||||
}
|
||||
|
||||
for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
|
||||
|
|
@ -1076,7 +1128,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
|||
if (tex_env_mode != GL_MODULATE)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << LL_ENDL;
|
||||
LL_WARNS("RenderState") << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << std::dec << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1092,7 +1144,8 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
|||
"GL_TEXTURE_GEN_S",
|
||||
"GL_TEXTURE_GEN_T",
|
||||
"GL_TEXTURE_GEN_Q",
|
||||
"GL_TEXTURE_GEN_R"
|
||||
"GL_TEXTURE_GEN_R",
|
||||
"GL_TEXTURE_RECTANGLE_ARB"
|
||||
};
|
||||
|
||||
static GLint value[] =
|
||||
|
|
@ -1104,7 +1157,8 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
|||
GL_TEXTURE_GEN_S,
|
||||
GL_TEXTURE_GEN_T,
|
||||
GL_TEXTURE_GEN_Q,
|
||||
GL_TEXTURE_GEN_R
|
||||
GL_TEXTURE_GEN_R,
|
||||
GL_TEXTURE_RECTANGLE_ARB
|
||||
};
|
||||
|
||||
GLint stackDepth = 0;
|
||||
|
|
@ -1132,7 +1186,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
|||
LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL;
|
||||
}
|
||||
|
||||
for (S32 j = (i == 0 ? 1 : 0); j < 8; j++)
|
||||
for (S32 j = (i == 0 ? 1 : 0); j < 9; j++)
|
||||
{
|
||||
if (glIsEnabled(value[j]))
|
||||
{
|
||||
|
|
@ -1140,6 +1194,18 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
|||
LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
glh::matrix4f mat;
|
||||
glh::matrix4f identity;
|
||||
identity.identity();
|
||||
|
||||
glGetFloatv(GL_TEXTURE_MATRIX, mat.m);
|
||||
|
||||
if (mat != identity)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->activate();
|
||||
|
|
@ -1261,6 +1327,22 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
|||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
gGL.getTexUnit(0)->activate();
|
||||
|
||||
if (gGLManager.mHasVertexShader)
|
||||
{ //make sure vertex attribs are all disabled
|
||||
GLint count;
|
||||
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &count);
|
||||
for (GLint i = 0; i < count; i++)
|
||||
{
|
||||
GLint enabled;
|
||||
glGetVertexAttribivARB((GLuint) i, GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB, &enabled);
|
||||
if (enabled)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL still has vertex attrib array " << i << " enabled." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
LL_GL_ERRS << "GL client array corruption detected. " << msg << LL_ENDL;
|
||||
|
|
@ -1646,6 +1728,7 @@ void LLGLNamePool::cleanupPools()
|
|||
LLGLDepthTest::LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled, GLenum depth_func)
|
||||
: mPrevDepthEnabled(sDepthEnabled), mPrevDepthFunc(sDepthFunc), mPrevWriteEnabled(sWriteEnabled)
|
||||
{
|
||||
stop_glerror();
|
||||
if (depth_enabled != sDepthEnabled)
|
||||
{
|
||||
gGL.flush();
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@ public:
|
|||
BOOL mHasMipMapGeneration;
|
||||
BOOL mHasCompressedTextures;
|
||||
BOOL mHasFramebufferObject;
|
||||
|
||||
BOOL mHasFramebufferMultisample;
|
||||
|
||||
// ARB Extensions
|
||||
BOOL mHasVertexBufferObject;
|
||||
BOOL mHasPBuffer;
|
||||
|
|
@ -86,6 +87,7 @@ public:
|
|||
BOOL mHasFragmentShader;
|
||||
BOOL mHasOcclusionQuery;
|
||||
BOOL mHasPointParameters;
|
||||
BOOL mHasDrawBuffers;
|
||||
|
||||
// Other extensions.
|
||||
BOOL mHasAnisotropic;
|
||||
|
|
|
|||
|
|
@ -281,6 +281,18 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
|
|||
#undef Status
|
||||
#endif // LL_LINUX && !LL_MESA_HEADLESS
|
||||
|
||||
#if LL_LINUX && defined(WINGDIAPI)
|
||||
// WINGDIAPI gets set if we are using the linux nvidia gl.h header which needs
|
||||
// the functions below setting up.
|
||||
# define LL_LINUX_NV_GL_HEADERS
|
||||
#endif // LL_LINUX && defined(WINGDIAPI)
|
||||
|
||||
#ifdef LL_LINUX_NV_GL_HEADERS
|
||||
// Missing functions when using nvidia headers:
|
||||
extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
|
||||
extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;
|
||||
extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements;
|
||||
#endif // LL_LINUX_NV_GL_HEADERS
|
||||
|
||||
// GL_ARB_vertex_buffer_object
|
||||
extern PFNGLBINDBUFFERARBPROC glBindBufferARB;
|
||||
|
|
@ -435,8 +447,6 @@ extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;
|
|||
extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
|
||||
extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB;
|
||||
|
||||
extern PFNGLCOLORTABLEEXTPROC glColorTableEXT;
|
||||
|
||||
//GL_EXT_framebuffer_object
|
||||
extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
|
||||
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
|
||||
|
|
@ -456,6 +466,14 @@ extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
|
|||
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
|
||||
extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
|
||||
|
||||
// GL_EXT_framebuffer_multisample
|
||||
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
|
||||
|
||||
// GL_EXT_framebuffer_blit
|
||||
extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
|
||||
|
||||
//GL_ARB_draw_buffers
|
||||
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
|
||||
|
||||
#elif LL_WINDOWS
|
||||
|
||||
|
|
@ -644,6 +662,14 @@ extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
|
|||
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
|
||||
extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
|
||||
|
||||
// GL_EXT_framebuffer_multisample
|
||||
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
|
||||
|
||||
// GL_EXT_framebuffer_blit
|
||||
extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
|
||||
|
||||
//GL_ARB_draw_buffers
|
||||
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
|
||||
|
||||
#elif LL_DARWIN
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
@ -680,6 +706,8 @@ extern void glFramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenu
|
|||
extern void glGetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, GLenum pname, GLint *params) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
|
||||
extern void glGenerateMipmapEXT(GLenum target) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
|
||||
|
||||
// GL_ARB_draw_buffers
|
||||
extern void glDrawBuffersARB(GLsizei n, const GLenum* bufs) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
|||
|
|
@ -256,6 +256,14 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
|
|||
S32 location = glGetUniformLocationARB(mProgramObject, name);
|
||||
if (location != -1)
|
||||
{
|
||||
//chop off "[0]" so we can always access the first element
|
||||
//of an array by the array name
|
||||
char* is_array = strstr(name, "[0]");
|
||||
if (is_array)
|
||||
{
|
||||
is_array[0] = 0;
|
||||
}
|
||||
|
||||
mUniformMap[name] = location;
|
||||
LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
|
||||
|
||||
|
|
@ -353,11 +361,17 @@ void LLGLSLShader::unbind()
|
|||
{
|
||||
if (gGLManager.mHasShaderObjects)
|
||||
{
|
||||
for (U32 i = 0; i < mAttribute.size(); ++i)
|
||||
stop_glerror();
|
||||
if (gGLManager.mIsNVIDIA)
|
||||
{
|
||||
vertexAttrib4f(i, 0,0,0,1);
|
||||
for (U32 i = 0; i < mAttribute.size(); ++i)
|
||||
{
|
||||
vertexAttrib4f(i, 0,0,0,1);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
glUseProgramObjectARB(0);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -390,14 +404,39 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
|
|||
return -1;
|
||||
}
|
||||
S32 index = mTexture[uniform];
|
||||
if (index != -1)
|
||||
if (index != -1 && gGL.getTexUnit(index)->getCurrType() != LLTexUnit::TT_NONE)
|
||||
{
|
||||
gGL.getTexUnit(index)->activate();
|
||||
if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode)
|
||||
{
|
||||
llerrs << "Texture channel " << index << " texture type corrupted." << llendl;
|
||||
}
|
||||
gGL.getTexUnit(index)->disable();
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform1i(U32 index, GLint x)
|
||||
{
|
||||
if (mProgramObject > 0)
|
||||
{
|
||||
if (mUniform.size() <= index)
|
||||
{
|
||||
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mUniform[index] >= 0)
|
||||
{
|
||||
std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
|
||||
if (iter == mValue.end() || iter->second.mV[0] != x)
|
||||
{
|
||||
glUniform1iARB(mUniform[index], x);
|
||||
mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform1f(U32 index, GLfloat x)
|
||||
{
|
||||
if (mProgramObject > 0)
|
||||
|
|
@ -489,6 +528,29 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
|
||||
{
|
||||
if (mProgramObject > 0)
|
||||
{
|
||||
if (mUniform.size() <= index)
|
||||
{
|
||||
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mUniform[index] >= 0)
|
||||
{
|
||||
std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
|
||||
LLVector4 vec(v[0],0.f,0.f,0.f);
|
||||
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
|
||||
{
|
||||
glUniform1ivARB(mUniform[index], count, v);
|
||||
mValue[mUniform[index]] = vec;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
|
||||
{
|
||||
if (mProgramObject > 0)
|
||||
|
|
@ -647,6 +709,22 @@ GLint LLGLSLShader::getUniformLocation(const string& uniform)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform1i(const string& uniform, GLint v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
if (location >= 0)
|
||||
{
|
||||
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
|
||||
LLVector4 vec(v,0.f,0.f,0.f);
|
||||
if (iter == mValue.end() || shouldChange(iter->second,vec))
|
||||
{
|
||||
glUniform1iARB(location, v);
|
||||
mValue[location] = vec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
|
|
|||
|
|
@ -78,18 +78,22 @@ public:
|
|||
BOOL mapAttributes(const std::vector<std::string> * attributes);
|
||||
BOOL mapUniforms(const std::vector<std::string> * uniforms);
|
||||
void mapUniform(GLint index, const std::vector<std::string> * uniforms);
|
||||
void uniform1i(U32 index, GLint i);
|
||||
void uniform1f(U32 index, GLfloat v);
|
||||
void uniform2f(U32 index, GLfloat x, GLfloat y);
|
||||
void uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z);
|
||||
void uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
void uniform1iv(U32 index, U32 count, const GLint* i);
|
||||
void uniform1fv(U32 index, U32 count, const GLfloat* v);
|
||||
void uniform2fv(U32 index, U32 count, const GLfloat* v);
|
||||
void uniform3fv(U32 index, U32 count, const GLfloat* v);
|
||||
void uniform4fv(U32 index, U32 count, const GLfloat* v);
|
||||
void uniform1i(const std::string& uniform, GLint i);
|
||||
void uniform1f(const std::string& uniform, GLfloat v);
|
||||
void uniform2f(const std::string& uniform, GLfloat x, GLfloat y);
|
||||
void uniform3f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z);
|
||||
void uniform4f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
void uniform1iv(const std::string& uniform, U32 count, const GLint* i);
|
||||
void uniform1fv(const std::string& uniform, U32 count, const GLfloat* v);
|
||||
void uniform2fv(const std::string& uniform, U32 count, const GLfloat* v);
|
||||
void uniform3fv(const std::string& uniform, U32 count, const GLfloat* v);
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
|
|||
F32 LLImageGL::sLastFrameTime = 0.f;
|
||||
|
||||
std::set<LLImageGL*> LLImageGL::sImageList;
|
||||
|
||||
//**************************************************************************************
|
||||
//below are functions for debug use
|
||||
//do not delete them even though they are not currently being used.
|
||||
|
|
@ -309,21 +308,21 @@ void LLImageGL::init(BOOL usemipmaps)
|
|||
#endif
|
||||
|
||||
mPickMask = NULL;
|
||||
mTextureState = NO_DELETE ;
|
||||
mTextureMemory = 0;
|
||||
mLastBindTime = 0.f;
|
||||
|
||||
mTarget = GL_TEXTURE_2D;
|
||||
mBindTarget = LLTexUnit::TT_TEXTURE;
|
||||
mUseMipMaps = usemipmaps;
|
||||
mHasMipMaps = FALSE;
|
||||
mHasMipMaps = false;
|
||||
mAutoGenMips = FALSE;
|
||||
mTexName = 0;
|
||||
mIsResident = 0;
|
||||
mClampS = FALSE;
|
||||
mClampT = FALSE;
|
||||
mClampR = FALSE;
|
||||
mMagFilterNearest = FALSE;
|
||||
mMinFilterNearest = FALSE;
|
||||
|
||||
mTexOptionsDirty = true;
|
||||
mAddressMode = LLTexUnit::TAM_WRAP;
|
||||
mFilterOption = LLTexUnit::TFO_ANISOTROPIC;
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
mComponents = 0;
|
||||
|
|
@ -339,6 +338,7 @@ void LLImageGL::init(BOOL usemipmaps)
|
|||
mHasExplicitFormat = FALSE;
|
||||
|
||||
mGLTextureCreated = FALSE ;
|
||||
mIsMask = FALSE;
|
||||
}
|
||||
|
||||
void LLImageGL::cleanup()
|
||||
|
|
@ -469,6 +469,11 @@ bool LLImageGL::bindDefaultImage(const S32 stage) const
|
|||
return false;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLImageGL::forceImmediateUpdate()
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes )
|
||||
{
|
||||
|
|
@ -498,7 +503,7 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
|
|||
void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
||||
{
|
||||
// LLFastTimer t1(LLFastTimer::FTM_TEMP1);
|
||||
|
||||
llpushcallstacks ;
|
||||
bool is_compressed = false;
|
||||
if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
|
||||
{
|
||||
|
|
@ -519,6 +524,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
// are stored BEFORE the largest image
|
||||
for (S32 d=mCurrentDiscardLevel; d<=mMaxDiscardLevel; d++)
|
||||
{
|
||||
|
||||
S32 w = getWidth(d);
|
||||
S32 h = getHeight(d);
|
||||
S32 gl_level = d-mCurrentDiscardLevel;
|
||||
|
|
@ -529,7 +535,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
if (is_compressed)
|
||||
{
|
||||
// LLFastTimer t2(LLFastTimer::FTM_TEMP4);
|
||||
S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
|
||||
S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
|
||||
glCompressedTexImage2DARB(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
|
||||
stop_glerror();
|
||||
}
|
||||
|
|
@ -543,7 +549,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
stop_glerror();
|
||||
}
|
||||
|
||||
glTexImage2D(mTarget, gl_level, mFormatInternal, w, h, 0, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in);
|
||||
LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in);
|
||||
if (gl_level == 0)
|
||||
{
|
||||
analyzeAlpha(data_in, w, h);
|
||||
}
|
||||
updatePickMask(w, h, data_in);
|
||||
|
||||
if(mFormatSwapBytes)
|
||||
|
|
@ -575,10 +585,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
S32 w = getWidth(mCurrentDiscardLevel);
|
||||
S32 h = getHeight(mCurrentDiscardLevel);
|
||||
|
||||
glTexImage2D(mTarget, 0, mFormatInternal,
|
||||
w, h, 0,
|
||||
LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
|
||||
w, h,
|
||||
mFormatPrimary, mFormatType,
|
||||
data_in);
|
||||
analyzeAlpha(data_in, w, h);
|
||||
stop_glerror();
|
||||
|
||||
updatePickMask(w, h, data_in);
|
||||
|
|
@ -630,7 +641,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
stop_glerror();
|
||||
}
|
||||
|
||||
glTexImage2D(mTarget, m, mFormatInternal, w, h, 0, mFormatPrimary, mFormatType, cur_mip_data);
|
||||
LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
|
||||
if (m == 0)
|
||||
{
|
||||
analyzeAlpha(data_in, w, h);
|
||||
}
|
||||
stop_glerror();
|
||||
if (m == 0)
|
||||
{
|
||||
|
|
@ -663,7 +678,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
{
|
||||
llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl;
|
||||
}
|
||||
mHasMipMaps = TRUE;
|
||||
mHasMipMaps = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -684,8 +699,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
stop_glerror();
|
||||
}
|
||||
|
||||
glTexImage2D(mTarget, 0, mFormatInternal, w, h, 0,
|
||||
LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h,
|
||||
mFormatPrimary, mFormatType, (GLvoid *)data_in);
|
||||
analyzeAlpha(data_in, w, h);
|
||||
|
||||
updatePickMask(w, h, data_in);
|
||||
|
||||
stop_glerror();
|
||||
|
|
@ -697,14 +714,16 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
}
|
||||
|
||||
}
|
||||
mHasMipMaps = FALSE;
|
||||
mHasMipMaps = false;
|
||||
}
|
||||
stop_glerror();
|
||||
mGLTextureCreated = true;
|
||||
llpushcallstacks ;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
|
||||
{
|
||||
llpushcallstacks ;
|
||||
if (!width || !height)
|
||||
{
|
||||
return TRUE;
|
||||
|
|
@ -780,6 +799,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
|
|||
|
||||
glTexSubImage2D(mTarget, 0, x_pos, y_pos,
|
||||
width, height, mFormatPrimary, mFormatType, datap);
|
||||
gGL.getTexUnit(0)->disable();
|
||||
stop_glerror();
|
||||
|
||||
if(mFormatSwapBytes)
|
||||
|
|
@ -792,6 +812,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
|
|||
stop_glerror();
|
||||
mGLTextureCreated = true;
|
||||
}
|
||||
llpushcallstacks ;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -816,6 +837,24 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
|
||||
{
|
||||
glGenTextures(numTextures, (GLuint*)textures);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
|
||||
{
|
||||
glDeleteTextures(numTextures, (GLuint*)textures);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
|
||||
{
|
||||
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels);
|
||||
}
|
||||
|
||||
//create an empty GL texture: just create a texture name
|
||||
//the texture is assiciate with some image by calling glTexImage outside LLImageGL
|
||||
BOOL LLImageGL::createGLTexture()
|
||||
|
|
@ -848,6 +887,7 @@ BOOL LLImageGL::createGLTexture()
|
|||
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/)
|
||||
{
|
||||
llpushcallstacks ;
|
||||
if (gGLManager.mIsDisabled)
|
||||
{
|
||||
llwarns << "Trying to create a texture while GL is disabled!" << llendl;
|
||||
|
|
@ -908,6 +948,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
|
|||
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
|
||||
{
|
||||
llpushcallstacks ;
|
||||
llassert(data_in);
|
||||
|
||||
if (discard_level < 0)
|
||||
|
|
@ -924,7 +965,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
GLuint old_name = mTexName;
|
||||
U32 old_name = mTexName;
|
||||
// S32 old_discard = mCurrentDiscardLevel;
|
||||
|
||||
if (usename != 0)
|
||||
|
|
@ -933,7 +974,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
}
|
||||
else
|
||||
{
|
||||
glGenTextures(1, (GLuint*)&mTexName);
|
||||
LLImageGL::generateTextures(1, &mTexName);
|
||||
stop_glerror();
|
||||
{
|
||||
// LLFastTimer t1(LLFastTimer::FTM_TEMP6);
|
||||
|
|
@ -963,9 +1004,11 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
|
||||
setImage(data_in, data_hasmips);
|
||||
|
||||
setClamp(mClampS, mClampT);
|
||||
setMipFilterNearest(mMagFilterNearest);
|
||||
|
||||
// Set texture options to our defaults.
|
||||
gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
|
||||
|
||||
// things will break if we don't unbind after creation
|
||||
gGL.getTexUnit(0)->unbind(mBindTarget);
|
||||
stop_glerror();
|
||||
|
|
@ -973,16 +1016,18 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
if (old_name != 0)
|
||||
{
|
||||
sGlobalTextureMemory -= mTextureMemory;
|
||||
glDeleteTextures(1, &old_name);
|
||||
LLImageGL::deleteTextures(1, &old_name);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
mTextureMemory = getMipBytes(discard_level);
|
||||
sGlobalTextureMemory += mTextureMemory;
|
||||
|
||||
setActive() ;
|
||||
|
||||
// mark this as bound at this point, so we don't throw it out immediately
|
||||
mLastBindTime = sLastFrameTime;
|
||||
|
||||
llpushcallstacks ;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1055,6 +1100,7 @@ BOOL LLImageGL::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_h
|
|||
|
||||
BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok)
|
||||
{
|
||||
llpushcallstacks ;
|
||||
if (discard_level < 0)
|
||||
{
|
||||
discard_level = mCurrentDiscardLevel;
|
||||
|
|
@ -1069,7 +1115,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
|
|||
|
||||
//explicitly unbind texture
|
||||
gGL.getTexUnit(0)->unbind(mBindTarget);
|
||||
llverify(gGL.getTexUnit(0)->bind(this));
|
||||
llverify(gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName));
|
||||
|
||||
//debug code, leave it there commented.
|
||||
//checkTexSize() ;
|
||||
|
|
@ -1157,7 +1203,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
|
|||
return FALSE ;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
||||
llpushcallstacks ;
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
|
@ -1179,8 +1225,10 @@ void LLImageGL::destroyGLTexture()
|
|||
sGlobalTextureMemory -= mTextureMemory;
|
||||
mTextureMemory = 0;
|
||||
|
||||
glDeleteTextures(1, (GLuint*)&mTexName);
|
||||
LLImageGL::deleteTextures(1, &mTexName);
|
||||
mTextureState = DELETED ;
|
||||
mTexName = 0;
|
||||
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
|
||||
mGLTextureCreated = FALSE ;
|
||||
stop_glerror();
|
||||
}
|
||||
|
|
@ -1188,89 +1236,35 @@ void LLImageGL::destroyGLTexture()
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void LLImageGL::glClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr)
|
||||
void LLImageGL::setAddressMode(LLTexUnit::eTextureAddressMode mode)
|
||||
{
|
||||
glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||
glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||
glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||
}
|
||||
|
||||
void LLImageGL::glClamp (BOOL clamps, BOOL clampt)
|
||||
{
|
||||
if (mTexName != 0)
|
||||
if (mAddressMode != mode)
|
||||
{
|
||||
glTexParameteri (LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||
glTexParameteri (LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||
mTexOptionsDirty = true;
|
||||
mAddressMode = mode;
|
||||
}
|
||||
|
||||
if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
|
||||
{
|
||||
gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureAddressMode(mode);
|
||||
mTexOptionsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void LLImageGL::setClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr)
|
||||
void LLImageGL::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
|
||||
{
|
||||
mClampS = clamps;
|
||||
mClampT = clampt;
|
||||
mClampR = clampr;
|
||||
glClampCubemap (clamps, clampt, clampr);
|
||||
}
|
||||
|
||||
void LLImageGL::setClamp(BOOL clamps, BOOL clampt)
|
||||
{
|
||||
mClampS = clamps;
|
||||
mClampT = clampt;
|
||||
glClamp (clamps, clampt);
|
||||
}
|
||||
|
||||
void LLImageGL::overrideClamp (BOOL clamps, BOOL clampt)
|
||||
{
|
||||
glClamp (clamps, clampt);
|
||||
}
|
||||
|
||||
void LLImageGL::restoreClamp (void)
|
||||
{
|
||||
glClamp (mClampS, mClampT);
|
||||
}
|
||||
|
||||
void LLImageGL::setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest)
|
||||
{
|
||||
mMagFilterNearest = mag_nearest;
|
||||
mMinFilterNearest = min_nearest;
|
||||
|
||||
if (mTexName != 0)
|
||||
if (mFilterOption != option)
|
||||
{
|
||||
if (mMinFilterNearest)
|
||||
{
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
else if (mHasMipMaps)
|
||||
{
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
if (mMagFilterNearest)
|
||||
{
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
if (gGLManager.mHasAnisotropic)
|
||||
{
|
||||
if (sGlobalUseAnisotropic && !mMagFilterNearest)
|
||||
{
|
||||
F32 largest_anisotropy;
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_anisotropy);
|
||||
glTexParameterf(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_anisotropy);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameterf(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
|
||||
}
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
mTexOptionsDirty = true;
|
||||
mFilterOption = option;
|
||||
}
|
||||
|
||||
if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
|
||||
{
|
||||
gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureFilteringOption(option);
|
||||
mTexOptionsDirty = false;
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
BOOL LLImageGL::getIsResident(BOOL test_now)
|
||||
|
|
@ -1357,6 +1351,115 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b
|
|||
mBindTarget = bind_target;
|
||||
}
|
||||
|
||||
void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
|
||||
{
|
||||
if (mFormatType != GL_UNSIGNED_BYTE)
|
||||
{
|
||||
llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl;
|
||||
}
|
||||
|
||||
U32 stride = 0;
|
||||
switch (mFormatPrimary)
|
||||
{
|
||||
case GL_LUMINANCE:
|
||||
case GL_ALPHA:
|
||||
stride = 1;
|
||||
break;
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
stride = 2;
|
||||
break;
|
||||
case GL_RGB:
|
||||
//no alpha
|
||||
mIsMask = FALSE;
|
||||
return;
|
||||
case GL_RGBA:
|
||||
stride = 4;
|
||||
break;
|
||||
default:
|
||||
llwarns << "Cannot analyze alpha of image with primary format " << std::hex << mFormatPrimary << std::dec << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
U32 length = w * h;
|
||||
const GLubyte* current = ((const GLubyte*) data_in)+stride-1;
|
||||
|
||||
S32 sample[16];
|
||||
memset(sample, 0, sizeof(S32)*16);
|
||||
|
||||
for (U32 i = 0; i < length; i++)
|
||||
{
|
||||
++sample[*current/16];
|
||||
current += stride;
|
||||
}
|
||||
|
||||
U32 total = 0;
|
||||
for (U32 i = 4; i < 11; i++)
|
||||
{
|
||||
total += sample[i];
|
||||
}
|
||||
|
||||
if (total > length/16)
|
||||
{
|
||||
mIsMask = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsMask = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLImageGL::isDeleted()
|
||||
{
|
||||
return mTextureState == DELETED ;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::isInactive()
|
||||
{
|
||||
return mTextureState == INACTIVE ;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::isDeletionCandidate()
|
||||
{
|
||||
return mTextureState == DELETION_CANDIDATE ;
|
||||
}
|
||||
|
||||
void LLImageGL::setDeletionCandidate()
|
||||
{
|
||||
if(mTexName && (mTextureState == INACTIVE))
|
||||
{
|
||||
mTextureState = DELETION_CANDIDATE ;
|
||||
}
|
||||
}
|
||||
|
||||
void LLImageGL::forceActive()
|
||||
{
|
||||
mTextureState = ACTIVE ;
|
||||
}
|
||||
|
||||
void LLImageGL::setActive()
|
||||
{
|
||||
if(mTextureState != NO_DELETE)
|
||||
{
|
||||
mTextureState = ACTIVE ;
|
||||
}
|
||||
}
|
||||
|
||||
//set the texture inactive
|
||||
void LLImageGL::setInactive()
|
||||
{
|
||||
if(mTexName && (mTextureState == ACTIVE) && !getBoundRecently())
|
||||
{
|
||||
mTextureState = INACTIVE ;
|
||||
}
|
||||
}
|
||||
|
||||
//set the texture to stay in memory
|
||||
void LLImageGL::setNoDelete()
|
||||
{
|
||||
mTextureState = NO_DELETE ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
|
||||
{
|
||||
if (mFormatType != GL_UNSIGNED_BYTE ||
|
||||
|
|
@ -1469,7 +1572,7 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
|
|||
llassert(w > 0 && h > 0 && cur_mip_data);
|
||||
U8 test = cur_mip_data[w*h*mComponents-1];
|
||||
{
|
||||
glTexImage2D(mTarget, m, mFormatInternal, w, h, 0, mFormatPrimary, mFormatType, cur_mip_data);
|
||||
LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
|
||||
stop_glerror();
|
||||
}
|
||||
if (prev_mip_data && prev_mip_data != rawdata)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
class LLImageGL : public LLRefCount
|
||||
{
|
||||
friend class LLTexUnit;
|
||||
public:
|
||||
// Size calculation
|
||||
static S32 dataFormatBits(S32 dataformat);
|
||||
|
|
@ -80,17 +81,22 @@ public:
|
|||
protected:
|
||||
virtual ~LLImageGL();
|
||||
|
||||
private:
|
||||
void glClamp (BOOL clamps, BOOL clampt);
|
||||
void glClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr = FALSE);
|
||||
void analyzeAlpha(const void* data_in, S32 w, S32 h);
|
||||
|
||||
public:
|
||||
virtual void dump(); // debugging info to llinfos
|
||||
virtual bool bindError(const S32 stage = 0) const;
|
||||
virtual bool bindDefaultImage(const S32 stage = 0) const;
|
||||
virtual void forceImmediateUpdate() ;
|
||||
|
||||
void setSize(S32 width, S32 height, S32 ncomponents);
|
||||
|
||||
// These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D()
|
||||
// for tracking purposes and will be deprecated in the future
|
||||
static void generateTextures(S32 numTextures, U32 *textures);
|
||||
static void deleteTextures(S32 numTextures, U32 *textures);
|
||||
static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels);
|
||||
|
||||
BOOL createGLTexture() ;
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0);
|
||||
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
|
||||
|
|
@ -103,14 +109,9 @@ public:
|
|||
// Read back a raw image for this discard level, if it exists
|
||||
BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok);
|
||||
void destroyGLTexture();
|
||||
|
||||
void setClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr = FALSE);
|
||||
void setClamp(BOOL clamps, BOOL clampt);
|
||||
void overrideClamp (BOOL clamps, BOOL clampt);
|
||||
void restoreClamp (void);
|
||||
void setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest = FALSE);
|
||||
|
||||
void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
|
||||
void dontDiscard() { mDontDiscard = 1; }
|
||||
void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; }
|
||||
|
||||
S32 getDiscardLevel() const { return mCurrentDiscardLevel; }
|
||||
S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; }
|
||||
|
|
@ -124,15 +125,12 @@ public:
|
|||
S32 getMipBytes(S32 discard_level = -1) const;
|
||||
BOOL getBoundRecently() const;
|
||||
LLGLenum getPrimaryFormat() const { return mFormatPrimary; }
|
||||
|
||||
BOOL getClampS() const { return mClampS; }
|
||||
BOOL getClampT() const { return mClampT; }
|
||||
BOOL getClampR() const { return mClampR; }
|
||||
BOOL getMipFilterNearest() const { return mMagFilterNearest; }
|
||||
|
||||
|
||||
BOOL getHasGLTexture() const { return mTexName != 0; }
|
||||
LLGLuint getTexName() const { return mTexName; }
|
||||
|
||||
BOOL getIsAlphaMask() const { return mIsMask; }
|
||||
|
||||
BOOL getIsResident(BOOL test_now = FALSE); // not const
|
||||
|
||||
void setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target);
|
||||
|
|
@ -152,6 +150,27 @@ public:
|
|||
BOOL getMask(const LLVector2 &tc);
|
||||
|
||||
void checkTexSize() const ;
|
||||
|
||||
// Sets the addressing mode used to sample the texture
|
||||
// (such as wrapping, mirrored wrapping, and clamp)
|
||||
// Note: this actually gets set the next time the texture is bound.
|
||||
void setAddressMode(LLTexUnit::eTextureAddressMode mode);
|
||||
LLTexUnit::eTextureAddressMode getAddressMode(void) const { return mAddressMode; }
|
||||
|
||||
// Sets the filtering options used to sample the texture
|
||||
// (such as point sampling, bilinear interpolation, mipmapping, and anisotropic filtering)
|
||||
// Note: this actually gets set the next time the texture is bound.
|
||||
void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
|
||||
LLTexUnit::eTextureFilterOptions getFilteringOption(void) const { return mFilterOption; }
|
||||
|
||||
BOOL isDeleted() ;
|
||||
BOOL isInactive() ;
|
||||
BOOL isDeletionCandidate();
|
||||
void setDeletionCandidate() ;
|
||||
void setInactive() ;
|
||||
void setActive() ;
|
||||
void forceActive() ;
|
||||
void setNoDelete() ;
|
||||
|
||||
protected:
|
||||
void init(BOOL usemipmaps);
|
||||
|
|
@ -166,9 +185,10 @@ private:
|
|||
LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
|
||||
U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel
|
||||
S8 mUseMipMaps;
|
||||
S8 mHasMipMaps;
|
||||
S8 mHasExplicitFormat; // If false (default), GL format is f(mComponents)
|
||||
S8 mAutoGenMips;
|
||||
|
||||
BOOL mIsMask;
|
||||
|
||||
bool mGLTextureCreated ;
|
||||
LLGLuint mTexName;
|
||||
|
|
@ -179,6 +199,7 @@ private:
|
|||
protected:
|
||||
LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)
|
||||
LLTexUnit::eTextureType mBindTarget; // Normally TT_TEXTURE, sometimes something else (ex. cube maps)
|
||||
bool mHasMipMaps;
|
||||
|
||||
LLGLboolean mIsResident;
|
||||
|
||||
|
|
@ -186,17 +207,27 @@ protected:
|
|||
S8 mMaxDiscardLevel;
|
||||
S8 mDontDiscard; // Keep full res version of this image (for UI, etc)
|
||||
|
||||
S8 mClampS; // Need to save clamp state
|
||||
S8 mClampT;
|
||||
S8 mClampR;
|
||||
S8 mMagFilterNearest; // if TRUE, set magfilter to GL_NEAREST
|
||||
S8 mMinFilterNearest; // if TRUE, set minfilter to GL_NEAREST
|
||||
bool mTexOptionsDirty;
|
||||
LLTexUnit::eTextureAddressMode mAddressMode; // Defaults to TAM_WRAP
|
||||
LLTexUnit::eTextureFilterOptions mFilterOption; // Defaults to TFO_TRILINEAR
|
||||
|
||||
|
||||
LLGLint mFormatInternal; // = GL internalformat
|
||||
LLGLenum mFormatPrimary; // = GL format (pixel data format)
|
||||
LLGLenum mFormatType;
|
||||
BOOL mFormatSwapBytes;// if true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1)
|
||||
|
||||
protected:
|
||||
typedef enum
|
||||
{
|
||||
DELETED = 0, //removed from memory
|
||||
DELETION_CANDIDATE, //ready to be removed from memory
|
||||
INACTIVE, //not be used for the last certain period (i.e., 30 seconds).
|
||||
ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds).
|
||||
NO_DELETE = 99 //stay in memory, can not be removed.
|
||||
} LLGLTexureState;
|
||||
LLGLTexureState mTextureState ;
|
||||
|
||||
// STATICS
|
||||
public:
|
||||
static std::set<LLImageGL*> sImageList;
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ void LLPostProcess::applyShaders(void)
|
|||
/// If any of the above shaders have been called update the frame buffer;
|
||||
if (tweaks.useColorFilter())
|
||||
{
|
||||
GLuint tex = mSceneRenderTexture->getTexName() ;
|
||||
U32 tex = mSceneRenderTexture->getTexName() ;
|
||||
copyFrameBuffer(tex, screenW, screenH);
|
||||
}
|
||||
applyNightVisionShader();
|
||||
|
|
@ -218,7 +218,7 @@ void LLPostProcess::applyShaders(void)
|
|||
/// If any of the above shaders have been called update the frame buffer;
|
||||
if (tweaks.useColorFilter().asBoolean() || tweaks.useNightVisionShader().asBoolean())
|
||||
{
|
||||
GLuint tex = mSceneRenderTexture->getTexName() ;
|
||||
U32 tex = mSceneRenderTexture->getTexName() ;
|
||||
copyFrameBuffer(tex, screenW, screenH);
|
||||
}
|
||||
applyBloomShader();
|
||||
|
|
@ -360,7 +360,7 @@ void LLPostProcess::doEffects(void)
|
|||
|
||||
/// Copy the screen buffer to the render texture
|
||||
{
|
||||
GLuint tex = mSceneRenderTexture->getTexName() ;
|
||||
U32 tex = mSceneRenderTexture->getTexName() ;
|
||||
copyFrameBuffer(tex, screenW, screenH);
|
||||
}
|
||||
|
||||
|
|
@ -386,7 +386,7 @@ void LLPostProcess::doEffects(void)
|
|||
checkError();
|
||||
}
|
||||
|
||||
void LLPostProcess::copyFrameBuffer(GLuint & texture, unsigned int width, unsigned int height)
|
||||
void LLPostProcess::copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height)
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture);
|
||||
glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, width, height, 0);
|
||||
|
|
@ -503,10 +503,8 @@ void LLPostProcess::createTexture(LLPointer<LLImageGL>& texture, unsigned int wi
|
|||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture->getTexName());
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -523,11 +521,9 @@ void LLPostProcess::createNoiseTexture(LLPointer<LLImageGL>& texture)
|
|||
if(texture->createGLTexture())
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ private:
|
|||
/// OpenGL Helper Functions
|
||||
void getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog);
|
||||
void createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height);
|
||||
void copyFrameBuffer(GLuint & texture, unsigned int width, unsigned int height);
|
||||
void copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height);
|
||||
void createNoiseTexture(LLPointer<LLImageGL>& texture);
|
||||
bool checkError(void);
|
||||
void checkShaderError(GLhandleARB shader);
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ static GLenum sGLCompareFunc[] =
|
|||
GL_GREATER
|
||||
};
|
||||
|
||||
const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD;
|
||||
const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0;
|
||||
|
||||
static GLenum sGLBlendFactor[] =
|
||||
{
|
||||
|
|
@ -96,7 +96,8 @@ LLTexUnit::LLTexUnit(S32 index)
|
|||
mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
|
||||
mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
|
||||
mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
|
||||
mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0)
|
||||
mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0),
|
||||
mHasMipMaps(false)
|
||||
{
|
||||
llassert_always(index < LL_NUM_TEXTURE_LAYERS);
|
||||
mIndex = index;
|
||||
|
|
@ -176,8 +177,9 @@ void LLTexUnit::disable(void)
|
|||
}
|
||||
}
|
||||
|
||||
bool LLTexUnit::bind(const LLImageGL* texture, bool forceBind)
|
||||
bool LLTexUnit::bind(LLImageGL* texture, bool forceBind)
|
||||
{
|
||||
stop_glerror();
|
||||
if (mIndex < 0) return false;
|
||||
|
||||
gGL.flush();
|
||||
|
|
@ -190,15 +192,30 @@ bool LLTexUnit::bind(const LLImageGL* texture, bool forceBind)
|
|||
|
||||
if (!texture->getTexName()) //if texture does not exist
|
||||
{
|
||||
//if deleted, will re-generate it immediately
|
||||
texture->forceImmediateUpdate() ;
|
||||
|
||||
return texture->bindDefaultImage(mIndex);
|
||||
}
|
||||
// Disabled caching of binding state.
|
||||
activate();
|
||||
enable(texture->getTarget());
|
||||
mCurrTexture = texture->getTexName();
|
||||
glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
|
||||
texture->updateBindStats();
|
||||
return true;
|
||||
|
||||
if (texture != NULL && ((mCurrTexture != texture->getTexName()) || forceBind))
|
||||
{
|
||||
activate();
|
||||
enable(texture->getTarget());
|
||||
mCurrTexture = texture->getTexName();
|
||||
glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
|
||||
texture->updateBindStats();
|
||||
texture->setActive() ;
|
||||
mHasMipMaps = texture->mHasMipMaps;
|
||||
if (texture->mTexOptionsDirty)
|
||||
{
|
||||
texture->mTexOptionsDirty = false;
|
||||
setTextureAddressMode(texture->mAddressMode);
|
||||
setTextureFilteringOption(texture->mFilterOption);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLTexUnit::bind(LLCubeMap* cubeMap)
|
||||
|
|
@ -207,8 +224,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
|
|||
|
||||
gGL.flush();
|
||||
|
||||
// Disabled caching of binding state.
|
||||
if (cubeMap != NULL)
|
||||
if (cubeMap != NULL && mCurrTexture != cubeMap->mImages[0]->getTexName())
|
||||
{
|
||||
if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
|
||||
{
|
||||
|
|
@ -216,8 +232,14 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
|
|||
enable(LLTexUnit::TT_CUBE_MAP);
|
||||
mCurrTexture = cubeMap->mImages[0]->getTexName();
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture);
|
||||
mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps;
|
||||
cubeMap->mImages[0]->updateBindStats();
|
||||
cubeMap->mImages[0]->setMipFilterNearest (FALSE, FALSE);
|
||||
if (cubeMap->mImages[0]->mTexOptionsDirty)
|
||||
{
|
||||
cubeMap->mImages[0]->mTexOptionsDirty = false;
|
||||
setTextureAddressMode(cubeMap->mImages[0]->mAddressMode);
|
||||
setTextureFilteringOption(cubeMap->mImages[0]->mFilterOption);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
@ -228,6 +250,8 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
|
|||
return false;
|
||||
}
|
||||
|
||||
// LLRenderTarget is unavailible on the mapserver since it uses FBOs.
|
||||
#if !LL_MESA_HEADLESS
|
||||
bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
|
||||
{
|
||||
if (mIndex < 0) return false;
|
||||
|
|
@ -245,23 +269,26 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
|
|||
|
||||
return true;
|
||||
}
|
||||
#endif // LL_MESA_HEADLESS
|
||||
|
||||
bool LLTexUnit::bindManual(eTextureType type, U32 texture)
|
||||
bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
|
||||
{
|
||||
if (mIndex < 0) return false;
|
||||
if (mIndex < 0 || mCurrTexture == texture) return false;
|
||||
|
||||
// Disabled caching of binding state.
|
||||
gGL.flush();
|
||||
|
||||
activate();
|
||||
enable(type);
|
||||
mCurrTexture = texture;
|
||||
glBindTexture(sGLTextureType[type], texture);
|
||||
mHasMipMaps = hasMips;
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLTexUnit::unbind(eTextureType type)
|
||||
{
|
||||
stop_glerror();
|
||||
|
||||
if (mIndex < 0) return;
|
||||
|
||||
// Disabled caching of binding state.
|
||||
|
|
@ -277,17 +304,57 @@ void LLTexUnit::unbind(eTextureType type)
|
|||
|
||||
void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
|
||||
{
|
||||
if (mIndex < 0) return;
|
||||
if (mIndex < 0 || mCurrTexture == 0) return;
|
||||
|
||||
if (true)
|
||||
activate();
|
||||
|
||||
glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]);
|
||||
glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]);
|
||||
if (mCurrTexType == TT_CUBE_MAP)
|
||||
{
|
||||
activate();
|
||||
glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]);
|
||||
}
|
||||
}
|
||||
|
||||
glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]);
|
||||
glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]);
|
||||
if (mCurrTexType == TT_CUBE_MAP)
|
||||
void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option)
|
||||
{
|
||||
if (mIndex < 0 || mCurrTexture == 0) return;
|
||||
|
||||
if (option == TFO_POINT)
|
||||
{
|
||||
glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
if (option >= TFO_TRILINEAR && mHasMipMaps)
|
||||
{
|
||||
glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
else if (option >= TFO_BILINEAR)
|
||||
{
|
||||
glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
if (gGLManager.mHasAnisotropic)
|
||||
{
|
||||
if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC)
|
||||
{
|
||||
glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]);
|
||||
if (gGL.mMaxAnisotropy < 1.f)
|
||||
{
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGL.mMaxAnisotropy);
|
||||
}
|
||||
glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGL.mMaxAnisotropy);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -590,12 +657,13 @@ void LLTexUnit::debugTextureUnit(void)
|
|||
|
||||
|
||||
LLRender::LLRender()
|
||||
: mDirty(false), mCount(0), mMode(LLRender::TRIANGLES)
|
||||
: mDirty(false), mCount(0), mMode(LLRender::TRIANGLES),
|
||||
mMaxAnisotropy(0.f)
|
||||
{
|
||||
mBuffer = new LLVertexBuffer(immediate_mask, 0);
|
||||
mBuffer->allocateBuffer(4096, 0, TRUE);
|
||||
mBuffer->getVertexStrider(mVerticesp);
|
||||
mBuffer->getTexCoordStrider(mTexcoordsp);
|
||||
mBuffer->getTexCoord0Strider(mTexcoordsp);
|
||||
mBuffer->getColorStrider(mColorsp);
|
||||
|
||||
mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS);
|
||||
|
|
@ -688,7 +756,10 @@ void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB
|
|||
mCurrColorMask[2] = writeColorB;
|
||||
mCurrColorMask[3] = writeAlpha;
|
||||
|
||||
glColorMask(writeColorR, writeColorG, writeColorB, writeAlpha);
|
||||
glColorMask(writeColorR ? GL_TRUE : GL_FALSE,
|
||||
writeColorG ? GL_TRUE : GL_FALSE,
|
||||
writeColorB ? GL_TRUE : GL_FALSE,
|
||||
writeAlpha ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
void LLRender::setSceneBlendType(eBlendType type)
|
||||
|
|
@ -768,6 +839,14 @@ bool LLRender::verifyTexUnitActive(U32 unitToVerify)
|
|||
}
|
||||
}
|
||||
|
||||
void LLRender::clearErrors()
|
||||
{
|
||||
while (glGetError())
|
||||
{
|
||||
//loop until no more error flags left
|
||||
}
|
||||
}
|
||||
|
||||
void LLRender::begin(const GLuint& mode)
|
||||
{
|
||||
if (mode != mMode)
|
||||
|
|
@ -853,13 +932,14 @@ void LLRender::flush()
|
|||
|
||||
mBuffer->setBuffer(immediate_mask);
|
||||
mBuffer->drawArrays(mMode, 0, mCount);
|
||||
|
||||
|
||||
mVerticesp[0] = mVerticesp[mCount];
|
||||
mTexcoordsp[0] = mTexcoordsp[mCount];
|
||||
mColorsp[0] = mColorsp[mCount];
|
||||
mCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
|
||||
{
|
||||
//the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095]
|
||||
|
|
|
|||
|
|
@ -71,6 +71,14 @@ public:
|
|||
TAM_CLAMP // No texture type is currently enabled
|
||||
} eTextureAddressMode;
|
||||
|
||||
typedef enum
|
||||
{ // Note: If mipmapping or anisotropic are not enabled or supported it should fall back gracefully
|
||||
TFO_POINT = 0, // Equal to: min=point, mag=point, mip=none.
|
||||
TFO_BILINEAR, // Equal to: min=linear, mag=linear, mip=point.
|
||||
TFO_TRILINEAR, // Equal to: min=linear, mag=linear, mip=linear.
|
||||
TFO_ANISOTROPIC // Equal to: min=anisotropic, max=anisotropic, mip=linear.
|
||||
} eTextureFilterOptions;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TB_REPLACE = 0,
|
||||
|
|
@ -131,30 +139,43 @@ public:
|
|||
// Sets this tex unit to be the currently active one
|
||||
void activate(void);
|
||||
|
||||
// Enables this texture unit for the given texture type (automatically disables any previously enabled texture type)
|
||||
// Enables this texture unit for the given texture type
|
||||
// (automatically disables any previously enabled texture type)
|
||||
void enable(eTextureType type);
|
||||
|
||||
// Disables the current texture unit
|
||||
void disable(void);
|
||||
|
||||
// Binds the LLImageGL to this texture unit
|
||||
// (automatically enables the unit for the LLImageGL's texture type)
|
||||
bool bind(const LLImageGL* texture, bool forceBind = false);
|
||||
bool bind(LLImageGL* texture, bool forceBind = false);
|
||||
|
||||
// Binds a cubemap to this texture unit
|
||||
// (automatically enables the texture unit for cubemaps)
|
||||
bool bind(LLCubeMap* cubeMap);
|
||||
|
||||
// Binds a render target to this texture unit (automatically enables the texture unit for the RT's texture type)
|
||||
// Binds a render target to this texture unit
|
||||
// (automatically enables the texture unit for the RT's texture type)
|
||||
bool bind(LLRenderTarget * renderTarget, bool bindDepth = false);
|
||||
|
||||
// Manually binds a texture to the texture unit (automatically enables the tex unit for the given texture type)
|
||||
bool bindManual(eTextureType type, U32 texture);
|
||||
// Manually binds a texture to the texture unit
|
||||
// (automatically enables the tex unit for the given texture type)
|
||||
bool bindManual(eTextureType type, U32 texture, bool hasMips = false);
|
||||
|
||||
// Unbinds the currently bound texture of the given type (only if there's a texture of the given type currently bound)
|
||||
// Unbinds the currently bound texture of the given type
|
||||
// (only if there's a texture of the given type currently bound)
|
||||
void unbind(eTextureType type);
|
||||
|
||||
// Sets the addressing mode used to sample the texture
|
||||
// Warning: this stays set for the bound texture forever,
|
||||
// make sure you want to permanently change the address mode for the bound texture.
|
||||
void setTextureAddressMode(eTextureAddressMode mode);
|
||||
|
||||
// Sets the filtering options used to sample the texture
|
||||
// Warning: this stays set for the bound texture forever,
|
||||
// make sure you want to permanently change the filtering for the bound texture.
|
||||
void setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option);
|
||||
|
||||
void setTextureBlendType(eTextureBlendType type);
|
||||
|
||||
inline void setTextureColorBlend(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2 = TBS_PREV_COLOR)
|
||||
|
|
@ -166,6 +187,12 @@ public:
|
|||
|
||||
static U32 getInternalType(eTextureType type);
|
||||
|
||||
U32 getCurrTexture(void) { return mCurrTexture; }
|
||||
|
||||
eTextureType getCurrType(void) { return mCurrTexType; }
|
||||
|
||||
void setHasMipMaps(bool hasMips) { mHasMipMaps = hasMips; }
|
||||
|
||||
protected:
|
||||
S32 mIndex;
|
||||
U32 mCurrTexture;
|
||||
|
|
@ -179,6 +206,7 @@ protected:
|
|||
eTextureBlendSrc mCurrAlphaSrc2;
|
||||
S32 mCurrColorScale;
|
||||
S32 mCurrAlphaScale;
|
||||
bool mHasMipMaps;
|
||||
|
||||
void debugTextureUnit(void);
|
||||
void setColorScale(S32 scale);
|
||||
|
|
@ -292,6 +320,8 @@ public:
|
|||
|
||||
void debugTexUnits(void);
|
||||
|
||||
void clearErrors();
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
GLfloat v[3];
|
||||
|
|
@ -316,6 +346,8 @@ private:
|
|||
LLStrider<LLColor4U> mColorsp;
|
||||
std::vector<LLTexUnit*> mTexUnits;
|
||||
LLTexUnit* mDummyTexUnit;
|
||||
|
||||
F32 mMaxAnisotropy;
|
||||
};
|
||||
|
||||
extern F64 gGLModelView[16];
|
||||
|
|
|
|||
|
|
@ -37,6 +37,24 @@
|
|||
#include "llgl.h"
|
||||
|
||||
|
||||
void check_framebuffer_status()
|
||||
{
|
||||
if (gDebugGL)
|
||||
{
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
switch (status)
|
||||
{
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
llerrs << "WTF?" << llendl;
|
||||
break;
|
||||
default:
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLRenderTarget::sUseFBO = FALSE;
|
||||
|
||||
LLRenderTarget::LLRenderTarget() :
|
||||
|
|
@ -48,7 +66,9 @@ LLRenderTarget::LLRenderTarget() :
|
|||
mStencil(0),
|
||||
mUseDepth(FALSE),
|
||||
mRenderDepth(FALSE),
|
||||
mUsage(LLTexUnit::TT_TEXTURE)
|
||||
mUsage(LLTexUnit::TT_TEXTURE),
|
||||
mSamples(0),
|
||||
mSampleBuffer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -57,40 +77,26 @@ LLRenderTarget::~LLRenderTarget()
|
|||
release();
|
||||
}
|
||||
|
||||
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, LLTexUnit::eTextureType usage, BOOL use_fbo)
|
||||
|
||||
void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer)
|
||||
{
|
||||
mSampleBuffer = buffer;
|
||||
}
|
||||
|
||||
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo)
|
||||
{
|
||||
stop_glerror();
|
||||
mResX = resx;
|
||||
mResY = resy;
|
||||
|
||||
mStencil = stencil;
|
||||
mUsage = usage;
|
||||
mUseDepth = depth;
|
||||
|
||||
release();
|
||||
|
||||
glGenTextures(1, (GLuint *) &mTex);
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, mTex);
|
||||
glTexImage2D(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, 0, color_fmt, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
|
||||
{
|
||||
glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
|
||||
glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ATI doesn't support mirrored repeat for rectangular textures.
|
||||
glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
|
||||
{
|
||||
|
||||
if (depth)
|
||||
{
|
||||
stop_glerror();
|
||||
|
|
@ -100,37 +106,141 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, LLT
|
|||
|
||||
glGenFramebuffersEXT(1, (GLuint *) &mFBO);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
if (mDepth)
|
||||
{
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
stop_glerror();
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
stop_glerror();
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
|
||||
if (mStencil)
|
||||
{
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
|
||||
stop_glerror();
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||
LLTexUnit::getInternalType(mUsage), mTex, 0);
|
||||
stop_glerror();
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
addColorAttachment(color_fmt);
|
||||
}
|
||||
|
||||
void LLRenderTarget::addColorAttachment(U32 color_fmt)
|
||||
{
|
||||
if (color_fmt == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
U32 offset = mTex.size();
|
||||
if (offset >= 4 ||
|
||||
offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))
|
||||
{
|
||||
llerrs << "Too many color attachments!" << llendl;
|
||||
}
|
||||
|
||||
U32 tex;
|
||||
LLImageGL::generateTextures(1, &tex);
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, tex);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
if (offset == 0)
|
||||
{
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
|
||||
}
|
||||
else
|
||||
{ //don't filter data attachments
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
}
|
||||
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
|
||||
{
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ATI doesn't support mirrored repeat for rectangular textures.
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
}
|
||||
if (mFBO)
|
||||
{
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+offset,
|
||||
LLTexUnit::getInternalType(mUsage), tex, 0);
|
||||
stop_glerror();
|
||||
|
||||
check_framebuffer_status();
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
mTex.push_back(tex);
|
||||
|
||||
}
|
||||
|
||||
void LLRenderTarget::allocateDepth()
|
||||
{
|
||||
glGenTextures(1, (GLuint *) &mDepth);
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
|
||||
U32 internal_type = LLTexUnit::getInternalType(mUsage);
|
||||
glTexParameteri(internal_type, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(internal_type, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexImage2D(internal_type, 0, GL_DEPTH24_STENCIL8_EXT, mResX, mResY, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
|
||||
if (mStencil)
|
||||
{
|
||||
//use render buffers where stencil buffers are in play
|
||||
glGenRenderbuffersEXT(1, (GLuint *) &mDepth);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepth);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, mResX, mResY);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLImageGL::generateTextures(1, &mDepth);
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
|
||||
U32 internal_type = LLTexUnit::getInternalType(mUsage);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH24_STENCIL8_EXT, mResX, mResY, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
|
||||
{
|
||||
if (!mFBO || !target.mFBO)
|
||||
{
|
||||
llerrs << "Cannot share depth buffer between non FBO render targets." << llendl;
|
||||
}
|
||||
|
||||
if (mDepth)
|
||||
{
|
||||
stop_glerror();
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, target.mFBO);
|
||||
stop_glerror();
|
||||
|
||||
if (mStencil)
|
||||
{
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
|
||||
stop_glerror();
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
stop_glerror();
|
||||
if (mStencil)
|
||||
{
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
target.mUseDepth = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void LLRenderTarget::release()
|
||||
|
|
@ -141,24 +251,63 @@ void LLRenderTarget::release()
|
|||
mFBO = 0;
|
||||
}
|
||||
|
||||
if (mTex)
|
||||
if (mTex.size() > 0)
|
||||
{
|
||||
glDeleteTextures(1, (GLuint *) &mTex);
|
||||
mTex = 0;
|
||||
LLImageGL::deleteTextures(mTex.size(), &mTex[0]);
|
||||
mTex.clear();
|
||||
}
|
||||
|
||||
if (mDepth)
|
||||
{
|
||||
glDeleteTextures(1, (GLuint *) &mDepth);
|
||||
if (mStencil)
|
||||
{
|
||||
glDeleteRenderbuffersEXT(1, (GLuint*) &mDepth);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLImageGL::deleteTextures(1, &mDepth);
|
||||
stop_glerror();
|
||||
}
|
||||
mDepth = 0;
|
||||
}
|
||||
|
||||
mSampleBuffer = NULL;
|
||||
}
|
||||
|
||||
void LLRenderTarget::bindTarget()
|
||||
{
|
||||
if (mFBO)
|
||||
{
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
|
||||
stop_glerror();
|
||||
if (mSampleBuffer)
|
||||
{
|
||||
mSampleBuffer->bindTarget(this);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
|
||||
stop_glerror();
|
||||
if (gGLManager.mHasDrawBuffers)
|
||||
{ //setup multiple render targets
|
||||
GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_COLOR_ATTACHMENT1_EXT,
|
||||
GL_COLOR_ATTACHMENT2_EXT,
|
||||
GL_COLOR_ATTACHMENT3_EXT};
|
||||
glDrawBuffersARB(mTex.size(), drawbuffers);
|
||||
}
|
||||
|
||||
if (mTex.empty())
|
||||
{ //no color buffer to draw to
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
}
|
||||
|
||||
check_framebuffer_status();
|
||||
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
glViewport(0, 0, mResX, mResY);
|
||||
|
|
@ -173,7 +322,7 @@ void LLRenderTarget::unbindTarget()
|
|||
}
|
||||
}
|
||||
|
||||
void LLRenderTarget::clear()
|
||||
void LLRenderTarget::clear(U32 mask_in)
|
||||
{
|
||||
U32 mask = GL_COLOR_BUFFER_BIT;
|
||||
if (mUseDepth)
|
||||
|
|
@ -182,17 +331,38 @@ void LLRenderTarget::clear()
|
|||
}
|
||||
if (mFBO)
|
||||
{
|
||||
glClear(mask);
|
||||
check_framebuffer_status();
|
||||
stop_glerror();
|
||||
glClear(mask & mask_in);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLGLEnable scissor(GL_SCISSOR_TEST);
|
||||
glScissor(0, 0, mResX, mResY);
|
||||
stop_glerror();
|
||||
glClear(mask);
|
||||
glClear(mask & mask_in);
|
||||
}
|
||||
}
|
||||
|
||||
U32 LLRenderTarget::getTexture(U32 attachment) const
|
||||
{
|
||||
if (attachment > mTex.size()-1)
|
||||
{
|
||||
llerrs << "Invalid attachment index." << llendl;
|
||||
}
|
||||
return mTex[attachment];
|
||||
}
|
||||
|
||||
void LLRenderTarget::bindTexture(U32 index, S32 channel)
|
||||
{
|
||||
if (index > mTex.size()-1)
|
||||
{
|
||||
llerrs << "Invalid attachment index." << llendl;
|
||||
}
|
||||
gGL.getTexUnit(channel)->bindManual(mUsage, mTex[index]);
|
||||
}
|
||||
|
||||
void LLRenderTarget::flush(BOOL fetch_depth)
|
||||
{
|
||||
gGL.flush();
|
||||
|
|
@ -211,16 +381,87 @@ void LLRenderTarget::flush(BOOL fetch_depth)
|
|||
gGL.getTexUnit(0)->bind(this, true);
|
||||
glCopyTexImage2D(LLTexUnit::getInternalType(mUsage), 0, GL_DEPTH24_STENCIL8_EXT, 0, 0, mResX, mResY, 0);
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->disable();
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !LL_DARWIN
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
if (mSampleBuffer)
|
||||
{
|
||||
LLGLEnable multisample(GL_MULTISAMPLE_ARB);
|
||||
stop_glerror();
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
|
||||
stop_glerror();
|
||||
check_framebuffer_status();
|
||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, mSampleBuffer->mFBO);
|
||||
check_framebuffer_status();
|
||||
|
||||
stop_glerror();
|
||||
glBlitFramebufferEXT(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
|
||||
stop_glerror();
|
||||
|
||||
if (mTex.size() > 1)
|
||||
{
|
||||
for (U32 i = 1; i < mTex.size(); ++i)
|
||||
{
|
||||
glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||
LLTexUnit::getInternalType(mUsage), mTex[i], 0);
|
||||
stop_glerror();
|
||||
glFramebufferRenderbufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, mSampleBuffer->mTex[i]);
|
||||
stop_glerror();
|
||||
glBlitFramebufferEXT(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < mTex.size(); ++i)
|
||||
{
|
||||
glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i,
|
||||
LLTexUnit::getInternalType(mUsage), mTex[i], 0);
|
||||
stop_glerror();
|
||||
glFramebufferRenderbufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_RENDERBUFFER_EXT, mSampleBuffer->mTex[i]);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
glFlush();
|
||||
}
|
||||
}
|
||||
|
||||
void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
|
||||
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter)
|
||||
{
|
||||
#if !LL_DARWIN
|
||||
if (!source.mFBO || !mFBO)
|
||||
{
|
||||
llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
|
||||
}
|
||||
|
||||
if (mSampleBuffer)
|
||||
{
|
||||
mSampleBuffer->copyContents(source, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mFBO);
|
||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFBO);
|
||||
|
||||
glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL LLRenderTarget::isComplete() const
|
||||
{
|
||||
return (mTex || mDepth) ? TRUE : FALSE;
|
||||
return (!mTex.empty() || mDepth) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void LLRenderTarget::getViewport(S32* viewport)
|
||||
|
|
@ -231,3 +472,191 @@ void LLRenderTarget::getViewport(S32* viewport)
|
|||
viewport[3] = mResY;
|
||||
}
|
||||
|
||||
//==================================================
|
||||
// LLMultisampleBuffer implementation
|
||||
//==================================================
|
||||
LLMultisampleBuffer::LLMultisampleBuffer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LLMultisampleBuffer::~LLMultisampleBuffer()
|
||||
{
|
||||
releaseSampleBuffer();
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::releaseSampleBuffer()
|
||||
{
|
||||
if (mFBO)
|
||||
{
|
||||
glDeleteFramebuffersEXT(1, (GLuint *) &mFBO);
|
||||
mFBO = 0;
|
||||
}
|
||||
|
||||
if (mTex.size() > 0)
|
||||
{
|
||||
glDeleteRenderbuffersEXT(mTex.size(), (GLuint *) &mTex[0]);
|
||||
mTex.clear();
|
||||
}
|
||||
|
||||
if (mDepth)
|
||||
{
|
||||
glDeleteRenderbuffersEXT(1, (GLuint *) &mDepth);
|
||||
mDepth = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::bindTarget()
|
||||
{
|
||||
bindTarget(this);
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
|
||||
{
|
||||
if (!ref)
|
||||
{
|
||||
ref = this;
|
||||
}
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
|
||||
if (gGLManager.mHasDrawBuffers)
|
||||
{ //setup multiple render targets
|
||||
GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_COLOR_ATTACHMENT1_EXT,
|
||||
GL_COLOR_ATTACHMENT2_EXT,
|
||||
GL_COLOR_ATTACHMENT3_EXT};
|
||||
glDrawBuffersARB(ref->mTex.size(), drawbuffers);
|
||||
}
|
||||
|
||||
check_framebuffer_status();
|
||||
|
||||
glViewport(0, 0, mResX, mResY);
|
||||
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo )
|
||||
{
|
||||
allocate(resx,resy,color_fmt,depth,stencil,usage,use_fbo,2);
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples )
|
||||
{
|
||||
stop_glerror();
|
||||
mResX = resx;
|
||||
mResY = resy;
|
||||
|
||||
mUsage = usage;
|
||||
mUseDepth = depth;
|
||||
mStencil = stencil;
|
||||
|
||||
releaseSampleBuffer();
|
||||
|
||||
if (!gGLManager.mHasFramebufferMultisample)
|
||||
{
|
||||
llerrs << "Attempting to allocate unsupported render target type!" << llendl;
|
||||
}
|
||||
|
||||
mSamples = samples;
|
||||
|
||||
if (mSamples <= 1)
|
||||
{
|
||||
llerrs << "Cannot create a multisample buffer with less than 2 samples." << llendl;
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
|
||||
{
|
||||
|
||||
if (depth)
|
||||
{
|
||||
stop_glerror();
|
||||
allocateDepth();
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
glGenFramebuffersEXT(1, (GLuint *) &mFBO);
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
|
||||
|
||||
if (mDepth)
|
||||
{
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
|
||||
if (mStencil)
|
||||
{
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
|
||||
}
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
addColorAttachment(color_fmt);
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
|
||||
{
|
||||
#if !LL_DARWIN
|
||||
if (color_fmt == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
U32 offset = mTex.size();
|
||||
if (offset >= 4 ||
|
||||
offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))
|
||||
{
|
||||
llerrs << "Too many color attachments!" << llendl;
|
||||
}
|
||||
|
||||
U32 tex;
|
||||
glGenRenderbuffersEXT(1, &tex);
|
||||
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, tex);
|
||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, color_fmt, mResX, mResY);
|
||||
stop_glerror();
|
||||
|
||||
if (mFBO)
|
||||
{
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+offset, GL_RENDERBUFFER_EXT, tex);
|
||||
stop_glerror();
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
switch (status)
|
||||
{
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
llerrs << "WTF?" << llendl;
|
||||
break;
|
||||
default:
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
mTex.push_back(tex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::allocateDepth()
|
||||
{
|
||||
#if !LL_DARWIN
|
||||
glGenRenderbuffersEXT(1, (GLuint* ) &mDepth);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepth);
|
||||
if (mStencil)
|
||||
{
|
||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, GL_DEPTH24_STENCIL8_EXT, mResX, mResY);
|
||||
}
|
||||
else
|
||||
{
|
||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, GL_DEPTH_COMPONENT16_ARB, mResX, mResY);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@
|
|||
#ifndef LL_LLRENDERTARGET_H
|
||||
#define LL_LLRENDERTARGET_H
|
||||
|
||||
// LLRenderTarget is unavailible on the mapserver since it uses FBOs.
|
||||
#if !LL_MESA_HEADLESS
|
||||
|
||||
#include "llgl.h"
|
||||
#include "llrender.h"
|
||||
|
||||
|
|
@ -60,6 +63,7 @@
|
|||
|
||||
*/
|
||||
|
||||
class LLMultisampleBuffer;
|
||||
|
||||
class LLRenderTarget
|
||||
{
|
||||
|
|
@ -68,15 +72,25 @@ public:
|
|||
static BOOL sUseFBO;
|
||||
|
||||
LLRenderTarget();
|
||||
~LLRenderTarget();
|
||||
virtual ~LLRenderTarget();
|
||||
|
||||
//allocate resources for rendering
|
||||
//must be called before use
|
||||
//multiple calls will release previously allocated resources
|
||||
void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, BOOL use_fbo = FALSE);
|
||||
void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, BOOL use_fbo = FALSE);
|
||||
|
||||
//provide this render target with a multisample resource.
|
||||
void setSampleBuffer(LLMultisampleBuffer* buffer);
|
||||
|
||||
//add color buffer attachment
|
||||
//limit of 4 color attachments per render target
|
||||
virtual void addColorAttachment(U32 color_fmt);
|
||||
|
||||
//allocate a depth texture
|
||||
void allocateDepth();
|
||||
virtual void allocateDepth();
|
||||
|
||||
//share depth buffer with provided render target
|
||||
virtual void shareDepthBuffer(LLRenderTarget& target);
|
||||
|
||||
//free any allocated resources
|
||||
//safe to call redundantly
|
||||
|
|
@ -84,14 +98,14 @@ public:
|
|||
|
||||
//bind target for rendering
|
||||
//applies appropriate viewport
|
||||
void bindTarget();
|
||||
virtual void bindTarget();
|
||||
|
||||
//unbind target for rendering
|
||||
static void unbindTarget();
|
||||
|
||||
//clear render targer, clears depth buffer if present,
|
||||
//uses scissor rect if in copy-to-texture mode
|
||||
void clear();
|
||||
void clear(U32 mask = 0xFFFFFFFF);
|
||||
|
||||
//get applied viewport
|
||||
void getViewport(S32* viewport);
|
||||
|
|
@ -104,10 +118,12 @@ public:
|
|||
|
||||
LLTexUnit::eTextureType getUsage(void) const { return mUsage; }
|
||||
|
||||
U32 getTexture(void) const { return mTex; }
|
||||
U32 getTexture(U32 attachment = 0) const;
|
||||
|
||||
U32 getDepth(void) const { return mDepth; }
|
||||
|
||||
void bindTexture(U32 index, S32 channel);
|
||||
|
||||
//flush rendering operations
|
||||
//must be called when rendering is complete
|
||||
//should be used 1:1 with bindTarget
|
||||
|
|
@ -116,23 +132,47 @@ public:
|
|||
// the current depth texture. A depth texture will be allocated if needed.
|
||||
void flush(BOOL fetch_depth = FALSE);
|
||||
|
||||
void copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
|
||||
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter);
|
||||
|
||||
//Returns TRUE if target is ready to be rendered into.
|
||||
//That is, if the target has been allocated with at least
|
||||
//one renderable attachment (i.e. color buffer, depth buffer).
|
||||
BOOL isComplete() const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
friend class LLMultisampleBuffer;
|
||||
U32 mResX;
|
||||
U32 mResY;
|
||||
U32 mTex;
|
||||
std::vector<U32> mTex;
|
||||
U32 mFBO;
|
||||
U32 mDepth;
|
||||
U32 mStencil;
|
||||
BOOL mStencil;
|
||||
BOOL mUseDepth;
|
||||
BOOL mRenderDepth;
|
||||
LLTexUnit::eTextureType mUsage;
|
||||
U32 mSamples;
|
||||
LLMultisampleBuffer* mSampleBuffer;
|
||||
|
||||
};
|
||||
|
||||
class LLMultisampleBuffer : public LLRenderTarget
|
||||
{
|
||||
public:
|
||||
LLMultisampleBuffer();
|
||||
virtual ~LLMultisampleBuffer();
|
||||
|
||||
void releaseSampleBuffer();
|
||||
|
||||
virtual void bindTarget();
|
||||
void bindTarget(LLRenderTarget* ref);
|
||||
virtual void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo);
|
||||
void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples);
|
||||
virtual void addColorAttachment(U32 color_fmt);
|
||||
virtual void allocateDepth();
|
||||
};
|
||||
|
||||
#endif //!LL_MESA_HEADLESS
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -69,8 +69,10 @@ S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] =
|
|||
{
|
||||
sizeof(LLVector3), // TYPE_VERTEX,
|
||||
sizeof(LLVector3), // TYPE_NORMAL,
|
||||
sizeof(LLVector2), // TYPE_TEXCOORD,
|
||||
sizeof(LLVector2), // TYPE_TEXCOORD0,
|
||||
sizeof(LLVector2), // TYPE_TEXCOORD1,
|
||||
sizeof(LLVector2), // TYPE_TEXCOORD2,
|
||||
sizeof(LLVector2), // TYPE_TEXCOORD3,
|
||||
sizeof(LLColor4U), // TYPE_COLOR,
|
||||
sizeof(LLVector3), // TYPE_BINORMAL,
|
||||
sizeof(F32), // TYPE_WEIGHT,
|
||||
|
|
@ -103,8 +105,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
|||
{
|
||||
MAP_VERTEX,
|
||||
MAP_NORMAL,
|
||||
MAP_TEXCOORD,
|
||||
MAP_COLOR
|
||||
MAP_TEXCOORD0,
|
||||
MAP_COLOR,
|
||||
};
|
||||
|
||||
GLenum array[] =
|
||||
|
|
@ -112,7 +114,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
|||
GL_VERTEX_ARRAY,
|
||||
GL_NORMAL_ARRAY,
|
||||
GL_TEXTURE_COORD_ARRAY,
|
||||
GL_COLOR_ARRAY
|
||||
GL_COLOR_ARRAY,
|
||||
};
|
||||
|
||||
for (U32 i = 0; i < 4; ++i)
|
||||
|
|
@ -123,7 +125,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
|||
{ //needs to be disabled
|
||||
glDisableClientState(array[i]);
|
||||
}
|
||||
else
|
||||
else if (gDebugGL)
|
||||
{ //needs to be enabled, make sure it was (DEBUG TEMPORARY)
|
||||
if (i > 0 && !glIsEnabled(array[i]))
|
||||
{
|
||||
|
|
@ -137,29 +139,55 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
|||
{ //needs to be enabled
|
||||
glEnableClientState(array[i]);
|
||||
}
|
||||
else if (glIsEnabled(array[i]))
|
||||
else if (gDebugGL && glIsEnabled(array[i]))
|
||||
{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
|
||||
llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sLastMask & MAP_TEXCOORD2)
|
||||
U32 map_tc[] =
|
||||
{
|
||||
if (!(data_mask & MAP_TEXCOORD2))
|
||||
MAP_TEXCOORD1,
|
||||
MAP_TEXCOORD2,
|
||||
MAP_TEXCOORD3
|
||||
};
|
||||
|
||||
for (U32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (sLastMask & map_tc[i])
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
if (!(data_mask & map_tc[i]))
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
}
|
||||
else if (data_mask & map_tc[i])
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
}
|
||||
|
||||
if (sLastMask & MAP_BINORMAL)
|
||||
{
|
||||
if (!(data_mask & MAP_BINORMAL))
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
}
|
||||
else if (data_mask & MAP_TEXCOORD2)
|
||||
else if (data_mask & MAP_BINORMAL)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
|
||||
|
||||
sLastMask = data_mask;
|
||||
}
|
||||
}
|
||||
|
|
@ -194,6 +222,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
|
|||
return;
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
|
||||
((U16*) getIndicesPointer()) + indices_offset);
|
||||
stop_glerror();
|
||||
|
|
@ -223,13 +252,14 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
|
|||
return;
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
|
||||
((U16*) getIndicesPointer()) + indices_offset);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
|
||||
{
|
||||
|
||||
if (first >= (U32) mRequestedNumVerts ||
|
||||
first + count > (U32) mRequestedNumVerts)
|
||||
{
|
||||
|
|
@ -247,6 +277,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
|
|||
return;
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
glDrawArrays(sGLMode[mode], first, count);
|
||||
stop_glerror();
|
||||
}
|
||||
|
|
@ -767,11 +798,7 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
|
|||
stop_glerror();
|
||||
mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
stop_glerror();
|
||||
/*if (sMapped)
|
||||
{
|
||||
llerrs << "Mapped two VBOs at the same time!" << llendl;
|
||||
}
|
||||
sMapped = TRUE;*/
|
||||
|
||||
if (!mMappedData)
|
||||
{
|
||||
//--------------------
|
||||
|
|
@ -896,14 +923,22 @@ bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index)
|
|||
{
|
||||
return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index);
|
||||
}
|
||||
bool LLVertexBuffer::getTexCoordStrider(LLStrider<LLVector2>& strider, S32 index)
|
||||
bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD>::get(*this, strider, index);
|
||||
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index);
|
||||
}
|
||||
bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index)
|
||||
bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index);
|
||||
}
|
||||
/*bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index);
|
||||
}
|
||||
bool LLVertexBuffer::getTexCoord3Strider(LLStrider<LLVector2>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD3>::get(*this, strider, index);
|
||||
}*/
|
||||
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index);
|
||||
|
|
@ -1101,24 +1136,39 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
|
|||
{
|
||||
glNormalPointer(GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_NORMAL]));
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD3)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE3_ARB);
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD3]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD2)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD2]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD)
|
||||
if (data_mask & MAP_TEXCOORD1)
|
||||
{
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD]));
|
||||
glClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD1]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_BINORMAL)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glTexCoordPointer(3,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_BINORMAL]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD0)
|
||||
{
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD0]));
|
||||
}
|
||||
if (data_mask & MAP_COLOR)
|
||||
{
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)(base + mOffsets[TYPE_COLOR]));
|
||||
}
|
||||
if (data_mask & MAP_BINORMAL)
|
||||
{
|
||||
glVertexAttribPointerARB(6, 3, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_BINORMAL]));
|
||||
}
|
||||
|
||||
if (data_mask & MAP_WEIGHT)
|
||||
{
|
||||
glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT]));
|
||||
|
|
|
|||
|
|
@ -100,8 +100,10 @@ public:
|
|||
enum {
|
||||
TYPE_VERTEX,
|
||||
TYPE_NORMAL,
|
||||
TYPE_TEXCOORD,
|
||||
TYPE_TEXCOORD0,
|
||||
TYPE_TEXCOORD1,
|
||||
TYPE_TEXCOORD2,
|
||||
TYPE_TEXCOORD3,
|
||||
TYPE_COLOR,
|
||||
// These use VertexAttribPointer and should possibly be made generic
|
||||
TYPE_BINORMAL,
|
||||
|
|
@ -113,16 +115,15 @@ public:
|
|||
enum {
|
||||
MAP_VERTEX = (1<<TYPE_VERTEX),
|
||||
MAP_NORMAL = (1<<TYPE_NORMAL),
|
||||
MAP_TEXCOORD = (1<<TYPE_TEXCOORD),
|
||||
MAP_TEXCOORD0 = (1<<TYPE_TEXCOORD0),
|
||||
MAP_TEXCOORD1 = (1<<TYPE_TEXCOORD1),
|
||||
MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
|
||||
MAP_TEXCOORD3 = (1<<TYPE_TEXCOORD3),
|
||||
MAP_COLOR = (1<<TYPE_COLOR),
|
||||
// These use VertexAttribPointer and should possibly be made generic
|
||||
MAP_BINORMAL = (1<<TYPE_BINORMAL),
|
||||
MAP_WEIGHT = (1<<TYPE_WEIGHT),
|
||||
MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
|
||||
MAP_DRAW = 0x2000, // Buffer is in draw (read-only) mode
|
||||
MAP_MAPPED = 0x4000, // Indicates that buffer has been mapped, but not to any type of data
|
||||
MAP_UNMAPPED = 0x8000 // Indicates that buffer has been logically un-mapped
|
||||
};
|
||||
|
||||
protected:
|
||||
|
|
@ -165,8 +166,8 @@ public:
|
|||
// vb->unmapBuffer();
|
||||
bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0);
|
||||
bool getIndexStrider(LLStrider<U16>& strider, S32 index=0);
|
||||
bool getTexCoordStrider(LLStrider<LLVector2>& strider, S32 index=0);
|
||||
bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0);
|
||||
bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0);
|
||||
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0);
|
||||
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
|
||||
bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
|
||||
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0);
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ void LLLineEditor::setCursor( S32 pos )
|
|||
{
|
||||
S32 width_chars_to_left = mGLFont->getWidth(mText.getWString().c_str(), 0, mScrollHPos);
|
||||
S32 last_visible_char = mGLFont->maxDrawableChars(mText.getWString().c_str(), llmax(0.f, (F32)(mMaxHPixels - mMinHPixels + width_chars_to_left)));
|
||||
S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mMaxHPixels - mMinHPixels), mText.length(), getCursor());
|
||||
S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mMaxHPixels - mMinHPixels - UI_LINEEDITOR_CURSOR_THICKNESS - UI_LINEEDITOR_H_PAD), mText.length(), getCursor());
|
||||
if (old_cursor_pos == last_visible_char)
|
||||
{
|
||||
mScrollHPos = llmin(mText.length(), llmax(min_scroll, mScrollHPos + SCROLL_INCREMENT_ADD));
|
||||
|
|
|
|||
|
|
@ -232,8 +232,7 @@ void LLViewBorder::drawTextures()
|
|||
//gGL.color4fv(UI_VERTEX_COLOR.mV);
|
||||
|
||||
//gGL.getTexUnit(0)->bind(mTexture);
|
||||
//glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
//glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
//gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
|
||||
|
||||
//drawTextureTrapezoid( 0.f, mBorderWidth, getRect().getWidth(), 0, 0 );
|
||||
//drawTextureTrapezoid( 90.f, mBorderWidth, getRect().getHeight(), (F32)getRect().getWidth(),0 );
|
||||
|
|
|
|||
|
|
@ -73,6 +73,10 @@ LLLFSThread::LLLFSThread(bool threaded) :
|
|||
LLQueuedThread("LFS", threaded),
|
||||
mPriorityCounter(PRIORITY_LOWBITS)
|
||||
{
|
||||
if(!mLocalAPRFilePoolp)
|
||||
{
|
||||
mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
|
||||
}
|
||||
}
|
||||
|
||||
LLLFSThread::~LLLFSThread()
|
||||
|
|
@ -184,8 +188,9 @@ bool LLLFSThread::Request::processRequest()
|
|||
if (mOperation == FILE_READ)
|
||||
{
|
||||
llassert(mOffset >= 0);
|
||||
apr_file_t* filep = ll_apr_file_open(mFileName, LL_APR_RB, mThread->mAPRPoolp);
|
||||
if (!filep)
|
||||
LLAPRFile infile ;
|
||||
infile.open(mThread->getLocalAPRFilePool(), mFileName, LL_APR_RB);
|
||||
if (!infile.getFileHandle())
|
||||
{
|
||||
llwarns << "LLLFS: Unable to read file: " << mFileName << llendl;
|
||||
mBytesRead = 0; // fail
|
||||
|
|
@ -193,13 +198,13 @@ bool LLLFSThread::Request::processRequest()
|
|||
}
|
||||
S32 off;
|
||||
if (mOffset < 0)
|
||||
off = ll_apr_file_seek(filep, APR_END, 0);
|
||||
off = infile.seek(APR_END, 0);
|
||||
else
|
||||
off = ll_apr_file_seek(filep, APR_SET, mOffset);
|
||||
off = infile.seek(APR_SET, mOffset);
|
||||
llassert_always(off >= 0);
|
||||
mBytesRead = ll_apr_file_read(filep, mBuffer, mBytes );
|
||||
apr_file_close(filep);
|
||||
mBytesRead = infile.read(mBuffer, mBytes );
|
||||
complete = true;
|
||||
infile.close() ;
|
||||
// llinfos << "LLLFSThread::READ:" << mFileName << " Bytes: " << mBytesRead << llendl;
|
||||
}
|
||||
else if (mOperation == FILE_WRITE)
|
||||
|
|
@ -207,8 +212,9 @@ bool LLLFSThread::Request::processRequest()
|
|||
apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
|
||||
if (mOffset < 0)
|
||||
flags |= APR_APPEND;
|
||||
apr_file_t* filep = ll_apr_file_open(mFileName, flags, mThread->mAPRPoolp);
|
||||
if (!filep)
|
||||
LLAPRFile outfile ;
|
||||
outfile.open(mThread->getLocalAPRFilePool(), mFileName, flags);
|
||||
if (!outfile.getFileHandle())
|
||||
{
|
||||
llwarns << "LLLFS: Unable to write file: " << mFileName << llendl;
|
||||
mBytesRead = 0; // fail
|
||||
|
|
@ -216,18 +222,17 @@ bool LLLFSThread::Request::processRequest()
|
|||
}
|
||||
if (mOffset >= 0)
|
||||
{
|
||||
S32 seek = ll_apr_file_seek(filep, APR_SET, mOffset);
|
||||
S32 seek = outfile.seek(APR_SET, mOffset);
|
||||
if (seek < 0)
|
||||
{
|
||||
apr_file_close(filep);
|
||||
llwarns << "LLLFS: Unable to write file (seek failed): " << mFileName << llendl;
|
||||
mBytesRead = 0; // fail
|
||||
return true;
|
||||
}
|
||||
}
|
||||
mBytesRead = ll_apr_file_write(filep, mBuffer, mBytes );
|
||||
mBytesRead = outfile.write(mBuffer, mBytes );
|
||||
complete = true;
|
||||
apr_file_close(filep);
|
||||
|
||||
// llinfos << "LLLFSThread::WRITE:" << mFileName << " Bytes: " << mBytesRead << "/" << mBytes << " Offset:" << mOffset << llendl;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -2070,9 +2070,11 @@ void LLVFS::dumpFiles()
|
|||
std::string extension = get_extension(type);
|
||||
std::string filename = id.asString() + extension;
|
||||
llinfos << " Writing " << filename << llendl;
|
||||
apr_file_t* file = ll_apr_file_open(filename, LL_APR_WB);
|
||||
ll_apr_file_write(file, buffer, size);
|
||||
apr_file_close(file);
|
||||
|
||||
LLAPRFile outfile ;
|
||||
outfile.open(filename, LL_APR_WB);
|
||||
outfile.write(buffer, size);
|
||||
outfile.close();
|
||||
delete[] buffer;
|
||||
files_extracted++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ static SDL_Surface *Load_BMP_Resource(const char *basename)
|
|||
#if LL_X11
|
||||
// This is an XFree86/XOrg-specific hack for detecting the amount of Video RAM
|
||||
// on this machine. It works by searching /var/log/var/log/Xorg.?.log or
|
||||
// /var/log/XFree86.?.log for a ': (VideoRAM|Memory): (%d+) kB' regex, where
|
||||
// /var/log/XFree86.?.log for a ': (VideoRAM ?|Memory): (%d+) kB' regex, where
|
||||
// '?' is the X11 display number derived from $DISPLAY
|
||||
static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str)
|
||||
{
|
||||
|
|
@ -285,6 +285,8 @@ static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str)
|
|||
// favourite regex implementation - libboost_regex - is
|
||||
// quite a heavy and troublesome dependency for the client, so
|
||||
// it seems a shame to introduce it for such a simple task.
|
||||
// *FIXME: libboost_regex is a dependency now anyway, so we may
|
||||
// as well use it instead of this hand-rolled nonsense.
|
||||
const char *part1_template = prefix_str;
|
||||
const char part2_template[] = " kB";
|
||||
char *part1 = strstr(line_buf, part1_template);
|
||||
|
|
@ -361,8 +363,17 @@ static int x11_detect_VRAM_kb()
|
|||
fp = fopen(fname.c_str(), "r");
|
||||
if (fp)
|
||||
{
|
||||
rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: ");
|
||||
rtn = x11_detect_VRAM_kb_fp(fp, ": Video RAM: ");
|
||||
fclose(fp);
|
||||
if (0 == rtn)
|
||||
{
|
||||
fp = fopen(fname.c_str(), "r");
|
||||
if (fp)
|
||||
{
|
||||
rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: ");
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -373,6 +373,8 @@ LLWindowWin32::LLWindowWin32(const std::string& title, const std::string& name,
|
|||
mMousePositionModified = FALSE;
|
||||
mInputProcessingPaused = FALSE;
|
||||
mPreeditor = NULL;
|
||||
mhDC = NULL;
|
||||
mhRC = NULL;
|
||||
|
||||
// Initialize the keyboard
|
||||
gKeyboard = new LLKeyboardWin32();
|
||||
|
|
@ -418,7 +420,7 @@ LLWindowWin32::LLWindowWin32(const std::string& title, const std::string& name,
|
|||
mhInstance = GetModuleHandle(NULL);
|
||||
mWndProc = NULL;
|
||||
|
||||
mSwapMethod = SWAP_METHOD_EXCHANGE;
|
||||
mSwapMethod = SWAP_METHOD_UNDEFINED;
|
||||
|
||||
// No WPARAM yet.
|
||||
mLastSizeWParam = 0;
|
||||
|
|
@ -844,8 +846,13 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
|
|||
RECT window_rect;
|
||||
S32 width = size.mX;
|
||||
S32 height = size.mY;
|
||||
BOOL auto_show = FALSE;
|
||||
|
||||
resetDisplayResolution();
|
||||
if (mhRC)
|
||||
{
|
||||
auto_show = TRUE;
|
||||
resetDisplayResolution();
|
||||
}
|
||||
|
||||
if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode))
|
||||
{
|
||||
|
|
@ -1183,8 +1190,28 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
|
|||
LL_INFOS("Window") << "Choosing pixel formats: " << num_formats << " pixel formats returned" << LL_ENDL;
|
||||
}
|
||||
|
||||
pixel_format = pixel_formats[0];
|
||||
|
||||
|
||||
S32 swap_method = 0;
|
||||
S32 cur_format = num_formats-1;
|
||||
GLint swap_query = WGL_SWAP_METHOD_ARB;
|
||||
|
||||
BOOL found_format = FALSE;
|
||||
|
||||
while (!found_format && wglGetPixelFormatAttribivARB(mhDC, pixel_format, 0, 1, &swap_query, &swap_method))
|
||||
{
|
||||
if (swap_method == WGL_SWAP_UNDEFINED_ARB || cur_format <= 0)
|
||||
{
|
||||
found_format = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
--cur_format;
|
||||
}
|
||||
}
|
||||
|
||||
pixel_format = pixel_formats[cur_format];
|
||||
|
||||
if (mhDC != 0) // Does The Window Have A Device Context?
|
||||
{
|
||||
wglMakeCurrent(mhDC, 0); // Set The Current Active Rendering Context To Zero
|
||||
|
|
@ -1227,9 +1254,6 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
int swap_method = 0;
|
||||
GLint swap_query = WGL_SWAP_METHOD_ARB;
|
||||
|
||||
if (wglGetPixelFormatAttribivARB(mhDC, pixel_format, 0, 1, &swap_query, &swap_method))
|
||||
{
|
||||
switch (swap_method)
|
||||
|
|
@ -1342,13 +1366,21 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
|
|||
}
|
||||
|
||||
SetWindowLong(mWindowHandle, GWL_USERDATA, (U32)this);
|
||||
show();
|
||||
|
||||
|
||||
//register joystick timer callback
|
||||
SetTimer( mWindowHandle, 0, 1000 / 30, NULL ); // 30 fps timer
|
||||
|
||||
// ok to post quit messages now
|
||||
mPostQuit = TRUE;
|
||||
|
||||
if (auto_show)
|
||||
{
|
||||
show();
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
swapBuffers();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ include(LScript)
|
|||
include(Linking)
|
||||
include(Mozlib)
|
||||
include(NDOF)
|
||||
include(GooglePerfTools)
|
||||
include(TemplateCheck)
|
||||
include(UI)
|
||||
include(UnixInstall)
|
||||
|
|
@ -1330,8 +1331,8 @@ if (WINDOWS)
|
|||
|
||||
set_target_properties(${VIEWER_BINARY_NAME}
|
||||
PROPERTIES
|
||||
LINK_FLAGS "/debug /NODEFAULTLIB:MSVCRT /SUBSYSTEM:WINDOWS"
|
||||
LINK_FLAGS_DEBUG "/NODEFAULTLIB:LIBCMT /NODEFAULTLIB:MSVCRTD"
|
||||
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS"
|
||||
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\""
|
||||
LINK_FLAGS_RELEASE ${release_flags}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
</array>
|
||||
<key>tags</key>
|
||||
<array>
|
||||
<string>ShaderLoading</string>
|
||||
</array>
|
||||
</map>
|
||||
</array>
|
||||
|
|
|
|||
|
|
@ -2256,7 +2256,18 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>DebugShowTime</key>
|
||||
<key>DebugShowRenderMatrices</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Display values of current view and projection matrices.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>DebugShowTime</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show depth buffer contents</string>
|
||||
|
|
@ -2635,6 +2646,17 @@
|
|||
<key>Value</key>
|
||||
<real>60.0</real>
|
||||
</map>
|
||||
<key>FPSLogFrequency</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Seconds between display of FPS in log (0 for never)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>10.0</real>
|
||||
</map>
|
||||
<key>FilterItemsPerFrame</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -6141,7 +6163,102 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderBumpmapMinDistanceSquared</key>
|
||||
|
||||
<key>RenderShadowGaussian</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Gaussian coefficients for the two shadow/SSAO blurring passes (z component unused).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>2.0</real>
|
||||
<real>2.0</real>
|
||||
<real>0.0</real>
|
||||
</array>
|
||||
</map>
|
||||
|
||||
<key>RenderShadowNearDist</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Near clip plane of shadow camera (affects precision of depth shadows).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>256</real>
|
||||
<real>256</real>
|
||||
<real>256</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>RenderShadowClipPlanes</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Near clip plane split distances for shadow map frusta.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>4.0</real>
|
||||
<real>8.0</real>
|
||||
<real>24.0</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>RenderSSAOScale</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Scaling factor for the area to sample for occluders (pixels at 1 meter away, inversely varying with distance)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>500.0</real>
|
||||
</map>
|
||||
<key>RenderSSAOMaxScale</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Maximum screen radius for sampling (pixels)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>60</integer>
|
||||
</map>
|
||||
<key>RenderSSAOFactor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Occlusion sensitivity factor for ambient occlusion (larger is more)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.30</real>
|
||||
</map>
|
||||
<key>RenderSSAOEffect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Multiplier for (1) value and (2) saturation (HSV definition), for areas which are totally occluded. Blends with original color for partly-occluded areas. (Third component is unused.)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>0.40</real>
|
||||
<real>1.00</real>
|
||||
<real>0.00</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>RenderBumpmapMinDistanceSquared</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Maximum distance at which to render bumpmapped primitives (distance in meters, squared)</string>
|
||||
|
|
@ -6152,6 +6269,17 @@
|
|||
<key>Value</key>
|
||||
<real>100.0</real>
|
||||
</map>
|
||||
<key>RenderNormalMapScale</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Scaler applied to height map when generating normal maps</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>128</real>
|
||||
</map>
|
||||
<key>RenderCubeMap</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -6192,7 +6320,7 @@
|
|||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
|
@ -6207,18 +6335,129 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderDeferred</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use deferred rendering pipeline.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderDynamicLOD</key>
|
||||
<key>RenderDelayCreation</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Throttle creation of drawables.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderAnimateRes</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Animate rezing prims.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
||||
<key>RenderAnimateTrees</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use GL matrix ops to animate tree branches.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderDeferredAlphaSoften</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Scalar for softening alpha surfaces (for soft particles).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.75</real>
|
||||
</map>
|
||||
<key>RenderDeferredNoise</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Noise scalar to hide banding in deferred render.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>4</real>
|
||||
</map>
|
||||
<key>RenderDeferred</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use deferred rendering pipeline.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderDeferredSunShadow</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Generate shadows from the sun.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderDeferredSunWash</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Amount local lights are washed out by sun.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.5</real>
|
||||
</map>
|
||||
<key>RenderShadowNoise</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Magnitude of noise on shadow samples.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>-0.0001</real>
|
||||
</map>
|
||||
<key>RenderShadowBlurSize</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Scale of shadow softening kernel.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.7</real>
|
||||
</map>
|
||||
<key>RenderShadowBlurSamples</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Number of samples to take for each pass of shadow blur (value range 1-16). Actual number of samples is value * 2 - 1.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<real>5</real>
|
||||
</map>
|
||||
<key>RenderDynamicLOD</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Dynamically adjust level of detail.</string>
|
||||
|
|
@ -6368,13 +6607,13 @@
|
|||
<key>RenderGlowMinLuminance</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Min luminance intensity necessary to consider an object bright enough to automatically glow. (Gets clamped to 0 - 1.0 range)</string>
|
||||
<string>Min luminance intensity necessary to consider an object bright enough to automatically glow.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
<real>2.5</real>
|
||||
</map>
|
||||
<key>RenderGlowResolutionPow</key>
|
||||
<map>
|
||||
|
|
@ -6534,6 +6773,17 @@
|
|||
<key>Value</key>
|
||||
<integer>4096</integer>
|
||||
</map>
|
||||
<key>RenderMaxNodeSize</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Maximum size of a single node's vertex data (in KB).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>4096</integer>
|
||||
</map>
|
||||
<key>RenderMaxVBOSize</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -6543,7 +6793,7 @@
|
|||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>32</integer>
|
||||
<integer>512</integer>
|
||||
</map>
|
||||
<key>RenderName</key>
|
||||
<map>
|
||||
|
|
@ -6644,6 +6894,17 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderShaderLightingMaxLevel</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Max lighting level to use in the shader (class 3 is default, 2 is less lights, 1 is sun/moon only. Works around shader compiler bugs on certain platforms.)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>3</integer>
|
||||
</map>
|
||||
<key>RenderShaderLODThreshold</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -9760,6 +10021,17 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderDelayVBUpdate</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Delay vertex buffer updates until just before rendering</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>UseStartScreen</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -10507,7 +10779,7 @@
|
|||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>WindowWidth</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* @file alphaF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2DRect positionMap;
|
||||
|
||||
uniform mat4 shadow_matrix[4];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
vec3 atmosLighting(vec3 light);
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
||||
varying vec3 vary_ambient;
|
||||
varying vec3 vary_directional;
|
||||
varying vec3 vary_fragcoord;
|
||||
varying vec3 vary_position;
|
||||
|
||||
uniform float alpha_soften;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
|
||||
frag *= screen_res;
|
||||
|
||||
vec3 samp_pos = texture2DRect(positionMap, frag).xyz;
|
||||
|
||||
float shadow = 1.0;
|
||||
vec4 pos = vec4(vary_position, 1.0);
|
||||
|
||||
if (pos.z > -shadow_clip.w)
|
||||
{
|
||||
if (pos.z < -shadow_clip.z)
|
||||
{
|
||||
vec4 lpos = shadow_matrix[3]*pos;
|
||||
shadow = shadow2DProj(shadowMap3, lpos).x;
|
||||
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
|
||||
}
|
||||
else if (pos.z < -shadow_clip.y)
|
||||
{
|
||||
vec4 lpos = shadow_matrix[2]*pos;
|
||||
shadow = shadow2DProj(shadowMap2, lpos).x;
|
||||
}
|
||||
else if (pos.z < -shadow_clip.x)
|
||||
{
|
||||
vec4 lpos = shadow_matrix[1]*pos;
|
||||
shadow = shadow2DProj(shadowMap1, lpos).x;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec4 lpos = shadow_matrix[0]*pos;
|
||||
shadow = shadow2DProj(shadowMap0, lpos).x;
|
||||
}
|
||||
}
|
||||
|
||||
vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, gl_Color.a);
|
||||
vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col;
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
if (samp_pos.z != 0.0)
|
||||
{
|
||||
float dist_factor = alpha_soften;
|
||||
float a = gl_Color.a;
|
||||
a *= a;
|
||||
dist_factor *= 1.0/(1.0-a);
|
||||
color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0);
|
||||
}
|
||||
|
||||
//gl_FragColor = gl_Color;
|
||||
gl_FragColor = color;
|
||||
//gl_FragColor = vec4(1,0,1,1);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* @file alphaV.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l);
|
||||
float calcPointLight(vec3 v, vec3 n, vec4 lp, float la);
|
||||
|
||||
vec3 atmosAmbient(vec3 light);
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity);
|
||||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
varying vec3 vary_ambient;
|
||||
varying vec3 vary_directional;
|
||||
varying vec3 vary_fragcoord;
|
||||
varying vec3 vary_position;
|
||||
|
||||
uniform float near_clip;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = ftransform();
|
||||
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
|
||||
vec4 pos = (gl_ModelViewMatrix * gl_Vertex);
|
||||
vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
|
||||
vary_position = pos.xyz;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
|
||||
vec4 col;
|
||||
col.a = gl_Color.a;
|
||||
|
||||
// Add windlight lights
|
||||
col.rgb = atmosAmbient(vec3(0.));
|
||||
col.rgb = scaleUpLight(col.rgb);
|
||||
|
||||
// Collect normal lights (need to be divided by two, as we later multiply by 2)
|
||||
col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation);
|
||||
col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation);
|
||||
col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation);
|
||||
col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation);
|
||||
col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation);
|
||||
col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation);
|
||||
col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
|
||||
col.rgb = scaleDownLight(col.rgb);
|
||||
|
||||
vary_ambient = col.rgb*gl_Color.rgb;
|
||||
vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a)));
|
||||
|
||||
col.rgb = min(col.rgb*gl_Color.rgb, 1.0);
|
||||
|
||||
gl_FrontColor = col;
|
||||
|
||||
gl_FogFragCoord = pos.z;
|
||||
|
||||
pos = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* @file avatarAlphaF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2D noiseMap;
|
||||
|
||||
uniform mat4 shadow_matrix[4];
|
||||
uniform vec4 shadow_clip;
|
||||
|
||||
vec3 atmosLighting(vec3 light);
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
||||
varying vec3 vary_ambient;
|
||||
varying vec3 vary_directional;
|
||||
varying vec4 vary_position;
|
||||
varying vec3 vary_normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
float shadow = 1.0;
|
||||
vec4 pos = vary_position;
|
||||
vec3 norm = normalize(vary_normal);
|
||||
|
||||
vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz;
|
||||
|
||||
if (pos.z > -shadow_clip.w)
|
||||
{
|
||||
|
||||
if (pos.z < -shadow_clip.z)
|
||||
{
|
||||
vec4 lpos = shadow_matrix[3]*pos;
|
||||
shadow = shadow2DProj(shadowMap3, lpos).x;
|
||||
}
|
||||
else if (pos.z < -shadow_clip.y)
|
||||
{
|
||||
vec4 lpos = shadow_matrix[2]*pos;
|
||||
shadow = shadow2DProj(shadowMap2, lpos).x;
|
||||
}
|
||||
else if (pos.z < -shadow_clip.x)
|
||||
{
|
||||
vec4 lpos = shadow_matrix[1]*pos;
|
||||
shadow = shadow2DProj(shadowMap1, lpos).x;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec4 lpos = shadow_matrix[0]*pos;
|
||||
shadow = shadow2DProj(shadowMap0, lpos).x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vec4 col = vec4(vary_ambient + vary_directional*shadow, gl_Color.a);
|
||||
vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col;
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
gl_FragColor = color;
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* @file avatarAlphaV.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
mat4 getSkinnedTransform();
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l);
|
||||
float calcPointLight(vec3 v, vec3 n, vec4 lp, float la);
|
||||
|
||||
vec3 atmosAmbient(vec3 light);
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity);
|
||||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
varying vec4 vary_position;
|
||||
varying vec3 vary_ambient;
|
||||
varying vec3 vary_directional;
|
||||
varying vec3 vary_normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
vec4 pos;
|
||||
vec3 norm;
|
||||
|
||||
mat4 trans = getSkinnedTransform();
|
||||
pos.x = dot(trans[0], gl_Vertex);
|
||||
pos.y = dot(trans[1], gl_Vertex);
|
||||
pos.z = dot(trans[2], gl_Vertex);
|
||||
pos.w = 1.0;
|
||||
|
||||
norm.x = dot(trans[0].xyz, gl_Normal);
|
||||
norm.y = dot(trans[1].xyz, gl_Normal);
|
||||
norm.z = dot(trans[2].xyz, gl_Normal);
|
||||
norm = normalize(norm);
|
||||
|
||||
gl_Position = gl_ProjectionMatrix * pos;
|
||||
vary_position = pos;
|
||||
vary_normal = norm;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
|
||||
vec4 col;
|
||||
col.a = gl_Color.a;
|
||||
|
||||
// Add windlight lights
|
||||
col.rgb = atmosAmbient(vec3(0.));
|
||||
col.rgb = scaleUpLight(col.rgb);
|
||||
|
||||
// Collect normal lights (need to be divided by two, as we later multiply by 2)
|
||||
col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation);
|
||||
col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation);
|
||||
col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation);
|
||||
col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation);
|
||||
col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation);
|
||||
col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation);
|
||||
col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
|
||||
col.rgb = scaleDownLight(col.rgb);
|
||||
|
||||
vary_ambient = col.rgb*gl_Color.rgb;
|
||||
vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a)));
|
||||
|
||||
col.rgb = min(col.rgb*gl_Color.rgb, 1.0);
|
||||
|
||||
gl_FrontColor = col;
|
||||
|
||||
gl_FogFragCoord = pos.z;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* @file avatarF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
varying vec3 vary_normal;
|
||||
varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy);
|
||||
gl_FragData[1] = vec4(0,0,0,0);
|
||||
gl_FragData[2] = vec4(normalize(vary_normal), 0.0);
|
||||
gl_FragData[3] = vary_position;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* @file avatarShadowF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy));
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* @file avatarShadowV.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
mat4 getSkinnedTransform();
|
||||
|
||||
attribute vec4 weight;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
vec4 pos;
|
||||
vec3 norm;
|
||||
|
||||
mat4 trans = getSkinnedTransform();
|
||||
pos.x = dot(trans[0], gl_Vertex);
|
||||
pos.y = dot(trans[1], gl_Vertex);
|
||||
pos.z = dot(trans[2], gl_Vertex);
|
||||
pos.w = 1.0;
|
||||
|
||||
norm.x = dot(trans[0].xyz, gl_Normal);
|
||||
norm.y = dot(trans[1].xyz, gl_Normal);
|
||||
norm.z = dot(trans[2].xyz, gl_Normal);
|
||||
norm = normalize(norm);
|
||||
|
||||
pos = gl_ProjectionMatrix * pos;
|
||||
//smash geometry against near clip plane
|
||||
pos.z = max(pos.z, -1.0);
|
||||
gl_Position = pos;
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* @file avatarV.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
mat4 getSkinnedTransform();
|
||||
|
||||
attribute vec4 weight;
|
||||
|
||||
varying vec3 vary_normal;
|
||||
varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
vec4 pos;
|
||||
vec3 norm;
|
||||
|
||||
mat4 trans = getSkinnedTransform();
|
||||
pos.x = dot(trans[0], gl_Vertex);
|
||||
pos.y = dot(trans[1], gl_Vertex);
|
||||
pos.z = dot(trans[2], gl_Vertex);
|
||||
pos.w = 1.0;
|
||||
|
||||
norm.x = dot(trans[0].xyz, gl_Normal);
|
||||
norm.y = dot(trans[1].xyz, gl_Normal);
|
||||
norm.z = dot(trans[2].xyz, gl_Normal);
|
||||
norm = normalize(norm);
|
||||
|
||||
vary_position = pos;
|
||||
vary_normal = norm;
|
||||
|
||||
gl_Position = gl_ProjectionMatrix * pos;
|
||||
//gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* @file blurLightF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
uniform sampler2DRect positionMap;
|
||||
uniform sampler2DRect normalMap;
|
||||
uniform sampler2DRect lightMap;
|
||||
|
||||
uniform float blur_size;
|
||||
uniform vec2 delta;
|
||||
uniform vec3 kern[32];
|
||||
uniform int kern_length;
|
||||
uniform float kern_scale;
|
||||
|
||||
varying vec2 vary_fragcoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;
|
||||
vec3 pos = texture2DRect(positionMap, vary_fragcoord.xy).xyz;
|
||||
vec2 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rg;
|
||||
|
||||
vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
|
||||
|
||||
vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
|
||||
vec2 col = defined_weight * ccol;
|
||||
|
||||
for (int i = 1; i < kern_length; i++)
|
||||
{
|
||||
vec2 tc = vary_fragcoord.xy + kern[i].z*dlt;
|
||||
vec3 samppos = texture2DRect(positionMap, tc).xyz;
|
||||
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
|
||||
if (d*d <= 0.003)
|
||||
{
|
||||
col += texture2DRect(lightMap, tc).rg*kern[i].xy;
|
||||
defined_weight += kern[i].xy;
|
||||
}
|
||||
}
|
||||
|
||||
col /= defined_weight;
|
||||
|
||||
gl_FragColor = vec4(col.r, col.g, 0.0, 1.0);
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* @file blurLightF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
varying vec2 vary_fragcoord;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = ftransform();
|
||||
vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* @file bumpF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2D bumpMap;
|
||||
|
||||
varying vec3 vary_mat0;
|
||||
varying vec3 vary_mat1;
|
||||
varying vec3 vary_mat2;
|
||||
varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb;
|
||||
vec3 norm = texture2D(bumpMap, gl_TexCoord[0].xy).rgb * 2.0 - 1.0;
|
||||
|
||||
vec3 tnorm = vec3(dot(norm,vary_mat0),
|
||||
dot(norm,vary_mat1),
|
||||
dot(norm,vary_mat2));
|
||||
|
||||
gl_FragData[0].rgb = gl_Color.rgb*col;
|
||||
gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a);
|
||||
gl_FragData[2] = vec4(normalize(tnorm), 0.0);
|
||||
gl_FragData[3] = vary_position;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* @file bumpV.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
varying vec3 vary_mat0;
|
||||
varying vec3 vary_mat1;
|
||||
varying vec3 vary_mat2;
|
||||
varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = ftransform();
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
|
||||
vary_position = gl_ModelViewMatrix * gl_Vertex;
|
||||
|
||||
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
|
||||
vec3 b = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz);
|
||||
vec3 t = cross(b, n);
|
||||
|
||||
vary_mat0 = vec3(t.x, b.x, n.x);
|
||||
vary_mat1 = vec3(t.y, b.y, n.y);
|
||||
vary_mat2 = vec3(t.z, b.z, n.z);
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
|
@ -8,9 +8,13 @@
|
|||
uniform sampler2D diffuseMap;
|
||||
|
||||
varying vec3 vary_normal;
|
||||
varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy);
|
||||
gl_FragColor.rgb = vary_normal*0.5+0.5;
|
||||
vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb;
|
||||
gl_FragData[0] = vec4(gl_Color.rgb*col, 1.0);
|
||||
gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a);
|
||||
gl_FragData[2] = vec4(normalize(vary_normal), 0.0);
|
||||
gl_FragData[3] = vary_position;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
varying vec3 vary_normal;
|
||||
varying vec3 vary_position;
|
||||
varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
@ -14,7 +14,7 @@ void main()
|
|||
gl_Position = ftransform();
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
|
||||
vary_position = (gl_ModelViewMatrix * gl_Vertex).xyz;
|
||||
vary_position = gl_ModelViewMatrix * gl_Vertex;
|
||||
|
||||
vary_normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* @file fullbrightF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2DRect positionMap;
|
||||
|
||||
uniform mat4 shadow_matrix[4];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light);
|
||||
vec3 fullbrightScaleSoftClip(vec3 light);
|
||||
|
||||
varying vec3 vary_ambient;
|
||||
varying vec3 vary_directional;
|
||||
varying vec4 vary_position;
|
||||
varying vec3 vary_normal;
|
||||
varying vec3 vary_fragcoord;
|
||||
|
||||
uniform float alpha_soften;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
|
||||
frag *= screen_res;
|
||||
|
||||
vec3 samp_pos = texture2DRect(positionMap, frag).xyz;
|
||||
|
||||
float shadow = 1.0;
|
||||
vec4 pos = vary_position;
|
||||
|
||||
vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy)*gl_Color;
|
||||
|
||||
color.rgb = fullbrightAtmosTransport(color.rgb);
|
||||
|
||||
color.rgb = fullbrightScaleSoftClip(color.rgb);
|
||||
|
||||
if (samp_pos.z != 0.0)
|
||||
{
|
||||
float dist_factor = alpha_soften;
|
||||
float a = gl_Color.a;
|
||||
a *= a;
|
||||
dist_factor *= 1.0/(1.0-a);
|
||||
color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0);
|
||||
}
|
||||
|
||||
//gl_FragColor = gl_Color;
|
||||
gl_FragColor = color;
|
||||
//gl_FragColor = vec4(1,0,1,1);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @file fullbrightV.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
vec3 atmosAmbient(vec3 light);
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity);
|
||||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
varying vec4 vary_position;
|
||||
varying vec3 vary_ambient;
|
||||
varying vec3 vary_directional;
|
||||
varying vec3 vary_normal;
|
||||
varying vec3 vary_fragcoord;
|
||||
uniform float near_clip;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = ftransform();
|
||||
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
|
||||
vec4 pos = (gl_ModelViewMatrix * gl_Vertex);
|
||||
vary_position = pos;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
|
||||
gl_FogFragCoord = pos.z;
|
||||
|
||||
pos = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* @file impostorF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2D normalMap;
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragData[0] = texture2D(diffuseMap, gl_TexCoord[0].xy);
|
||||
gl_FragData[1] = texture2D(specularMap, gl_TexCoord[0].xy);
|
||||
gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, vary_position.z);
|
||||
gl_FragData[3] = vary_position;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* @file impostorV.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = ftransform();
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
|
||||
vary_position = gl_ModelViewMatrix * gl_Vertex;
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* @file multiPointLightF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
uniform sampler2DRect diffuseRect;
|
||||
uniform sampler2DRect specularRect;
|
||||
uniform sampler2DRect positionMap;
|
||||
uniform sampler2DRect normalMap;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform sampler2DRect lightMap;
|
||||
uniform sampler2D noiseMap;
|
||||
|
||||
uniform vec3 env_mat[3];
|
||||
uniform float sun_wash;
|
||||
|
||||
uniform int light_count;
|
||||
|
||||
uniform vec4 light[16];
|
||||
uniform vec4 light_col[16];
|
||||
|
||||
varying vec3 vary_fragcoord;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res;
|
||||
vec3 pos = texture2DRect(positionMap, frag.xy).xyz;
|
||||
vec3 norm = normalize(texture2DRect(normalMap, frag.xy).xyz);
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
|
||||
float noise = texture2D(noiseMap, frag.xy/128.0).b;
|
||||
vec3 out_col = vec3(0,0,0);
|
||||
|
||||
for (int i = 0; i < light_count; ++i)
|
||||
{
|
||||
vec3 lv = light[i].xyz-pos;
|
||||
float dist2 = dot(lv,lv);
|
||||
if (dist2 > light[i].w)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
float da = dot(norm, lv);
|
||||
if (da < 0.0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
lv = normalize(lv);
|
||||
da = dot(norm, lv);
|
||||
|
||||
float fa = light_col[i].a+1.0;
|
||||
float dist_atten = clamp(1.0-(dist2-light[i].w*(1.0-fa))/(light[i].w*fa), 0.0, 1.0);
|
||||
dist_atten *= noise;
|
||||
|
||||
float lit = da * dist_atten;
|
||||
|
||||
vec3 col = light_col[i].rgb*lit*diff;
|
||||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
vec3 ref = reflect(normalize(pos), norm);
|
||||
float sa = dot(ref,lv);
|
||||
sa = max(sa, 0.0);
|
||||
sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0);
|
||||
sa *= noise;
|
||||
col += da*sa*light_col[i].rgb*spec.rgb;
|
||||
}
|
||||
|
||||
out_col += col;
|
||||
}
|
||||
|
||||
//attenuate point light contribution by SSAO component
|
||||
out_col *= texture2DRect(lightMap, frag.xy).g;
|
||||
|
||||
gl_FragColor.rgb = out_col;
|
||||
gl_FragColor.a = 0.0;
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* @file pointLightF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
uniform sampler2DRect diffuseRect;
|
||||
uniform sampler2DRect specularRect;
|
||||
uniform sampler2DRect positionMap;
|
||||
uniform sampler2DRect normalMap;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform sampler2DRect lightMap;
|
||||
uniform sampler2D noiseMap;
|
||||
|
||||
uniform vec3 env_mat[3];
|
||||
uniform float sun_wash;
|
||||
|
||||
varying vec4 vary_light;
|
||||
|
||||
varying vec3 vary_fragcoord;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
|
||||
frag *= screen_res;
|
||||
vec3 pos = texture2DRect(positionMap, frag).xyz;
|
||||
vec3 lv = vary_light.xyz-pos;
|
||||
float dist2 = dot(lv,lv);
|
||||
if (dist2 > vary_light.w)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, frag).xyz;
|
||||
float da = dot(norm, lv);
|
||||
if (da < 0.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
norm = normalize(norm);
|
||||
lv = normalize(lv);
|
||||
da = dot(norm, lv);
|
||||
|
||||
float noise = texture2D(noiseMap, frag/128.0).b;
|
||||
|
||||
vec3 col = texture2DRect(diffuseRect, frag).rgb;
|
||||
float fa = gl_Color.a+1.0;
|
||||
float dist_atten = clamp(1.0-(dist2-vary_light.w*(1.0-fa))/(vary_light.w*fa), 0.0, 1.0);
|
||||
float lit = da * dist_atten * noise;
|
||||
|
||||
col = gl_Color.rgb*lit*col;
|
||||
|
||||
vec4 spec = texture2DRect(specularRect, frag);
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
vec3 ref = reflect(normalize(pos), norm);
|
||||
float sa = dot(ref,lv);
|
||||
sa = max(sa, 0.0);
|
||||
sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0);
|
||||
sa *= noise;
|
||||
col += da*sa*gl_Color.rgb*spec.rgb;
|
||||
}
|
||||
|
||||
//attenuate point light contribution by SSAO component
|
||||
col *= texture2DRect(lightMap, frag.xy).g;
|
||||
|
||||
|
||||
gl_FragColor.rgb = col;
|
||||
gl_FragColor.a = 0.0;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* @file pointLightF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
varying vec4 vary_light;
|
||||
varying vec3 vary_fragcoord;
|
||||
|
||||
uniform vec2 screen_res;
|
||||
uniform float near_clip;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = ftransform();
|
||||
|
||||
vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
|
||||
|
||||
vec4 tex = gl_MultiTexCoord0;
|
||||
tex.w = 1.0;
|
||||
|
||||
vary_light = gl_MultiTexCoord0;
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* @file shadowF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(1,1,1,texture2D(diffuseMap, gl_TexCoord[0].xy).a * gl_Color.a);
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* @file shadowV.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
vec4 pos = gl_ModelViewProjectionMatrix*gl_Vertex;
|
||||
//smash geometry against the near clip plane (great for ortho projections)
|
||||
pos.z = max(pos.z, -1.0);
|
||||
gl_Position = pos;
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
|
@ -0,0 +1,279 @@
|
|||
/**
|
||||
* @file softenLightF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
uniform sampler2DRect diffuseRect;
|
||||
uniform sampler2DRect specularRect;
|
||||
uniform sampler2DRect positionMap;
|
||||
uniform sampler2DRect normalMap;
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2DRect lightMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform samplerCube environmentMap;
|
||||
|
||||
uniform float blur_size;
|
||||
uniform float blur_fidelity;
|
||||
|
||||
// Inputs
|
||||
uniform vec4 morphFactor;
|
||||
uniform vec3 camPosLocal;
|
||||
//uniform vec4 camPosWorld;
|
||||
uniform vec4 gamma;
|
||||
uniform vec4 lightnorm;
|
||||
uniform vec4 sunlight_color;
|
||||
uniform vec4 ambient;
|
||||
uniform vec4 blue_horizon;
|
||||
uniform vec4 blue_density;
|
||||
uniform vec4 haze_horizon;
|
||||
uniform vec4 haze_density;
|
||||
uniform vec4 cloud_shadow;
|
||||
uniform vec4 density_multiplier;
|
||||
uniform vec4 distance_multiplier;
|
||||
uniform vec4 max_y;
|
||||
uniform vec4 glow;
|
||||
uniform float scene_light_strength;
|
||||
uniform vec3 env_mat[3];
|
||||
uniform mat4 shadow_matrix[3];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform mat3 ssao_effect_mat;
|
||||
|
||||
varying vec4 vary_light;
|
||||
varying vec2 vary_fragcoord;
|
||||
|
||||
vec3 vary_PositionEye;
|
||||
|
||||
vec3 vary_SunlitColor;
|
||||
vec3 vary_AmblitColor;
|
||||
vec3 vary_AdditiveColor;
|
||||
vec3 vary_AtmosAttenuation;
|
||||
|
||||
vec3 getPositionEye()
|
||||
{
|
||||
return vary_PositionEye;
|
||||
}
|
||||
vec3 getSunlitColor()
|
||||
{
|
||||
return vary_SunlitColor;
|
||||
}
|
||||
vec3 getAmblitColor()
|
||||
{
|
||||
return vary_AmblitColor;
|
||||
}
|
||||
vec3 getAdditiveColor()
|
||||
{
|
||||
return vary_AdditiveColor;
|
||||
}
|
||||
vec3 getAtmosAttenuation()
|
||||
{
|
||||
return vary_AtmosAttenuation;
|
||||
}
|
||||
|
||||
|
||||
void setPositionEye(vec3 v)
|
||||
{
|
||||
vary_PositionEye = v;
|
||||
}
|
||||
|
||||
void setSunlitColor(vec3 v)
|
||||
{
|
||||
vary_SunlitColor = v;
|
||||
}
|
||||
|
||||
void setAmblitColor(vec3 v)
|
||||
{
|
||||
vary_AmblitColor = v;
|
||||
}
|
||||
|
||||
void setAdditiveColor(vec3 v)
|
||||
{
|
||||
vary_AdditiveColor = v;
|
||||
}
|
||||
|
||||
void setAtmosAttenuation(vec3 v)
|
||||
{
|
||||
vary_AtmosAttenuation = v;
|
||||
}
|
||||
|
||||
void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
|
||||
|
||||
vec3 P = inPositionEye;
|
||||
setPositionEye(P);
|
||||
|
||||
//(TERRAIN) limit altitude
|
||||
if (P.y > max_y.x) P *= (max_y.x / P.y);
|
||||
if (P.y < -max_y.x) P *= (-max_y.x / P.y);
|
||||
|
||||
vec3 tmpLightnorm = lightnorm.xyz;
|
||||
|
||||
vec3 Pn = normalize(P);
|
||||
float Plen = length(P);
|
||||
|
||||
vec4 temp1 = vec4(0);
|
||||
vec3 temp2 = vec3(0);
|
||||
vec4 blue_weight;
|
||||
vec4 haze_weight;
|
||||
vec4 sunlight = sunlight_color;
|
||||
vec4 light_atten;
|
||||
|
||||
//sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
//this is used later for sunlight modulation at various altitudes
|
||||
light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x);
|
||||
//I had thought blue_density and haze_density should have equal weighting,
|
||||
//but attenuation due to haze_density tends to seem too strong
|
||||
|
||||
temp1 = blue_density + vec4(haze_density.r);
|
||||
blue_weight = blue_density / temp1;
|
||||
haze_weight = vec4(haze_density.r) / temp1;
|
||||
|
||||
//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
|
||||
temp2.y = max(0.0, tmpLightnorm.y);
|
||||
temp2.y = 1. / temp2.y;
|
||||
sunlight *= exp( - light_atten * temp2.y);
|
||||
|
||||
// main atmospheric scattering line integral
|
||||
temp2.z = Plen * density_multiplier.x;
|
||||
|
||||
// Transparency (-> temp1)
|
||||
// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati
|
||||
// compiler gets confused.
|
||||
temp1 = exp(-temp1 * temp2.z * distance_multiplier.x);
|
||||
|
||||
//final atmosphere attenuation factor
|
||||
setAtmosAttenuation(temp1.rgb);
|
||||
|
||||
//compute haze glow
|
||||
//(can use temp2.x as temp because we haven't used it yet)
|
||||
temp2.x = dot(Pn, tmpLightnorm.xyz);
|
||||
temp2.x = 1. - temp2.x;
|
||||
//temp2.x is 0 at the sun and increases away from sun
|
||||
temp2.x = max(temp2.x, .03); //was glow.y
|
||||
//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
|
||||
temp2.x *= glow.x;
|
||||
//higher glow.x gives dimmer glow (because next step is 1 / "angle")
|
||||
temp2.x = pow(temp2.x, glow.z);
|
||||
//glow.z should be negative, so we're doing a sort of (1 / "angle") function
|
||||
|
||||
//add "minimum anti-solar illumination"
|
||||
temp2.x += .25;
|
||||
|
||||
//increase ambient when there are more clouds
|
||||
vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5;
|
||||
|
||||
/* decrease value and saturation (that in HSV, not HSL) for occluded areas
|
||||
* // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
|
||||
* // The following line of code performs the equivalent of:
|
||||
* float ambAlpha = tmpAmbient.a;
|
||||
* float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
|
||||
* vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
|
||||
* tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
|
||||
*/
|
||||
tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
|
||||
|
||||
//haze color
|
||||
setAdditiveColor(
|
||||
vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient)
|
||||
+ (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x
|
||||
+ tmpAmbient)));
|
||||
|
||||
//brightness of surface both sunlight and ambient
|
||||
setSunlitColor(vec3(sunlight * .5));
|
||||
setAmblitColor(vec3(tmpAmbient * .25));
|
||||
setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
|
||||
}
|
||||
|
||||
vec3 atmosLighting(vec3 light)
|
||||
{
|
||||
light *= getAtmosAttenuation().r;
|
||||
light += getAdditiveColor();
|
||||
return (2.0 * light);
|
||||
}
|
||||
|
||||
vec3 atmosTransport(vec3 light) {
|
||||
light *= getAtmosAttenuation().r;
|
||||
light += getAdditiveColor() * 2.0;
|
||||
return light;
|
||||
}
|
||||
vec3 atmosGetDiffuseSunlightColor()
|
||||
{
|
||||
return getSunlitColor();
|
||||
}
|
||||
|
||||
vec3 scaleDownLight(vec3 light)
|
||||
{
|
||||
return (light / scene_light_strength );
|
||||
}
|
||||
|
||||
vec3 scaleUpLight(vec3 light)
|
||||
{
|
||||
return (light * scene_light_strength);
|
||||
}
|
||||
|
||||
vec3 atmosAmbient(vec3 light)
|
||||
{
|
||||
return getAmblitColor() + light / 2.0;
|
||||
}
|
||||
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity)
|
||||
{
|
||||
return getSunlitColor() * lightIntensity;
|
||||
}
|
||||
|
||||
vec3 scaleSoftClip(vec3 light)
|
||||
{
|
||||
//soft clip effect:
|
||||
light = 1. - clamp(light, vec3(0.), vec3(1.));
|
||||
light = 1. - pow(light, gamma.xxx);
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
vec3 pos = texture2DRect(positionMap, tc).xyz;
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
|
||||
|
||||
float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
|
||||
|
||||
vec4 diffuse = vec4(texture2DRect(diffuseRect, tc).rgb, 1.0);
|
||||
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
|
||||
|
||||
vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
|
||||
float scol = scol_ambocc.r;
|
||||
float ambocc = scol_ambocc.g;
|
||||
|
||||
calcAtmospherics(pos.xyz, ambocc);
|
||||
|
||||
vec3 col = atmosAmbient(vec3(0));
|
||||
col += atmosAffectDirectionalLight(min(da, scol));
|
||||
|
||||
col *= diffuse.rgb;
|
||||
|
||||
if (spec.a > 0.2)
|
||||
{
|
||||
vec3 ref = reflect(pos.xyz, norm.xyz);
|
||||
vec3 rc;
|
||||
rc.x = dot(ref, env_mat[0]);
|
||||
rc.y = dot(ref, env_mat[1]);
|
||||
rc.z = dot(ref, env_mat[2]);
|
||||
|
||||
vec3 refcol = textureCube(environmentMap, rc).rgb;
|
||||
col.rgb += refcol * spec.rgb;
|
||||
}
|
||||
|
||||
col = atmosLighting(col);
|
||||
col = scaleSoftClip(col);
|
||||
|
||||
gl_FragColor.rgb = col;
|
||||
gl_FragColor.a = 0.0;
|
||||
//gl_FragColor.rg = scol_ambocc.rg;
|
||||
//gl_FragColor.rgb = norm.rgb*0.5+0.5;
|
||||
//gl_FragColor.rgb = vec3(ambocc);
|
||||
//gl_FragColor.rgb = vec3(scol);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* @file softenLightF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
uniform vec2 screen_res;
|
||||
|
||||
varying vec4 vary_light;
|
||||
varying vec2 vary_fragcoord;
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = ftransform();
|
||||
|
||||
vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
|
||||
|
||||
vec4 tex = gl_MultiTexCoord0;
|
||||
tex.w = 1.0;
|
||||
|
||||
vary_light = gl_MultiTexCoord0;
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* @file sunLightF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
uniform sampler2DRect positionMap;
|
||||
uniform sampler2DRect normalMap;
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2D noiseMap;
|
||||
|
||||
// Inputs
|
||||
uniform mat4 shadow_matrix[4];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform float ssao_radius;
|
||||
uniform float ssao_max_radius;
|
||||
uniform float ssao_factor;
|
||||
uniform float ssao_factor_inv;
|
||||
|
||||
varying vec2 vary_fragcoord;
|
||||
varying vec4 vary_light;
|
||||
|
||||
//calculate decreases in ambient lighting when crowded out (SSAO)
|
||||
float calcAmbientOcclusion(vec4 pos, vec3 norm)
|
||||
{
|
||||
vec2 kern[8];
|
||||
// exponentially (^2) distant occlusion samples spread around origin
|
||||
kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
|
||||
kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
|
||||
kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
|
||||
kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
|
||||
kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
|
||||
kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
|
||||
kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
|
||||
kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
|
||||
|
||||
vec2 pos_screen = vary_fragcoord.xy;
|
||||
vec3 pos_world = pos.xyz;
|
||||
vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
|
||||
|
||||
float angle_hidden = 0.0;
|
||||
int points = 0;
|
||||
|
||||
float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
|
||||
|
||||
// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect);
|
||||
vec3 samppos_world = texture2DRect(positionMap, samppos_screen).xyz;
|
||||
|
||||
vec3 diff = pos_world - samppos_world;
|
||||
float dist2 = dot(diff, diff);
|
||||
|
||||
// assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
|
||||
// --> solid angle shrinking by the square of distance
|
||||
//radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
|
||||
//(k should vary inversely with # of samples, but this is taken care of later)
|
||||
|
||||
//if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces
|
||||
// angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor)
|
||||
angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
|
||||
|
||||
// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
|
||||
points = points + int(diff.z > -1.0);
|
||||
}
|
||||
|
||||
angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
|
||||
|
||||
return 1.0 - (float(points != 0) * angle_hidden);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 pos_screen = vary_fragcoord.xy;
|
||||
vec4 pos = vec4(texture2DRect(positionMap, pos_screen).xyz, 1.0);
|
||||
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
|
||||
|
||||
/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
|
||||
{
|
||||
gl_FragColor = vec4(0.0); // doesn't matter
|
||||
return;
|
||||
}*/
|
||||
|
||||
float shadow = 1.0;
|
||||
float dp_directional_light = max(0.0, dot(norm, vary_light.xyz));
|
||||
|
||||
if (dp_directional_light == 0.0)
|
||||
{
|
||||
// if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup
|
||||
shadow = 0.0;
|
||||
}
|
||||
else if (pos.z > -shadow_clip.w)
|
||||
{
|
||||
if (pos.z < -shadow_clip.z)
|
||||
{
|
||||
vec4 lpos = shadow_matrix[3]*pos;
|
||||
shadow = shadow2DProj(shadowMap3, lpos).x;
|
||||
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
|
||||
}
|
||||
else if (pos.z < -shadow_clip.y)
|
||||
{
|
||||
vec4 lpos = shadow_matrix[2]*pos;
|
||||
shadow = shadow2DProj(shadowMap2, lpos).x;
|
||||
}
|
||||
else if (pos.z < -shadow_clip.x)
|
||||
{
|
||||
vec4 lpos = shadow_matrix[1]*pos;
|
||||
shadow = shadow2DProj(shadowMap1, lpos).x;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec4 lpos = shadow_matrix[0]*pos;
|
||||
shadow = shadow2DProj(shadowMap0, lpos).x;
|
||||
}
|
||||
|
||||
// take the most-shadowed value out of these two:
|
||||
// * the blurred sun shadow in the light (shadow) map
|
||||
// * an unblurred dot product between the sun and this norm
|
||||
// the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting
|
||||
shadow = min(shadow, dp_directional_light);
|
||||
}
|
||||
else
|
||||
{
|
||||
// more distant than the shadow map covers - just use directional shading as shadow
|
||||
shadow = dp_directional_light;
|
||||
}
|
||||
|
||||
gl_FragColor[0] = shadow;
|
||||
gl_FragColor[1] = calcAmbientOcclusion(pos, norm);
|
||||
//gl_FragColor[2] is unused as of August 2008, may be used for debugging
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* @file sunLightF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
varying vec4 vary_light;
|
||||
varying vec2 vary_fragcoord;
|
||||
|
||||
uniform vec2 screen_res;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = ftransform();
|
||||
vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;
|
||||
vec4 tex = gl_MultiTexCoord0;
|
||||
tex.w = 1.0;
|
||||
|
||||
vary_light = gl_MultiTexCoord0;
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* @file terrainF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
uniform sampler2D detail_0;
|
||||
uniform sampler2D detail_1;
|
||||
uniform sampler2D detail_2;
|
||||
uniform sampler2D detail_3;
|
||||
uniform sampler2D alpha_ramp;
|
||||
|
||||
varying vec3 vary_normal;
|
||||
varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
|
||||
|
||||
vec4 color0 = texture2D(detail_0, gl_TexCoord[0].xy);
|
||||
vec4 color1 = texture2D(detail_1, gl_TexCoord[0].xy);
|
||||
vec4 color2 = texture2D(detail_2, gl_TexCoord[0].xy);
|
||||
vec4 color3 = texture2D(detail_3, gl_TexCoord[0].xy);
|
||||
|
||||
float alpha1 = texture2D(alpha_ramp, gl_TexCoord[0].zw).a;
|
||||
float alpha2 = texture2D(alpha_ramp,gl_TexCoord[1].xy).a;
|
||||
float alphaFinal = texture2D(alpha_ramp, gl_TexCoord[1].zw).a;
|
||||
vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
|
||||
|
||||
gl_FragData[0] = vec4(outColor.rgb, 1.0);
|
||||
gl_FragData[1] = vec4(outColor.rgb*0.2, 0.2);
|
||||
gl_FragData[2] = vec4(normalize(vary_normal), 0.0);
|
||||
gl_FragData[3] = vary_position;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @file terrainV.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
varying vec3 vary_normal;
|
||||
varying vec4 vary_position;
|
||||
|
||||
vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
|
||||
{
|
||||
vec4 tcoord;
|
||||
|
||||
tcoord.x = dot(vpos, tp0);
|
||||
tcoord.y = dot(vpos, tp1);
|
||||
tcoord.z = tc.z;
|
||||
tcoord.w = tc.w;
|
||||
|
||||
tcoord = mat * tcoord;
|
||||
|
||||
return tcoord;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
|
||||
vary_position = gl_ModelViewMatrix * gl_Vertex;
|
||||
vary_normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
|
||||
// Transform and pass tex coords
|
||||
gl_TexCoord[0].xy = texgen_object(gl_Vertex, gl_MultiTexCoord0, gl_TextureMatrix[0], gl_ObjectPlaneS[0], gl_ObjectPlaneT[0]).xy;
|
||||
|
||||
vec4 t = gl_MultiTexCoord1;
|
||||
|
||||
gl_TexCoord[0].zw = t.xy;
|
||||
gl_TexCoord[1].xy = t.xy-vec2(2.0, 0.0);
|
||||
gl_TexCoord[1].zw = t.xy-vec2(1.0, 0.0);
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* @file treeF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
varying vec3 vary_normal;
|
||||
varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy);
|
||||
gl_FragData[0] = gl_Color*col;
|
||||
gl_FragData[1] = vec4(0,0,0,0);
|
||||
gl_FragData[2] = vec4(normalize(vary_normal), 0.0);
|
||||
gl_FragData[3] = vary_position;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* @file treeV.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
varying vec3 vary_normal;
|
||||
varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = ftransform();
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
|
||||
vary_position = gl_ModelViewMatrix * gl_Vertex;
|
||||
|
||||
vary_normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
/**
|
||||
* @file waterF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
vec3 scaleSoftClip(vec3 inColor);
|
||||
vec3 atmosTransport(vec3 inColor);
|
||||
|
||||
uniform sampler2D bumpMap;
|
||||
uniform sampler2D screenTex;
|
||||
uniform sampler2D refTex;
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2D noiseMap;
|
||||
|
||||
uniform mat4 shadow_matrix[4];
|
||||
uniform vec4 shadow_clip;
|
||||
|
||||
uniform float sunAngle;
|
||||
uniform float sunAngle2;
|
||||
uniform vec3 lightDir;
|
||||
uniform vec3 specular;
|
||||
uniform float lightExp;
|
||||
uniform float refScale;
|
||||
uniform float kd;
|
||||
uniform vec2 screenRes;
|
||||
uniform vec3 normScale;
|
||||
uniform float fresnelScale;
|
||||
uniform float fresnelOffset;
|
||||
uniform float blurMultiplier;
|
||||
|
||||
|
||||
//bigWave is (refCoord.w, view.w);
|
||||
varying vec4 refCoord;
|
||||
varying vec4 littleWave;
|
||||
varying vec4 view;
|
||||
varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color;
|
||||
float dist = length(view.xy);
|
||||
|
||||
//normalize view vector
|
||||
vec3 viewVec = normalize(view.xyz);
|
||||
|
||||
//get wave normals
|
||||
vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
|
||||
vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
|
||||
vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
|
||||
//get base fresnel components
|
||||
|
||||
vec3 df = vec3(
|
||||
dot(viewVec, wave1),
|
||||
dot(viewVec, (wave2 + wave3) * 0.5),
|
||||
dot(viewVec, wave3)
|
||||
) * fresnelScale + fresnelOffset;
|
||||
df *= df;
|
||||
|
||||
vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
|
||||
|
||||
float dist2 = dist;
|
||||
dist = max(dist, 5.0);
|
||||
|
||||
float dmod = sqrt(dist);
|
||||
|
||||
vec2 dmod_scale = vec2(dmod*dmod, dmod);
|
||||
|
||||
//get reflected color
|
||||
vec2 refdistort1 = wave1.xy*normScale.x;
|
||||
vec2 refvec1 = distort+refdistort1/dmod_scale;
|
||||
vec4 refcol1 = texture2D(refTex, refvec1);
|
||||
|
||||
vec2 refdistort2 = wave2.xy*normScale.y;
|
||||
vec2 refvec2 = distort+refdistort2/dmod_scale;
|
||||
vec4 refcol2 = texture2D(refTex, refvec2);
|
||||
|
||||
vec2 refdistort3 = wave3.xy*normScale.z;
|
||||
vec2 refvec3 = distort+refdistort3/dmod_scale;
|
||||
vec4 refcol3 = texture2D(refTex, refvec3);
|
||||
|
||||
vec4 refcol = refcol1 + refcol2 + refcol3;
|
||||
float df1 = df.x + df.y + df.z;
|
||||
refcol *= df1 * 0.333;
|
||||
|
||||
vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
|
||||
wavef.z *= max(-viewVec.z, 0.1);
|
||||
wavef = normalize(wavef);
|
||||
|
||||
float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
|
||||
|
||||
vec2 refdistort4 = wavef.xy*0.125;
|
||||
refdistort4.y -= abs(refdistort4.y);
|
||||
vec2 refvec4 = distort+refdistort4/dmod;
|
||||
float dweight = min(dist2*blurMultiplier, 1.0);
|
||||
vec4 baseCol = texture2D(refTex, refvec4);
|
||||
refcol = mix(baseCol*df2, refcol, dweight);
|
||||
|
||||
//get specular component
|
||||
float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
|
||||
|
||||
//harden specular
|
||||
spec = pow(spec, 128.0);
|
||||
|
||||
//figure out distortion vector (ripply)
|
||||
vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
|
||||
|
||||
vec4 fb = texture2D(screenTex, distort2);
|
||||
|
||||
//mix with reflection
|
||||
// Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug
|
||||
color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
|
||||
|
||||
float shadow = 1.0;
|
||||
vec4 pos = vary_position;
|
||||
|
||||
vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz;
|
||||
|
||||
if (pos.z > -shadow_clip.w)
|
||||
{
|
||||
vec4 spos = pos;
|
||||
|
||||
if (pos.z < -shadow_clip.z)
|
||||
{
|
||||
vec4 lpos = (shadow_matrix[3]*spos);
|
||||
shadow = shadow2DProj(shadowMap3, lpos).x;
|
||||
}
|
||||
else if (pos.z < -shadow_clip.y)
|
||||
{
|
||||
vec4 lpos = (shadow_matrix[2]*spos);
|
||||
shadow = shadow2DProj(shadowMap2, lpos).x;
|
||||
}
|
||||
else if (pos.z < -shadow_clip.x)
|
||||
{
|
||||
vec4 lpos = (shadow_matrix[1]*spos);
|
||||
shadow = shadow2DProj(shadowMap1, lpos).x;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec4 lpos = (shadow_matrix[0]*spos);
|
||||
shadow = shadow2DProj(shadowMap0, lpos).x;
|
||||
}
|
||||
}
|
||||
|
||||
spec *= shadow;
|
||||
color.rgb += spec * specular;
|
||||
|
||||
color.rgb = atmosTransport(color.rgb);
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
color.a = spec * sunAngle2;
|
||||
|
||||
gl_FragColor = color;
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* @file waterV.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
uniform vec2 d1;
|
||||
uniform vec2 d2;
|
||||
uniform float time;
|
||||
uniform vec3 eyeVec;
|
||||
uniform float waterHeight;
|
||||
|
||||
varying vec4 refCoord;
|
||||
varying vec4 littleWave;
|
||||
varying vec4 view;
|
||||
|
||||
varying vec4 vary_position;
|
||||
|
||||
float wave(vec2 v, float t, float f, vec2 d, float s)
|
||||
{
|
||||
return (dot(d, v)*f + t*s)*f;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
vec4 position = gl_Vertex;
|
||||
mat4 modelViewProj = gl_ModelViewProjectionMatrix;
|
||||
|
||||
vec4 oPosition;
|
||||
|
||||
//get view vector
|
||||
vec3 oEyeVec;
|
||||
oEyeVec.xyz = position.xyz-eyeVec;
|
||||
|
||||
float d = length(oEyeVec.xy);
|
||||
float ld = min(d, 2560.0);
|
||||
|
||||
position.xy = eyeVec.xy + oEyeVec.xy/d*ld;
|
||||
view.xyz = oEyeVec;
|
||||
|
||||
d = clamp(ld/1536.0-0.5, 0.0, 1.0);
|
||||
d *= d;
|
||||
|
||||
oPosition = position;
|
||||
oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
|
||||
vary_position = gl_ModelViewMatrix * oPosition;
|
||||
oPosition = modelViewProj * oPosition;
|
||||
|
||||
refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
|
||||
|
||||
//get wave position parameter (create sweeping horizontal waves)
|
||||
vec3 v = position.xyz;
|
||||
v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0;
|
||||
|
||||
//push position for further horizon effect.
|
||||
position.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
|
||||
position.w = 1.0;
|
||||
position = position*gl_ModelViewMatrix;
|
||||
|
||||
calcAtmospherics((gl_ModelViewMatrix * gl_Vertex).xyz);
|
||||
|
||||
|
||||
//pass wave parameters to pixel shader
|
||||
vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
|
||||
//get two normal map (detail map) texture coordinates
|
||||
littleWave.xy = (v.xy) * vec2(0.45, 0.9) + d2 * time * 0.13;
|
||||
littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1;
|
||||
view.w = bigWave.y;
|
||||
refCoord.w = bigWave.x;
|
||||
|
||||
gl_Position = oPosition;
|
||||
}
|
||||
|
|
@ -20,8 +20,8 @@ void main()
|
|||
|
||||
/// CALCULATING LUMINANCE (Using NTSC lum weights)
|
||||
/// http://en.wikipedia.org/wiki/Luma_%28video%29
|
||||
float lum = smoothstep(minLuminance, 1.0, dot(col.rgb, lumWeights ) );
|
||||
float warmth = smoothstep(minLuminance, 1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) );
|
||||
float lum = smoothstep(minLuminance, minLuminance+1.0, dot(col.rgb, lumWeights ) );
|
||||
float warmth = smoothstep(minLuminance, minLuminance+1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) );
|
||||
|
||||
gl_FragColor.rgb = col.rgb;
|
||||
gl_FragColor.a = max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
vec3 scaleSoftClip(vec3 inColor);
|
||||
vec3 atmosTransport(vec3 inColor);
|
||||
vec3 applyWaterFog(vec4 inColor);
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2D bumpMap;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ WLSkyDetail 1 128
|
|||
Disregard128DefaultDrawDistance 1 1
|
||||
Disregard96DefaultDrawDistance 1 1
|
||||
RenderTextureMemoryMultiple 1 1.0
|
||||
RenderShaderLightingMaxLevel 1 3
|
||||
|
||||
|
||||
//
|
||||
// Low Graphics Settings
|
||||
|
|
@ -473,17 +475,47 @@ list NVIDIA_GeForce_Go_6
|
|||
RenderVBOEnable 1 0
|
||||
Disregard128DefaultDrawDistance 1 0
|
||||
|
||||
list NVIDIA_GeForce_7000
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_7100
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_7200
|
||||
Disregard128DefaultDrawDistance 1 0
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_7300
|
||||
Disregard128DefaultDrawDistance 1 0
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_7400
|
||||
Disregard128DefaultDrawDistance 1 0
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_7500
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_7600
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_7700
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_7800
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_7900
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
|
||||
list NVIDIA_GeForce_Go_7200
|
||||
Disregard128DefaultDrawDistance 1 0
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_Go_7300
|
||||
Disregard128DefaultDrawDistance 1 0
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_Go_7300_LE
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_Go_7400
|
||||
Disregard128DefaultDrawDistance 1 0
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_Go_7600
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_Go_7700
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_Go_7800
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
list NVIDIA_GeForce_Go_7900
|
||||
RenderShaderLightingMaxLevel 1 2
|
||||
|
||||
|
|
|
|||
|
|
@ -735,3 +735,37 @@ From Vivox:
|
|||
Attn: customer support
|
||||
40 Speen Street Suite 402
|
||||
Framingham, MA 01701
|
||||
|
||||
|
||||
========================
|
||||
google-perftools license
|
||||
========================
|
||||
|
||||
Copyright (c) 2005, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
|
|||
|
|
@ -358,7 +358,6 @@ LLAgent::LLAgent() :
|
|||
|
||||
mFrameAgent(),
|
||||
|
||||
mCrouching(FALSE),
|
||||
mIsBusy(FALSE),
|
||||
|
||||
mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed
|
||||
|
|
@ -477,8 +476,16 @@ void LLAgent::cleanup()
|
|||
{
|
||||
setSitCamera(LLUUID::null);
|
||||
mAvatarObject = NULL;
|
||||
mLookAt = NULL;
|
||||
mPointAt = NULL;
|
||||
if(mLookAt)
|
||||
{
|
||||
mLookAt->markDead() ;
|
||||
mLookAt = NULL;
|
||||
}
|
||||
if(mPointAt)
|
||||
{
|
||||
mPointAt->markDead() ;
|
||||
mPointAt = NULL;
|
||||
}
|
||||
mRegionp = NULL;
|
||||
setFocusObject(NULL);
|
||||
}
|
||||
|
|
@ -2726,7 +2733,7 @@ BOOL LLAgent::needsRenderAvatar()
|
|||
// TRUE if we need to render your own avatar's head.
|
||||
BOOL LLAgent::needsRenderHead()
|
||||
{
|
||||
return mShowAvatar && !cameraMouselook();
|
||||
return (LLVOAvatar::sVisibleInFirstPerson && LLPipeline::sReflectionRender) || (mShowAvatar && !cameraMouselook());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue