Rigged attachment integration WIP.
parent
d71716aa6d
commit
f324787a70
|
|
@ -124,7 +124,7 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
|
|||
{
|
||||
GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second);
|
||||
LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
|
||||
if (mShaderLevel > 0)
|
||||
if (shaderhandle > 0)
|
||||
{
|
||||
attachObject(shaderhandle);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ void main()
|
|||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
|
||||
vary_normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
vary_nomral = normalize(gl_NormalMatrix * gl_Normal);
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,11 +248,6 @@ void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures
|
|||
{
|
||||
}
|
||||
|
||||
BOOL LLFacePool::moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
S32 LLFacePool::drawLoop(face_array_t& face_list)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -187,8 +187,6 @@ public:
|
|||
virtual void resetDrawOrders();
|
||||
void resetAll();
|
||||
|
||||
BOOL moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data = FALSE);
|
||||
|
||||
void destroy();
|
||||
|
||||
void buildEdges();
|
||||
|
|
|
|||
|
|
@ -39,13 +39,17 @@
|
|||
#include "m3math.h"
|
||||
|
||||
#include "lldrawable.h"
|
||||
#include "lldrawpoolbump.h"
|
||||
#include "llface.h"
|
||||
#include "llmeshrepository.h"
|
||||
#include "llsky.h"
|
||||
#include "llviewercamera.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "noise.h"
|
||||
#include "pipeline.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llvovolume.h"
|
||||
#include "llvolume.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llrendersphere.h"
|
||||
#include "llviewerpartsim.h"
|
||||
|
|
@ -94,6 +98,8 @@ static BOOL sRenderingSkinned = FALSE;
|
|||
S32 normal_channel = -1;
|
||||
S32 specular_channel = -1;
|
||||
S32 diffuse_channel = -1;
|
||||
S32 cube_channel = -1;
|
||||
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_SHADOW_AVATAR("Avatar Shadow");
|
||||
|
||||
|
|
@ -358,7 +364,7 @@ S32 LLDrawPoolAvatar::getNumPasses()
|
|||
}
|
||||
else if (getVertexShaderLevel() > 0)
|
||||
{
|
||||
return 4;
|
||||
return 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -402,7 +408,10 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)
|
|||
beginSkinned();
|
||||
break;
|
||||
case 3:
|
||||
beginRigged();
|
||||
beginRiggedSimple();
|
||||
break;
|
||||
case 4:
|
||||
beginRiggedShinySimple();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -429,7 +438,10 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)
|
|||
endSkinned();
|
||||
break;
|
||||
case 3:
|
||||
endRigged();
|
||||
endRiggedSimple();
|
||||
break;
|
||||
case 4:
|
||||
endRiggedShinySimple();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -616,14 +628,15 @@ void LLDrawPoolAvatar::endSkinned()
|
|||
gGL.getTexUnit(0)->activate();
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::beginRigged()
|
||||
void LLDrawPoolAvatar::beginRiggedSimple()
|
||||
{
|
||||
sVertexProgram = &gSkinnedObjectSimpleProgram;
|
||||
diffuse_channel = 0;
|
||||
gSkinnedObjectSimpleProgram.bind();
|
||||
LLVertexBuffer::sWeight4Loc = gSkinnedObjectSimpleProgram.getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT);
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::endRigged()
|
||||
void LLDrawPoolAvatar::endRiggedSimple()
|
||||
{
|
||||
sVertexProgram = NULL;
|
||||
LLVertexBuffer::unbind();
|
||||
|
|
@ -631,6 +644,23 @@ void LLDrawPoolAvatar::endRigged()
|
|||
LLVertexBuffer::sWeight4Loc = -1;
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::beginRiggedShinySimple()
|
||||
{
|
||||
sVertexProgram = &gSkinnedObjectShinySimpleProgram;
|
||||
sVertexProgram->bind();
|
||||
LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, diffuse_channel, cube_channel, false);
|
||||
LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT);
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::endRiggedShinySimple()
|
||||
{
|
||||
LLVertexBuffer::unbind();
|
||||
LLDrawPoolBump::unbindCubeMap(sVertexProgram, 2, diffuse_channel, cube_channel, false);
|
||||
sVertexProgram->unbind();
|
||||
sVertexProgram = NULL;
|
||||
LLVertexBuffer::sWeight4Loc = -1;
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::beginDeferredRigged()
|
||||
{
|
||||
sVertexProgram = &gDeferredSkinnedDiffuseProgram;
|
||||
|
|
@ -790,9 +820,16 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 3)
|
||||
{
|
||||
avatarp->renderSkinnedAttachments();
|
||||
renderRiggedSimple(avatarp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pass == 4)
|
||||
{
|
||||
renderRiggedShinySimple(avatarp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (sShaderLevel > 0)
|
||||
{
|
||||
|
|
@ -830,13 +867,146 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face, U32 data_mask)
|
||||
{
|
||||
LLVertexBuffer* buff = face->mVertexBuffer;
|
||||
|
||||
if (!buff ||
|
||||
!buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) ||
|
||||
buff->getRequestedVerts() != vol_face.mVertices.size())
|
||||
{
|
||||
face->setGeomIndex(0);
|
||||
face->setIndicesIndex(0);
|
||||
face->setSize(vol_face.mVertices.size(), vol_face.mIndices.size());
|
||||
|
||||
face->mVertexBuffer = new LLVertexBuffer(data_mask, 0);
|
||||
face->mVertexBuffer->allocateBuffer(vol_face.mVertices.size(), vol_face.mIndices.size(), true);
|
||||
|
||||
U16 offset = 0;
|
||||
|
||||
LLMatrix4 mat_vert = skin->mBindShapeMatrix;
|
||||
glh::matrix4f m((F32*) mat_vert.mMatrix);
|
||||
m = m.inverse().transpose();
|
||||
|
||||
F32 mat3[] =
|
||||
{ m.m[0], m.m[1], m.m[2],
|
||||
m.m[4], m.m[5], m.m[6],
|
||||
m.m[8], m.m[9], m.m[10] };
|
||||
|
||||
LLMatrix3 mat_normal(mat3);
|
||||
|
||||
face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
|
||||
buff = face->mVertexBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, const U32 data_mask)
|
||||
{
|
||||
for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
|
||||
{
|
||||
LLFace* face = mRiggedFace[type][i];
|
||||
LLDrawable* drawable = face->getDrawable();
|
||||
if (!drawable)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LLVOVolume* vobj = drawable->getVOVolume();
|
||||
|
||||
if (!vobj)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LLVolume* volume = vobj->getVolume();
|
||||
S32 te = face->getTEOffset();
|
||||
|
||||
if (!volume || volume->getNumVolumeFaces() <= te)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LLUUID mesh_id = volume->getParams().getSculptID();
|
||||
if (mesh_id.isNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id);
|
||||
if (!skin)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const LLVolumeFace& vol_face = volume->getVolumeFace(te);
|
||||
updateRiggedFaceVertexBuffer(face, skin, volume, vol_face, data_mask);
|
||||
|
||||
LLVertexBuffer* buff = face->mVertexBuffer;
|
||||
|
||||
if (buff)
|
||||
{
|
||||
LLMatrix4 mat[64];
|
||||
|
||||
for (U32 i = 0; i < skin->mJointNames.size(); ++i)
|
||||
{
|
||||
LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);
|
||||
if (joint)
|
||||
{
|
||||
mat[i] = skin->mInvBindMatrix[i];
|
||||
mat[i] *= joint->getWorldMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette",
|
||||
skin->mJointNames.size(),
|
||||
FALSE,
|
||||
(GLfloat*) mat[0].mMatrix);
|
||||
LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette[0]",
|
||||
skin->mJointNames.size(),
|
||||
FALSE,
|
||||
(GLfloat*) mat[0].mMatrix);
|
||||
|
||||
buff->setBuffer(data_mask);
|
||||
|
||||
U16 start = face->getGeomStart();
|
||||
U16 end = start + face->getGeomCount()-1;
|
||||
S32 offset = face->getIndicesStart();
|
||||
U32 count = face->getIndicesCount();
|
||||
|
||||
gGL.getTexUnit(0)->bind(face->getTexture());
|
||||
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar)
|
||||
{
|
||||
const U32 data_mask = LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_NORMAL |
|
||||
LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
LLVertexBuffer::MAP_COLOR |
|
||||
LLVertexBuffer::MAP_WEIGHT4;
|
||||
|
||||
renderRigged(avatar, RIGGED_SIMPLE, data_mask);
|
||||
}
|
||||
|
||||
|
||||
void LLDrawPoolAvatar::renderRiggedShinySimple(LLVOAvatar* avatar)
|
||||
{
|
||||
const U32 data_mask = LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_NORMAL |
|
||||
LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
LLVertexBuffer::MAP_COLOR |
|
||||
LLVertexBuffer::MAP_WEIGHT4;
|
||||
|
||||
renderRigged(avatar, RIGGED_SHINY_SIMPLE, data_mask);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// renderForSelect()
|
||||
//-----------------------------------------------------------------------------
|
||||
void LLDrawPoolAvatar::renderForSelect()
|
||||
{
|
||||
|
||||
|
||||
if (mDrawFace.empty())
|
||||
{
|
||||
return;
|
||||
|
|
@ -930,6 +1100,64 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
|
|||
return LLColor3(0.f, 1.f, 0.f);
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
|
||||
{
|
||||
if (facep->getReferenceIndex() != -1)
|
||||
{
|
||||
llerrs << "Tried to add a rigged face that's referenced elsewhere." << llendl;
|
||||
}
|
||||
|
||||
if (type >= NUM_RIGGED_PASSES)
|
||||
{
|
||||
llerrs << "Invalid rigged face type." << llendl;
|
||||
}
|
||||
|
||||
facep->setReferenceIndex(mRiggedFace[type].size());
|
||||
facep->mDrawPoolp = this;
|
||||
mRiggedFace[type].push_back(facep);
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep, U32 type)
|
||||
{
|
||||
S32 index = facep->getReferenceIndex();
|
||||
if (index == -1)
|
||||
{
|
||||
llerrs << "Tried to remove rigged face with invalid index." << llendl;
|
||||
}
|
||||
|
||||
if (type > RIGGED_UNKNOWN)
|
||||
{
|
||||
llerrs << "Invalid rigged face type." << llendl;
|
||||
}
|
||||
|
||||
facep->setReferenceIndex(-1);
|
||||
facep->mDrawPoolp = NULL;
|
||||
|
||||
if (type == RIGGED_UNKNOWN)
|
||||
{
|
||||
for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i)
|
||||
{
|
||||
if (mRiggedFace[i].size() > index && mRiggedFace[i][index] == facep)
|
||||
{
|
||||
type = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type >= NUM_RIGGED_PASSES)
|
||||
{
|
||||
llerrs << "Could not find face for removal from current drawpool." << llendl;
|
||||
}
|
||||
|
||||
mRiggedFace[type].erase(mRiggedFace[type].begin()+index);
|
||||
|
||||
for (S32 i = index; i < mRiggedFace[type].size(); ++i)
|
||||
{ //bump indexes of currently held faces down after removal
|
||||
mRiggedFace[type][i]->setReferenceIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
LLVertexBufferAvatar::LLVertexBufferAvatar()
|
||||
: LLVertexBuffer(sDataMask,
|
||||
GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets
|
||||
|
|
|
|||
|
|
@ -37,6 +37,11 @@
|
|||
|
||||
class LLVOAvatar;
|
||||
class LLGLSLShader;
|
||||
class LLFace;
|
||||
class LLMeshSkinInfo;
|
||||
class LLVolume;
|
||||
class LLVolumeFace;
|
||||
|
||||
|
||||
class LLDrawPoolAvatar : public LLFacePool
|
||||
{
|
||||
|
|
@ -91,12 +96,14 @@ public:
|
|||
void beginRigid();
|
||||
void beginImpostor();
|
||||
void beginSkinned();
|
||||
void beginRigged();
|
||||
|
||||
void beginRiggedSimple();
|
||||
void beginRiggedShinySimple();
|
||||
|
||||
void endRigid();
|
||||
void endImpostor();
|
||||
void endSkinned();
|
||||
void endRigged();
|
||||
void endRiggedSimple();
|
||||
void endRiggedShinySimple();
|
||||
|
||||
void beginDeferredImpostor();
|
||||
void beginDeferredRigid();
|
||||
|
|
@ -108,11 +115,40 @@ public:
|
|||
void endDeferredSkinned();
|
||||
void endDeferredRigged();
|
||||
|
||||
void updateRiggedFaceVertexBuffer(LLFace* facep,
|
||||
const LLMeshSkinInfo* skin,
|
||||
LLVolume* volume,
|
||||
const LLVolumeFace& vol_face,
|
||||
U32 data_mask);
|
||||
|
||||
void renderRigged(LLVOAvatar* avatar, U32 type, const U32 data_mask);
|
||||
void renderRiggedSimple(LLVOAvatar* avatar);
|
||||
void renderRiggedShinySimple(LLVOAvatar* avatar);
|
||||
|
||||
/*virtual*/ LLViewerTexture *getDebugTexture();
|
||||
/*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
|
||||
|
||||
void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null.
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RIGGED_SIMPLE = 0,
|
||||
RIGGED_SHINY_SIMPLE,
|
||||
RIGGED_SHINY_FULLBRIGHT,
|
||||
RIGGED_SHINY_BUMP,
|
||||
RIGGED_BUMP,
|
||||
RIGGED_FULLBRIGHT,
|
||||
RIGGED_ALPHA,
|
||||
NUM_RIGGED_PASSES,
|
||||
RIGGED_UNKNOWN,
|
||||
} eRiggedPass;
|
||||
|
||||
|
||||
void addRiggedFace(LLFace* facep, U32 type);
|
||||
void removeRiggedFace(LLFace* facep, U32 type = RIGGED_UNKNOWN);
|
||||
|
||||
std::vector<LLFace*> mRiggedFace[NUM_RIGGED_PASSES];
|
||||
|
||||
static BOOL sSkipOpaque;
|
||||
static BOOL sSkipTransparent;
|
||||
static LLGLSLShader* sVertexProgram;
|
||||
|
|
|
|||
|
|
@ -323,30 +323,43 @@ void LLDrawPoolBump::beginShiny(bool invisible)
|
|||
sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
|
||||
}
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
if (getVertexShaderLevel() > 0)
|
||||
{
|
||||
shader = &gObjectShinyWaterProgram;
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
shader = &gObjectShinyWaterProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = &gObjectShinyProgram;
|
||||
}
|
||||
shader->bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = &gObjectShinyProgram;
|
||||
shader = NULL;
|
||||
}
|
||||
|
||||
bindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible);
|
||||
}
|
||||
|
||||
//static
|
||||
void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible)
|
||||
{
|
||||
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
|
||||
if( cube_map )
|
||||
{
|
||||
if (!invisible && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0 )
|
||||
if (!invisible && shader )
|
||||
{
|
||||
LLMatrix4 mat;
|
||||
mat.initRows(LLVector4(gGLModelView+0),
|
||||
LLVector4(gGLModelView+4),
|
||||
LLVector4(gGLModelView+8),
|
||||
LLVector4(gGLModelView+12));
|
||||
shader->bind();
|
||||
LLVector3 vec = LLVector3(gShinyOrigin) * mat;
|
||||
LLVector4 vec4(vec, gShinyOrigin.mV[3]);
|
||||
shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
|
||||
if (mVertexShaderLevel > 1)
|
||||
if (shader_level > 1)
|
||||
{
|
||||
cube_map->setMatrix(1);
|
||||
// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
|
||||
|
|
@ -408,22 +421,16 @@ void LLDrawPoolBump::renderShiny(bool invisible)
|
|||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolBump::endShiny(bool invisible)
|
||||
//static
|
||||
void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_SHINY);
|
||||
if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||
|
||||
(invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
|
||||
if( cube_map )
|
||||
{
|
||||
cube_map->disable();
|
||||
cube_map->restoreMatrix();
|
||||
|
||||
if (!invisible && mVertexShaderLevel > 1)
|
||||
if (!invisible && shader_level > 1)
|
||||
{
|
||||
shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
|
||||
|
||||
|
|
@ -434,7 +441,6 @@ void LLDrawPoolBump::endShiny(bool invisible)
|
|||
shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
|
||||
}
|
||||
}
|
||||
shader->unbind();
|
||||
}
|
||||
}
|
||||
gGL.getTexUnit(diffuse_channel)->disable();
|
||||
|
|
@ -442,6 +448,22 @@ void LLDrawPoolBump::endShiny(bool invisible)
|
|||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
|
||||
}
|
||||
|
||||
void LLDrawPoolBump::endShiny(bool invisible)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_SHINY);
|
||||
if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||
|
||||
(invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unbindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible);
|
||||
if (shader)
|
||||
{
|
||||
shader->unbind();
|
||||
}
|
||||
|
||||
diffuse_channel = -1;
|
||||
cube_channel = 0;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
class LLImageRaw;
|
||||
class LLSpatialGroup;
|
||||
class LLDrawInfo;
|
||||
class LLGLSLShader;
|
||||
class LLViewerFetchedTexture;
|
||||
|
||||
class LLDrawPoolBump : public LLRenderPass
|
||||
|
|
@ -79,6 +80,9 @@ public:
|
|||
void renderBump();
|
||||
void endBump();
|
||||
|
||||
static void bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible);
|
||||
static void unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible);
|
||||
|
||||
virtual S32 getNumDeferredPasses();
|
||||
/*virtual*/ void beginDeferredPass(S32 pass);
|
||||
/*virtual*/ void endDeferredPass(S32 pass);
|
||||
|
|
|
|||
|
|
@ -205,7 +205,12 @@ void LLFace::destroy()
|
|||
if (mDrawPoolp)
|
||||
{
|
||||
LLFastTimer t(FTM_DESTROY_DRAWPOOL);
|
||||
|
||||
if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR)
|
||||
mDrawPoolp->removeFace(this);
|
||||
|
||||
|
||||
|
||||
mDrawPoolp = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -234,6 +234,7 @@ public:
|
|||
private:
|
||||
friend class LLGeometryManager;
|
||||
friend class LLVolumeGeometryManager;
|
||||
friend class LLDrawPoolAvatar;
|
||||
|
||||
U32 mState;
|
||||
LLFacePool* mDrawPoolp;
|
||||
|
|
|
|||
|
|
@ -5219,6 +5219,25 @@ void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplif
|
|||
return ;
|
||||
}
|
||||
|
||||
//virtual
|
||||
LLVOAvatar* LLViewerObject::getAvatar() const
|
||||
{
|
||||
if (isAttachment())
|
||||
{
|
||||
LLViewerObject* vobj = (LLViewerObject*) getParent();
|
||||
|
||||
while (vobj && !vobj->asAvatar())
|
||||
{
|
||||
vobj = (LLViewerObject*) vobj->getParent();
|
||||
}
|
||||
|
||||
return (LLVOAvatar*) vobj;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
class ObjectPhysicsProperties : public LLHTTPNode
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -181,6 +181,7 @@ public:
|
|||
void setOnActiveList(BOOL on_active) { mOnActiveList = on_active; }
|
||||
|
||||
virtual BOOL isAttachment() const { return FALSE; }
|
||||
virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment
|
||||
virtual BOOL isHUDAttachment() const { return FALSE; }
|
||||
virtual void updateRadius() {};
|
||||
virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius()
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ LLGLSLShader gObjectShinyWaterProgram;
|
|||
|
||||
//object hardware skinning shaders
|
||||
LLGLSLShader gSkinnedObjectSimpleProgram;
|
||||
LLGLSLShader gSkinnedObjectShinySimpleProgram;
|
||||
|
||||
//environment shaders
|
||||
LLGLSLShader gTerrainProgram;
|
||||
|
|
@ -154,6 +155,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
|
|||
mShaderList.push_back(&gObjectFullbrightProgram);
|
||||
mShaderList.push_back(&gObjectFullbrightShinyProgram);
|
||||
mShaderList.push_back(&gSkinnedObjectSimpleProgram);
|
||||
mShaderList.push_back(&gSkinnedObjectShinySimpleProgram);
|
||||
mShaderList.push_back(&gTerrainProgram);
|
||||
mShaderList.push_back(&gTerrainWaterProgram);
|
||||
mShaderList.push_back(&gObjectSimpleWaterProgram);
|
||||
|
|
@ -505,6 +507,9 @@ void LLViewerShaderMgr::setShaders()
|
|||
if (!loadShadersDeferred())
|
||||
{
|
||||
gSavedSettings.setBOOL("RenderDeferred", FALSE);
|
||||
reentrance = false;
|
||||
setShaders();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -557,6 +562,8 @@ void LLViewerShaderMgr::unloadShaders()
|
|||
gObjectShinyWaterProgram.unload();
|
||||
|
||||
gSkinnedObjectSimpleProgram.unload();
|
||||
gSkinnedObjectShinySimpleProgram.unload();
|
||||
|
||||
|
||||
gWaterProgram.unload();
|
||||
gUnderWaterProgram.unload();
|
||||
|
|
@ -917,7 +924,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
|
|||
gDeferredGIProgram.unload();
|
||||
gDeferredGIFinalProgram.unload();
|
||||
gDeferredWaterProgram.unload();
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
mVertexShaderLevel[SHADER_AVATAR] = 1;
|
||||
|
|
@ -1251,6 +1258,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
|
|||
gObjectFullbrightProgram.unload();
|
||||
gObjectFullbrightWaterProgram.unload();
|
||||
gSkinnedObjectSimpleProgram.unload();
|
||||
gSkinnedObjectShinySimpleProgram.unload();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -1376,6 +1385,22 @@ BOOL LLViewerShaderMgr::loadShadersObject()
|
|||
success = gSkinnedObjectSimpleProgram.createShader(NULL, NULL);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
gSkinnedObjectShinySimpleProgram.mName = "Skinned Shiny Simple Shader";
|
||||
gSkinnedObjectShinySimpleProgram.mFeatures.calculatesLighting = true;
|
||||
gSkinnedObjectShinySimpleProgram.mFeatures.calculatesAtmospherics = true;
|
||||
gSkinnedObjectShinySimpleProgram.mFeatures.hasGamma = true;
|
||||
gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true;
|
||||
gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true;
|
||||
gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true;
|
||||
gSkinnedObjectShinySimpleProgram.mShaderFiles.clear();
|
||||
gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
|
||||
gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
|
||||
gSkinnedObjectShinySimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
|
||||
success = gSkinnedObjectShinySimpleProgram.createShader(NULL, &mShinyUniforms);
|
||||
}
|
||||
|
||||
if( !success )
|
||||
{
|
||||
mVertexShaderLevel[SHADER_OBJECT] = 0;
|
||||
|
|
|
|||
|
|
@ -315,6 +315,7 @@ extern LLGLSLShader gObjectShinyProgram;
|
|||
extern LLGLSLShader gObjectShinyWaterProgram;
|
||||
|
||||
extern LLGLSLShader gSkinnedObjectSimpleProgram;
|
||||
extern LLGLSLShader gSkinnedObjectShinySimpleProgram;
|
||||
|
||||
//environment shaders
|
||||
extern LLGLSLShader gTerrainProgram;
|
||||
|
|
|
|||
|
|
@ -3642,7 +3642,7 @@ bool LLVOAvatar::shouldAlphaMask()
|
|||
|
||||
U32 LLVOAvatar::renderSkinnedAttachments()
|
||||
{
|
||||
U32 num_indices = 0;
|
||||
/*U32 num_indices = 0;
|
||||
|
||||
const U32 data_mask = LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_NORMAL |
|
||||
|
|
@ -3670,107 +3670,14 @@ U32 LLVOAvatar::renderSkinnedAttachments()
|
|||
LLFace* face = drawable->getFace(i);
|
||||
if (face->isState(LLFace::RIGGED))
|
||||
{
|
||||
LLVolume* volume = attached_object->getVolume();
|
||||
if (!volume || volume->getNumVolumeFaces() <= i)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const LLVolumeFace& vol_face = volume->getVolumeFace(i);
|
||||
|
||||
const LLMeshSkinInfo* skin = NULL;
|
||||
LLVertexBuffer* buff = face->mVertexBuffer;
|
||||
LLUUID mesh_id = volume->getParams().getSculptID();;
|
||||
|
||||
if (!buff ||
|
||||
!buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) ||
|
||||
buff->getRequestedVerts() != vol_face.mVertices.size())
|
||||
{
|
||||
face->mVertexBuffer = NULL;
|
||||
face->mLastVertexBuffer = NULL;
|
||||
buff = NULL;
|
||||
|
||||
if (mesh_id.notNull())
|
||||
{
|
||||
skin = gMeshRepo.getSkinInfo(mesh_id);
|
||||
if (skin)
|
||||
{
|
||||
face->mVertexBuffer = new LLVertexBuffer(data_mask, 0);
|
||||
face->mVertexBuffer->allocateBuffer(vol_face.mVertices.size(), vol_face.mIndices.size(), true);
|
||||
|
||||
face->setGeomIndex(0);
|
||||
face->setIndicesIndex(0);
|
||||
face->setSize(vol_face.mVertices.size(), vol_face.mIndices.size());
|
||||
|
||||
U16 offset = 0;
|
||||
|
||||
LLMatrix4 mat_vert = skin->mBindShapeMatrix;
|
||||
glh::matrix4f m((F32*) mat_vert.mMatrix);
|
||||
m = m.inverse().transpose();
|
||||
|
||||
F32 mat3[] =
|
||||
{ m.m[0], m.m[1], m.m[2],
|
||||
m.m[4], m.m[5], m.m[6],
|
||||
m.m[8], m.m[9], m.m[10] };
|
||||
|
||||
LLMatrix3 mat_normal(mat3);
|
||||
|
||||
face->getGeometryVolume(*volume, i, mat_vert, mat_normal, offset, true);
|
||||
buff = face->mVertexBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buff && mesh_id.notNull())
|
||||
{
|
||||
if (!skin)
|
||||
{
|
||||
skin = gMeshRepo.getSkinInfo(mesh_id);
|
||||
}
|
||||
|
||||
if (skin)
|
||||
{
|
||||
LLMatrix4 mat[64];
|
||||
|
||||
for (U32 i = 0; i < skin->mJointNames.size(); ++i)
|
||||
{
|
||||
LLJoint* joint = getJoint(skin->mJointNames[i]);
|
||||
if (joint)
|
||||
{
|
||||
mat[i] = skin->mInvBindMatrix[i];
|
||||
mat[i] *= joint->getWorldMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette",
|
||||
skin->mJointNames.size(),
|
||||
FALSE,
|
||||
(GLfloat*) mat[0].mMatrix);
|
||||
LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette[0]",
|
||||
skin->mJointNames.size(),
|
||||
FALSE,
|
||||
(GLfloat*) mat[0].mMatrix);
|
||||
|
||||
buff->setBuffer(data_mask);
|
||||
|
||||
U16 start = face->getGeomStart();
|
||||
U16 end = start + face->getGeomCount()-1;
|
||||
S32 offset = face->getIndicesStart();
|
||||
U32 count = face->getIndicesCount();
|
||||
|
||||
gGL.getTexUnit(0)->bind(face->getTexture());
|
||||
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num_indices;
|
||||
return num_indices;*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include "object_flags.h"
|
||||
#include "llagentconstants.h"
|
||||
#include "lldrawable.h"
|
||||
#include "lldrawpoolavatar.h"
|
||||
#include "lldrawpoolbump.h"
|
||||
#include "llface.h"
|
||||
#include "llspatialpartition.h"
|
||||
|
|
@ -73,6 +74,8 @@
|
|||
#include "llmeshrepository.h"
|
||||
#include "llagent.h"
|
||||
#include "llviewermediafocus.h"
|
||||
#include "llvoavatar.h"
|
||||
|
||||
|
||||
const S32 MIN_QUIET_FRAMES_COALESCE = 30;
|
||||
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
|
||||
|
|
@ -3415,6 +3418,33 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
|
|||
static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume");
|
||||
static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
|
||||
|
||||
LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
|
||||
{
|
||||
LLVOAvatar* avatar = vobj->getAvatar();
|
||||
|
||||
if (avatar)
|
||||
{
|
||||
LLDrawable* drawable = avatar->mDrawable;
|
||||
if (drawable && drawable->getNumFaces() > 0)
|
||||
{
|
||||
LLFace* face = drawable->getFace(0);
|
||||
if (face)
|
||||
{
|
||||
LLDrawPool* drawpool = face->getPool();
|
||||
if (drawpool)
|
||||
{
|
||||
if (drawpool->getType() == LLDrawPool::POOL_AVATAR)
|
||||
{
|
||||
return (LLDrawPoolAvatar*) drawpool;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
||||
{
|
||||
|
|
@ -3499,13 +3529,47 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
facep->mVertexBuffer = NULL;
|
||||
facep->mLastVertexBuffer = NULL;
|
||||
facep->setState(LLFace::RIGGED);
|
||||
|
||||
//get drawpool of avatar with rigged face
|
||||
LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
|
||||
|
||||
if (pool)
|
||||
{
|
||||
const LLTextureEntry* te = facep->getTextureEntry();
|
||||
|
||||
//remove face from old pool if it exists
|
||||
LLDrawPool* old_pool = facep->getPool();
|
||||
if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR)
|
||||
{
|
||||
((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
|
||||
}
|
||||
|
||||
//add face to new pool
|
||||
if (te->getShiny())
|
||||
{
|
||||
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY_SIMPLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
facep->clearState(LLFace::RIGGED);
|
||||
if (facep->isState(LLFace::RIGGED))
|
||||
{ //face is not rigged but used to be, remove from rigged face pool
|
||||
LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
|
||||
if (pool)
|
||||
{
|
||||
pool->removeRiggedFace(facep);
|
||||
}
|
||||
facep->clearState(LLFace::RIGGED);
|
||||
}
|
||||
}
|
||||
|
||||
if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
|
||||
|
|
|
|||
Loading…
Reference in New Issue