Merge remote branch 'shyotl/V2Renderer'
Conflicts: indra/cmake/00-Common.cmake
This commit is contained in:
@@ -31,10 +31,6 @@ if (WINDOWS)
|
||||
# Don't build DLLs.
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
if (MSVC10)
|
||||
set(MSVC100 TRUE)
|
||||
endif (MSVC10)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd"
|
||||
CACHE STRING "C++ compiler debug options" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
@@ -69,10 +65,9 @@ if (WINDOWS)
|
||||
/Zc:forScope
|
||||
/nologo
|
||||
/Oy-
|
||||
/Zc:wchar_t-
|
||||
)
|
||||
|
||||
if(MSVC80 OR MSVC90 OR MSVC100)
|
||||
if(MSVC80 OR MSVC90 OR MSVC10)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
|
||||
CACHE STRING "C++ compiler release options" FORCE)
|
||||
@@ -82,7 +77,10 @@ if (WINDOWS)
|
||||
set(CMAKE_C_FLAGS_RELEASESSE2
|
||||
"${CMAKE_CXX_FLAGS_RELEASESSE2} -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
|
||||
CACHE STRING "C compiler release-SSE2 options" FORCE)
|
||||
endif (MSVC80 OR MSVC90 OR MSVC100)
|
||||
add_definitions(
|
||||
/Zc:wchar_t-
|
||||
)
|
||||
endif (MSVC80 OR MSVC90 OR MSVC10)
|
||||
|
||||
# Are we using the crummy Visual Studio KDU build workaround?
|
||||
if (NOT VS_DISABLE_FATAL_WARNINGS)
|
||||
|
||||
@@ -426,7 +426,16 @@ protected:
|
||||
template <typename T>
|
||||
class LLSingleton
|
||||
{
|
||||
static bool &needsInit()
|
||||
{
|
||||
static bool needs_init = true;
|
||||
return needs_init;
|
||||
}
|
||||
public:
|
||||
static bool instanceExists()
|
||||
{
|
||||
return !needsInit();
|
||||
}
|
||||
virtual ~LLSingleton() {}
|
||||
#ifdef LL_MSVC7
|
||||
// workaround for VC7 compiler bug
|
||||
@@ -445,7 +454,7 @@ public:
|
||||
#endif
|
||||
{
|
||||
static T instance;
|
||||
static bool needs_init = true;
|
||||
bool &needs_init = needsInit();
|
||||
if (needs_init)
|
||||
{
|
||||
needs_init = false;
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));}
|
||||
|
||||
void skip(const U32 index) { mBytep += mSkip*index;}
|
||||
|
||||
U32 getSkip() const { return mSkip; }
|
||||
Object* get() { return mObjectp; }
|
||||
Object* operator->() { return mObjectp; }
|
||||
Object& operator *() { return *mObjectp; }
|
||||
|
||||
@@ -59,11 +59,13 @@
|
||||
BOOL gDebugGL = FALSE;
|
||||
BOOL gClothRipple = FALSE;
|
||||
BOOL gNoRender = FALSE;
|
||||
BOOL gGLActive = FALSE;
|
||||
LLMatrix4 gGLObliqueProjectionInverse;
|
||||
|
||||
#define LL_GL_NAME_POOLING 0
|
||||
|
||||
LLGLNamePool::pool_list_t LLGLNamePool::sInstances;
|
||||
std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
|
||||
|
||||
#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
|
||||
// ATI prototypes
|
||||
|
||||
@@ -361,6 +361,35 @@ protected:
|
||||
virtual void releaseName(GLuint name) = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
Interface for objects that need periodic GL updates applied to them.
|
||||
Used to synchronize GL updates with GL thread.
|
||||
*/
|
||||
class LLGLUpdate
|
||||
{
|
||||
public:
|
||||
|
||||
static std::list<LLGLUpdate*> sGLQ;
|
||||
|
||||
BOOL mInQ;
|
||||
LLGLUpdate()
|
||||
: mInQ(FALSE)
|
||||
{
|
||||
}
|
||||
virtual ~LLGLUpdate()
|
||||
{
|
||||
if (mInQ)
|
||||
{
|
||||
std::list<LLGLUpdate*>::iterator iter = std::find(sGLQ.begin(), sGLQ.end(), this);
|
||||
if (iter != sGLQ.end())
|
||||
{
|
||||
sGLQ.erase(iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void updateGL() = 0;
|
||||
};
|
||||
|
||||
extern LLMatrix4 gGLObliqueProjectionInverse;
|
||||
|
||||
#include "llglstates.h"
|
||||
@@ -379,4 +408,6 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
|
||||
|
||||
extern BOOL gClothRipple;
|
||||
extern BOOL gNoRender;
|
||||
extern BOOL gGLActive;
|
||||
|
||||
#endif // LL_LLGL_H
|
||||
|
||||
@@ -352,8 +352,21 @@ void LLImageGL::restoreGL()
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageGL::dirtyTexOptions()
|
||||
{
|
||||
for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
|
||||
iter != sImageList.end(); iter++)
|
||||
{
|
||||
LLImageGL* glimage = *iter;
|
||||
glimage->mTexOptionsDirty = true;
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//for server side use only.
|
||||
//static
|
||||
BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, BOOL usemipmaps)
|
||||
{
|
||||
@@ -361,12 +374,14 @@ BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, BOOL usemipmaps)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//for server side use only.
|
||||
BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, U32 width, U32 height, U8 components, BOOL usemipmaps)
|
||||
{
|
||||
dest = new LLImageGL(width, height, components, usemipmaps);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//for server side use only.
|
||||
BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, BOOL usemipmaps)
|
||||
{
|
||||
dest = new LLImageGL(imageraw, usemipmaps);
|
||||
|
||||
@@ -68,6 +68,7 @@ public:
|
||||
// Save off / restore GL textures
|
||||
static void destroyGL(BOOL save_state = TRUE);
|
||||
static void restoreGL();
|
||||
static void dirtyTexOptions();
|
||||
|
||||
// Sometimes called externally for textures not using LLImageGL (should go away...)
|
||||
static S32 updateBoundTexMemStatic(const S32 delta, const S32 size, S32 category) ;
|
||||
@@ -137,6 +138,7 @@ public:
|
||||
BOOL getBoundRecently() const;
|
||||
BOOL isJustBound() const;
|
||||
LLGLenum getPrimaryFormat() const { return mFormatPrimary; }
|
||||
LLGLenum getFormatType() const { return mFormatType; }
|
||||
|
||||
BOOL getHasGLTexture() const { return mTexName != 0; }
|
||||
LLGLuint getTexName() const { return mTexName; }
|
||||
|
||||
@@ -56,6 +56,7 @@ U32 LLVertexBuffer::sSetCount = 0;
|
||||
S32 LLVertexBuffer::sCount = 0;
|
||||
S32 LLVertexBuffer::sGLCount = 0;
|
||||
S32 LLVertexBuffer::sMappedCount = 0;
|
||||
BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ;
|
||||
BOOL LLVertexBuffer::sEnableVBOs = TRUE;
|
||||
U32 LLVertexBuffer::sGLRenderBuffer = 0;
|
||||
U32 LLVertexBuffer::sGLRenderIndices = 0;
|
||||
@@ -287,9 +288,21 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
|
||||
}
|
||||
|
||||
//static
|
||||
void LLVertexBuffer::initClass(bool use_vbo)
|
||||
void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
|
||||
{
|
||||
sEnableVBOs = use_vbo;
|
||||
sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ;
|
||||
if(sEnableVBOs)
|
||||
{
|
||||
//llassert_always(glBindBufferARB) ; //double check the extention for VBO is loaded.
|
||||
|
||||
llinfos << "VBO is enabled." << llendl ;
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "VBO is disabled." << llendl ;
|
||||
}
|
||||
|
||||
sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
|
||||
LLGLNamePool::registerPool(&sDynamicVBOPool);
|
||||
LLGLNamePool::registerPool(&sDynamicIBOPool);
|
||||
LLGLNamePool::registerPool(&sStreamVBOPool);
|
||||
@@ -346,7 +359,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
|
||||
mGLBuffer(0),
|
||||
mGLIndices(0),
|
||||
mMappedData(NULL),
|
||||
mMappedIndexData(NULL), mLocked(FALSE),
|
||||
mMappedIndexData(NULL),
|
||||
mVertexLocked(FALSE),
|
||||
mIndexLocked(FALSE),
|
||||
mFinal(FALSE),
|
||||
mFilthy(FALSE),
|
||||
mEmpty(TRUE),
|
||||
@@ -544,6 +559,8 @@ void LLVertexBuffer::destroyGLBuffer()
|
||||
{
|
||||
if (useVBOs())
|
||||
{
|
||||
freeClientBuffer() ;
|
||||
|
||||
if (mMappedData || mMappedIndexData)
|
||||
{
|
||||
llerrs << "Vertex buffer destroyed while mapped!" << llendl;
|
||||
@@ -571,6 +588,8 @@ void LLVertexBuffer::destroyGLIndices()
|
||||
{
|
||||
if (useVBOs())
|
||||
{
|
||||
freeClientBuffer() ;
|
||||
|
||||
if (mMappedData || mMappedIndexData)
|
||||
{
|
||||
llerrs << "Vertex buffer destroyed while mapped." << llendl;
|
||||
@@ -768,6 +787,7 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
|
||||
|
||||
if (mResized && useVBOs())
|
||||
{
|
||||
freeClientBuffer() ;
|
||||
setBuffer(0);
|
||||
}
|
||||
}
|
||||
@@ -782,104 +802,228 @@ BOOL LLVertexBuffer::useVBOs() const
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void LLVertexBuffer::freeClientBuffer()
|
||||
{
|
||||
if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData))
|
||||
{
|
||||
delete[] mMappedData ;
|
||||
delete[] mMappedIndexData ;
|
||||
mMappedData = NULL ;
|
||||
mMappedIndexData = NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
void LLVertexBuffer::allocateClientVertexBuffer()
|
||||
{
|
||||
if(!mMappedData)
|
||||
{
|
||||
U32 size = getSize() ;
|
||||
mMappedData = new U8[size];
|
||||
memset((void*)mMappedData, 0, size);
|
||||
}
|
||||
}
|
||||
|
||||
void LLVertexBuffer::allocateClientIndexBuffer()
|
||||
{
|
||||
if(!mMappedIndexData)
|
||||
{
|
||||
U32 size = getIndicesSize();
|
||||
mMappedIndexData = new U8[size];
|
||||
memset((void*)mMappedIndexData, 0, size);
|
||||
}
|
||||
}
|
||||
|
||||
// Map for data access
|
||||
volatile U8* LLVertexBuffer::mapBuffer(S32 access)
|
||||
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
if (mFinal)
|
||||
{
|
||||
llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl;
|
||||
llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl;
|
||||
}
|
||||
if (!useVBOs() && !mMappedData && !mMappedIndexData)
|
||||
{
|
||||
llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl;
|
||||
llerrs << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << llendl;
|
||||
}
|
||||
|
||||
if (!mLocked && useVBOs())
|
||||
if (!mVertexLocked && useVBOs())
|
||||
{
|
||||
setBuffer(0);
|
||||
mLocked = TRUE;
|
||||
stop_glerror();
|
||||
mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
stop_glerror();
|
||||
mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
stop_glerror();
|
||||
{
|
||||
setBuffer(0, type);
|
||||
mVertexLocked = TRUE;
|
||||
stop_glerror();
|
||||
|
||||
if(sDisableVBOMapping)
|
||||
{
|
||||
allocateClientVertexBuffer() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
if (!mMappedData)
|
||||
{
|
||||
//--------------------
|
||||
//print out more debug info before crash
|
||||
llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
|
||||
GLint size ;
|
||||
glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
|
||||
llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
|
||||
//--------------------
|
||||
|
||||
GLint buff;
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
|
||||
if ((GLuint)buff != mGLBuffer)
|
||||
if(!sDisableVBOMapping)
|
||||
{
|
||||
llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
|
||||
//--------------------
|
||||
//print out more debug info before crash
|
||||
llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
|
||||
GLint size ;
|
||||
glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
|
||||
llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
|
||||
//--------------------
|
||||
|
||||
GLint buff;
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
|
||||
if ((GLuint)buff != mGLBuffer)
|
||||
{
|
||||
llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
|
||||
}
|
||||
|
||||
|
||||
llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
|
||||
}
|
||||
|
||||
|
||||
llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
|
||||
}
|
||||
|
||||
if (!mMappedIndexData)
|
||||
{
|
||||
GLint buff;
|
||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
|
||||
if ((GLuint)buff != mGLIndices)
|
||||
else
|
||||
{
|
||||
llerrs << "Invalid GL index buffer bound: " << buff << llendl;
|
||||
llerrs << "memory allocation for vertex data failed." << llendl ;
|
||||
}
|
||||
|
||||
llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
|
||||
}
|
||||
|
||||
sMappedCount++;
|
||||
}
|
||||
|
||||
return mMappedData;
|
||||
}
|
||||
|
||||
void LLVertexBuffer::unmapBuffer()
|
||||
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
if (mMappedData || mMappedIndexData)
|
||||
if (mFinal)
|
||||
{
|
||||
if (useVBOs() && mLocked)
|
||||
llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl;
|
||||
}
|
||||
if (!useVBOs() && !mMappedData && !mMappedIndexData)
|
||||
{
|
||||
llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl;
|
||||
}
|
||||
|
||||
if (!mIndexLocked && useVBOs())
|
||||
{
|
||||
{
|
||||
|
||||
setBuffer(0, TYPE_INDEX);
|
||||
mIndexLocked = TRUE;
|
||||
stop_glerror();
|
||||
|
||||
if(sDisableVBOMapping)
|
||||
{
|
||||
allocateClientIndexBuffer() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
if (!mMappedIndexData)
|
||||
{
|
||||
|
||||
if(!sDisableVBOMapping)
|
||||
{
|
||||
GLint buff;
|
||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
|
||||
if ((GLuint)buff != mGLIndices)
|
||||
{
|
||||
llerrs << "Invalid GL index buffer bound: " << buff << llendl;
|
||||
}
|
||||
|
||||
llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "memory allocation for Index data failed. " << llendl ;
|
||||
}
|
||||
}
|
||||
|
||||
sMappedCount++;
|
||||
}
|
||||
|
||||
return mMappedIndexData ;
|
||||
}
|
||||
|
||||
void LLVertexBuffer::unmapBuffer(S32 type)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
if (!useVBOs())
|
||||
{
|
||||
return ; //nothing to unmap
|
||||
}
|
||||
|
||||
bool updated_all = false ;
|
||||
if (mMappedData && mVertexLocked && type != TYPE_INDEX)
|
||||
{
|
||||
updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating
|
||||
|
||||
if(sDisableVBOMapping)
|
||||
{
|
||||
stop_glerror();
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (void*)mMappedData);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
stop_glerror();
|
||||
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
|
||||
stop_glerror();
|
||||
|
||||
mMappedData = NULL;
|
||||
}
|
||||
|
||||
mVertexLocked = FALSE ;
|
||||
sMappedCount--;
|
||||
}
|
||||
|
||||
if(mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX))
|
||||
{
|
||||
if(sDisableVBOMapping)
|
||||
{
|
||||
stop_glerror();
|
||||
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (void*)mMappedIndexData);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
stop_glerror();
|
||||
glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
|
||||
stop_glerror();
|
||||
|
||||
/*if (!sMapped)
|
||||
{
|
||||
llerrs << "Redundantly unmapped VBO!" << llendl;
|
||||
}
|
||||
sMapped = FALSE;*/
|
||||
sMappedCount--;
|
||||
mMappedIndexData = NULL ;
|
||||
}
|
||||
|
||||
if (mUsage == GL_STATIC_DRAW_ARB)
|
||||
{ //static draw buffers can only be mapped a single time
|
||||
//throw out client data (we won't be using it again)
|
||||
mEmpty = TRUE;
|
||||
mFinal = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEmpty = FALSE;
|
||||
}
|
||||
mIndexLocked = FALSE ;
|
||||
sMappedCount--;
|
||||
}
|
||||
|
||||
mMappedIndexData = NULL;
|
||||
mMappedData = NULL;
|
||||
|
||||
mLocked = FALSE;
|
||||
if(updated_all)
|
||||
{
|
||||
if(mUsage == GL_STATIC_DRAW_ARB)
|
||||
{
|
||||
//static draw buffers can only be mapped a single time
|
||||
//throw out client data (we won't be using it again)
|
||||
mEmpty = TRUE;
|
||||
mFinal = TRUE;
|
||||
|
||||
if(sDisableVBOMapping)
|
||||
{
|
||||
freeClientBuffer() ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mEmpty = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -893,15 +1037,16 @@ template <class T,S32 type> struct VertexBufferStrider
|
||||
strider_t& strider,
|
||||
S32 index)
|
||||
{
|
||||
if (vbo.mapBuffer() == NULL)
|
||||
{
|
||||
llwarns << "mapBuffer failed!" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (type == LLVertexBuffer::TYPE_INDEX)
|
||||
{
|
||||
S32 stride = sizeof(T);
|
||||
|
||||
if (vbo.mapIndexBuffer() == NULL)
|
||||
{
|
||||
llwarns << "mapIndexBuffer failed!" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
strider = (T*)(vbo.getMappedIndices() + index*stride);
|
||||
strider.setStride(0);
|
||||
return TRUE;
|
||||
@@ -909,6 +1054,13 @@ template <class T,S32 type> struct VertexBufferStrider
|
||||
else if (vbo.hasDataType(type))
|
||||
{
|
||||
S32 stride = vbo.getStride();
|
||||
|
||||
if (vbo.mapVertexBuffer(type) == NULL)
|
||||
{
|
||||
llwarns << "mapVertexBuffer failed!" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
strider = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride);
|
||||
strider.setStride(stride);
|
||||
return TRUE;
|
||||
@@ -989,7 +1141,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride)
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Set for rendering
|
||||
void LLVertexBuffer::setBuffer(U32 data_mask)
|
||||
void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
//set up pointers if the data mask is different ...
|
||||
@@ -1023,6 +1175,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
|
||||
sIBOActive = TRUE;
|
||||
}
|
||||
|
||||
BOOL error = FALSE;
|
||||
if (gDebugGL)
|
||||
{
|
||||
GLint buff;
|
||||
@@ -1085,7 +1238,11 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
|
||||
}
|
||||
}
|
||||
|
||||
unmapBuffer();
|
||||
if (error)
|
||||
{
|
||||
llerrs << "LLVertexBuffer::mapBuffer failed" << llendl;
|
||||
}
|
||||
unmapBuffer(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
static BOOL sUseStreamDraw;
|
||||
static BOOL sOmitBlank;
|
||||
|
||||
static void initClass(bool use_vbo);
|
||||
static void initClass(bool use_vbo, bool no_vbo_mapping);
|
||||
static void cleanupClass();
|
||||
static void setupClientArrays(U32 data_mask);
|
||||
static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
|
||||
@@ -147,15 +147,20 @@ protected:
|
||||
void updateNumVerts(S32 nverts);
|
||||
void updateNumIndices(S32 nindices);
|
||||
virtual BOOL useVBOs() const;
|
||||
void unmapBuffer();
|
||||
void unmapBuffer(S32 type);
|
||||
void freeClientBuffer() ;
|
||||
void allocateClientVertexBuffer() ;
|
||||
void allocateClientIndexBuffer() ;
|
||||
|
||||
public:
|
||||
LLVertexBuffer(U32 typemask, S32 usage);
|
||||
|
||||
// map for data access
|
||||
volatile U8* mapBuffer(S32 access = -1);
|
||||
volatile U8* mapVertexBuffer(S32 type = -1, S32 access = -1);
|
||||
volatile U8* mapIndexBuffer(S32 access = -1);
|
||||
|
||||
// set for rendering
|
||||
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
|
||||
virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0
|
||||
// allocate buffer
|
||||
void allocateBuffer(S32 nverts, S32 nindices, bool create);
|
||||
virtual void resizeBuffer(S32 newnverts, S32 newnindices);
|
||||
@@ -178,7 +183,7 @@ public:
|
||||
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0);
|
||||
|
||||
BOOL isEmpty() const { return mEmpty; }
|
||||
BOOL isLocked() const { return mLocked; }
|
||||
BOOL isLocked() const { return mVertexLocked || mIndexLocked; }
|
||||
S32 getNumVerts() const { return mNumVerts; }
|
||||
S32 getNumIndices() const { return mNumIndices; }
|
||||
S32 getRequestedVerts() const { return mRequestedNumVerts; }
|
||||
@@ -217,13 +222,14 @@ protected:
|
||||
U32 mGLIndices; // GL IBO handle
|
||||
volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
|
||||
volatile U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
|
||||
BOOL mLocked; // if TRUE, buffer is being or has been written to in client memory
|
||||
BOOL mVertexLocked; // if TRUE, vertex buffer is being or has been written to in client memory
|
||||
BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory
|
||||
BOOL mFinal; // if TRUE, buffer can not be mapped again
|
||||
BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags)
|
||||
BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
|
||||
S32 mOffsets[TYPE_MAX];
|
||||
BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
|
||||
BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not
|
||||
BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded)
|
||||
S32 mOffsets[TYPE_MAX];
|
||||
|
||||
class DirtyRegion
|
||||
{
|
||||
@@ -248,13 +254,14 @@ public:
|
||||
static std::vector<U32> sDeleteList;
|
||||
typedef std::list<LLVertexBuffer*> buffer_list_t;
|
||||
|
||||
static BOOL sDisableVBOMapping; //disable glMapBufferARB
|
||||
static BOOL sEnableVBOs;
|
||||
static BOOL sVBOActive;
|
||||
static BOOL sIBOActive;
|
||||
static S32 sTypeOffsets[TYPE_MAX];
|
||||
static U32 sGLMode[LLRender::NUM_MODES];
|
||||
static U32 sGLRenderBuffer;
|
||||
static U32 sGLRenderIndices;
|
||||
static BOOL sVBOActive;
|
||||
static BOOL sIBOActive;
|
||||
static U32 sGLRenderIndices;
|
||||
static U32 sLastMask;
|
||||
static U32 sAllocatedBytes;
|
||||
static U32 sBindCount;
|
||||
|
||||
@@ -9832,6 +9832,17 @@
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderVBOMappingDisable</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Disable VBO glMapBufferARB</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderVolumeLODFactor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -12789,6 +12800,17 @@
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>SkipReflectOcclusionUpdates</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable optimization that prevents occlusion updates for refelction pass</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>UseOutfitFolders</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -71,14 +71,14 @@ void main()
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
if (samp_pos.z != 0.0)
|
||||
/*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;
|
||||
|
||||
@@ -37,8 +37,8 @@ void main()
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
|
||||
vec4 col;
|
||||
col.a = gl_Color.a;
|
||||
|
||||
vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
|
||||
|
||||
// Add windlight lights
|
||||
col.rgb = atmosAmbient(vec3(0.));
|
||||
|
||||
@@ -12,7 +12,14 @@ varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy);
|
||||
vec4 diff = gl_Color*texture2D(diffuseMap, gl_TexCoord[0].xy);
|
||||
|
||||
if (diff.a < 0.2)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
gl_FragData[0] = vec4(diff.rgb, 0.0);
|
||||
gl_FragData[1] = vec4(0,0,0,0);
|
||||
gl_FragData[2] = vec4(normalize(vary_normal), 0.0);
|
||||
gl_FragData[3] = vary_position;
|
||||
|
||||
@@ -13,7 +13,8 @@ varying vec4 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragData[0] = texture2D(diffuseMap, gl_TexCoord[0].xy);
|
||||
vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy);
|
||||
gl_FragData[0] = vec4(col.rgb, col.a <= 0.5 ? 0.0 : 0.005);
|
||||
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;
|
||||
|
||||
@@ -77,6 +77,12 @@ void main()
|
||||
|
||||
//attenuate point light contribution by SSAO component
|
||||
out_col *= texture2DRect(lightMap, frag.xy).g;
|
||||
|
||||
|
||||
if (dot(out_col, out_col) <= 0.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
gl_FragColor.rgb = out_col;
|
||||
gl_FragColor.a = 0.0;
|
||||
|
||||
@@ -69,6 +69,11 @@ void main()
|
||||
//attenuate point light contribution by SSAO component
|
||||
col *= texture2DRect(lightMap, frag.xy).g;
|
||||
|
||||
if (dot(col, col) <= 0.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
|
||||
gl_FragColor.rgb = col;
|
||||
gl_FragColor.a = 0.0;
|
||||
|
||||
@@ -13,7 +13,7 @@ varying vec4 vary_position;
|
||||
void main()
|
||||
{
|
||||
vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy);
|
||||
gl_FragData[0] = gl_Color*col;
|
||||
gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005);
|
||||
gl_FragData[1] = vec4(0,0,0,0);
|
||||
gl_FragData[2] = vec4(normalize(vary_normal), 0.0);
|
||||
gl_FragData[3] = vary_position;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* $License$
|
||||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
vec3 scaleSoftClip(vec3 inColor);
|
||||
vec3 atmosTransport(vec3 inColor);
|
||||
|
||||
@@ -32,6 +33,7 @@ uniform vec3 normScale;
|
||||
uniform float fresnelScale;
|
||||
uniform float fresnelOffset;
|
||||
uniform float blurMultiplier;
|
||||
uniform mat4 norm_mat; //region space to screen space
|
||||
|
||||
|
||||
//bigWave is (refCoord.w, view.w);
|
||||
@@ -88,7 +90,7 @@ void main()
|
||||
refcol *= df1 * 0.333;
|
||||
|
||||
vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
|
||||
wavef.z *= max(-viewVec.z, 0.1);
|
||||
// wavef.z *= max(-viewVec.z, 0.1);
|
||||
wavef = normalize(wavef);
|
||||
|
||||
float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
|
||||
@@ -101,10 +103,10 @@ void main()
|
||||
refcol = mix(baseCol*df2, refcol, dweight);
|
||||
|
||||
//get specular component
|
||||
float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
|
||||
// float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
|
||||
|
||||
//harden specular
|
||||
spec = pow(spec, 128.0);
|
||||
// spec = pow(spec, 128.0);
|
||||
|
||||
//figure out distortion vector (ripply)
|
||||
vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
|
||||
@@ -118,13 +120,13 @@ void main()
|
||||
float shadow = 1.0;
|
||||
vec4 pos = vary_position;
|
||||
|
||||
vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz;
|
||||
//vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz;
|
||||
|
||||
if (pos.z > -shadow_clip.w)
|
||||
{
|
||||
// if (pos.z > -shadow_clip.w)
|
||||
// {
|
||||
vec4 spos = pos;
|
||||
|
||||
if (pos.z < -shadow_clip.z)
|
||||
/* if (pos.z < -shadow_clip.z)
|
||||
{
|
||||
vec4 lpos = (shadow_matrix[3]*spos);
|
||||
shadow = shadow2DProj(shadowMap3, lpos).x;
|
||||
@@ -144,14 +146,19 @@ void main()
|
||||
vec4 lpos = (shadow_matrix[0]*spos);
|
||||
shadow = shadow2DProj(shadowMap0, lpos).x;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
spec *= shadow;
|
||||
color.rgb += spec * specular;
|
||||
// spec *= shadow;
|
||||
// color.rgb += spec * specular;
|
||||
|
||||
color.rgb = atmosTransport(color.rgb);
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
color.a = spec * sunAngle2;
|
||||
// color.rgb = atmosTransport(color.rgb);
|
||||
// color.rgb = scaleSoftClip(color.rgb);
|
||||
// color.a = spec * sunAngle2;
|
||||
|
||||
gl_FragColor = color;
|
||||
// gl_FragColor = color;
|
||||
vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz;
|
||||
|
||||
gl_FragData[0] = vec4(color.rgb, 0.5); // diffuse
|
||||
gl_FragData[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
|
||||
gl_FragData[2] = vec4(screenspacewavef, 0.0); // normalxyz, displace
|
||||
}
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
#include "llinventoryview.h"
|
||||
|
||||
#include "llcommandlineparser.h"
|
||||
#include "llprogressview.h"
|
||||
|
||||
// [RLVa:KB]
|
||||
#include "rlvhandler.h"
|
||||
@@ -734,6 +735,7 @@ bool LLAppViewer::init()
|
||||
//
|
||||
// Initialize the window
|
||||
//
|
||||
gGLActive = TRUE;
|
||||
initWindow();
|
||||
|
||||
// call all self-registered classes
|
||||
@@ -875,7 +877,8 @@ bool LLAppViewer::mainLoop()
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_FRAME);
|
||||
pingMainloopTimeout("Main:MiscNativeWindowEvents");
|
||||
|
||||
|
||||
if (gViewerWindow)
|
||||
{
|
||||
LLFastTimer t2(LLFastTimer::FTM_MESSAGES);
|
||||
gViewerWindow->mWindow->processMiscNativeEvents();
|
||||
@@ -883,6 +886,7 @@ bool LLAppViewer::mainLoop()
|
||||
|
||||
pingMainloopTimeout("Main:GatherInput");
|
||||
|
||||
if (gViewerWindow)
|
||||
{
|
||||
LLFastTimer t2(LLFastTimer::FTM_MESSAGES);
|
||||
if (!restoreErrorTrap())
|
||||
@@ -958,11 +962,12 @@ bool LLAppViewer::mainLoop()
|
||||
if (!LLApp::isExiting())
|
||||
{
|
||||
pingMainloopTimeout("Main:Display");
|
||||
gGLActive = TRUE;
|
||||
display();
|
||||
|
||||
pingMainloopTimeout("Main:Snapshot");
|
||||
LLFloaterSnapshot::update(); // take snapshots
|
||||
|
||||
gGLActive = FALSE;
|
||||
#if LL_LCD_COMPILE
|
||||
// update LCD Screen
|
||||
pingMainloopTimeout("Main:LCD");
|
||||
@@ -989,7 +994,7 @@ bool LLAppViewer::mainLoop()
|
||||
|
||||
// yield cooperatively when not running as foreground window
|
||||
if ( gNoRender
|
||||
|| !gViewerWindow->mWindow->getVisible()
|
||||
|| (gViewerWindow && !gViewerWindow->mWindow->getVisible())
|
||||
|| !gFocusMgr.getAppHasFocus())
|
||||
{
|
||||
// Sleep if we're not rendering, or the window is minimized.
|
||||
@@ -1141,11 +1146,14 @@ bool LLAppViewer::cleanup()
|
||||
llinfos << "Cleaning Up" << llendflush;
|
||||
|
||||
// Must clean up texture references before viewer window is destroyed.
|
||||
LLHUDManager::getInstance()->updateEffects();
|
||||
LLHUDObject::updateAll();
|
||||
LLHUDManager::getInstance()->cleanupEffects();
|
||||
LLHUDObject::cleanupHUDObjects();
|
||||
llinfos << "HUD Objects cleaned up" << llendflush;
|
||||
if(LLHUDManager::instanceExists())
|
||||
{
|
||||
LLHUDManager::getInstance()->updateEffects();
|
||||
LLHUDObject::updateAll();
|
||||
LLHUDManager::getInstance()->cleanupEffects();
|
||||
LLHUDObject::cleanupHUDObjects();
|
||||
llinfos << "HUD Objects cleaned up" << llendflush;
|
||||
}
|
||||
|
||||
LLKeyframeDataCache::clear();
|
||||
|
||||
@@ -1157,8 +1165,10 @@ bool LLAppViewer::cleanup()
|
||||
// Note: this is where gWorldMap used to be deleted.
|
||||
|
||||
// Note: this is where gHUDManager used to be deleted.
|
||||
LLHUDManager::getInstance()->shutdownClass();
|
||||
|
||||
if(LLHUDManager::instanceExists())
|
||||
{
|
||||
LLHUDManager::getInstance()->shutdownClass();
|
||||
}
|
||||
|
||||
delete gAssetStorage;
|
||||
gAssetStorage = NULL;
|
||||
@@ -1247,21 +1257,25 @@ bool LLAppViewer::cleanup()
|
||||
llinfos << "Shutting down." << llendflush;
|
||||
|
||||
// Destroy the UI
|
||||
gViewerWindow->shutdownViews();
|
||||
if( gViewerWindow)
|
||||
gViewerWindow->shutdownViews();
|
||||
|
||||
// Clean up selection managers after UI is destroyed, as UI may be observing them.
|
||||
// Clean up before GL is shut down because we might be holding on to objects with texture references
|
||||
LLSelectMgr::cleanupGlobals();
|
||||
|
||||
// Shut down OpenGL
|
||||
gViewerWindow->shutdownGL();
|
||||
if( gViewerWindow)
|
||||
{
|
||||
gViewerWindow->shutdownGL();
|
||||
|
||||
// Destroy window, and make sure we're not fullscreen
|
||||
// This may generate window reshape and activation events.
|
||||
// Therefore must do this before destroying the message system.
|
||||
delete gViewerWindow;
|
||||
gViewerWindow = NULL;
|
||||
llinfos << "ViewerWindow deleted" << llendflush;
|
||||
// Destroy window, and make sure we're not fullscreen
|
||||
// This may generate window reshape and activation events.
|
||||
// Therefore must do this before destroying the message system.
|
||||
delete gViewerWindow;
|
||||
gViewerWindow = NULL;
|
||||
llinfos << "ViewerWindow deleted" << llendflush;
|
||||
}
|
||||
|
||||
// viewer UI relies on keyboard so keep it aound until viewer UI isa gone
|
||||
delete gKeyboard;
|
||||
@@ -1369,6 +1383,9 @@ bool LLAppViewer::cleanup()
|
||||
|
||||
writeDebugInfo();
|
||||
|
||||
// Stop the plugin read thread if it's running.
|
||||
LLPluginProcessParent::setUseReadThread(false);
|
||||
|
||||
// Let threads finish
|
||||
LLTimer idleTimer;
|
||||
idleTimer.reset();
|
||||
@@ -1394,8 +1411,8 @@ bool LLAppViewer::cleanup()
|
||||
|
||||
// Delete workers first
|
||||
// shotdown all worker threads before deleting them in case of co-dependencies
|
||||
sTextureCache->shutdown();
|
||||
sTextureFetch->shutdown();
|
||||
sTextureCache->shutdown();
|
||||
sImageDecodeThread->shutdown();
|
||||
sTextureFetch->shutDownTextureCacheThread();
|
||||
sTextureFetch->shutDownImageDecodeThread();
|
||||
@@ -1424,7 +1441,10 @@ bool LLAppViewer::cleanup()
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
llinfos << "Auditing VFS" << llendl;
|
||||
gVFS->audit();
|
||||
if(gVFS)
|
||||
{
|
||||
gVFS->audit();
|
||||
}
|
||||
#endif
|
||||
|
||||
// For safety, the LLVFS has to be deleted *after* LLVFSThread. This should be cleaned up.
|
||||
@@ -2525,7 +2545,7 @@ void LLAppViewer::handleViewerCrash()
|
||||
gMessageSystem->stopLogging();
|
||||
}
|
||||
|
||||
LLWorld::getInstance()->getInfo(gDebugInfo);
|
||||
if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo);
|
||||
|
||||
// Close the debug file
|
||||
pApp->writeDebugInfo();
|
||||
@@ -2692,6 +2712,13 @@ void LLAppViewer::requestQuit()
|
||||
|
||||
if( (LLStartUp::getStartupState() < STATE_STARTED) || !region )
|
||||
{
|
||||
// If we have a region, make some attempt to send a logout request first.
|
||||
// This prevents the halfway-logged-in avatar from hanging around inworld for a couple minutes.
|
||||
if(region)
|
||||
{
|
||||
sendLogoutRequest();
|
||||
}
|
||||
|
||||
// Quit immediately
|
||||
forceQuit();
|
||||
return;
|
||||
@@ -2731,6 +2758,11 @@ static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_q
|
||||
|
||||
void LLAppViewer::userQuit()
|
||||
{
|
||||
if (gDisconnected || gViewerWindow->getProgressView()->getVisible())
|
||||
{
|
||||
requestQuit();
|
||||
}
|
||||
else
|
||||
LLNotifications::instance().add("ConfirmQuit");
|
||||
}
|
||||
|
||||
@@ -3311,10 +3343,13 @@ void LLAppViewer::idle()
|
||||
if (LLStartUp::getStartupState() < STATE_STARTED)
|
||||
{
|
||||
// Skip rest if idle startup returns false (essentially, no world yet)
|
||||
gGLActive = TRUE;
|
||||
if (!idle_startup())
|
||||
{
|
||||
gGLActive = FALSE;
|
||||
return;
|
||||
}
|
||||
gGLActive = FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -3641,6 +3676,7 @@ void LLAppViewer::idle()
|
||||
// forcibly quit if it has taken too long
|
||||
if (mQuitRequested)
|
||||
{
|
||||
gGLActive = TRUE;
|
||||
idleShutdown();
|
||||
}
|
||||
|
||||
|
||||
@@ -384,8 +384,6 @@ void LLDrawable::makeActive()
|
||||
mParent->makeActive();
|
||||
}
|
||||
|
||||
gPipeline.setActive(this, TRUE);
|
||||
|
||||
//all child objects must also be active
|
||||
llassert_always(mVObjp);
|
||||
|
||||
@@ -432,7 +430,6 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
|
||||
if (isState(ACTIVE))
|
||||
{
|
||||
clearState(ACTIVE);
|
||||
gPipeline.setActive(this, FALSE);
|
||||
|
||||
if (mParent.notNull() && mParent->isActive() && warning_enabled)
|
||||
{
|
||||
@@ -676,6 +673,11 @@ BOOL LLDrawable::updateMoveDamped()
|
||||
|
||||
void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
|
||||
{
|
||||
if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
//switch LOD with the spatial group to avoid artifacts
|
||||
//LLSpatialGroup* sg = getSpatialGroup();
|
||||
|
||||
@@ -953,11 +955,31 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
|
||||
return retval;
|
||||
}
|
||||
|
||||
const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
|
||||
//static
|
||||
S32 LLDrawable::getMinVisFrameRange()
|
||||
{
|
||||
return MIN_VIS_FRAME_RANGE ;
|
||||
}
|
||||
|
||||
BOOL LLDrawable::isRecentlyVisible() const
|
||||
{
|
||||
//currently visible or visible in the previous frame.
|
||||
return isVisible() || (mVisible == sCurVisible - 1) ;
|
||||
BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE) ;
|
||||
|
||||
if(!vis)
|
||||
{
|
||||
LLSpatialGroup* group = getSpatialGroup();
|
||||
if (group && group->isRecentlyVisible())
|
||||
{
|
||||
mVisible = sCurVisible;
|
||||
vis = TRUE ;
|
||||
}
|
||||
}
|
||||
|
||||
return vis ;
|
||||
}
|
||||
|
||||
BOOL LLDrawable::isVisible() const
|
||||
{
|
||||
if (mVisible == sCurVisible)
|
||||
@@ -1007,8 +1029,8 @@ BOOL LLDrawable::isVisible() const
|
||||
// Spatial Partition Bridging Drawable
|
||||
//=======================================
|
||||
|
||||
LLSpatialBridge::LLSpatialBridge(LLDrawable* root, U32 data_mask)
|
||||
: LLSpatialPartition(data_mask, FALSE)
|
||||
LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask)
|
||||
: LLSpatialPartition(data_mask, render_by_group, FALSE)
|
||||
{
|
||||
mDrawable = root;
|
||||
root->setSpatialBridge(this);
|
||||
@@ -1019,8 +1041,12 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, U32 data_mask)
|
||||
mPartitionType = LLViewerRegion::PARTITION_VOLUME;
|
||||
|
||||
mOctree->balance();
|
||||
LLSpatialPartition *part = mDrawable->getRegion()->getSpatialPartition(mPartitionType);
|
||||
|
||||
mDrawable->getRegion()->getSpatialPartition(mPartitionType)->put(this);
|
||||
if (part)
|
||||
{
|
||||
part->put(this);
|
||||
}
|
||||
}
|
||||
|
||||
LLSpatialBridge::~LLSpatialBridge()
|
||||
@@ -1334,8 +1360,13 @@ void LLSpatialBridge::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL imm
|
||||
|
||||
BOOL LLSpatialBridge::updateMove()
|
||||
{
|
||||
LLSpatialPartition* part = mDrawable->getRegion()->getSpatialPartition(mPartitionType);
|
||||
llassert_always(part);
|
||||
mOctree->balance();
|
||||
mDrawable->getRegion()->getSpatialPartition(mPartitionType)->move(this, getSpatialGroup(), TRUE);
|
||||
if (part)
|
||||
{
|
||||
part->move(this, getSpatialGroup(), TRUE);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1439,9 +1470,8 @@ void LLDrawable::updateFaceSize(S32 idx)
|
||||
}
|
||||
|
||||
LLBridgePartition::LLBridgePartition()
|
||||
: LLSpatialPartition(0, TRUE)
|
||||
: LLSpatialPartition(0, FALSE, 0)
|
||||
{
|
||||
mRenderByGroup = FALSE;
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
|
||||
mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
|
||||
mLODPeriod = 16;
|
||||
|
||||
@@ -281,6 +281,7 @@ public:
|
||||
S32 mQuietCount;
|
||||
|
||||
static S32 getCurrentFrame() { return sCurVisible; }
|
||||
static S32 getMinVisFrameRange();
|
||||
|
||||
void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
|
||||
LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }
|
||||
|
||||
@@ -482,7 +482,8 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
|
||||
{
|
||||
if (params.mTexture.notNull())
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(params.mTexture.get(), TRUE);
|
||||
params.mTexture->addTextureStats(params.mVSize);
|
||||
gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
|
||||
if (params.mTextureMatrix)
|
||||
{
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
|
||||
@@ -61,7 +61,9 @@ static BOOL deferred_render = FALSE;
|
||||
|
||||
LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
|
||||
LLRenderPass(type), current_shader(NULL), target_shader(NULL),
|
||||
simple_shader(NULL), fullbright_shader(NULL)
|
||||
simple_shader(NULL), fullbright_shader(NULL),
|
||||
mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF),
|
||||
mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -88,22 +90,23 @@ void LLDrawPoolAlpha::beginDeferredPass(S32 pass)
|
||||
|
||||
void LLDrawPoolAlpha::endDeferredPass(S32 pass)
|
||||
{
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.4f);
|
||||
|
||||
}
|
||||
|
||||
void LLDrawPoolAlpha::renderDeferred(S32 pass)
|
||||
{
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS);
|
||||
gDeferredTreeProgram.bind();
|
||||
LLGLEnable test(GL_ALPHA_TEST);
|
||||
//render alpha masked objects
|
||||
LLRenderPass::renderTexture(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
|
||||
gDeferredTreeProgram.unbind();
|
||||
}
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
|
||||
}
|
||||
|
||||
void LLDrawPoolAlpha::renderDeferred(S32 pass)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
|
||||
{
|
||||
@@ -178,8 +181,15 @@ void LLDrawPoolAlpha::render(S32 pass)
|
||||
|
||||
LLGLSPipelineAlpha gls_pipeline_alpha;
|
||||
|
||||
gGL.setColorMask(true, true);
|
||||
if (LLPipeline::sFastAlpha && !deferred_render)
|
||||
{
|
||||
mColorSFactor = LLRender::BF_ONE; // }
|
||||
mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow
|
||||
mAlphaSFactor = LLRender::BF_ZERO;
|
||||
mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds
|
||||
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
|
||||
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f);
|
||||
if (mVertexShaderLevel > 0)
|
||||
{
|
||||
@@ -203,8 +213,17 @@ void LLDrawPoolAlpha::render(S32 pass)
|
||||
}
|
||||
|
||||
LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE);
|
||||
|
||||
mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend
|
||||
mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
|
||||
mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression
|
||||
mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
|
||||
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
|
||||
|
||||
renderAlpha(getVertexDataMask());
|
||||
|
||||
gGL.setColorMask(true, false);
|
||||
|
||||
if (deferred_render && current_shader != NULL)
|
||||
{
|
||||
gPipeline.unbindDeferredShader(*current_shader);
|
||||
@@ -283,6 +302,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
if (group->mSpatialPartition->mRenderByGroup &&
|
||||
!group->isDead())
|
||||
{
|
||||
bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow.
|
||||
// All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress.
|
||||
group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE &&
|
||||
group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_CLOUD &&
|
||||
group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE;
|
||||
|
||||
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
|
||||
|
||||
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
|
||||
@@ -291,88 +316,115 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
|
||||
LLRenderPass::applyModelMatrix(params);
|
||||
|
||||
if (params.mTexture.notNull())
|
||||
{
|
||||
gGL.getTexUnit(0)->activate();
|
||||
gGL.getTexUnit(0)->bind(params.mTexture.get());
|
||||
|
||||
if (params.mTextureMatrix)
|
||||
if (params.mFullbright)
|
||||
{
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
|
||||
gPipeline.mTextureMatrixOps++;
|
||||
// Turn off lighting if it hasn't already been so.
|
||||
if (light_enabled || !initialized_lighting)
|
||||
{
|
||||
initialized_lighting = TRUE;
|
||||
if (use_shaders)
|
||||
{
|
||||
target_shader = fullbright_shader;
|
||||
}
|
||||
else
|
||||
{
|
||||
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
|
||||
}
|
||||
light_enabled = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.mFullbright)
|
||||
{
|
||||
// Turn off lighting if it hasn't already been so.
|
||||
if (light_enabled || !initialized_lighting)
|
||||
// Turn on lighting if it isn't already.
|
||||
else if (!light_enabled || !initialized_lighting)
|
||||
{
|
||||
initialized_lighting = TRUE;
|
||||
if (use_shaders)
|
||||
{
|
||||
target_shader = fullbright_shader;
|
||||
target_shader = simple_shader;
|
||||
}
|
||||
else
|
||||
{
|
||||
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
|
||||
gPipeline.enableLightsDynamic();
|
||||
}
|
||||
light_enabled = FALSE;
|
||||
light_enabled = TRUE;
|
||||
}
|
||||
}
|
||||
// Turn on lighting if it isn't already.
|
||||
else if (!light_enabled || !initialized_lighting)
|
||||
{
|
||||
initialized_lighting = TRUE;
|
||||
if (use_shaders)
|
||||
{
|
||||
target_shader = simple_shader;
|
||||
}
|
||||
else
|
||||
{
|
||||
gPipeline.enableLightsDynamic();
|
||||
}
|
||||
light_enabled = TRUE;
|
||||
}
|
||||
|
||||
// If we need shaders, and we're not ALREADY using the proper shader, then bind it
|
||||
// (this way we won't rebind shaders unnecessarily).
|
||||
if(use_shaders && (current_shader != target_shader))
|
||||
{
|
||||
llassert(target_shader != NULL);
|
||||
if (deferred_render && current_shader != NULL)
|
||||
// If we need shaders, and we're not ALREADY using the proper shader, then bind it
|
||||
// (this way we won't rebind shaders unnecessarily).
|
||||
if(use_shaders && (current_shader != target_shader))
|
||||
{
|
||||
gPipeline.unbindDeferredShader(*current_shader);
|
||||
llassert(target_shader != NULL);
|
||||
if (deferred_render && current_shader != NULL)
|
||||
{
|
||||
gPipeline.unbindDeferredShader(*current_shader);
|
||||
}
|
||||
current_shader = target_shader;
|
||||
if (deferred_render)
|
||||
{
|
||||
gPipeline.bindDeferredShader(*current_shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
current_shader->bind();
|
||||
}
|
||||
}
|
||||
current_shader = target_shader;
|
||||
if (deferred_render)
|
||||
else if (!use_shaders && current_shader != NULL)
|
||||
{
|
||||
gPipeline.bindDeferredShader(*current_shader);
|
||||
|
||||
if (deferred_render)
|
||||
{
|
||||
gPipeline.unbindDeferredShader(*current_shader);
|
||||
}
|
||||
LLGLSLShader::bindNoShader();
|
||||
current_shader = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_shader->bind();
|
||||
}
|
||||
}
|
||||
else if (!use_shaders && current_shader != NULL)
|
||||
{
|
||||
LLGLSLShader::bindNoShader();
|
||||
if (deferred_render)
|
||||
{
|
||||
gPipeline.unbindDeferredShader(*current_shader);
|
||||
}
|
||||
current_shader = NULL;
|
||||
}
|
||||
|
||||
if (params.mGroup)
|
||||
{
|
||||
params.mGroup->rebuildMesh();
|
||||
if (params.mGroup)
|
||||
{
|
||||
params.mGroup->rebuildMesh();
|
||||
}
|
||||
|
||||
|
||||
if (params.mTexture.notNull())
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(params.mTexture.get());
|
||||
if(params.mTexture.notNull())
|
||||
{
|
||||
params.mTexture->addTextureStats(params.mVSize);
|
||||
}
|
||||
if (params.mTextureMatrix)
|
||||
{
|
||||
gGL.getTexUnit(0)->activate();
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
|
||||
gPipeline.mTextureMatrixOps++;
|
||||
}
|
||||
}
|
||||
}
|
||||
params.mVertexBuffer->setBuffer(mask);
|
||||
params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
|
||||
gPipeline.addTrianglesDrawn(params.mCount/3);
|
||||
|
||||
// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
|
||||
if (draw_glow_for_this_partition &&
|
||||
params.mGlowColor.mV[3] > 0)
|
||||
{
|
||||
// install glow-accumulating blend mode
|
||||
gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
|
||||
LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
|
||||
|
||||
// glow doesn't use vertex colors from the mesh data
|
||||
params.mVertexBuffer->setBuffer(mask & ~LLVertexBuffer::MAP_COLOR);
|
||||
glColor4ubv(params.mGlowColor.mV);
|
||||
|
||||
// do the actual drawing, again
|
||||
params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
|
||||
gPipeline.addTrianglesDrawn(params.mCount/3);
|
||||
|
||||
// restore our alpha blend mode
|
||||
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
|
||||
}
|
||||
|
||||
if (params.mTextureMatrix && params.mTexture.notNull())
|
||||
{
|
||||
gGL.getTexUnit(0)->activate();
|
||||
@@ -383,6 +435,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
}
|
||||
}
|
||||
|
||||
if (deferred_render && current_shader != NULL)
|
||||
{
|
||||
gPipeline.unbindDeferredShader(*current_shader);
|
||||
LLVertexBuffer::unbind();
|
||||
LLGLState::checkStates();
|
||||
LLGLState::checkTextureChannels();
|
||||
LLGLState::checkClientArrays();
|
||||
}
|
||||
|
||||
if (!light_enabled)
|
||||
{
|
||||
gPipeline.enableLightsDynamic();
|
||||
|
||||
@@ -83,6 +83,12 @@ private:
|
||||
LLGLSLShader* target_shader;
|
||||
LLGLSLShader* simple_shader;
|
||||
LLGLSLShader* fullbright_shader;
|
||||
|
||||
// our 'normal' alpha blend function for this pass
|
||||
LLRender::eBlendFactor mColorSFactor;
|
||||
LLRender::eBlendFactor mColorDFactor;
|
||||
LLRender::eBlendFactor mAlphaSFactor;
|
||||
LLRender::eBlendFactor mAlphaDFactor;
|
||||
};
|
||||
|
||||
class LLDrawPoolAlphaPostWater : public LLDrawPoolAlpha
|
||||
|
||||
@@ -158,8 +158,8 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()
|
||||
|
||||
void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS);
|
||||
|
||||
sSkipTransparent = TRUE;
|
||||
|
||||
if (LLPipeline::sImpostorRender)
|
||||
{
|
||||
beginDeferredSkinned();
|
||||
@@ -182,7 +182,7 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
|
||||
|
||||
void LLDrawPoolAvatar::endDeferredPass(S32 pass)
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS);
|
||||
sSkipTransparent = FALSE;
|
||||
|
||||
if (LLPipeline::sImpostorRender)
|
||||
{
|
||||
@@ -317,6 +317,10 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
|
||||
return;
|
||||
}
|
||||
|
||||
if (sShaderLevel > 0)
|
||||
{
|
||||
gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX];
|
||||
}
|
||||
avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);
|
||||
|
||||
}
|
||||
@@ -353,7 +357,7 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)
|
||||
switch (pass)
|
||||
{
|
||||
case 0:
|
||||
beginFootShadow();
|
||||
beginImpostor();
|
||||
break;
|
||||
case 1:
|
||||
beginRigid();
|
||||
@@ -377,7 +381,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)
|
||||
switch (pass)
|
||||
{
|
||||
case 0:
|
||||
endFootShadow();
|
||||
endImpostor();
|
||||
break;
|
||||
case 1:
|
||||
endRigid();
|
||||
@@ -387,7 +391,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::beginFootShadow()
|
||||
void LLDrawPoolAvatar::beginImpostor()
|
||||
{
|
||||
if (!LLPipeline::sReflectionRender)
|
||||
{
|
||||
@@ -398,7 +402,7 @@ void LLDrawPoolAvatar::beginFootShadow()
|
||||
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::endFootShadow()
|
||||
void LLDrawPoolAvatar::endImpostor()
|
||||
{
|
||||
gPipeline.enableLightsDynamic();
|
||||
}
|
||||
@@ -568,7 +572,6 @@ void LLDrawPoolAvatar::endSkinned()
|
||||
|
||||
void LLDrawPoolAvatar::beginDeferredSkinned()
|
||||
{
|
||||
sSkipTransparent = TRUE;
|
||||
sShaderLevel = mVertexShaderLevel;
|
||||
sVertexProgram = &gDeferredAvatarProgram;
|
||||
|
||||
@@ -583,7 +586,6 @@ void LLDrawPoolAvatar::beginDeferredSkinned()
|
||||
|
||||
void LLDrawPoolAvatar::endDeferredSkinned()
|
||||
{
|
||||
sSkipTransparent = FALSE;
|
||||
// if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done
|
||||
sRenderingSkinned = FALSE;
|
||||
disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]);
|
||||
|
||||
@@ -90,11 +90,11 @@ public:
|
||||
/*virtual*/ void renderShadow(S32 pass);
|
||||
|
||||
void beginRigid();
|
||||
void beginFootShadow();
|
||||
void beginImpostor();
|
||||
void beginSkinned();
|
||||
|
||||
void endRigid();
|
||||
void endFootShadow();
|
||||
void endImpostor();
|
||||
void endSkinned();
|
||||
|
||||
void beginDeferredImpostor();
|
||||
|
||||
@@ -263,7 +263,7 @@ void LLDrawPoolGrass::endDeferredPass(S32 pass)
|
||||
|
||||
void LLDrawPoolGrass::renderDeferred(S32 pass)
|
||||
{
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
|
||||
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS);
|
||||
|
||||
@@ -49,8 +49,11 @@
|
||||
#include "pipeline.h"
|
||||
#include "llviewershadermgr.h"
|
||||
|
||||
LLDrawPoolSky::LLDrawPoolSky() :
|
||||
LLFacePool(POOL_SKY), mShader(NULL)
|
||||
LLDrawPoolSky::LLDrawPoolSky()
|
||||
: LLFacePool(POOL_SKY),
|
||||
|
||||
mSkyTex(NULL),
|
||||
mShader(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -73,19 +73,19 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerImage *texturep) :
|
||||
TRUE, TRUE, GL_ALPHA8, GL_ALPHA,
|
||||
LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb"));
|
||||
|
||||
gGL.getTexUnit(0)->bind(mAlphaRampImagep.get());
|
||||
//gGL.getTexUnit(0)->bind(mAlphaRampImagep.get());
|
||||
mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
m2DAlphaRampImagep = gImageList.getImageFromFile("alpha_gradient_2d.j2c",
|
||||
TRUE, TRUE, GL_ALPHA8, GL_ALPHA,
|
||||
LLUUID("38b86f85-2575-52a9-a531-23108d8da837"));
|
||||
|
||||
gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
|
||||
//gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
|
||||
m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_TERRAIN);
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
//gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
|
||||
LLDrawPoolTerrain::~LLDrawPoolTerrain()
|
||||
|
||||
@@ -52,7 +52,6 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerImage *texturep) :
|
||||
LLFacePool(POOL_TREE),
|
||||
mTexturep(texturep)
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(mTexturep.get());
|
||||
mTexturep->setAddressMode(LLTexUnit::TAM_WRAP);
|
||||
}
|
||||
|
||||
@@ -142,8 +141,8 @@ void LLDrawPoolTree::endRenderPass(S32 pass)
|
||||
void LLDrawPoolTree::beginDeferredPass(S32 pass)
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_RENDER_TREES);
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
|
||||
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
|
||||
|
||||
shader = &gDeferredTreeProgram;
|
||||
shader->bind();
|
||||
}
|
||||
|
||||
@@ -137,6 +137,19 @@ void LLDrawPoolWater::endPostDeferredPass(S32 pass)
|
||||
deferred_render = FALSE;
|
||||
}
|
||||
|
||||
//===============================
|
||||
//DEFERRED IMPLEMENTATION
|
||||
//===============================
|
||||
void LLDrawPoolWater::renderDeferred(S32 pass)
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_RENDER_WATER);
|
||||
deferred_render = TRUE;
|
||||
shade();
|
||||
deferred_render = FALSE;
|
||||
}
|
||||
|
||||
//=========================================
|
||||
|
||||
void LLDrawPoolWater::render(S32 pass)
|
||||
{
|
||||
LLFastTimer ftm(LLFastTimer::FTM_RENDER_WATER);
|
||||
@@ -338,7 +351,10 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
|
||||
|
||||
void LLDrawPoolWater::shade()
|
||||
{
|
||||
gGL.setColorMask(true, true);
|
||||
if (!deferred_render)
|
||||
{
|
||||
gGL.setColorMask(true, true);
|
||||
}
|
||||
|
||||
LLVOSky *voskyp = gSky.mVOSkyp;
|
||||
|
||||
@@ -354,7 +370,7 @@ void LLDrawPoolWater::shade()
|
||||
LLVector3 light_dir;
|
||||
LLColor3 light_color;
|
||||
|
||||
if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS)
|
||||
if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS)
|
||||
{
|
||||
light_dir = gSky.getSunDirection();
|
||||
light_dir.normVec();
|
||||
@@ -401,6 +417,15 @@ void LLDrawPoolWater::shade()
|
||||
shader = &gWaterProgram;
|
||||
}
|
||||
|
||||
if (deferred_render)
|
||||
{
|
||||
gPipeline.bindDeferredShader(*shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader->bind();
|
||||
}
|
||||
|
||||
sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
|
||||
|
||||
S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX);
|
||||
@@ -436,15 +461,6 @@ void LLDrawPoolWater::shade()
|
||||
|
||||
S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX);
|
||||
|
||||
if (deferred_render)
|
||||
{
|
||||
gPipeline.bindDeferredShader(*shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader->bind();
|
||||
}
|
||||
|
||||
if (screentex > -1)
|
||||
{
|
||||
shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
|
||||
@@ -545,7 +561,7 @@ void LLDrawPoolWater::shade()
|
||||
sNeedsDistortionUpdate = TRUE;
|
||||
face->renderIndexed();
|
||||
}
|
||||
else if (gGLManager.mHasDepthClamp)
|
||||
else if (gGLManager.mHasDepthClamp || deferred_render)
|
||||
{
|
||||
face->renderIndexed();
|
||||
}
|
||||
@@ -575,7 +591,10 @@ void LLDrawPoolWater::shade()
|
||||
|
||||
gGL.getTexUnit(0)->activate();
|
||||
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
|
||||
gGL.setColorMask(true, false);
|
||||
if (!deferred_render)
|
||||
{
|
||||
gGL.setColorMask(true, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -71,10 +71,12 @@ public:
|
||||
/*virtual*/ LLDrawPool *instancePool();
|
||||
static void restoreGL();
|
||||
|
||||
/*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); }
|
||||
/*virtual*/ S32 getNumPostDeferredPasses() { return 0; } //getNumPasses(); }
|
||||
/*virtual*/ void beginPostDeferredPass(S32 pass);
|
||||
/*virtual*/ void endPostDeferredPass(S32 pass);
|
||||
/*virtual*/ void renderPostDeferred(S32 pass) { render(pass); }
|
||||
/*virtual*/ S32 getNumDeferredPasses() { return 1; }
|
||||
/*virtual*/ void renderDeferred(S32 pass = 0);
|
||||
|
||||
/*virtual*/ S32 getNumPasses();
|
||||
/*virtual*/ void render(S32 pass = 0);
|
||||
|
||||
@@ -160,14 +160,14 @@ void LLDrawPoolWLSky::renderStars(void) const
|
||||
// *NOTE: have to have bound the cloud noise texture already since register
|
||||
// combiners blending below requires something to be bound
|
||||
// and we might as well only bind once.
|
||||
//gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
|
||||
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
gPipeline.disableLights();
|
||||
|
||||
if (!LLPipeline::sReflectionRender)
|
||||
/*if (!LLPipeline::sReflectionRender)
|
||||
{
|
||||
glPointSize(2.f);
|
||||
}
|
||||
}*/
|
||||
|
||||
// *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid
|
||||
// clamping and allow the star_alpha param to brighten the stars.
|
||||
@@ -175,17 +175,26 @@ void LLDrawPoolWLSky::renderStars(void) const
|
||||
LLColor4 star_alpha(LLColor4::black);
|
||||
star_alpha.mV[3] = LLWLParamManager::instance()->mCurParams.getFloat("star_brightness", error) / 2.f;
|
||||
llassert_always(!error);
|
||||
|
||||
|
||||
// gl_FragColor.rgb = gl_Color.rgb;
|
||||
// gl_FragColor.a = gl_Color.a * star_alpha.a;
|
||||
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
|
||||
gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_PREV_ALPHA, LLTexUnit::TBS_CONST_ALPHA);
|
||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, star_alpha.mV);
|
||||
//New
|
||||
gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex());
|
||||
|
||||
gGL.pushMatrix();
|
||||
glRotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
|
||||
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
|
||||
gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_CONST_ALPHA, LLTexUnit::TBS_TEX_ALPHA);
|
||||
/*//Old
|
||||
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
|
||||
gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_PREV_ALPHA, LLTexUnit::TBS_CONST_ALPHA); */
|
||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, star_alpha.mV);
|
||||
|
||||
gSky.mVOWLSkyp->drawStars();
|
||||
|
||||
glPointSize(1.f);
|
||||
|
||||
gGL.popMatrix(); //New
|
||||
//glPointSize(1.f);
|
||||
|
||||
// and disable the combiner states
|
||||
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
|
||||
}
|
||||
@@ -284,9 +293,10 @@ void LLDrawPoolWLSky::render(S32 pass)
|
||||
LLImageGL * tex = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture();
|
||||
gGL.getTexUnit(0)->bind(tex);
|
||||
|
||||
renderHeavenlyBodies();
|
||||
|
||||
renderStars();
|
||||
|
||||
renderHeavenlyBodies();
|
||||
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
static const U32 SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_TEXCOORD0;
|
||||
static const U32 STAR_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_COLOR;
|
||||
LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0;
|
||||
|
||||
LLDrawPoolWLSky(void);
|
||||
/*virtual*/ ~LLDrawPoolWLSky();
|
||||
|
||||
@@ -157,6 +157,7 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
|
||||
mGeomIndex = 0;
|
||||
mIndicesCount = 0;
|
||||
mIndicesIndex = 0;
|
||||
mIndexInTex = 0;
|
||||
mTexture = NULL;
|
||||
mTEOffset = -1;
|
||||
|
||||
@@ -205,6 +206,7 @@ void LLFace::destroy()
|
||||
if (group)
|
||||
{
|
||||
group->dirtyGeom();
|
||||
gPipeline.markRebuild(group, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,12 +274,36 @@ void LLFace::setTexture(LLViewerImage* tex)
|
||||
mTexture->removeFace(this) ;
|
||||
}
|
||||
|
||||
mTexture = tex ;
|
||||
|
||||
if(mTexture.notNull())
|
||||
if(tex)
|
||||
{
|
||||
mTexture->addFace(this) ;
|
||||
}
|
||||
tex->addFace(this) ;
|
||||
}
|
||||
|
||||
mTexture = tex ;
|
||||
}
|
||||
|
||||
void LLFace::dirtyTexture()
|
||||
{
|
||||
gPipeline.markTextured(getDrawable());
|
||||
}
|
||||
|
||||
void LLFace::switchTexture(LLViewerImage* new_texture)
|
||||
{
|
||||
if(mTexture == new_texture)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
if(!new_texture)
|
||||
{
|
||||
llerrs << "Can not switch to a null texture." << llendl;
|
||||
return;
|
||||
}
|
||||
new_texture->addTextureStats(mTexture->mMaxVirtualSize) ;
|
||||
|
||||
getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
|
||||
setTexture(new_texture) ;
|
||||
dirtyTexture();
|
||||
}
|
||||
|
||||
void LLFace::setTEOffset(const S32 te_offset)
|
||||
@@ -453,8 +479,15 @@ void LLFace::renderForSelect(U32 data_mask)
|
||||
|
||||
void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color)
|
||||
{
|
||||
if(mDrawablep.isNull() || mVertexBuffer.isNull() || mDrawablep->getSpatialGroup() == NULL ||
|
||||
mDrawablep->getSpatialGroup()->isState(LLSpatialGroup::GEOM_DIRTY))
|
||||
if (mDrawablep->getSpatialGroup() == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mDrawablep->getSpatialGroup()->rebuildGeom();
|
||||
mDrawablep->getSpatialGroup()->rebuildMesh();
|
||||
|
||||
if(mDrawablep.isNull() || mVertexBuffer.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -473,17 +506,13 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color)
|
||||
glMultMatrixf((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix);
|
||||
}
|
||||
|
||||
setFaceColor(color);
|
||||
renderSetColor();
|
||||
|
||||
glColor4fv(color.mV);
|
||||
mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
LLGLState::checkClientArrays("", LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
|
||||
#endif
|
||||
mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
|
||||
|
||||
unsetFaceColor();
|
||||
unsetFaceColor();
|
||||
gGL.popMatrix();
|
||||
}
|
||||
}
|
||||
@@ -805,6 +834,7 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,
|
||||
// by planarProjection(). This is needed to match planar texgen parameters.
|
||||
void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const
|
||||
{
|
||||
const LLMatrix4& vol_mat = getWorldMatrix();
|
||||
const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);
|
||||
LLVector3 normal = vf.mVertices[0].mNormal;
|
||||
LLVector3 binormal = vf.mVertices[0].mBinormal;
|
||||
@@ -819,8 +849,8 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po
|
||||
ang = (projected_binormal.mV[VX] < 0.f) ? -ang : ang;
|
||||
binormal.rotVec(ang, normal);
|
||||
LLQuaternion local_rot( binormal % normal, binormal, normal );
|
||||
*face_rot = local_rot * mXform->getWorldRotation();
|
||||
*face_pos = mXform->getWorldPosition();
|
||||
*face_rot = local_rot * vol_mat.quaternion();
|
||||
*face_pos = vol_mat.getTranslation();
|
||||
}
|
||||
|
||||
// Returns the necessary texture transform to align this face's TE to align_to's TE
|
||||
@@ -1089,7 +1119,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
if (full_rebuild)
|
||||
{
|
||||
mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
|
||||
for (U16 i = 0; i < num_indices; i++)
|
||||
for (U32 i = 0; i < (U32) num_indices; i++)
|
||||
{
|
||||
*indicesp++ = vf.mIndices[i] + index_offset;
|
||||
}
|
||||
@@ -1256,6 +1286,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
mTexExtents[1].setVec(1,1);
|
||||
xform(mTexExtents[0], cos_ang, sin_ang, os, ot, ms, mt);
|
||||
xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt);
|
||||
|
||||
F32 es = vf.mTexCoordExtents[1].mV[0] - vf.mTexCoordExtents[0].mV[0] ;
|
||||
F32 et = vf.mTexCoordExtents[1].mV[1] - vf.mTexCoordExtents[0].mV[1] ;
|
||||
mTexExtents[0][0] *= es ;
|
||||
mTexExtents[1][0] *= es ;
|
||||
mTexExtents[0][1] *= et ;
|
||||
mTexExtents[1][1] *= et ;
|
||||
}
|
||||
|
||||
mLastVertexBuffer = mVertexBuffer;
|
||||
@@ -1305,13 +1342,13 @@ F32 LLFace::getTextureVirtualSize()
|
||||
}
|
||||
|
||||
face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area);
|
||||
if (mImportanceToCamera < 1.0f && face_area > LLViewerImage::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
|
||||
if (/*mImportanceToCamera < 1.0f && */face_area > LLViewerImage::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
|
||||
{
|
||||
if (mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture.notNull() && mTexture->isLargeImage())
|
||||
{
|
||||
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setVirtualSize(face_area);
|
||||
|
||||
@@ -1413,8 +1450,9 @@ F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist)
|
||||
if(cos_angle_to_view_dir > LLViewerCamera::getInstance()->getCosHalfFov() &&
|
||||
dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0])
|
||||
{
|
||||
F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ;
|
||||
F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();
|
||||
LLViewerCamera* camera = LLViewerCamera::getInstance();
|
||||
F32 camera_moving_speed = camera->getAverageSpeed() ;
|
||||
F32 camera_angular_speed = camera->getAverageAngularSpeed();
|
||||
|
||||
if(camera_moving_speed > 10.0f || camera_angular_speed > 1.0f)
|
||||
{
|
||||
|
||||
@@ -87,8 +87,9 @@ public:
|
||||
U16 getGeomCount() const { return mGeomCount; } // vertex count for this face
|
||||
U16 getGeomIndex() const { return mGeomIndex; } // index into draw pool
|
||||
U16 getGeomStart() const { return mGeomIndex; } // index into draw pool
|
||||
LLViewerImage* getTexture() const { return mTexture; }
|
||||
void setTexture(LLViewerImage* tex) ;
|
||||
void switchTexture(LLViewerImage* new_texture);
|
||||
void dirtyTexture();
|
||||
LLXformMatrix* getXform() const { return mXform; }
|
||||
BOOL hasGeometry() const { return mGeomCount > 0; }
|
||||
LLVector3 getPositionAgent() const;
|
||||
@@ -126,8 +127,8 @@ public:
|
||||
LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; }
|
||||
void setPoolType(U32 type) { mPoolType = type; }
|
||||
S32 getTEOffset() { return mTEOffset; }
|
||||
LLViewerImage* getTexture() { return mTexture; }
|
||||
|
||||
LLViewerImage* getTexture() const { return mTexture; }
|
||||
|
||||
void setViewerObject(LLViewerObject* object);
|
||||
void setPool(LLFacePool *pool, LLViewerImage *texturep);
|
||||
|
||||
@@ -262,7 +263,7 @@ public:
|
||||
{
|
||||
bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
|
||||
{
|
||||
return lhs->mDistance > rhs->mDistance; // farthest = first
|
||||
return !lhs || (rhs && (lhs->mDistance > rhs->mDistance)); // farthest = first
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -705,7 +705,7 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
|
||||
}
|
||||
|
||||
if (volume->mLODChanged || volume->mFaceMappingChanged ||
|
||||
volume->mVolumeChanged)
|
||||
volume->mVolumeChanged || drawable->isState(LLDrawable::REBUILD_MATERIAL))
|
||||
{
|
||||
volume->regenFaces();
|
||||
volume->mDrawable->setState(LLDrawable::REBUILD_VOLUME);
|
||||
|
||||
@@ -193,7 +193,8 @@ void LLFloaterHardwareSettings::apply()
|
||||
}
|
||||
else if (old_anisotropic != LLImageGL::sGlobalUseAnisotropic)
|
||||
{
|
||||
gViewerWindow->restartDisplay(logged_in);
|
||||
LLImageGL::dirtyTexOptions();
|
||||
gViewerWindow->restartDisplay(logged_in);
|
||||
}
|
||||
|
||||
refresh();
|
||||
|
||||
@@ -1056,7 +1056,8 @@ void LLViewerObjectList::renderObjectBeacons()
|
||||
|
||||
S32 last_line_width = -1;
|
||||
// gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
|
||||
|
||||
|
||||
BOOL flush = FALSE;
|
||||
for (S32 i = 0; i < mDebugBeacons.count(); i++)
|
||||
{
|
||||
const LLDebugBeacon &debug_beacon = mDebugBeacons[i];
|
||||
@@ -1065,11 +1066,12 @@ void LLViewerObjectList::renderObjectBeacons()
|
||||
S32 line_width = debug_beacon.mLineWidth;
|
||||
if (line_width != last_line_width)
|
||||
{
|
||||
if (i > 0)
|
||||
if (flush)
|
||||
{
|
||||
gGL.end();
|
||||
gGL.flush();
|
||||
}
|
||||
flush = TRUE;
|
||||
gGL.flush();
|
||||
glLineWidth( (F32)line_width );
|
||||
last_line_width = line_width;
|
||||
gGL.begin(LLRender::LINES);
|
||||
@@ -1095,7 +1097,8 @@ void LLViewerObjectList::renderObjectBeacons()
|
||||
|
||||
S32 last_line_width = -1;
|
||||
// gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
|
||||
|
||||
|
||||
BOOL flush = FALSE;
|
||||
for (S32 i = 0; i < mDebugBeacons.count(); i++)
|
||||
{
|
||||
const LLDebugBeacon &debug_beacon = mDebugBeacons[i];
|
||||
@@ -1103,11 +1106,12 @@ void LLViewerObjectList::renderObjectBeacons()
|
||||
S32 line_width = debug_beacon.mLineWidth;
|
||||
if (line_width != last_line_width)
|
||||
{
|
||||
if (i > 0)
|
||||
if (flush)
|
||||
{
|
||||
gGL.end();
|
||||
gGL.flush();
|
||||
}
|
||||
flush = TRUE;
|
||||
gGL.flush();
|
||||
glLineWidth( (F32)line_width );
|
||||
last_line_width = line_width;
|
||||
gGL.begin(LLRender::LINES);
|
||||
|
||||
@@ -647,6 +647,8 @@ bool LLHUDEffectLookAt::calcTargetPosition()
|
||||
}
|
||||
|
||||
LLVOAvatar* source_avatar = (LLVOAvatar*)(LLViewerObject*)mSourceObject;
|
||||
if (!source_avatar->isBuilt())
|
||||
return false;
|
||||
|
||||
if (target_obj && target_obj->mDrawable.notNull())
|
||||
{
|
||||
|
||||
@@ -608,9 +608,11 @@ void LLPanelFace::getState()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// planar align
|
||||
bool align_planar = false;
|
||||
bool identical_planar_aligned = false;
|
||||
bool is_planar = false;
|
||||
{
|
||||
LLCheckBoxCtrl* cb_planar_align = getChild<LLCheckBoxCtrl>("checkbox planar align");
|
||||
align_planar = (cb_planar_align && cb_planar_align->get());
|
||||
@@ -621,13 +623,12 @@ void LLPanelFace::getState()
|
||||
return (object->getTE(face)->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR);
|
||||
}
|
||||
} func;
|
||||
|
||||
bool is_planar;
|
||||
|
||||
bool texgens_identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, is_planar );
|
||||
bool enabled = (editable && texgens_identical && is_planar);
|
||||
childSetValue("checkbox planar align", align_planar && enabled);
|
||||
childSetEnabled("checkbox planar align", enabled);
|
||||
|
||||
|
||||
if (align_planar && enabled)
|
||||
{
|
||||
struct f2 : public LLSelectedTEGetFunctor<LLFace *>
|
||||
|
||||
@@ -110,6 +110,7 @@ const S32 OWNERSHIP_COST_PER_OBJECT = 10; // Must be the same as economy_constan
|
||||
const S32 MAX_ACTION_QUEUE_SIZE = 20;
|
||||
const S32 MAX_SILS_PER_FRAME = 50;
|
||||
const S32 MAX_OBJECTS_PER_PACKET = 254;
|
||||
const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF;
|
||||
|
||||
//
|
||||
// Globals
|
||||
@@ -219,6 +220,9 @@ LLSelectMgr::LLSelectMgr()
|
||||
mSelectedObjects = new LLObjectSelection();
|
||||
mHoverObjects = new LLObjectSelection();
|
||||
mHighlightedObjects = new LLObjectSelection();
|
||||
|
||||
mForceSelection = FALSE;
|
||||
mShowSelection = FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -551,7 +555,7 @@ BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id)
|
||||
object_found = TRUE;
|
||||
break; // must break here, may have removed multiple objects from list
|
||||
}
|
||||
else if (object->isAvatar())
|
||||
else if (object->isAvatar() && object->getParent() && ((LLViewerObject*)object->getParent())->mID == id)
|
||||
{
|
||||
// It's possible the item being removed has an avatar sitting on it
|
||||
// So remove the avatar that is sitting on the object.
|
||||
@@ -787,41 +791,53 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab
|
||||
|
||||
LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp, S32 face)
|
||||
{
|
||||
// Always blitz hover list when setting
|
||||
mHoverObjects->deleteAllNodes();
|
||||
|
||||
if (!objectp)
|
||||
{
|
||||
mHoverObjects->deleteAllNodes();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Can't select yourself
|
||||
if (objectp->mID == gAgentID)
|
||||
{
|
||||
mHoverObjects->deleteAllNodes();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Can't select land
|
||||
if (objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
|
||||
{
|
||||
mHoverObjects->deleteAllNodes();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Collect all of the objects
|
||||
LLDynamicArray<LLViewerObject*> objects;
|
||||
objectp = objectp->getRootEdit();
|
||||
objectp->addThisAndNonJointChildren(objects);
|
||||
mHoverObjects->mPrimaryObject = objectp;
|
||||
|
||||
for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
|
||||
iter != objects.end(); ++iter)
|
||||
objectp = objectp->getRootEdit();
|
||||
|
||||
// is the requested object the same as the existing hover object root?
|
||||
// NOTE: there is only ever one linked set in mHoverObjects
|
||||
if (mHoverObjects->getFirstRootObject() != objectp)
|
||||
{
|
||||
LLViewerObject* cur_objectp = *iter;
|
||||
LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE);
|
||||
nodep->selectTE(face, TRUE);
|
||||
mHoverObjects->addNodeAtEnd(nodep);
|
||||
|
||||
// Collect all of the objects
|
||||
LLDynamicArray<LLViewerObject*> objects;
|
||||
objectp = objectp->getRootEdit();
|
||||
objectp->addThisAndNonJointChildren(objects);
|
||||
|
||||
mHoverObjects->deleteAllNodes();
|
||||
for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
|
||||
iter != objects.end(); ++iter)
|
||||
{
|
||||
LLViewerObject* cur_objectp = *iter;
|
||||
LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE);
|
||||
nodep->selectTE(face, TRUE);
|
||||
mHoverObjects->addNodeAtEnd(nodep);
|
||||
}
|
||||
|
||||
requestObjectPropertiesFamily(objectp);
|
||||
}
|
||||
|
||||
requestObjectPropertiesFamily(objectp);
|
||||
return mHoverObjects;
|
||||
}
|
||||
|
||||
@@ -5059,6 +5075,7 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
|
||||
mName = nodep.mName;
|
||||
mDescription = nodep.mDescription;
|
||||
mCategory = nodep.mCategory;
|
||||
mInventorySerial = 0;
|
||||
mSavedPositionLocal = nodep.mSavedPositionLocal;
|
||||
mSavedPositionGlobal = nodep.mSavedPositionGlobal;
|
||||
mSavedScale = nodep.mSavedScale;
|
||||
@@ -5097,7 +5114,7 @@ LLSelectNode::~LLSelectNode()
|
||||
|
||||
void LLSelectNode::selectAllTEs(BOOL b)
|
||||
{
|
||||
mTESelectMask = b ? 0xFFFFFFFF : 0x0;
|
||||
mTESelectMask = b ? TE_SELECT_MASK_ALL : 0x0;
|
||||
mLastTESelected = 0;
|
||||
}
|
||||
|
||||
@@ -5732,8 +5749,22 @@ void LLSelectMgr::redo()
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL LLSelectMgr::canDoDelete() const
|
||||
{
|
||||
bool can_delete = false;
|
||||
// This function is "logically const" - it does not change state in
|
||||
// a way visible outside the selection manager.
|
||||
LLSelectMgr* self = const_cast<LLSelectMgr*>(this);
|
||||
LLViewerObject* obj = self->mSelectedObjects->getFirstDeleteableObject();
|
||||
// Note: Can only delete root objects (see getFirstDeleteableObject() for more info)
|
||||
return const_cast<LLSelectMgr*>(this)->mSelectedObjects->getFirstDeleteableObject() != NULL; // HACK: casting away constness - MG
|
||||
if (obj!= NULL)
|
||||
{
|
||||
// all the faces needs to be selected
|
||||
if(self->mSelectedObjects->contains(obj,SELECT_ALL_TES ))
|
||||
{
|
||||
can_delete = true;
|
||||
}
|
||||
}
|
||||
|
||||
return can_delete;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -6136,8 +6167,14 @@ BOOL LLObjectSelection::contains(LLViewerObject* object, S32 te)
|
||||
LLSelectNode* nodep = *iter;
|
||||
if (nodep->getObject() == object)
|
||||
{
|
||||
// Optimization
|
||||
if (nodep->getTESelectMask() == TE_SELECT_MASK_ALL)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL all_selected = TRUE;
|
||||
for (S32 i = 0; i < SELECT_MAX_TES; i++)
|
||||
for (S32 i = 0; i < object->getNumTEs(); i++)
|
||||
{
|
||||
all_selected = all_selected && nodep->isTESelected(i);
|
||||
}
|
||||
|
||||
@@ -67,6 +67,9 @@ F32 elevation_from_vector(const LLVector3 &v);
|
||||
LLSky gSky;
|
||||
// ---------------- LLSky ----------------
|
||||
|
||||
const F32 LLSky::NIGHTTIME_ELEVATION = -8.0f; // degrees
|
||||
const F32 LLSky::NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -42,9 +42,6 @@
|
||||
#include "llvosky.h"
|
||||
#include "llvoground.h"
|
||||
|
||||
const F32 NIGHTTIME_ELEVATION = -8.0f; // degrees
|
||||
const F32 NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD);
|
||||
|
||||
class LLViewerCamera;
|
||||
|
||||
class LLVOWLSky;
|
||||
@@ -111,6 +108,9 @@ public:
|
||||
// Legacy stuff
|
||||
LLVector3 mSunDefaultPosition;
|
||||
|
||||
static const F32 NIGHTTIME_ELEVATION; // degrees
|
||||
static const F32 NIGHTTIME_ELEVATION_COS;
|
||||
|
||||
protected:
|
||||
BOOL mOverrideSimSunPosition;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -43,6 +43,7 @@
|
||||
#include "llcubemap.h"
|
||||
#include "lldrawpool.h"
|
||||
#include "llface.h"
|
||||
#include "llviewercamera.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
@@ -153,12 +154,12 @@ public:
|
||||
class LLSpatialGroup : public LLOctreeListener<LLDrawable>
|
||||
{
|
||||
friend class LLSpatialPartition;
|
||||
friend class LLOctreeStateCheck;
|
||||
public:
|
||||
static U32 sNodeCount;
|
||||
static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE
|
||||
|
||||
typedef std::vector<LLPointer<LLSpatialGroup> > sg_vector_t;
|
||||
typedef std::set<LLPointer<LLSpatialGroup> > sg_set_t;
|
||||
typedef std::vector<LLPointer<LLSpatialBridge> > bridge_list_t;
|
||||
typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t;
|
||||
typedef std::map<U32, drawmap_elem_t > draw_map_t;
|
||||
@@ -183,6 +184,14 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct CompareUpdateUrgency
|
||||
{
|
||||
bool operator()(const LLPointer<LLSpatialGroup> lhs, const LLPointer<LLSpatialGroup> rhs)
|
||||
{
|
||||
return lhs->getUpdateUrgency() > rhs->getUpdateUrgency();
|
||||
}
|
||||
};
|
||||
|
||||
struct CompareDepthGreater
|
||||
{
|
||||
bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs)
|
||||
@@ -193,53 +202,67 @@ public:
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OCCLUDED = 0x00000001,
|
||||
IN_QUEUE = 0x00000002,
|
||||
QUERY_PENDING = 0x00000004,
|
||||
ACTIVE_OCCLUSION = 0x00000008,
|
||||
DISCARD_QUERY = 0x00000010,
|
||||
DEAD = 0x00000020,
|
||||
EARLY_FAIL = 0x00000040,
|
||||
DIRTY = 0x00000080,
|
||||
OBJECT_DIRTY = 0x00000100,
|
||||
GEOM_DIRTY = 0x00000200,
|
||||
ALPHA_DIRTY = 0x00000800,
|
||||
SKIP_FRUSTUM_CHECK = 0x00001000,
|
||||
IN_IMAGE_QUEUE = 0x00002000,
|
||||
IMAGE_DIRTY = 0x00004000,
|
||||
OCCLUSION_DIRTY = 0x00008000,
|
||||
MESH_DIRTY = 0x00010000,
|
||||
OCCLUDED = 0x00010000,
|
||||
QUERY_PENDING = 0x00020000,
|
||||
ACTIVE_OCCLUSION = 0x00040000,
|
||||
DISCARD_QUERY = 0x00080000,
|
||||
EARLY_FAIL = 0x00100000,
|
||||
} eOcclusionState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DEAD = 0x00000001,
|
||||
DIRTY = 0x00000002,
|
||||
OBJECT_DIRTY = 0x00000004,
|
||||
GEOM_DIRTY = 0x00000008,
|
||||
ALPHA_DIRTY = 0x00000010,
|
||||
SKIP_FRUSTUM_CHECK = 0x00000020,
|
||||
IN_IMAGE_QUEUE = 0x00000040,
|
||||
IMAGE_DIRTY = 0x00000080,
|
||||
OCCLUSION_DIRTY = 0x00000100,
|
||||
MESH_DIRTY = 0x00000200,
|
||||
NEW_DRAWINFO = 0x00000400,
|
||||
IN_BUILD_Q1 = 0x00000800,
|
||||
IN_BUILD_Q2 = 0x00001000,
|
||||
STATE_MASK = 0x0000FFFF,
|
||||
} eSpatialState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STATE_MODE_SINGLE = 0, //set one node
|
||||
STATE_MODE_BRANCH, //set entire branch
|
||||
STATE_MODE_DIFF //set entire branch as long as current state is different
|
||||
STATE_MODE_DIFF, //set entire branch as long as current state is different
|
||||
STATE_MODE_ALL_CAMERAS, //used for occlusion state, set state for all cameras
|
||||
} eSetStateMode;
|
||||
|
||||
LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part);
|
||||
|
||||
BOOL isDead() { return isState(DEAD); }
|
||||
BOOL isState(U32 state) const { return mState & state ? TRUE : FALSE; }
|
||||
BOOL isState(eSpatialState state) const; //Using enum type here and below to force type-safeness.
|
||||
BOOL isOcclusionState(eOcclusionState state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; }
|
||||
U32 getState() { return mState; }
|
||||
void setState(U32 state);
|
||||
void clearState(U32 state);
|
||||
void setState(eSpatialState state);
|
||||
void clearState(eSpatialState state);
|
||||
|
||||
void clearDrawMap();
|
||||
void validate();
|
||||
void checkStates();
|
||||
void validateDrawMap();
|
||||
|
||||
void setState(U32 state, S32 mode);
|
||||
void setState(eSpatialState state, S32 mode);
|
||||
void clearState(eSpatialState state, S32 mode);
|
||||
|
||||
void setOcclusionState(eOcclusionState state, S32 mode = STATE_MODE_SINGLE);
|
||||
void clearOcclusionState(eOcclusionState state, S32 mode = STATE_MODE_SINGLE);
|
||||
|
||||
LLSpatialGroup* getParent();
|
||||
|
||||
void clearState(U32 state, S32 mode);
|
||||
|
||||
BOOL addObject(LLDrawable *drawablep, BOOL add_all = FALSE, BOOL from_octree = FALSE);
|
||||
BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
|
||||
BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
|
||||
BOOL isVisible() const;
|
||||
BOOL isRecentlyVisible() const;
|
||||
void setVisible();
|
||||
void shift(const LLVector3 &offset);
|
||||
BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax);
|
||||
@@ -252,6 +275,7 @@ public:
|
||||
|
||||
void updateDistance(LLCamera& camera);
|
||||
BOOL needsUpdate();
|
||||
F32 getUpdateUrgency() const;
|
||||
BOOL changeLOD();
|
||||
void rebuildGeom();
|
||||
void rebuildMesh();
|
||||
@@ -261,6 +285,8 @@ public:
|
||||
element_list& getData() { return mOctreeNode->getData(); }
|
||||
U32 getElementCount() const { return mOctreeNode->getElementCount(); }
|
||||
|
||||
void drawObjectBox(LLColor4 col);
|
||||
|
||||
//LISTENER FUNCTIONS
|
||||
virtual void handleInsertion(const TreeNode* node, LLDrawable* face);
|
||||
virtual void handleRemoval(const TreeNode* node, LLDrawable* face);
|
||||
@@ -273,6 +299,7 @@ protected:
|
||||
virtual ~LLSpatialGroup();
|
||||
|
||||
U32 mState;
|
||||
U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS];
|
||||
S32 mLODHash;
|
||||
static S32 sLODSeed;
|
||||
|
||||
@@ -291,12 +318,12 @@ public:
|
||||
|
||||
LLPointer<LLVertexBuffer> mVertexBuffer;
|
||||
F32* mOcclusionVerts;
|
||||
GLuint mOcclusionQuery;
|
||||
GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
|
||||
|
||||
U32 mBufferUsage;
|
||||
draw_map_t mDrawMap;
|
||||
|
||||
S32 mVisible;
|
||||
S32 mVisible[LLViewerCamera::NUM_CAMERAS];
|
||||
F32 mDistance;
|
||||
F32 mDepth;
|
||||
F32 mLastUpdateDistance;
|
||||
@@ -309,6 +336,15 @@ public:
|
||||
F32 mRadius;
|
||||
};
|
||||
|
||||
inline LLSpatialGroup::eOcclusionState operator|(const LLSpatialGroup::eOcclusionState &a, const LLSpatialGroup::eOcclusionState &b)
|
||||
{
|
||||
return LLSpatialGroup::eOcclusionState(+a | +b);
|
||||
}
|
||||
inline LLSpatialGroup::eSpatialState operator|(const LLSpatialGroup::eSpatialState &a, const LLSpatialGroup::eSpatialState &b)
|
||||
{
|
||||
return LLSpatialGroup::eSpatialState(+a | +b);
|
||||
}
|
||||
|
||||
class LLGeometryManager
|
||||
{
|
||||
public:
|
||||
@@ -325,9 +361,8 @@ public:
|
||||
class LLSpatialPartition: public LLGeometryManager
|
||||
{
|
||||
public:
|
||||
static BOOL sFreezeState; //if true, no spatialgroup state updates will be made
|
||||
|
||||
LLSpatialPartition(U32 data_mask, U32 mBufferUsage = GL_STATIC_DRAW_ARB);
|
||||
//static BOOL sFreezeState; //if true, no spatialgroup state updates will be made
|
||||
LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage);
|
||||
virtual ~LLSpatialPartition();
|
||||
|
||||
LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);
|
||||
@@ -392,7 +427,7 @@ protected:
|
||||
public:
|
||||
typedef std::vector<LLPointer<LLSpatialBridge> > bridge_vector_t;
|
||||
|
||||
LLSpatialBridge(LLDrawable* root, U32 data_mask);
|
||||
LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask);
|
||||
|
||||
virtual BOOL isSpatialBridge() const { return TRUE; }
|
||||
|
||||
@@ -473,14 +508,22 @@ private:
|
||||
U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES];
|
||||
|
||||
sg_list_t mVisibleGroups;
|
||||
sg_list_t::iterator mVisibleGroupsEnd;
|
||||
sg_list_t mAlphaGroups;
|
||||
sg_list_t::iterator mAlphaGroupsEnd;
|
||||
sg_list_t mOcclusionGroups;
|
||||
sg_list_t::iterator mOcclusionGroupsEnd;
|
||||
sg_list_t mDrawableGroups;
|
||||
sg_list_t::iterator mDrawableGroupsEnd;
|
||||
drawable_list_t mVisibleList;
|
||||
drawable_list_t::iterator mVisibleListEnd;
|
||||
bridge_list_t mVisibleBridge;
|
||||
bridge_list_t::iterator mVisibleBridgeEnd;
|
||||
drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES];
|
||||
drawinfo_list_t::iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES];
|
||||
};
|
||||
|
||||
|
||||
//spatial partition for water (implemented in LLVOWater.cpp)
|
||||
class LLWaterPartition : public LLSpatialPartition
|
||||
{
|
||||
|
||||
@@ -160,6 +160,7 @@ void LLSurface::initClasses()
|
||||
void LLSurface::setRegion(LLViewerRegion *regionp)
|
||||
{
|
||||
mRegionp = regionp;
|
||||
mWaterObjp = NULL; // depends on regionp, needs recreating
|
||||
}
|
||||
|
||||
// Assumes that arguments are powers of 2, and that
|
||||
@@ -1282,6 +1283,10 @@ BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y,
|
||||
}
|
||||
}
|
||||
|
||||
if (!mWaterTexturep->getHasGLTexture())
|
||||
{
|
||||
mWaterTexturep->createGLTexture(0, raw);
|
||||
}
|
||||
mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ LLSurfacePatch::LLSurfacePatch() :
|
||||
mHeightsGenerated(FALSE),
|
||||
mDataOffset(0),
|
||||
mDataZ(NULL),
|
||||
mDataNorm(NULL),
|
||||
mVObjp(NULL),
|
||||
mOriginRegion(0.f, 0.f, 0.f),
|
||||
mCenterRegion(0.f, 0.f, 0.f),
|
||||
@@ -712,17 +713,7 @@ BOOL LLSurfacePatch::updateTexture()
|
||||
if (mVObjp)
|
||||
{
|
||||
mVObjp->dirtyGeom();
|
||||
}
|
||||
updateCompositionStats();
|
||||
F32 tex_patch_size = meters_per_grid*grids_per_patch_edge;
|
||||
if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY],
|
||||
tex_patch_size, tex_patch_size))
|
||||
{
|
||||
mSTexUpdate = FALSE;
|
||||
|
||||
// Also generate the water texture
|
||||
mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY],
|
||||
tex_patch_size, tex_patch_size);
|
||||
gPipeline.markGLRebuild(mVObjp);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -735,6 +726,28 @@ BOOL LLSurfacePatch::updateTexture()
|
||||
}
|
||||
}
|
||||
|
||||
void LLSurfacePatch::updateGL()
|
||||
{
|
||||
F32 meters_per_grid = getSurface()->getMetersPerGrid();
|
||||
F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge();
|
||||
|
||||
LLViewerRegion *regionp = getSurface()->getRegion();
|
||||
LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal();
|
||||
|
||||
LLVLComposition* comp = regionp->getComposition();
|
||||
|
||||
updateCompositionStats();
|
||||
F32 tex_patch_size = meters_per_grid*grids_per_patch_edge;
|
||||
if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY],
|
||||
tex_patch_size, tex_patch_size))
|
||||
{
|
||||
mSTexUpdate = FALSE;
|
||||
|
||||
// Also generate the water texture
|
||||
mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY],
|
||||
tex_patch_size, tex_patch_size);
|
||||
}
|
||||
}
|
||||
|
||||
void LLSurfacePatch::dirtyZ()
|
||||
{
|
||||
|
||||
@@ -90,6 +90,7 @@ public:
|
||||
|
||||
void updateCameraDistanceRegion( const LLVector3 &pos_region);
|
||||
void updateVisibility();
|
||||
void updateGL();
|
||||
|
||||
void dirtyZ(); // Dirty the z values of this patch
|
||||
void setHasReceivedData();
|
||||
|
||||
@@ -1420,22 +1420,21 @@ void LLTextureCache::readHeaderCache()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (num_entries > sCacheMaxEntries)
|
||||
if (num_entries - empty_entries > sCacheMaxEntries)
|
||||
{
|
||||
// Special case: cache size was reduced, need to remove entries
|
||||
// Note: After we prune entries, we will call this again and create the LRU
|
||||
U32 entries_to_purge = (num_entries-empty_entries) - sCacheMaxEntries;
|
||||
llinfos << "Texture Cache Entries: " << num_entries << " Max: " << sCacheMaxEntries << " Empty: " << empty_entries << " Purging: " << entries_to_purge << llendl;
|
||||
if (entries_to_purge > 0)
|
||||
// We can exit the following loop with the given condition, since if we'd reach the end of the lru set we'd have:
|
||||
// purge_list.size() = lru.size() = num_entries - empty_entries = entries_to_purge + sCacheMaxEntries >= entries_to_purge
|
||||
// So, it's certain that iter will never reach lru.end() first.
|
||||
std::set<lru_data_t>::iterator iter = lru.begin();
|
||||
while (purge_list.size() < entries_to_purge)
|
||||
{
|
||||
for (std::set<lru_data_t>::iterator iter = lru.begin(); iter != lru.end(); ++iter)
|
||||
{
|
||||
purge_list.insert(iter->second);
|
||||
if (purge_list.size() >= entries_to_purge)
|
||||
break;
|
||||
}
|
||||
purge_list.insert(iter->second);
|
||||
++iter;
|
||||
}
|
||||
llassert_always(purge_list.size() >= entries_to_purge);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -302,7 +302,10 @@ public:
|
||||
const LLChannelDescriptors& channels,
|
||||
const LLIOPipe::buffer_ptr_t& buffer)
|
||||
{
|
||||
if ((gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog")) || (gSavedSettings.getBOOL("LogTextureDownloadsToSimulator")))
|
||||
static LLCachedControl<bool> log_to_viewer_log("LogTextureDownloadsToViewerLog",false);
|
||||
static LLCachedControl<bool> log_to_sim("LogTextureDownloadsToSimulator",false);
|
||||
|
||||
if (log_to_viewer_log || log_to_sim)
|
||||
{
|
||||
mFetcher->mTextureInfo.setRequestStartTime(mID, mStartTime);
|
||||
U64 timeNow = LLTimer::getTotalTime();
|
||||
@@ -2127,7 +2130,9 @@ void LLTextureFetch::sendRequestListToSimulators()
|
||||
// llinfos << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard
|
||||
// << " Packet: " << packet << " Priority: " << req->mImagePriority << llendl;
|
||||
|
||||
if ((gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog")) || (gSavedSettings.getBOOL("LogTextureDownloadsToSimulator")))
|
||||
static LLCachedControl<bool> log_to_viewer_log("LogTextureDownloadsToViewerLog",false);
|
||||
static LLCachedControl<bool> log_to_sim("LogTextureDownloadsToSimulator",false);
|
||||
if (log_to_viewer_log || log_to_sim)
|
||||
{
|
||||
mTextureInfo.setRequestStartTime(req->mID, LLTimer::getTotalTime());
|
||||
mTextureInfo.setRequestOffset(req->mID, 0);
|
||||
@@ -2347,7 +2352,10 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1
|
||||
|
||||
if(packet_num >= (worker->mTotalPackets - 1))
|
||||
{
|
||||
if ((gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog")) || (gSavedSettings.getBOOL("LogTextureDownloadsToSimulator")))
|
||||
static LLCachedControl<bool> log_to_viewer_log("LogTextureDownloadsToViewerLog",false);
|
||||
static LLCachedControl<bool> log_to_sim("LogTextureDownloadsToSimulator",false);
|
||||
|
||||
if (log_to_viewer_log || log_to_sim)
|
||||
{
|
||||
U64 timeNow = LLTimer::getTotalTime();
|
||||
mTextureInfo.setRequestSize(id, worker->mFileSize);
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
#include "lltoolmgr.h"
|
||||
#include "llviewerjoystick.h"
|
||||
|
||||
U32 LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
|
||||
|
||||
//glu pick matrix implementation borrowed from Mesa3D
|
||||
glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLint* viewport)
|
||||
{
|
||||
|
||||
@@ -54,6 +54,24 @@ const BOOL NOT_FOR_SELECTION = FALSE;
|
||||
class LLViewerCamera : public LLCamera, public LLSingleton<LLViewerCamera>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CAMERA_WORLD = 0,
|
||||
CAMERA_SHADOW0,
|
||||
CAMERA_SHADOW1,
|
||||
CAMERA_SHADOW2,
|
||||
CAMERA_SHADOW3,
|
||||
CAMERA_SHADOW4,
|
||||
CAMERA_SHADOW5,
|
||||
CAMERA_WATER0,
|
||||
CAMERA_WATER1,
|
||||
CAMERA_GI_SOURCE,
|
||||
NUM_CAMERAS
|
||||
} eCameraID;
|
||||
|
||||
static U32 sCurCameraID;
|
||||
|
||||
LLViewerCamera();
|
||||
|
||||
void updateCameraLocation(const LLVector3 ¢er,
|
||||
|
||||
@@ -356,6 +356,15 @@ static bool handleRenderUseVBOChanged(const LLSD& newvalue)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool handleRenderUseVBOMappingChanged(const LLSD& newvalue)
|
||||
{
|
||||
if (gPipeline.isInit())
|
||||
{
|
||||
gPipeline.setDisableVBOMapping(newvalue.asBoolean());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool handleWLSkyDetailChanged(const LLSD&)
|
||||
{
|
||||
if (gSky.mVOWLSkyp.notNull())
|
||||
@@ -602,6 +611,7 @@ void settings_setup_listeners()
|
||||
gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
|
||||
gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
|
||||
gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _1));
|
||||
gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleRenderUseVBOMappingChanged, _1));
|
||||
gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _1));
|
||||
gSavedSettings.getControl("RenderLightingDetail")->getSignal()->connect(boost::bind(&handleRenderLightingDetailChanged, _1));
|
||||
gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _1));
|
||||
|
||||
@@ -131,6 +131,7 @@ void display_startup()
|
||||
return;
|
||||
}
|
||||
|
||||
gPipeline.updateGL();
|
||||
LLGLSDefault gls_default;
|
||||
|
||||
// Required for HTML update in login screen
|
||||
@@ -241,6 +242,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_RENDER);
|
||||
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{ //hack to make sky show up in deferred snapshots
|
||||
for_snapshot = FALSE;
|
||||
}
|
||||
|
||||
if (LLPipeline::sRenderFrameTest)
|
||||
{
|
||||
send_agent_pause();
|
||||
@@ -614,6 +620,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time
|
||||
gPipeline.createObjects(max_geom_update_time);
|
||||
gPipeline.updateGeom(max_geom_update_time);
|
||||
gPipeline.updateGL();
|
||||
stop_glerror();
|
||||
|
||||
gFrameStats.start(LLFrameStats::UPDATE_CULL);
|
||||
@@ -666,6 +673,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
LLGLState::checkClientArrays();
|
||||
|
||||
static LLCullResult result;
|
||||
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
|
||||
gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip);
|
||||
stop_glerror();
|
||||
|
||||
@@ -706,6 +714,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
|
||||
}
|
||||
|
||||
LLVertexBuffer::unbind();
|
||||
|
||||
LLGLState::checkStates();
|
||||
LLGLState::checkTextureChannels();
|
||||
LLGLState::checkClientArrays();
|
||||
@@ -781,7 +791,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
//
|
||||
LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort");
|
||||
{
|
||||
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
|
||||
gFrameStats.start(LLFrameStats::STATE_SORT);
|
||||
gPipeline.sAllowRebuildPriorityGroup = TRUE ;
|
||||
gPipeline.stateSort(*LLViewerCamera::getInstance(), result);
|
||||
stop_glerror();
|
||||
|
||||
@@ -866,6 +878,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
gPipeline.mDeferredScreen.bindTarget();
|
||||
glClearColor(0,0,0,0);
|
||||
gPipeline.mDeferredScreen.clear();
|
||||
}
|
||||
else
|
||||
@@ -882,7 +895,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
|
||||
&& !gRestoreGL)
|
||||
{
|
||||
|
||||
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
|
||||
gGL.setColorMask(true, false);
|
||||
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
@@ -932,6 +945,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
render_ui();
|
||||
}
|
||||
|
||||
gPipeline.rebuildGroups();
|
||||
|
||||
LLSpatialGroup::sNoDelete = FALSE;
|
||||
}
|
||||
|
||||
@@ -980,9 +995,10 @@ void render_hud_attachments()
|
||||
bool render_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) && gSavedSettings.getBOOL("RenderHUDParticles");
|
||||
|
||||
//only render hud objects
|
||||
U32 mask = gPipeline.getRenderTypeMask();
|
||||
gPipeline.pushRenderTypeMask();
|
||||
|
||||
// turn off everything
|
||||
gPipeline.setRenderTypeMask(0);
|
||||
gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES);
|
||||
// turn on HUD
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
|
||||
// turn on HUD particles
|
||||
@@ -1009,6 +1025,7 @@ void render_hud_attachments()
|
||||
static LLCullResult result;
|
||||
LLSpatialGroup::sNoDelete = TRUE;
|
||||
|
||||
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
|
||||
gPipeline.updateCull(hud_cam, result);
|
||||
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP);
|
||||
@@ -1016,6 +1033,15 @@ void render_hud_attachments()
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_SHINY);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISIBLE);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY);
|
||||
|
||||
gPipeline.stateSort(hud_cam, result);
|
||||
|
||||
@@ -1024,8 +1050,10 @@ void render_hud_attachments()
|
||||
LLSpatialGroup::sNoDelete = FALSE;
|
||||
|
||||
render_hud_elements();
|
||||
|
||||
//restore type mask
|
||||
gPipeline.setRenderTypeMask(mask);
|
||||
gPipeline.popRenderTypeMask();
|
||||
|
||||
if (has_ui)
|
||||
{
|
||||
gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
|
||||
@@ -1056,7 +1084,6 @@ BOOL setup_hud_matrices()
|
||||
S32 tile_height = llround((F32)gViewerWindow->getWindowHeight() / zoom_factor);
|
||||
int tile_y = sub_region / num_horizontal_tiles;
|
||||
int tile_x = sub_region - (tile_y * num_horizontal_tiles);
|
||||
glh::matrix4f mat;
|
||||
|
||||
whole_screen.setLeftTopAndSize(tile_x * tile_width, gViewerWindow->getWindowHeight() - (tile_y * tile_height), tile_width, tile_height);
|
||||
}
|
||||
@@ -1158,6 +1185,10 @@ void render_ui(F32 zoom_factor, int subfield)
|
||||
render_ui_3d();
|
||||
LLGLState::checkStates();
|
||||
}
|
||||
else
|
||||
{
|
||||
render_disconnected_background();
|
||||
}
|
||||
|
||||
render_ui_2d();
|
||||
LLGLState::checkStates();
|
||||
@@ -1343,6 +1374,12 @@ void render_disconnected_background()
|
||||
gGL.color4f(1,1,1,1);
|
||||
if (!gDisconnectedImagep && gDisconnected)
|
||||
{
|
||||
//Default black image.
|
||||
gDisconnectedImagep = new LLImageGL( FALSE );
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,3);
|
||||
raw->clear();
|
||||
gDisconnectedImagep->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER);
|
||||
|
||||
llinfos << "Loading last bitmap..." << llendl;
|
||||
|
||||
std::string temp_str;
|
||||
@@ -1355,8 +1392,6 @@ void render_disconnected_background()
|
||||
return;
|
||||
}
|
||||
|
||||
gDisconnectedImagep = new LLImageGL( FALSE );
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw;
|
||||
if (!image_bmp->decode(raw, 0.0f))
|
||||
{
|
||||
llinfos << "Bitmap decode failed" << llendl;
|
||||
|
||||
@@ -59,13 +59,9 @@ BOOL LLViewerJoint::sDisableLOD = FALSE;
|
||||
// Class Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
LLViewerJoint::LLViewerJoint()
|
||||
: LLJoint()
|
||||
{
|
||||
mUpdateXform = TRUE;
|
||||
mValid = FALSE;
|
||||
mComponents = SC_JOINT | SC_BONE | SC_AXES;
|
||||
mMinPixelArea = DEFAULT_LOD;
|
||||
mPickName = PN_DEFAULT;
|
||||
mVisible = TRUE;
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
@@ -73,13 +69,21 @@ LLViewerJoint::LLViewerJoint()
|
||||
// LLViewerJoint()
|
||||
// Class Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) :
|
||||
LLJoint(name, parent)
|
||||
LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent)
|
||||
: LLJoint(name, parent)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
void LLViewerJoint::init()
|
||||
{
|
||||
mValid = FALSE;
|
||||
mComponents = SC_JOINT | SC_BONE | SC_AXES;
|
||||
mMinPixelArea = DEFAULT_LOD;
|
||||
mPickName = PN_DEFAULT;
|
||||
mVisible = TRUE;
|
||||
mMeshID = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -436,13 +440,13 @@ void LLViewerJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pix
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind)
|
||||
void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
|
||||
{
|
||||
for (child_list_t::iterator iter = mChildren.begin();
|
||||
iter != mChildren.end(); ++iter)
|
||||
{
|
||||
LLViewerJoint* joint = (LLViewerJoint*)(*iter);
|
||||
joint->updateFaceData(face, pixel_area, damp_wind);
|
||||
joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ public:
|
||||
PickName getPickName() { return mPickName; }
|
||||
|
||||
virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
|
||||
virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE);
|
||||
virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
|
||||
virtual BOOL updateLOD(F32 pixel_area, BOOL activate);
|
||||
virtual void updateJointGeometry();
|
||||
virtual void dump();
|
||||
@@ -143,6 +143,8 @@ public:
|
||||
void setMeshID( S32 id ) {mMeshID = id;}
|
||||
|
||||
protected:
|
||||
void init();
|
||||
|
||||
BOOL mValid;
|
||||
U32 mComponents;
|
||||
F32 mMinPixelArea;
|
||||
|
||||
@@ -116,7 +116,7 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
|
||||
object->mDrawable->makeActive();
|
||||
LLVector3 current_pos = object->getRenderPosition();
|
||||
LLQuaternion current_rot = object->getRenderRotation();
|
||||
LLQuaternion attachment_pt_inv_rot = ~getWorldRotation();
|
||||
LLQuaternion attachment_pt_inv_rot = ~(getWorldRotation());
|
||||
|
||||
current_pos -= getWorldPosition();
|
||||
current_pos.rotVec(attachment_pt_inv_rot);
|
||||
@@ -173,10 +173,22 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
|
||||
// Pass through anyway to let setupDrawable()
|
||||
// re-connect object to the joint correctly
|
||||
}
|
||||
|
||||
// Two instances of the same inventory item attached --
|
||||
// Request detach, and kill the object in the meantime.
|
||||
if (getAttachedObject(object->getAttachmentItemID()))
|
||||
{
|
||||
llinfos << "(same object re-attached)" << llendl;
|
||||
object->markDead();
|
||||
|
||||
// If this happens to be attached to self, then detach.
|
||||
LLVOAvatar::detachAttachmentIntoInventory(object->getAttachmentItemID());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mAttachedObjects.push_back(object);
|
||||
setupDrawable(object);
|
||||
|
||||
|
||||
if (mIsHUDAttachment)
|
||||
{
|
||||
if (object->mText.notNull())
|
||||
|
||||
@@ -148,6 +148,7 @@ LLViewerJointMesh::LLViewerJointMesh()
|
||||
mTexture( NULL ),
|
||||
mLayerSet( NULL ),
|
||||
mTestImageName( 0 ),
|
||||
mFaceIndexCount(0),
|
||||
mIsTransparent(FALSE)
|
||||
{
|
||||
|
||||
@@ -573,7 +574,10 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
||||
else
|
||||
if ( !is_dummy && mTexture.notNull() )
|
||||
{
|
||||
old_mode = mTexture->getAddressMode();
|
||||
if(mTexture->getHasGLTexture())
|
||||
{
|
||||
old_mode = mTexture->getAddressMode();
|
||||
}
|
||||
gGL.getTexUnit(0)->bind(mTexture.get());
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
}
|
||||
@@ -663,7 +667,8 @@ void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32
|
||||
//-----------------------------------------------------------------------------
|
||||
// updateFaceData()
|
||||
//-----------------------------------------------------------------------------
|
||||
void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind)
|
||||
|
||||
void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
|
||||
{
|
||||
mFace = face;
|
||||
|
||||
@@ -690,29 +695,98 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
|
||||
face->mVertexBuffer->getIndexStrider(indicesp);
|
||||
stop_glerror();
|
||||
|
||||
for (U16 i = 0; i < mMesh->getNumVertices(); i++)
|
||||
verticesp += mMesh->mFaceVertexOffset;
|
||||
tex_coordsp += mMesh->mFaceVertexOffset;
|
||||
normalsp += mMesh->mFaceVertexOffset;
|
||||
vertex_weightsp += mMesh->mFaceVertexOffset;
|
||||
clothing_weightsp += mMesh->mFaceVertexOffset;
|
||||
|
||||
const U32* __restrict coords = (U32*) mMesh->getCoords();
|
||||
const U32* __restrict tex_coords = (U32*) mMesh->getTexCoords();
|
||||
const U32* __restrict normals = (U32*) mMesh->getNormals();
|
||||
const U32* __restrict weights = (U32*) mMesh->getWeights();
|
||||
const U32* __restrict cloth_weights = (U32*) mMesh->getClothingWeights();
|
||||
|
||||
const U32 num_verts = mMesh->getNumVertices();
|
||||
|
||||
U32 i = 0;
|
||||
|
||||
const U32 skip = verticesp.getSkip()/sizeof(U32);
|
||||
|
||||
U32* __restrict v = (U32*) verticesp.get();
|
||||
U32* __restrict n = (U32*) normalsp.get();
|
||||
|
||||
if (terse_update)
|
||||
{
|
||||
verticesp[mMesh->mFaceVertexOffset + i] = *(mMesh->getCoords() + i);
|
||||
tex_coordsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getTexCoords() + i);
|
||||
normalsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getNormals() + i);
|
||||
vertex_weightsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getWeights() + i);
|
||||
if (damp_wind)
|
||||
for (S32 i = num_verts; i > 0; --i)
|
||||
{
|
||||
clothing_weightsp[mMesh->mFaceVertexOffset + i] = LLVector4(0,0,0,0);
|
||||
//morph target application only, only update positions and normals
|
||||
v[0] = coords[0];
|
||||
v[1] = coords[1];
|
||||
v[2] = coords[2];
|
||||
coords += 3;
|
||||
v += skip;
|
||||
}
|
||||
else
|
||||
|
||||
for (S32 i = num_verts; i > 0; --i)
|
||||
{
|
||||
clothing_weightsp[mMesh->mFaceVertexOffset + i] = (*(mMesh->getClothingWeights() + i));
|
||||
n[0] = normals[0];
|
||||
n[1] = normals[1];
|
||||
n[2] = normals[2];
|
||||
normals += 3;
|
||||
n += skip;
|
||||
}
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < mMesh->getNumFaces(); i++)
|
||||
{
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
else
|
||||
{
|
||||
U32 k = i*3+j+mMesh->mFaceIndexOffset;
|
||||
indicesp[k] = mMesh->getFaces()[i][j] + mMesh->mFaceVertexOffset;
|
||||
|
||||
U32* __restrict tc = (U32*) tex_coordsp.get();
|
||||
U32* __restrict vw = (U32*) vertex_weightsp.get();
|
||||
U32* __restrict cw = (U32*) clothing_weightsp.get();
|
||||
|
||||
do
|
||||
{
|
||||
v[0] = *(coords++);
|
||||
v[1] = *(coords++);
|
||||
v[2] = *(coords++);
|
||||
v += skip;
|
||||
|
||||
tc[0] = *(tex_coords++);
|
||||
tc[1] = *(tex_coords++);
|
||||
tc += skip;
|
||||
|
||||
n[0] = *(normals++);
|
||||
n[1] = *(normals++);
|
||||
n[2] = *(normals++);
|
||||
n += skip;
|
||||
|
||||
vw[0] = *(weights++);
|
||||
vw += skip;
|
||||
|
||||
cw[0] = *(cloth_weights++);
|
||||
cw[1] = *(cloth_weights++);
|
||||
cw[2] = *(cloth_weights++);
|
||||
cw[3] = *(cloth_weights++);
|
||||
cw += skip;
|
||||
}
|
||||
while (++i < num_verts);
|
||||
|
||||
const U32 idx_count = mMesh->getNumFaces()*3;
|
||||
|
||||
indicesp += mMesh->mFaceIndexOffset;
|
||||
|
||||
U16* __restrict idx = indicesp.get();
|
||||
S32* __restrict src_idx = (S32*) mMesh->getFaces();
|
||||
|
||||
i = 0;
|
||||
|
||||
const S32 offset = (S32) mMesh->mFaceVertexOffset;
|
||||
|
||||
do
|
||||
{
|
||||
*(idx++) = *(src_idx++)+offset;
|
||||
}
|
||||
while (++i < idx_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
/*virtual*/ U32 drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy );
|
||||
|
||||
/*virtual*/ void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
|
||||
/*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE);
|
||||
/*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
|
||||
/*virtual*/ BOOL updateLOD(F32 pixel_area, BOOL activate);
|
||||
/*virtual*/ void updateJointGeometry();
|
||||
/*virtual*/ void dump();
|
||||
|
||||
@@ -1365,10 +1365,12 @@ void init_debug_rendering_menu(LLMenuGL* menu)
|
||||
&LLPipeline::toggleRenderTypeControl, NULL,
|
||||
&LLPipeline::hasRenderTypeControl,
|
||||
(void*)LLPipeline::RENDER_TYPE_GRASS, '0', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
|
||||
//NOTE: Using a static variable, as an unsigned long long cannot fit in the space of a pointer. Pass pointer to callbacks
|
||||
static U64 cloud_flags = (1ULL<<LLPipeline::RENDER_TYPE_WL_CLOUDS | 1ULL<<LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS);
|
||||
sub_menu->append(new LLMenuItemCheckGL("Clouds", //This clobbers skyuseclassicclouds, but.. big deal.
|
||||
&LLPipeline::toggleRenderPairedTypeControl, NULL,
|
||||
&LLPipeline::hasRenderPairedTypeControl,
|
||||
(void*)(1<<LLPipeline::RENDER_TYPE_WL_CLOUDS | 1<<LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS), '-', MASK_CONTROL|MASK_ALT| MASK_SHIFT));
|
||||
(void*)&cloud_flags, '-', MASK_CONTROL|MASK_ALT| MASK_SHIFT));
|
||||
sub_menu->append(new LLMenuItemCheckGL("Particles",
|
||||
&LLPipeline::toggleRenderTypeControl, NULL,
|
||||
&LLPipeline::hasRenderTypeControl,
|
||||
|
||||
@@ -208,7 +208,9 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
|
||||
mState(0),
|
||||
mMedia(NULL),
|
||||
mClickAction(0),
|
||||
mAttachmentItemID(LLUUID::null)
|
||||
mAttachmentItemID(LLUUID::null),
|
||||
mLastUpdateType(OUT_UNKNOWN),
|
||||
mLastUpdateCached(FALSE)
|
||||
{
|
||||
if(!is_global)
|
||||
{
|
||||
@@ -454,7 +456,6 @@ void LLViewerObject::initVOClasses()
|
||||
llinfos << "Viewer Object size: " << sizeof(LLViewerObject) << llendl;
|
||||
LLVOGrass::initClass();
|
||||
LLVOWater::initClass();
|
||||
LLVOSky::initClass();
|
||||
LLVOVolume::initClass();
|
||||
}
|
||||
|
||||
@@ -2860,6 +2861,11 @@ BOOL LLViewerObject::updateGeometry(LLDrawable *drawable)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLViewerObject::updateGL()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLViewerObject::updateFaceSize(S32 idx)
|
||||
{
|
||||
|
||||
@@ -3786,6 +3792,15 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos
|
||||
}
|
||||
|
||||
|
||||
void LLViewerObject::changeTEImage(S32 index, LLViewerImage* new_image)
|
||||
{
|
||||
if(index < 0 || index >= getNumTEs())
|
||||
{
|
||||
return ;
|
||||
}
|
||||
mTEImages[index] = new_image ;
|
||||
}
|
||||
|
||||
S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
|
||||
{
|
||||
// Invalid host == get from the agent's sim
|
||||
@@ -4651,7 +4666,7 @@ bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_
|
||||
bool LLViewerObject::setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin)
|
||||
{
|
||||
ExtraParameter* param = getExtraParameterEntryCreate(param_type);
|
||||
if (param->in_use != in_use)
|
||||
if (param && param->in_use != in_use)
|
||||
{
|
||||
param->in_use = in_use;
|
||||
parameterChanged(param_type, param->data, in_use, local_origin);
|
||||
@@ -5071,7 +5086,7 @@ U32 LLViewerObject::getPartitionType() const
|
||||
return LLViewerRegion::PARTITION_NONE;
|
||||
}
|
||||
|
||||
void LLViewerObject::dirtySpatialGroup() const
|
||||
void LLViewerObject::dirtySpatialGroup(BOOL priority) const
|
||||
{
|
||||
if (mDrawable)
|
||||
{
|
||||
@@ -5079,6 +5094,7 @@ void LLViewerObject::dirtySpatialGroup() const
|
||||
if (group)
|
||||
{
|
||||
group->dirtyGeom();
|
||||
gPipeline.markRebuild(group, priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5266,7 +5282,25 @@ std::string LLViewerObject::getAttachmentPointName()
|
||||
return llformat("unsupported point %d", point);
|
||||
}
|
||||
// </edit>
|
||||
EObjectUpdateType LLViewerObject::getLastUpdateType() const
|
||||
{
|
||||
return mLastUpdateType;
|
||||
}
|
||||
|
||||
void LLViewerObject::setLastUpdateType(EObjectUpdateType last_update_type)
|
||||
{
|
||||
mLastUpdateType = last_update_type;
|
||||
}
|
||||
|
||||
BOOL LLViewerObject::getLastUpdateCached() const
|
||||
{
|
||||
return mLastUpdateCached;
|
||||
}
|
||||
|
||||
void LLViewerObject::setLastUpdateCached(BOOL last_update_cached)
|
||||
{
|
||||
mLastUpdateCached = last_update_cached;
|
||||
}
|
||||
|
||||
const LLUUID &LLViewerObject::extractAttachmentItemID()
|
||||
{
|
||||
|
||||
@@ -81,6 +81,7 @@ typedef enum e_object_update_type
|
||||
OUT_TERSE_IMPROVED,
|
||||
OUT_FULL_COMPRESSED,
|
||||
OUT_FULL_CACHED,
|
||||
OUT_UNKNOWN,
|
||||
} EObjectUpdateType;
|
||||
|
||||
|
||||
@@ -116,7 +117,7 @@ public:
|
||||
|
||||
//============================================================================
|
||||
|
||||
class LLViewerObject : public LLPrimitive, public LLRefCount
|
||||
class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
|
||||
{
|
||||
protected:
|
||||
~LLViewerObject(); // use unref()
|
||||
@@ -194,6 +195,7 @@ public:
|
||||
|
||||
virtual LLDrawable* createDrawable(LLPipeline *pipeline);
|
||||
virtual BOOL updateGeometry(LLDrawable *drawable);
|
||||
virtual void updateGL();
|
||||
virtual void updateFaceSize(S32 idx);
|
||||
virtual BOOL updateLOD();
|
||||
virtual BOOL setDrawableParent(LLDrawable* parentp);
|
||||
@@ -312,6 +314,7 @@ public:
|
||||
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
|
||||
/*virtual*/ BOOL setMaterial(const U8 material);
|
||||
virtual void setTEImage(const U8 te, LLViewerImage *imagep); // Not derived from LLPrimitive
|
||||
void changeTEImage(S32 index, LLViewerImage* new_image) ;
|
||||
LLViewerImage *getTEImage(const U8 te) const;
|
||||
|
||||
void fitFaceTexture(const U8 face);
|
||||
@@ -450,6 +453,7 @@ public:
|
||||
inline BOOL flagAnimSource() const { return ((mFlags & FLAGS_ANIM_SOURCE) != 0); }
|
||||
inline BOOL flagCameraSource() const { return ((mFlags & FLAGS_CAMERA_SOURCE) != 0); }
|
||||
inline BOOL flagCameraDecoupled() const { return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); }
|
||||
inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 0); }
|
||||
|
||||
bool getIncludeInSearch() const;
|
||||
void setIncludeInSearch(bool include_in_search);
|
||||
@@ -474,7 +478,7 @@ public:
|
||||
|
||||
virtual S32 getLOD() const { return 3; }
|
||||
virtual U32 getPartitionType() const;
|
||||
virtual void dirtySpatialGroup() const;
|
||||
virtual void dirtySpatialGroup(BOOL priority = FALSE) const;
|
||||
virtual void dirtyMesh();
|
||||
|
||||
virtual LLNetworkData* getParameterEntry(U16 param_type) const;
|
||||
@@ -673,8 +677,14 @@ public:
|
||||
const LLUUID &getAttachmentItemID() const { return mAttachmentItemID; }
|
||||
void setAttachmentItemID(const LLUUID &id) { mAttachmentItemID = id; }
|
||||
const LLUUID &extractAttachmentItemID(); // find&set the inventory item ID of the attached object
|
||||
EObjectUpdateType getLastUpdateType() const;
|
||||
void setLastUpdateType(EObjectUpdateType last_update_type);
|
||||
BOOL getLastUpdateCached() const;
|
||||
void setLastUpdateCached(BOOL last_update_cached);
|
||||
private:
|
||||
LLUUID mAttachmentItemID; // ItemID when item is in user inventory.
|
||||
EObjectUpdateType mLastUpdateType;
|
||||
BOOL mLastUpdateCached;
|
||||
};
|
||||
|
||||
typedef std::vector<LLViewerObject*> llvo_vec_t;
|
||||
|
||||
@@ -570,6 +570,9 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
||||
}
|
||||
}
|
||||
// </edit>
|
||||
|
||||
objectp->setLastUpdateType(update_type);
|
||||
objectp->setLastUpdateCached(cached);
|
||||
}
|
||||
|
||||
LLVOAvatar::cullAvatarsByPixelArea();
|
||||
@@ -842,13 +845,14 @@ void LLViewerObjectList::clearDebugText()
|
||||
void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_OBJECT);
|
||||
if (mDeadObjects.count(objectp->mID))
|
||||
if (mDeadObjects.find(objectp->mID) != mDeadObjects.end())
|
||||
{
|
||||
llinfos << "Object " << objectp->mID << " already on dead list, ignoring cleanup!" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
mDeadObjects.insert(std::pair<LLUUID, LLPointer<LLViewerObject> >(objectp->mID, objectp));
|
||||
else
|
||||
{
|
||||
mDeadObjects.insert(std::pair<LLUUID, LLPointer<LLViewerObject> >(objectp->mID, objectp));
|
||||
}
|
||||
|
||||
// Cleanup any references we have to this object
|
||||
// Remove from object map so noone can look it up.
|
||||
@@ -1064,7 +1068,7 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
|
||||
{
|
||||
objectp = getObject(i);
|
||||
// There could be dead objects on the object list, so don't update stuff if the object is dead.
|
||||
if (objectp)
|
||||
if (objectp && !objectp->isDead())
|
||||
{
|
||||
objectp->updatePositionCaches();
|
||||
|
||||
@@ -1097,7 +1101,7 @@ void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap)
|
||||
for (S32 i = 0; i < mMapObjects.count(); i++)
|
||||
{
|
||||
LLViewerObject* objectp = mMapObjects[i];
|
||||
if (!objectp->getRegion() || objectp->isOrphaned() || objectp->isAttachment())
|
||||
if (objectp->isDead() || !objectp->getRegion() || objectp->isOrphaned() || objectp->isAttachment())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -97,8 +97,7 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_
|
||||
mOwnership[i] = PARCEL_PUBLIC;
|
||||
}
|
||||
|
||||
// Make sure the texture matches the ownership information.
|
||||
updateOverlayTexture();
|
||||
gPipeline.markGLRebuild(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -711,6 +710,11 @@ void LLViewerParcelOverlay::setDirty()
|
||||
mDirty = TRUE;
|
||||
}
|
||||
|
||||
void LLViewerParcelOverlay::updateGL()
|
||||
{
|
||||
updateOverlayTexture();
|
||||
}
|
||||
|
||||
void LLViewerParcelOverlay::idleUpdate(bool force_update)
|
||||
{
|
||||
if (gGLManager.mIsDisabled)
|
||||
@@ -720,7 +724,7 @@ void LLViewerParcelOverlay::idleUpdate(bool force_update)
|
||||
if (mOverlayTextureIdx >= 0 && (!(mDirty && force_update)))
|
||||
{
|
||||
// We are in the middle of updating the overlay texture
|
||||
updateOverlayTexture();
|
||||
gPipeline.markGLRebuild(this);
|
||||
return;
|
||||
}
|
||||
// Only if we're dirty and it's been a while since the last update.
|
||||
|
||||
@@ -40,13 +40,14 @@
|
||||
#include "llframetimer.h"
|
||||
#include "lluuid.h"
|
||||
#include "llviewerimage.h"
|
||||
#include "llgl.h"
|
||||
|
||||
class LLViewerRegion;
|
||||
class LLVector3;
|
||||
class LLColor4U;
|
||||
class LLVector2;
|
||||
|
||||
class LLViewerParcelOverlay
|
||||
class LLViewerParcelOverlay : public LLGLUpdate
|
||||
{
|
||||
public:
|
||||
LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters);
|
||||
@@ -76,6 +77,7 @@ public:
|
||||
void setDirty();
|
||||
|
||||
void idleUpdate(bool update_now = false);
|
||||
void updateGL();
|
||||
|
||||
private:
|
||||
// This is in parcel rows and columns, not grid rows and columns
|
||||
|
||||
@@ -81,6 +81,7 @@ F32 calc_desired_size(LLVector3 pos, LLVector2 scale)
|
||||
LLViewerPart::LLViewerPart() :
|
||||
mPartID(0),
|
||||
mLastUpdateTime(0.f),
|
||||
mSkipOffset(0.f),
|
||||
mVPCallback(NULL),
|
||||
mImagep(NULL)
|
||||
{
|
||||
|
||||
@@ -127,7 +127,8 @@ LLGLSLShader gDeferredFullbrightProgram(LLViewerShaderMgr::SHADER_DEFERRED); /
|
||||
GLint gAvatarMatrixParam;
|
||||
|
||||
LLViewerShaderMgr::LLViewerShaderMgr() :
|
||||
mVertexShaderLevel(SHADER_COUNT, 0)
|
||||
mVertexShaderLevel(SHADER_COUNT, 0),
|
||||
mMaxAvatarShaderLevel(0)
|
||||
{}
|
||||
|
||||
LLViewerShaderMgr::~LLViewerShaderMgr()
|
||||
@@ -253,10 +254,15 @@ S32 LLViewerShaderMgr::getVertexShaderLevel(S32 type)
|
||||
|
||||
void LLViewerShaderMgr::setShaders()
|
||||
{
|
||||
if (!gPipeline.mInitialized || !sInitialized)
|
||||
//setShaders might be called redundantly by gSavedSettings, so return on reentrance
|
||||
static bool reentrance = false;
|
||||
|
||||
if (!gPipeline.mInitialized || !sInitialized || reentrance)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
reentrance = true;
|
||||
|
||||
initAttribsAndUniforms();
|
||||
gPipeline.releaseGLBuffers();
|
||||
@@ -269,8 +275,8 @@ void LLViewerShaderMgr::setShaders()
|
||||
}
|
||||
else
|
||||
{
|
||||
LLPipeline::sRenderGlow =
|
||||
LLPipeline::sWaterReflections = FALSE;
|
||||
LLPipeline::sRenderGlow = FALSE;
|
||||
LLPipeline::sWaterReflections = FALSE;
|
||||
}
|
||||
|
||||
//hack to reset buffers that change behavior with shaders
|
||||
@@ -302,6 +308,21 @@ void LLViewerShaderMgr::setShaders()
|
||||
S32 wl_class = 2;
|
||||
S32 water_class = 2;
|
||||
S32 deferred_class = 0;
|
||||
|
||||
if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
|
||||
gSavedSettings.getBOOL("RenderDeferred"))
|
||||
{
|
||||
deferred_class = 1;
|
||||
|
||||
//make sure framebuffer objects are enabled
|
||||
gSavedSettings.setBOOL("RenderUseFBO", TRUE);
|
||||
|
||||
//make sure hardware skinning is enabled
|
||||
gSavedSettings.setBOOL("RenderAvatarVP", TRUE);
|
||||
|
||||
//make sure atmospheric shaders are enabled
|
||||
gSavedSettings.setBOOL("WindLightUseAtmosShaders", TRUE);
|
||||
}
|
||||
if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders")
|
||||
&& gSavedSettings.getBOOL("WindLightUseAtmosShaders")))
|
||||
{
|
||||
@@ -310,11 +331,6 @@ void LLViewerShaderMgr::setShaders()
|
||||
wl_class = 1;
|
||||
}
|
||||
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
deferred_class = 1;
|
||||
}
|
||||
|
||||
if(!gSavedSettings.getBOOL("EnableRippleWater"))
|
||||
{
|
||||
water_class = 0;
|
||||
@@ -428,6 +444,7 @@ void LLViewerShaderMgr::setShaders()
|
||||
gViewerWindow->setCursor(UI_CURSOR_ARROW);
|
||||
}
|
||||
gPipeline.createGLBuffers();
|
||||
reentrance = false;
|
||||
}
|
||||
|
||||
void LLViewerShaderMgr::unloadShaders()
|
||||
|
||||
@@ -1544,7 +1544,7 @@ LLViewerWindow::LLViewerWindow(
|
||||
{
|
||||
gSavedSettings.setBOOL("RenderVBOEnable", FALSE);
|
||||
}
|
||||
LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"));
|
||||
LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
|
||||
|
||||
if (LLFeatureManager::getInstance()->isSafe()
|
||||
|| (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
|
||||
@@ -2065,6 +2065,9 @@ LLViewerWindow::~LLViewerWindow()
|
||||
{
|
||||
llinfos << "Destroying Window" << llendl;
|
||||
destroyWindow();
|
||||
|
||||
delete mDebugText;
|
||||
mDebugText = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -5395,11 +5398,15 @@ void LLPickInfo::fetchResults()
|
||||
|
||||
// put global position into land_pos
|
||||
LLVector3d land_pos;
|
||||
if (gViewerWindow->mousePointOnLandGlobal(mPickPt.mX, mPickPt.mY, &land_pos))
|
||||
if (!gViewerWindow->mousePointOnLandGlobal(mPickPt.mX, mPickPt.mY, &land_pos))
|
||||
{
|
||||
// Fudge the land focus a little bit above ground.
|
||||
mPosGlobal = land_pos + LLVector3d::z_axis * 0.1f;
|
||||
// The selected point is beyond the draw distance or is otherwise
|
||||
// not selectable. Return before calling mPickCallback().
|
||||
return;
|
||||
}
|
||||
|
||||
// Fudge the land focus a little bit above ground.
|
||||
mPosGlobal = land_pos + LLVector3d::z_axis * 0.1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -830,7 +830,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
|
||||
mBakedTextureData[i].mTextureIndex = getTextureIndex((EBakedTextureIndex)i);
|
||||
}
|
||||
|
||||
mDirtyMesh = TRUE; // Dirty geometry, need to regenerate.
|
||||
mDirtyMesh = 2; // Dirty geometry, need to regenerate.
|
||||
mMeshTexturesDirty = FALSE;
|
||||
mShadow0Facep = NULL;
|
||||
mShadow1Facep = NULL;
|
||||
mHeadp = NULL;
|
||||
@@ -2461,7 +2462,7 @@ void LLVOAvatar::updateMeshData()
|
||||
}
|
||||
if(num_vertices < 1)//skip empty meshes
|
||||
{
|
||||
break ;
|
||||
continue ;
|
||||
}
|
||||
if(last_v_num > 0)//put the last inserted part into next vertex buffer.
|
||||
{
|
||||
@@ -2483,6 +2484,8 @@ void LLVOAvatar::updateMeshData()
|
||||
// resize immediately
|
||||
facep->setSize(num_vertices, num_indices);
|
||||
|
||||
bool terse_update = false;
|
||||
|
||||
if(facep->mVertexBuffer.isNull())
|
||||
{
|
||||
facep->mVertexBuffer = new LLVertexBufferAvatar();
|
||||
@@ -2490,7 +2493,15 @@ void LLVOAvatar::updateMeshData()
|
||||
}
|
||||
else
|
||||
{
|
||||
facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ;
|
||||
if (facep->mVertexBuffer->getRequestedIndices() == num_indices &&
|
||||
facep->mVertexBuffer->getRequestedVerts() == num_vertices)
|
||||
{
|
||||
terse_update = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ;
|
||||
}
|
||||
}
|
||||
|
||||
facep->setGeomIndex(0);
|
||||
@@ -2505,7 +2516,7 @@ void LLVOAvatar::updateMeshData()
|
||||
|
||||
for(S32 k = j ; k < part_index ; k++)
|
||||
{
|
||||
mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR);
|
||||
mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update);
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
@@ -4903,13 +4914,20 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
|
||||
return num_indices;
|
||||
}
|
||||
|
||||
if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
|
||||
LLFace* face = mDrawable->getFace(0);
|
||||
|
||||
bool needs_rebuild = !face || face->mVertexBuffer.isNull() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY);
|
||||
|
||||
if (needs_rebuild || mDirtyMesh)
|
||||
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
|
||||
if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
|
||||
{
|
||||
updateMeshData();
|
||||
mDirtyMesh = FALSE;
|
||||
mDirtyMesh = 0;
|
||||
mNeedsSkin = TRUE;
|
||||
mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
|
||||
}
|
||||
}
|
||||
|
||||
if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
|
||||
{
|
||||
@@ -6693,7 +6711,7 @@ BOOL LLVOAvatar::updateJointLODs()
|
||||
if (res)
|
||||
{
|
||||
sNumLODChangesThisFrame++;
|
||||
dirtyMesh();
|
||||
dirtyMesh(2);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -6728,11 +6746,20 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)
|
||||
|
||||
mNumInitFaces = mDrawable->getNumFaces() ;
|
||||
|
||||
dirtyMesh();
|
||||
dirtyMesh(2);
|
||||
return mDrawable;
|
||||
}
|
||||
|
||||
|
||||
void LLVOAvatar::updateGL()
|
||||
{
|
||||
if (mMeshTexturesDirty)
|
||||
{
|
||||
updateMeshTextures();
|
||||
mMeshTexturesDirty = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// updateGeometry()
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -6874,9 +6901,12 @@ void LLVOAvatar::updateSexDependentLayerSets( BOOL set_by_user )
|
||||
//-----------------------------------------------------------------------------
|
||||
void LLVOAvatar::dirtyMesh()
|
||||
{
|
||||
mDirtyMesh = TRUE;
|
||||
dirtyMesh(1);
|
||||
}
|
||||
void LLVOAvatar::dirtyMesh(S32 priority)
|
||||
{
|
||||
mDirtyMesh = llmax(mDirtyMesh, priority);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// hideSkirt()
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -9142,7 +9172,8 @@ void LLVOAvatar::onFirstTEMessageReceived()
|
||||
}
|
||||
}
|
||||
|
||||
updateMeshTextures();
|
||||
mMeshTexturesDirty = TRUE;
|
||||
gPipeline.markGLRebuild(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9227,6 +9258,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
|
||||
}
|
||||
|
||||
setCompositeUpdatesEnabled( FALSE );
|
||||
mMeshTexturesDirty = TRUE;
|
||||
gPipeline.markGLRebuild(this);
|
||||
|
||||
if (!mIsSelf)
|
||||
{
|
||||
@@ -10437,21 +10470,22 @@ void LLVOAvatar::updateFreezeCounter(S32 counter)
|
||||
|
||||
BOOL LLVOAvatar::updateLOD()
|
||||
{
|
||||
if (isImpostor())
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
BOOL res = updateJointLODs();
|
||||
|
||||
LLFace* facep = mDrawable->getFace(0);
|
||||
if (facep->mVertexBuffer.isNull() ||
|
||||
(LLVertexBuffer::sEnableVBOs &&
|
||||
((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) !=
|
||||
(facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE))))
|
||||
if (facep->mVertexBuffer.isNull())
|
||||
{
|
||||
mDirtyMesh = TRUE;
|
||||
dirtyMesh(2);
|
||||
}
|
||||
|
||||
if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
|
||||
if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
|
||||
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
|
||||
updateMeshData();
|
||||
mDirtyMesh = FALSE;
|
||||
mDirtyMesh = 0;
|
||||
mNeedsSkin = TRUE;
|
||||
mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ public:
|
||||
// LLViewerObject interface
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
virtual void updateGL();
|
||||
static void initClass(); // Initialize data that's only init'd once per class.
|
||||
static void cleanupClass(); // Cleanup data that's only init'd once per class.
|
||||
static BOOL parseSkeletonFile(const std::string& filename);
|
||||
@@ -246,7 +247,7 @@ public:
|
||||
BOOL isVisible();
|
||||
BOOL isSelf() const { return mIsSelf; }
|
||||
BOOL isCulled() const { return mCulled; }
|
||||
|
||||
bool isBuilt() const { return mIsBuilt; }
|
||||
public:
|
||||
static void cullAvatarsByPixelArea();
|
||||
void setVisibilityRank(U32 rank);
|
||||
@@ -295,7 +296,6 @@ public:
|
||||
void processAvatarAppearance( LLMessageSystem* mesgsys );
|
||||
void onFirstTEMessageReceived();
|
||||
void updateSexDependentLayerSets( BOOL set_by_user );
|
||||
void dirtyMesh(); // Dirty the avatar mesh
|
||||
void hideSkirt();
|
||||
|
||||
|
||||
@@ -660,7 +660,6 @@ private:
|
||||
BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients
|
||||
|
||||
// LLFrameTimer mUpdateLODTimer; // controls frequency of LOD change calculations
|
||||
BOOL mDirtyMesh;
|
||||
BOOL mTurning; // controls hysteresis on avatar rotation
|
||||
F32 mSpeed; // misc. animation repeated state
|
||||
|
||||
@@ -673,7 +672,7 @@ private:
|
||||
BOOL mMeshValid;
|
||||
BOOL mVisible;
|
||||
LLFrameTimer mMeshInvisibleTime;
|
||||
|
||||
|
||||
// Lip synch morph stuff
|
||||
bool mLipSyncActive; // we're morphing for lip sync
|
||||
LLVisualParam* mOohMorph; // cached pointers morphs for lip sync
|
||||
@@ -878,6 +877,13 @@ private:
|
||||
static LLVOAvatarSkeletonInfo* sAvatarSkeletonInfo;
|
||||
static LLVOAvatarXmlInfo* sAvatarXmlInfo;
|
||||
|
||||
public:
|
||||
void dirtyMesh();
|
||||
private:
|
||||
void dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority
|
||||
S32 mDirtyMesh; // 0 -- not dirty, 1 -- morphed, 2 -- LOD
|
||||
BOOL mMeshTexturesDirty;
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// Diagnostics
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -104,7 +104,10 @@ LLVOCacheEntry::LLVOCacheEntry(LLFILE *fp)
|
||||
|
||||
LLVOCacheEntry::~LLVOCacheEntry()
|
||||
{
|
||||
delete [] mBuffer;
|
||||
if(mBuffer)
|
||||
{
|
||||
delete [] mBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -123,7 +123,10 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
dirtySpatialGroup();
|
||||
if (drawable->isVisible())
|
||||
{
|
||||
dirtySpatialGroup(TRUE);
|
||||
}
|
||||
|
||||
LLFace *facep;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "llsurface.h"
|
||||
#include "llsurfacepatch.h"
|
||||
#include "llvosky.h"
|
||||
#include "llvotree.h"
|
||||
#include "llviewercamera.h"
|
||||
#include "llviewerimagelist.h"
|
||||
#include "llviewerregion.h"
|
||||
@@ -304,6 +305,22 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if(LLVOTree::isTreeRenderingStopped()) //stop rendering grass
|
||||
{
|
||||
if(mNumBlades)
|
||||
{
|
||||
mNumBlades = 0 ;
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
|
||||
}
|
||||
return TRUE ;
|
||||
}
|
||||
else if(!mNumBlades)//restart grass rendering
|
||||
{
|
||||
mNumBlades = GRASS_MAX_BLADES ;
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime()))
|
||||
{
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
|
||||
@@ -350,7 +367,20 @@ BOOL LLVOGrass::updateLOD()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(LLVOTree::isTreeRenderingStopped())
|
||||
{
|
||||
if(mNumBlades)
|
||||
{
|
||||
mNumBlades = 0 ;
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
|
||||
}
|
||||
return TRUE ;
|
||||
}
|
||||
if(!mNumBlades)
|
||||
{
|
||||
mNumBlades = GRASS_MAX_BLADES;
|
||||
}
|
||||
|
||||
LLFace* face = mDrawable->getFace(0);
|
||||
|
||||
F32 tan_angle = 0.f;
|
||||
@@ -396,7 +426,22 @@ BOOL LLVOGrass::updateGeometry(LLDrawable *drawable)
|
||||
{
|
||||
LLFastTimer ftm(LLFastTimer::FTM_UPDATE_GRASS);
|
||||
dirtySpatialGroup();
|
||||
plantBlades();
|
||||
|
||||
if(!mNumBlades)//stop rendering grass
|
||||
{
|
||||
if (mDrawable->getNumFaces() > 0)
|
||||
{
|
||||
LLFace* facep = mDrawable->getFace(0);
|
||||
if(facep)
|
||||
{
|
||||
facep->setSize(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plantBlades();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -437,6 +482,11 @@ void LLVOGrass::getGeometry(S32 idx,
|
||||
LLStrider<LLColor4U>& colorsp,
|
||||
LLStrider<U16>& indicesp)
|
||||
{
|
||||
if(!mNumBlades)//stop rendering grass
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion());
|
||||
if (mPatch)
|
||||
mLastPatchUpdateTime = mPatch->getLastUpdateTime();
|
||||
|
||||
@@ -154,6 +154,11 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
|
||||
group = drawable->getSpatialGroup();
|
||||
}
|
||||
|
||||
if (group && group->isVisible())
|
||||
{
|
||||
dirtySpatialGroup(TRUE);
|
||||
}
|
||||
|
||||
if (!num_parts)
|
||||
{
|
||||
if (group && drawable->getNumFaces())
|
||||
@@ -352,12 +357,11 @@ U32 LLVOPartGroup::getPartitionType() const
|
||||
}
|
||||
|
||||
LLParticlePartition::LLParticlePartition()
|
||||
: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK)
|
||||
: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB)
|
||||
{
|
||||
mRenderPass = LLRenderPass::PASS_ALPHA;
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES;
|
||||
mPartitionType = LLViewerRegion::PARTITION_PARTICLE;
|
||||
mBufferUsage = GL_DYNAMIC_DRAW_ARB;
|
||||
mSlopRatio = 0.f;
|
||||
mLODPeriod = 1;
|
||||
}
|
||||
@@ -375,6 +379,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
|
||||
|
||||
mFaceList.clear();
|
||||
|
||||
LLViewerCamera* camera = LLViewerCamera::getInstance();
|
||||
for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
|
||||
{
|
||||
LLDrawable* drawablep = *i;
|
||||
@@ -404,7 +409,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
|
||||
}
|
||||
|
||||
count++;
|
||||
facep->mDistance = (facep->mCenterLocal - LLViewerCamera::getInstance()->getOrigin()) * LLViewerCamera::getInstance()->getAtAxis();
|
||||
facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();
|
||||
obj->mDepth += facep->mDistance;
|
||||
|
||||
mFaceList.push_back(facep);
|
||||
|
||||
@@ -78,16 +78,9 @@ static const LLVector2 TEX01 = LLVector2(0.f, 1.f);
|
||||
static const LLVector2 TEX10 = LLVector2(1.f, 0.f);
|
||||
static const LLVector2 TEX11 = LLVector2(1.f, 1.f);
|
||||
|
||||
// Exported global semi-constants.
|
||||
// Exported globals
|
||||
LLUUID gSunTextureID = IMG_SUN;
|
||||
LLUUID gMoonTextureID = IMG_MOON;
|
||||
// Exported global constants.
|
||||
LLColor3 const gAirScaSeaLevel = calc_air_sca_sea_level();
|
||||
F32 const AIR_SCA_INTENS = color_intens(gAirScaSeaLevel);
|
||||
F32 const AIR_SCA_AVG = AIR_SCA_INTENS / 3.f;
|
||||
|
||||
//static
|
||||
LLColor3 LLHaze::sAirScaSeaLevel;
|
||||
|
||||
class LLFastLn
|
||||
{
|
||||
@@ -191,6 +184,23 @@ inline void color_gamma_correct(LLColor3 &col)
|
||||
}
|
||||
}
|
||||
|
||||
static LLColor3 calc_air_sca_sea_level()
|
||||
{
|
||||
static LLColor3 WAVE_LEN(675, 520, 445);
|
||||
static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN);
|
||||
static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1);
|
||||
static LLColor3 n4 = n21 * n21;
|
||||
static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f;
|
||||
static LLColor3 wl4 = wl2 * wl2;
|
||||
static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4;
|
||||
static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2);
|
||||
return dens_div_N * color_div ( mult_const, wl4 );
|
||||
}
|
||||
|
||||
// static constants.
|
||||
LLColor3 const LLHaze::sAirScaSeaLevel = calc_air_sca_sea_level();
|
||||
F32 const LLHaze::sAirScaIntense = color_intens(LLHaze::sAirScaSeaLevel);
|
||||
F32 const LLHaze::sAirScaAvg = LLHaze::sAirScaIntense / 3.f;
|
||||
|
||||
|
||||
/***************************************
|
||||
@@ -389,22 +399,21 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
|
||||
mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
mHeavenlyBodyUpdated = FALSE ;
|
||||
|
||||
mDrawRefl = 0;
|
||||
mHazeConcentration = 0.f;
|
||||
mInterpVal = 0.f;
|
||||
}
|
||||
|
||||
|
||||
LLVOSky::~LLVOSky()
|
||||
{
|
||||
// Don't delete images - it'll get deleted by gImageList on shutdown
|
||||
// Don't delete images - it'll get deleted by gTextureList on shutdown
|
||||
// This needs to be done for each texture
|
||||
|
||||
mCubeMap = NULL;
|
||||
}
|
||||
|
||||
void LLVOSky::initClass()
|
||||
{
|
||||
LLHaze::initClass();
|
||||
}
|
||||
|
||||
|
||||
void LLVOSky::init()
|
||||
{
|
||||
@@ -969,7 +978,7 @@ void LLVOSky::calcAtmospherics(void)
|
||||
|
||||
// and vary_sunlight will work properly with moon light
|
||||
F32 lighty = unclamped_lightnorm[1];
|
||||
if(lighty < NIGHTTIME_ELEVATION_COS)
|
||||
if(lighty < LLSky::NIGHTTIME_ELEVATION_COS)
|
||||
{
|
||||
lighty = -lighty;
|
||||
}
|
||||
@@ -1080,10 +1089,10 @@ BOOL LLVOSky::updateSky()
|
||||
++next_frame;
|
||||
next_frame = next_frame % cycle_frame_no;
|
||||
|
||||
sInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no;
|
||||
mInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no;
|
||||
// sInterpVal = (F32)next_frame / cycle_frame_no;
|
||||
LLSkyTex::setInterpVal( sInterpVal );
|
||||
LLHeavenBody::setInterpVal( sInterpVal );
|
||||
LLSkyTex::setInterpVal( mInterpVal );
|
||||
LLHeavenBody::setInterpVal( mInterpVal );
|
||||
calcAtmospherics();
|
||||
|
||||
if (mForceUpdate || total_no_tiles == frame)
|
||||
@@ -2151,17 +2160,8 @@ void LLVOSky::updateFog(const F32 distance)
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLHaze::initClass()
|
||||
{
|
||||
sAirScaSeaLevel = LLHaze::calcAirScaSeaLevel();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Functions used a lot.
|
||||
|
||||
|
||||
F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply)
|
||||
{
|
||||
F32 mv = color_max(col);
|
||||
|
||||
@@ -147,8 +147,8 @@ protected:
|
||||
|
||||
static S32 getResolution() { return sResolution; }
|
||||
static S32 getCurrent() { return sCurrent; }
|
||||
static S32 stepCurrent() { sCurrent++; sCurrent&=1; return sCurrent; }
|
||||
static S32 getNext() { return ((sCurrent+1) % 2); }
|
||||
static S32 stepCurrent() { sCurrent++; sCurrent &= 1; return sCurrent; }
|
||||
static S32 getNext() { return ((sCurrent+1) & 1); }
|
||||
static S32 getWhich(const BOOL curr) { return curr ? sCurrent : getNext(); }
|
||||
|
||||
void initEmpty(const S32 tex);
|
||||
@@ -298,24 +298,6 @@ LL_FORCE_INLINE LLColor3 refr_ind_calc(const LLColor3 &wave_length)
|
||||
}
|
||||
|
||||
|
||||
LL_FORCE_INLINE LLColor3 calc_air_sca_sea_level()
|
||||
{
|
||||
const static LLColor3 WAVE_LEN(675, 520, 445);
|
||||
const static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN);
|
||||
const static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1);
|
||||
const static LLColor3 n4 = n21 * n21;
|
||||
const static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f;
|
||||
const static LLColor3 wl4 = wl2 * wl2;
|
||||
const static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4;
|
||||
const static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2);
|
||||
return dens_div_N * color_div ( mult_const, wl4 );
|
||||
}
|
||||
|
||||
// Non-POD constants.
|
||||
extern LLColor3 const gAirScaSeaLevel;
|
||||
extern F32 const AIR_SCA_INTENS;
|
||||
extern F32 const AIR_SCA_AVG;
|
||||
|
||||
class LLHaze
|
||||
{
|
||||
public:
|
||||
@@ -323,18 +305,15 @@ public:
|
||||
LLHaze(const F32 g, const LLColor3& sca, const F32 fo = 2.f) :
|
||||
mG(g), mSigSca(0.25f/F_PI * sca), mFalloff(fo), mAbsCoef(0.f)
|
||||
{
|
||||
mAbsCoef = color_intens(mSigSca) / AIR_SCA_INTENS;
|
||||
mAbsCoef = color_intens(mSigSca) / sAirScaIntense;
|
||||
}
|
||||
|
||||
LLHaze(const F32 g, const F32 sca, const F32 fo = 2.f) : mG(g),
|
||||
mSigSca(0.25f/F_PI * LLColor3(sca, sca, sca)), mFalloff(fo)
|
||||
{
|
||||
mAbsCoef = 0.01f * sca / AIR_SCA_AVG;
|
||||
mAbsCoef = 0.01f * sca / sAirScaAvg;
|
||||
}
|
||||
|
||||
static void initClass();
|
||||
|
||||
|
||||
F32 getG() const { return mG; }
|
||||
|
||||
void setG(const F32 g)
|
||||
@@ -350,12 +329,12 @@ public:
|
||||
void setSigSca(const LLColor3& s)
|
||||
{
|
||||
mSigSca = s;
|
||||
mAbsCoef = 0.01f * color_intens(mSigSca) / AIR_SCA_INTENS;
|
||||
mAbsCoef = 0.01f * color_intens(mSigSca) / sAirScaIntense;
|
||||
}
|
||||
|
||||
void setSigSca(const F32 s0, const F32 s1, const F32 s2)
|
||||
{
|
||||
mSigSca = AIR_SCA_AVG * LLColor3 (s0, s1, s2);
|
||||
mSigSca = sAirScaAvg * LLColor3 (s0, s1, s2);
|
||||
mAbsCoef = 0.01f * (s0 + s1 + s2) / 3;
|
||||
}
|
||||
|
||||
@@ -399,10 +378,11 @@ public:
|
||||
|
||||
static inline LLColor3 calcAirSca(const F32 h);
|
||||
static inline void calcAirSca(const F32 h, LLColor3 &result);
|
||||
static LLColor3 calcAirScaSeaLevel() { return gAirScaSeaLevel; }
|
||||
static const LLColor3 &getAirScaSeaLevel() { return sAirScaSeaLevel; }
|
||||
public:
|
||||
static LLColor3 sAirScaSeaLevel;
|
||||
|
||||
private:
|
||||
static LLColor3 const sAirScaSeaLevel;
|
||||
static F32 const sAirScaIntense;
|
||||
static F32 const sAirScaAvg;
|
||||
|
||||
protected:
|
||||
F32 mG;
|
||||
@@ -480,7 +460,6 @@ public:
|
||||
LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
|
||||
|
||||
// Initialize/delete data that's only inited once per class.
|
||||
static void initClass();
|
||||
void init();
|
||||
void initCubeMap();
|
||||
void initEmpty();
|
||||
@@ -614,7 +593,7 @@ protected:
|
||||
LLColor3 mLastTotalAmbient;
|
||||
F32 mAmbientScale;
|
||||
LLColor3 mNightColorShift;
|
||||
F32 sInterpVal;
|
||||
F32 mInterpVal;
|
||||
|
||||
LLColor4 mFogColor;
|
||||
LLColor4 mGLFogCol;
|
||||
@@ -661,14 +640,12 @@ F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply = FALSE);
|
||||
|
||||
inline LLColor3 LLHaze::calcAirSca(const F32 h)
|
||||
{
|
||||
static const LLColor3 air_sca_sea_level = calcAirScaSeaLevel();
|
||||
return calcFalloff(h) * air_sca_sea_level;
|
||||
return calcFalloff(h) * sAirScaSeaLevel;
|
||||
}
|
||||
|
||||
inline void LLHaze::calcAirSca(const F32 h, LLColor3 &result)
|
||||
{
|
||||
static const LLColor3 air_sca_sea_level = calcAirScaSeaLevel();
|
||||
result = air_sca_sea_level;
|
||||
result = sAirScaSeaLevel;
|
||||
result *= calcFalloff(h);
|
||||
}
|
||||
|
||||
|
||||
@@ -177,11 +177,19 @@ LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline)
|
||||
}
|
||||
|
||||
|
||||
void LLVOSurfacePatch::updateGL()
|
||||
{
|
||||
if (mPatchp)
|
||||
{
|
||||
mPatchp->updateGL();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable)
|
||||
{
|
||||
LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TERRAIN);
|
||||
|
||||
dirtySpatialGroup();
|
||||
dirtySpatialGroup(TRUE);
|
||||
|
||||
S32 min_comp, max_comp, range;
|
||||
min_comp = lltrunc(mPatchp->getMinComposition());
|
||||
@@ -1013,12 +1021,10 @@ U32 LLVOSurfacePatch::getPartitionType() const
|
||||
}
|
||||
|
||||
LLTerrainPartition::LLTerrainPartition()
|
||||
: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK)
|
||||
: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB)
|
||||
{
|
||||
mOcclusionEnabled = FALSE;
|
||||
mRenderByGroup = FALSE;
|
||||
mInfiniteFarClip = TRUE;
|
||||
mBufferUsage = GL_DYNAMIC_DRAW_ARB;
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_TERRAIN;
|
||||
mPartitionType = LLViewerRegion::PARTITION_TERRAIN;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ public:
|
||||
virtual U32 getPartitionType() const;
|
||||
|
||||
/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
|
||||
/*virtual*/ void updateGL();
|
||||
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
|
||||
/*virtual*/ BOOL updateLOD();
|
||||
/*virtual*/ void updateFaceSize(S32 idx);
|
||||
|
||||
@@ -101,6 +101,12 @@ LLVOTree::~LLVOTree()
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
bool LLVOTree::isTreeRenderingStopped()
|
||||
{
|
||||
return LLVOTree::sTreeFactor < LLVOTree::sLODAngles[4 - 1] ;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLVOTree::initClass()
|
||||
{
|
||||
@@ -1324,9 +1330,8 @@ U32 LLVOTree::getPartitionType() const
|
||||
}
|
||||
|
||||
LLTreePartition::LLTreePartition()
|
||||
: LLSpatialPartition(0)
|
||||
: LLSpatialPartition(0, FALSE, 0)
|
||||
{
|
||||
mRenderByGroup = FALSE;
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_TREE;
|
||||
mPartitionType = LLViewerRegion::PARTITION_TREE;
|
||||
mSlopRatio = 0.f;
|
||||
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
// Initialize data that's only inited once per class.
|
||||
static void initClass();
|
||||
static void cleanupClass();
|
||||
static bool isTreeRenderingStopped();
|
||||
|
||||
/*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys,
|
||||
void **user_data,
|
||||
|
||||
@@ -87,8 +87,10 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
|
||||
mRelativeXform.setIdentity();
|
||||
mRelativeXformInvTrans.setIdentity();
|
||||
|
||||
mFaceMappingChanged = FALSE;
|
||||
mLOD = MIN_LOD;
|
||||
mTextureAnimp = NULL;
|
||||
mVolumeChanged = FALSE;
|
||||
mVObjRadius = LLVector3(1,1,0.5f).length();
|
||||
mNumFaces = 0;
|
||||
mLODChanged = FALSE;
|
||||
@@ -104,6 +106,20 @@ LLVOVolume::~LLVOVolume()
|
||||
mVolumeImpl = NULL;
|
||||
}
|
||||
|
||||
void LLVOVolume::markDead()
|
||||
{
|
||||
if (!mDead)
|
||||
{
|
||||
|
||||
if (mSculptTexture.notNull())
|
||||
{
|
||||
mSculptTexture->removeVolume(this);
|
||||
}
|
||||
}
|
||||
|
||||
LLViewerObject::markDead();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLVOVolume::initClass()
|
||||
@@ -407,6 +423,18 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
|
||||
mVolumeImpl->doIdleUpdate(agent, world, time);
|
||||
}
|
||||
|
||||
const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40;
|
||||
|
||||
if (mDrawable->isActive())
|
||||
{
|
||||
if (mDrawable->isRoot() &&
|
||||
mDrawable->mQuietCount++ > MAX_ACTIVE_OBJECT_QUIET_FRAMES &&
|
||||
(!mDrawable->getParent() || !mDrawable->getParent()->isActive()))
|
||||
{
|
||||
mDrawable->makeStatic();
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -443,7 +471,7 @@ void LLVOVolume::updateTextureVirtualSize()
|
||||
{
|
||||
// Update the pixel area of all faces
|
||||
|
||||
if(mDrawable.isNull() || !mDrawable->isVisible())
|
||||
if(!isVisible())
|
||||
{
|
||||
return ;
|
||||
}
|
||||
@@ -465,6 +493,7 @@ void LLVOVolume::updateTextureVirtualSize()
|
||||
|
||||
const S32 num_faces = mDrawable->getNumFaces();
|
||||
F32 min_vsize=999999999.f, max_vsize=0.f;
|
||||
LLViewerCamera* camera = LLViewerCamera::getInstance();
|
||||
for (S32 i = 0; i < num_faces; i++)
|
||||
{
|
||||
LLFace* face = mDrawable->getFace(i);
|
||||
@@ -485,6 +514,7 @@ void LLVOVolume::updateTextureVirtualSize()
|
||||
vsize = area;
|
||||
imagep->setBoostLevel(LLViewerImageBoostLevel::BOOST_HUD);
|
||||
face->setPixelArea(area); // treat as full screen
|
||||
face->setVirtualSize(vsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -513,8 +543,7 @@ void LLVOVolume::updateTextureVirtualSize()
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
face->setVirtualSize(vsize);
|
||||
|
||||
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
|
||||
{
|
||||
if (vsize < min_vsize) min_vsize = vsize;
|
||||
@@ -554,9 +583,9 @@ void LLVOVolume::updateTextureVirtualSize()
|
||||
|
||||
//if the sculpty very close to the view point, load first
|
||||
{
|
||||
LLVector3 lookAt = getPositionAgent() - LLViewerCamera::getInstance()->getOrigin();
|
||||
LLVector3 lookAt = getPositionAgent() - camera->getOrigin();
|
||||
F32 dist = lookAt.normVec() ;
|
||||
F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ;
|
||||
F32 cos_angle_to_view_dir = lookAt * camera->getXAxis() ;
|
||||
mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ;
|
||||
}
|
||||
}
|
||||
@@ -719,6 +748,8 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail
|
||||
|
||||
if (isSculpted())
|
||||
{
|
||||
updateSculptTexture();
|
||||
|
||||
if (mSculptTexture.notNull())
|
||||
{
|
||||
sculpt();
|
||||
@@ -850,9 +881,6 @@ BOOL LLVOVolume::calcLOD()
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//update face texture sizes on lod calculation
|
||||
updateTextureVirtualSize();
|
||||
|
||||
S32 cur_detail = 0;
|
||||
|
||||
F32 radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length();
|
||||
@@ -1163,7 +1191,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
|
||||
return res;
|
||||
}
|
||||
|
||||
dirtySpatialGroup();
|
||||
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
|
||||
|
||||
BOOL compiled = FALSE;
|
||||
|
||||
@@ -2124,7 +2152,7 @@ U32 LLVOVolume::getPartitionType() const
|
||||
}
|
||||
|
||||
LLVolumePartition::LLVolumePartition()
|
||||
: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, FALSE)
|
||||
: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB)
|
||||
{
|
||||
mLODPeriod = 16;
|
||||
mDepthMask = FALSE;
|
||||
@@ -2135,7 +2163,7 @@ LLVolumePartition::LLVolumePartition()
|
||||
}
|
||||
|
||||
LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep)
|
||||
: LLSpatialBridge(drawablep, LLVOVolume::VERTEX_DATA_MASK)
|
||||
: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK)
|
||||
{
|
||||
mDepthMask = FALSE;
|
||||
mLODPeriod = 16;
|
||||
@@ -2169,6 +2197,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
|
||||
BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) ||
|
||||
(type == LLRenderPass::PASS_INVISIBLE) ||
|
||||
(type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT));
|
||||
|
||||
if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL))
|
||||
{
|
||||
llwarns << "Non fullbright face has no normals!" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
const LLMatrix4* tex_mat = NULL;
|
||||
if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE)
|
||||
@@ -2481,7 +2515,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
||||
|
||||
if (LLPipeline::sDelayVBUpdate)
|
||||
{
|
||||
group->setState(LLSpatialGroup::MESH_DIRTY);
|
||||
group->setState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
|
||||
}
|
||||
|
||||
mFaceList.clear();
|
||||
@@ -2572,7 +2606,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
||||
}
|
||||
}
|
||||
|
||||
group->clearState(LLSpatialGroup::MESH_DIRTY);
|
||||
group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2752,74 +2786,77 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
}
|
||||
}
|
||||
else if (gPipeline.canUseVertexShaders()
|
||||
&& group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD
|
||||
&& LLPipeline::sRenderBump
|
||||
&& te->getShiny())
|
||||
{
|
||||
{ //shiny
|
||||
if (tex->getPrimaryFormat() == GL_ALPHA)
|
||||
{
|
||||
{ //invisiprim+shiny
|
||||
registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
|
||||
registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
|
||||
}
|
||||
else if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
{ //deferred rendering
|
||||
if (te->getBumpmap())
|
||||
{
|
||||
{ //register in deferred bump pass
|
||||
registerFace(group, facep, LLRenderPass::PASS_BUMP);
|
||||
}
|
||||
else if (te->getFullbright())
|
||||
{
|
||||
{ //register in post deferred fullbright shiny pass
|
||||
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
|
||||
}
|
||||
else
|
||||
{
|
||||
{ //register in deferred simple pass (deferred simple includes shiny)
|
||||
llassert(mask & LLVertexBuffer::MAP_NORMAL);
|
||||
registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
|
||||
}
|
||||
}
|
||||
else if (fullbright)
|
||||
{
|
||||
{ //not deferred, register in standard fullbright shiny pass
|
||||
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
|
||||
}
|
||||
else
|
||||
{
|
||||
{ //not deferred or fullbright, register in standard shiny pass
|
||||
registerFace(group, facep, LLRenderPass::PASS_SHINY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{ //not alpha and not shiny
|
||||
if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)
|
||||
{
|
||||
{ //invisiprim
|
||||
registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
|
||||
}
|
||||
else if (fullbright)
|
||||
{
|
||||
{ //fullbright
|
||||
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LLPipeline::sRenderDeferred && te->getBumpmap())
|
||||
{
|
||||
if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap())
|
||||
{ //non-shiny or fullbright deferred bump
|
||||
registerFace(group, facep, LLRenderPass::PASS_BUMP);
|
||||
}
|
||||
else
|
||||
{
|
||||
{ //all around simple
|
||||
llassert(mask & LLVertexBuffer::MAP_NORMAL);
|
||||
registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_alpha && te->getShiny())
|
||||
//not sure why this is here -- shiny HUD attachments maybe? -- davep 5/11/2010
|
||||
if (!is_alpha && te->getShiny() && LLPipeline::sRenderBump)
|
||||
{
|
||||
registerFace(group, facep, LLRenderPass::PASS_SHINY);
|
||||
}
|
||||
}
|
||||
|
||||
//not sure why this is here, and looks like it might cause bump mapped objects to get rendered redundantly -- davep 5/11/2010
|
||||
if (!is_alpha && !LLPipeline::sRenderDeferred)
|
||||
{
|
||||
llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);
|
||||
facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE);
|
||||
|
||||
if (!force_simple && te->getBumpmap())
|
||||
if (!force_simple && te->getBumpmap() && LLPipeline::sRenderBump)
|
||||
{
|
||||
registerFace(group, facep, LLRenderPass::PASS_BUMP);
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ public:
|
||||
|
||||
public:
|
||||
LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
|
||||
/*virtual*/ void markDead(); // Override (and call through to parent) to clean up media references
|
||||
|
||||
/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
|
||||
|
||||
|
||||
@@ -69,8 +69,9 @@ const U32 WIDTH = (N_RES * WAVE_STEP); //128.f //64 // width of wave tile, in
|
||||
const F32 WAVE_STEP_INV = (1. / WAVE_STEP);
|
||||
|
||||
|
||||
LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
|
||||
: LLStaticViewerObject(id, pcode, regionp)
|
||||
LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) :
|
||||
LLStaticViewerObject(id, pcode, regionp),
|
||||
mRenderType(LLPipeline::RENDER_TYPE_WATER)
|
||||
{
|
||||
// Terrain must draw during selection passes so it can block objects behind it.
|
||||
mbCanSelect = FALSE;
|
||||
@@ -78,9 +79,9 @@ LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regi
|
||||
|
||||
mUseTexture = TRUE;
|
||||
mIsEdgePatch = FALSE;
|
||||
mRenderType = LLPipeline::RENDER_TYPE_WATER;
|
||||
}
|
||||
|
||||
|
||||
void LLVOWater::markDead()
|
||||
{
|
||||
LLViewerObject::markDead();
|
||||
@@ -281,9 +282,8 @@ U32 LLVOVoidWater::getPartitionType() const
|
||||
}
|
||||
|
||||
LLWaterPartition::LLWaterPartition()
|
||||
: LLSpatialPartition(0)
|
||||
: LLSpatialPartition(0, FALSE, 0)
|
||||
{
|
||||
mRenderByGroup = FALSE;
|
||||
mInfiniteFarClip = TRUE;
|
||||
mDrawableType = LLPipeline::RENDER_TYPE_WATER;
|
||||
mPartitionType = LLViewerRegion::PARTITION_WATER;
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
/*virtual*/ void updateTextures();
|
||||
/*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area
|
||||
|
||||
/*virtual*/ U32 getPartitionType() const;
|
||||
virtual U32 getPartitionType() const;
|
||||
|
||||
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
|
||||
|
||||
|
||||
@@ -49,12 +49,12 @@ const U32 LLVOWLSky::MAX_SKY_DETAIL = 180;
|
||||
|
||||
inline U32 LLVOWLSky::getNumStacks(void)
|
||||
{
|
||||
return gSavedSettings.getU32("WLSkyDetail");
|
||||
return llmin(MAX_SKY_DETAIL, llmax(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail")));
|
||||
}
|
||||
|
||||
inline U32 LLVOWLSky::getNumSlices(void)
|
||||
{
|
||||
return 2 * gSavedSettings.getU32("WLSkyDetail");
|
||||
return 2 * llmin(MAX_SKY_DETAIL, llmax(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail")));
|
||||
}
|
||||
|
||||
inline U32 LLVOWLSky::getFanNumVerts(void)
|
||||
@@ -489,7 +489,7 @@ void LLVOWLSky::drawStars(void)
|
||||
if (mStarsVerts.notNull())
|
||||
{
|
||||
mStarsVerts->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK);
|
||||
mStarsVerts->draw(LLRender::POINTS, getStarsNumIndices(), 0);
|
||||
mStarsVerts->drawArrays(LLRender::QUADS, 0, getStarsNumVerts()*4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -769,17 +769,17 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)
|
||||
{
|
||||
LLStrider<LLVector3> verticesp;
|
||||
LLStrider<LLColor4U> colorsp;
|
||||
LLStrider<U16> indicesp;
|
||||
LLStrider<LLVector2> texcoordsp;
|
||||
|
||||
if (mStarsVerts.isNull())
|
||||
{
|
||||
mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW);
|
||||
mStarsVerts->allocateBuffer(getStarsNumVerts(), getStarsNumIndices(), TRUE);
|
||||
mStarsVerts->allocateBuffer(getStarsNumVerts()*4, 0, TRUE);
|
||||
}
|
||||
|
||||
BOOL success = mStarsVerts->getVertexStrider(verticesp)
|
||||
&& mStarsVerts->getIndexStrider(indicesp)
|
||||
&& mStarsVerts->getColorStrider(colorsp);
|
||||
&& mStarsVerts->getColorStrider(colorsp)
|
||||
&& mStarsVerts->getTexCoord0Strider(texcoordsp);
|
||||
|
||||
if(!success)
|
||||
{
|
||||
@@ -789,11 +789,37 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)
|
||||
// *TODO: fix LLStrider with a real prefix increment operator so it can be
|
||||
// used as a model of OutputIterator. -Brad
|
||||
// std::copy(mStarVertices.begin(), mStarVertices.end(), verticesp);
|
||||
|
||||
if (mStarVertices.size() < getStarsNumVerts())
|
||||
{
|
||||
llerrs << "Star reference geometry insufficient." << llendl;
|
||||
}
|
||||
|
||||
for (U32 vtx = 0; vtx < getStarsNumVerts(); ++vtx)
|
||||
{
|
||||
LLVector3 at = mStarVertices[vtx];
|
||||
at.normVec();
|
||||
LLVector3 left = at%LLVector3(0,0,1);
|
||||
LLVector3 up = at%left;
|
||||
|
||||
F32 sc = 0.5f+ll_frand()*1.25f;
|
||||
left *= sc;
|
||||
up *= sc;
|
||||
|
||||
*(verticesp++) = mStarVertices[vtx];
|
||||
*(verticesp++) = mStarVertices[vtx]+left;
|
||||
*(verticesp++) = mStarVertices[vtx]+left+up;
|
||||
*(verticesp++) = mStarVertices[vtx]+up;
|
||||
|
||||
*(texcoordsp++) = LLVector2(0,0);
|
||||
*(texcoordsp++) = LLVector2(0,1);
|
||||
*(texcoordsp++) = LLVector2(1,1);
|
||||
*(texcoordsp++) = LLVector2(1,0);
|
||||
|
||||
*(colorsp++) = LLColor4U(mStarColors[vtx]);
|
||||
*(colorsp++) = LLColor4U(mStarColors[vtx]);
|
||||
*(colorsp++) = LLColor4U(mStarColors[vtx]);
|
||||
*(colorsp++) = LLColor4U(mStarColors[vtx]);
|
||||
*(indicesp++) = vtx;
|
||||
}
|
||||
|
||||
mStarsVerts->setBuffer(0);
|
||||
|
||||
@@ -301,7 +301,7 @@ void LLWaterParamManager::update(LLViewerCamera * cam)
|
||||
mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
|
||||
|
||||
LLVector3 sunMoonDir;
|
||||
if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS)
|
||||
if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS)
|
||||
{
|
||||
sunMoonDir = gSky.getSunDirection();
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ void LLWLParamManager::propagateParameters(void)
|
||||
{
|
||||
mLightDir = sunDir;
|
||||
}
|
||||
else if(sunDir.mV[1] < 0 && sunDir.mV[1] > NIGHTTIME_ELEVATION_COS)
|
||||
else if(sunDir.mV[1] < 0 && sunDir.mV[1] > LLSky::NIGHTTIME_ELEVATION_COS)
|
||||
{
|
||||
// clamp v1 to 0 so sun never points up and causes weirdness on some machines
|
||||
LLVector3 vec(sunDir.mV[0], sunDir.mV[1], sunDir.mV[2]);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -46,6 +46,8 @@
|
||||
#include "lldrawable.h"
|
||||
#include "llrendertarget.h"
|
||||
|
||||
#include <stack>
|
||||
|
||||
class LLViewerImage;
|
||||
class LLEdge;
|
||||
class LLFace;
|
||||
@@ -94,6 +96,7 @@ public:
|
||||
|
||||
void resetVertexBuffers(LLDrawable* drawable);
|
||||
void setUseVBO(BOOL use_vbo);
|
||||
void setDisableVBOMapping(BOOL no_vbo_mapping);
|
||||
void generateImpostor(LLVOAvatar* avatar);
|
||||
void bindScreenToTexture();
|
||||
void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0);
|
||||
@@ -129,6 +132,8 @@ public:
|
||||
void markMoved(LLDrawable *drawablep, BOOL damped_motion = FALSE);
|
||||
void markShift(LLDrawable *drawablep);
|
||||
void markTextured(LLDrawable *drawablep);
|
||||
void markGLRebuild(LLGLUpdate* glu);
|
||||
void markRebuild(LLSpatialGroup* group, BOOL priority = FALSE);
|
||||
void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE);
|
||||
|
||||
//get the object between start and end that's closest to start.
|
||||
@@ -179,10 +184,14 @@ public:
|
||||
void updateMove();
|
||||
BOOL visibleObjectsInFrustum(LLCamera& camera);
|
||||
BOOL getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max);
|
||||
BOOL getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0));
|
||||
void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane
|
||||
void createObjects(F32 max_dtime);
|
||||
void createObject(LLViewerObject* vobj);
|
||||
void updateGeom(F32 max_dtime);
|
||||
void updateGL();
|
||||
void rebuildPriorityGroups();
|
||||
void rebuildGroups();
|
||||
|
||||
//calculate pixel area of given box from vantage point of given camera
|
||||
static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera);
|
||||
@@ -234,8 +243,7 @@ public:
|
||||
void shiftObjects(const LLVector3 &offset);
|
||||
|
||||
void setLight(LLDrawable *drawablep, BOOL is_light);
|
||||
void setActive(LLDrawable *drawablep, BOOL active);
|
||||
|
||||
|
||||
BOOL hasRenderBatches(const U32 type) const;
|
||||
LLCullResult::drawinfo_list_t::iterator beginRenderMap(U32 type);
|
||||
LLCullResult::drawinfo_list_t::iterator endRenderMap(U32 type);
|
||||
@@ -243,11 +251,20 @@ public:
|
||||
LLCullResult::sg_list_t::iterator endAlphaGroups();
|
||||
|
||||
void addTrianglesDrawn(S32 count);
|
||||
BOOL hasRenderType(const U32 type) const { return (type && (mRenderTypeMask & (1<<type))) ? TRUE : FALSE; }
|
||||
|
||||
BOOL hasRenderDebugFeatureMask(const U32 mask) const { return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; }
|
||||
BOOL hasRenderDebugMask(const U32 mask) const { return (mRenderDebugMask & mask) ? TRUE : FALSE; }
|
||||
void setRenderTypeMask(const U32 mask) { mRenderTypeMask = mask; }
|
||||
U32 getRenderTypeMask() const { return mRenderTypeMask; }
|
||||
BOOL hasRenderType(const U32 type) const;
|
||||
BOOL hasAnyRenderType(const U32 type, ...) const;
|
||||
|
||||
void setRenderTypeMask(U32 type, ...);
|
||||
void orRenderTypeMask(U32 type, ...);
|
||||
void andRenderTypeMask(U32 type, ...);
|
||||
void clearRenderTypeMask(U32 type, ...);
|
||||
|
||||
void pushRenderTypeMask();
|
||||
void popRenderTypeMask();
|
||||
|
||||
static void toggleRenderType(U32 type);
|
||||
|
||||
// For UI control of render features
|
||||
@@ -317,17 +334,31 @@ public:
|
||||
RENDER_TYPE_TREE = LLDrawPool::POOL_TREE,
|
||||
RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE,
|
||||
RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER,
|
||||
RENDER_TYPE_WATER = LLDrawPool::POOL_WATER,
|
||||
RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA,
|
||||
RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW,
|
||||
|
||||
RENDER_TYPE_WATER = LLDrawPool::POOL_WATER,
|
||||
RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA,
|
||||
RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW,
|
||||
RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE,
|
||||
RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS,
|
||||
RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT,
|
||||
RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE,
|
||||
RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY,
|
||||
RENDER_TYPE_PASS_FULLBRIGHT_SHINY = LLRenderPass::PASS_FULLBRIGHT_SHINY,
|
||||
RENDER_TYPE_PASS_SHINY = LLRenderPass::PASS_SHINY,
|
||||
RENDER_TYPE_PASS_BUMP = LLRenderPass::PASS_BUMP,
|
||||
RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW,
|
||||
RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA,
|
||||
RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK,
|
||||
RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK,
|
||||
RENDER_TYPE_PASS_ALPHA_SHADOW = LLRenderPass::PASS_ALPHA_SHADOW,
|
||||
// Following are object types (only used in drawable mRenderType)
|
||||
RENDER_TYPE_HUD = LLDrawPool::NUM_POOL_TYPES,
|
||||
RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,
|
||||
RENDER_TYPE_VOLUME,
|
||||
RENDER_TYPE_PARTICLES,
|
||||
RENDER_TYPE_WL_CLOUDS,
|
||||
RENDER_TYPE_CLASSIC_CLOUDS,
|
||||
RENDER_TYPE_HUD_PARTICLES
|
||||
RENDER_TYPE_HUD_PARTICLES,
|
||||
NUM_RENDER_TYPES,
|
||||
END_RENDER_TYPES = NUM_RENDER_TYPES
|
||||
};
|
||||
|
||||
enum LLRenderDebugFeatureMask
|
||||
@@ -420,7 +451,9 @@ public:
|
||||
static BOOL sRenderAttachedLights;
|
||||
static BOOL sRenderAttachedParticles;
|
||||
static BOOL sRenderDeferred;
|
||||
static BOOL sAllowRebuildPriorityGroup;
|
||||
static S32 sVisibleLightCount;
|
||||
static F32 sMinRenderSize;
|
||||
|
||||
//screen texture
|
||||
LLRenderTarget mScreen;
|
||||
@@ -457,7 +490,9 @@ public:
|
||||
S32 mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed
|
||||
|
||||
protected:
|
||||
U32 mRenderTypeMask;
|
||||
BOOL mRenderTypeEnabled[NUM_RENDER_TYPES];
|
||||
std::stack<std::string> mRenderTypeEnableStack;
|
||||
|
||||
U32 mRenderDebugFeatureMask;
|
||||
U32 mRenderDebugMask;
|
||||
|
||||
@@ -508,10 +543,10 @@ protected:
|
||||
//
|
||||
LLDrawable::drawable_list_t mBuildQ1; // priority
|
||||
LLDrawable::drawable_list_t mBuildQ2; // non-priority
|
||||
LLSpatialGroup::sg_vector_t mGroupQ1; //priority
|
||||
LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority
|
||||
LLViewerObject::vobj_list_t mCreateQ;
|
||||
|
||||
LLDrawable::drawable_set_t mActiveQ;
|
||||
|
||||
LLDrawable::drawable_set_t mRetexturedList;
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user