diff options
author | Steven Bennetts <steve@lindenlab.com> | 2007-03-02 21:25:50 +0000 |
---|---|---|
committer | Steven Bennetts <steve@lindenlab.com> | 2007-03-02 21:25:50 +0000 |
commit | 4dabd9c0472deb49573fdafef2fa413e59703f19 (patch) | |
tree | 06c680d6a2047e03838d6548bccd26c7baf9d652 /indra/newview/lldrawpoolavatar.cpp | |
parent | d4462963c6ba5db2088723bbedc7b60f1184c594 (diff) |
merge release@58699 beta-1-14-0@58707 -> release
Diffstat (limited to 'indra/newview/lldrawpoolavatar.cpp')
-rw-r--r-- | indra/newview/lldrawpoolavatar.cpp | 631 |
1 files changed, 320 insertions, 311 deletions
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index dfe75084b5..9b9825deff 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -13,7 +13,6 @@ #include "llvoavatar.h" #include "m3math.h" -#include "llagparray.h" #include "llagent.h" #include "lldrawable.h" #include "llface.h" @@ -23,6 +22,11 @@ #include "noise.h" #include "pipeline.h" +static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK; +static U32 sBufferUsage = GL_STREAM_DRAW_ARB; +static U32 sShaderLevel = 0; +static LLGLSLShader* sVertexProgram = NULL; + extern F32 gFrameDTClamped; extern BOOL gUseGLPick; @@ -56,53 +60,13 @@ S32 AVATAR_VERTEX_BYTES = 48; BOOL gAvatarEmbossBumpMap = FALSE; +static BOOL sRenderingSkinned = FALSE; LLDrawPoolAvatar::LLDrawPoolAvatar() : -LLDrawPool(POOL_AVATAR, - DATA_SIMPLE_IL_MASK, - DATA_VERTEX_WEIGHTS_MASK | DATA_CLOTHING_WEIGHTS_MASK ) +LLFacePool(POOL_AVATAR) { - mCleanupUnused = FALSE; - - // Overide the data layout - mDataMaskIL = 0; - mStride = 0; - for (S32 i = 0; i < DATA_MAX_TYPES; i++) - { - mDataOffsets[i] = 0; - } - - // Note: padding is to speed up SSE code - mDataMaskIL |= DATA_VERTICES_MASK; - mDataOffsets[DATA_VERTICES] = mStride; - mStride += sDataSizes[DATA_VERTICES]; - - mStride += 4; - - mDataMaskIL |= DATA_NORMALS_MASK; - mDataOffsets[DATA_NORMALS] = mStride; - mStride += sDataSizes[DATA_NORMALS]; - - mStride += 4; - - // Note: binormals are stripped off in software blending - mDataMaskIL |= DATA_BINORMALS_MASK; - mDataOffsets[DATA_BINORMALS] = mStride; - mStride += sDataSizes[DATA_BINORMALS]; - - mStride += 4; // To keep the structure 16-byte aligned (for SSE happiness) - - mDataMaskIL |= DATA_TEX_COORDS0_MASK; - mDataOffsets[DATA_TEX_COORDS0] = mStride; - mStride += sDataSizes[DATA_TEX_COORDS0]; - - mDataMaskIL |= DATA_TEX_COORDS1_MASK; - mDataOffsets[DATA_TEX_COORDS1] = mStride; - mStride += sDataSizes[DATA_TEX_COORDS1]; - //LLDebugVarMessageBox::show("acceleration", &CLOTHING_ACCEL_FORCE_FACTOR, 10.f, 0.1f); - //LLDebugVarMessageBox::show("gravity", &CLOTHING_GRAVITY_EFFECT, 10.f, 0.1f); - + //LLDebugVarMessageBox::show("gravity", &CLOTHING_GRAVITY_EFFECT, 10.f, 0.1f); } //----------------------------------------------------------------------------- @@ -113,41 +77,194 @@ LLDrawPool *LLDrawPoolAvatar::instancePool() return new LLDrawPoolAvatar(); } +BOOL gRenderAvatar = TRUE; +static LLMatrix4 sModelViewMatrix = LLMatrix4(); -S32 LLDrawPoolAvatar::rebuild() +S32 LLDrawPoolAvatar::getVertexShaderLevel() const { - mRebuildTime++; - if (mRebuildTime > mRebuildFreq) - { - flushAGP(); - - mRebuildTime = 0; - } - - return 0; + return (S32) gPipeline.getVertexShaderLevel(LLPipeline::SHADER_AVATAR); } -BOOL gRenderAvatar = TRUE; - void LLDrawPoolAvatar::prerender() { mVertexShaderLevel = gPipeline.getVertexShaderLevel(LLPipeline::SHADER_AVATAR); + sShaderLevel = mVertexShaderLevel; + + if (sShaderLevel > 0) + { + sBufferUsage = GL_STATIC_DRAW_ARB; + } + else + { + sBufferUsage = GL_STREAM_DRAW_ARB; + } +} + +LLMatrix4& LLDrawPoolAvatar::getModelView() +{ + return sModelViewMatrix; } //----------------------------------------------------------------------------- // render() //----------------------------------------------------------------------------- + +S32 LLDrawPoolAvatar::getNumPasses() +{ + return 3; +} + void LLDrawPoolAvatar::render(S32 pass) { LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); - renderAvatars(NULL); // render all avatars + renderAvatars(NULL, pass); // render all avatars +} + +void LLDrawPoolAvatar::beginRenderPass(S32 pass) +{ + //reset vertex buffer mappings + LLVertexBuffer::unbind(); + + switch (pass) + { + case 0: + beginFootShadow(); + break; + case 1: + glGetFloatv(GL_MODELVIEW_MATRIX, (F32*) sModelViewMatrix.mMatrix); + beginRigid(); + break; + case 2: + beginSkinned(); + break; + } +} + +void LLDrawPoolAvatar::endRenderPass(S32 pass) +{ + switch (pass) + { + case 0: + endFootShadow(); + break; + case 1: + endRigid(); + break; + case 2: + endSkinned(); + } +} + +void LLDrawPoolAvatar::beginFootShadow() +{ + glDepthMask(GL_FALSE); + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); +} + +void LLDrawPoolAvatar::endFootShadow() +{ + gPipeline.enableLightsDynamic(1.f); + glDepthMask(GL_TRUE); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +void LLDrawPoolAvatar::beginRigid() +{ + sVertexProgram = &gPipeline.mAvatarEyeballProgram; + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + if (sShaderLevel > 0) + { //eyeballs render with the specular shader + gPipeline.mAvatarEyeballProgram.bind(); + gPipeline.mMaterialIndex = gPipeline.mAvatarEyeballProgram.mAttribute[LLPipeline::GLSL_MATERIAL_COLOR]; + gPipeline.mSpecularIndex = gPipeline.mAvatarEyeballProgram.mAttribute[LLPipeline::GLSL_SPECULAR_COLOR]; + } +} + +void LLDrawPoolAvatar::endRigid() +{ + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +void LLDrawPoolAvatar::beginSkinned() +{ + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + sVertexProgram = &gPipeline.mAvatarProgram; + + if (sShaderLevel > 0) // for hardware blending + { + sRenderingSkinned = TRUE; + glClientActiveTextureARB(GL_TEXTURE1_ARB); + if (sShaderLevel >= SHADER_LEVEL_BUMP) + { + gPipeline.mMaterialIndex = sVertexProgram->mAttribute[LLPipeline::GLSL_MATERIAL_COLOR]; + gPipeline.mSpecularIndex = sVertexProgram->mAttribute[LLPipeline::GLSL_SPECULAR_COLOR]; + } + sVertexProgram->bind(); + if (sShaderLevel >= SHADER_LEVEL_CLOTH) + { + enable_cloth_weights(sVertexProgram->mAttribute[LLPipeline::GLSL_AVATAR_CLOTHING]); + } + enable_vertex_weighting(sVertexProgram->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]); + + if (sShaderLevel >= SHADER_LEVEL_BUMP) + { + enable_binormals(sVertexProgram->mAttribute[LLPipeline::GLSL_BINORMAL]); + } + + sVertexProgram->enableTexture(LLPipeline::GLSL_BUMP_MAP); + glActiveTextureARB(GL_TEXTURE0_ARB); + } } -void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, BOOL no_shaders) +void LLDrawPoolAvatar::endSkinned() { - if (no_shaders) + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done + if (sShaderLevel > 0) { - mVertexShaderLevel = 0; + sRenderingSkinned = FALSE; + sVertexProgram->disableTexture(LLPipeline::GLSL_BUMP_MAP); + glActiveTextureARB(GL_TEXTURE0_ARB); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + disable_vertex_weighting(sVertexProgram->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]); + if (sShaderLevel >= SHADER_LEVEL_BUMP) + { + disable_binormals(sVertexProgram->mAttribute[LLPipeline::GLSL_BINORMAL]); + } + if ((sShaderLevel >= SHADER_LEVEL_CLOTH)) + { + disable_cloth_weights(sVertexProgram->mAttribute[LLPipeline::GLSL_AVATAR_CLOTHING]); + } + + sVertexProgram->unbind(); + } + + glActiveTextureARB(GL_TEXTURE0_ARB); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + + +void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) +{ + if (pass == -1) + { + for (S32 i = 1; i < getNumPasses(); i++) + { //skip foot shadows + prerender(); + beginRenderPass(i); + renderAvatars(single_avatar, i); + endRenderPass(i); + } + + return; } if (!gRenderAvatar) @@ -176,13 +293,95 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, BOOL no_shaders) avatarp = (LLVOAvatar *)(facep->getDrawable()->getVObj()); } - if (avatarp->isDead() || avatarp->mDrawable.isNull()) + if (avatarp->isDead() || avatarp->mDrawable.isNull()) { return; } LLOverrideFaceColor color(this, 1.0f, 1.0f, 1.0f, 1.0f); + if (pass == 0) + { + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS)) + { + mIndicesDrawn += avatarp->renderFootShadows(); + } + return; + } + + if (avatarp->mSpecialRenderMode == 0) // normal + { + gPipeline.enableLightsAvatar(avatarp->mDrawable->getSunShadowFactor()); + } + else if (avatarp->mSpecialRenderMode == 1) // anim preview + { + gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f)); + } + else // 2=image preview, 3=morph view + { + gPipeline.enableLightsAvatarEdit(LLColor4(.5f, .5f, .5f, 1.f)); + } + + if (pass == 1) + { + // render rigid meshes (eyeballs) first + mIndicesDrawn += avatarp->renderRigid(); + + if (!gRenderForSelect && avatarp->mIsSelf && LLVOAvatar::sAvatarLoadTest) + { + LLVector3 orig_pos_root = avatarp->mRoot.getPosition(); + LLVector3 next_pos_root = orig_pos_root; + for (S32 i = 0; i < NUM_TEST_AVATARS; i++) + { + next_pos_root.mV[VX] += 1.f; + if (i % 5 == 0) + { + next_pos_root.mV[VY] += 1.f; + next_pos_root.mV[VX] = orig_pos_root.mV[VX]; + } + + avatarp->mRoot.setPosition(next_pos_root); // avatar load test + avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test + + mIndicesDrawn += avatarp->renderRigid(); + } + avatarp->mRoot.setPosition(orig_pos_root); // avatar load test + avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test + } + return; + } + + + if (sShaderLevel > 0) + { + gPipeline.mAvatarMatrixParam = sVertexProgram->mUniform[LLPipeline::GLSL_AVATAR_MATRIX]; + } + + if ((sShaderLevel >= SHADER_LEVEL_CLOTH)) + { + LLMatrix4 rot_mat; + gCamera->getMatrixToLocal(rot_mat); + LLMatrix4 cfr(OGL_TO_CFR_ROTATION); + rot_mat *= cfr; + + LLVector4 wind; + wind.setVec(avatarp->mWindVec); + wind.mV[VW] = 0; + wind = wind * rot_mat; + wind.mV[VW] = avatarp->mWindVec.mV[VW]; + + sVertexProgram->vertexAttrib4fv(LLPipeline::GLSL_AVATAR_WIND, wind.mV); + F32 phase = -1.f * (avatarp->mRipplePhase); + + F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); + LLVector4 sin_params(freq, freq, freq, phase); + sVertexProgram->vertexAttrib4fv(LLPipeline::GLSL_AVATAR_SINWAVE, sin_params.mV); + + LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f); + gravity = gravity * rot_mat; + sVertexProgram->vertexAttrib4fv(LLPipeline::GLSL_AVATAR_GRAVITY, gravity.mV); + } + if( !single_avatar || (avatarp == single_avatar) ) { if (LLVOAvatar::sShowCollisionVolumes) @@ -191,8 +390,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, BOOL no_shaders) avatarp->renderCollisionVolumes(); } - LLGLEnable normalize(GL_NORMALIZE); - if (avatarp->mIsSelf && LLAgent::sDebugDisplayTarget) { LLGLSNoTexture gls_no_texture; @@ -248,171 +445,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, BOOL no_shaders) color.setColor(1.0f, 1.0f, 1.0f, 1.0f); } - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - LLGLSLShader* vertex_program = &gPipeline.mAvatarProgram; - if (mVertexShaderLevel > 0) - { - gPipeline.mAvatarMatrixParam = vertex_program->mUniform[LLPipeline::GLSL_AVATAR_MATRIX]; - } - - //-------------------------------------------------------------------------------- - // this is where we first hit the software blending path - // if enabled, we need to set up the proper buffers and avoid setting other state - //-------------------------------------------------------------------------------- - if (!(mVertexShaderLevel > 0)) - { - - // performance could be increased by better utilizing the buffers, for example, only using 1k buffers for lo-res - // avatars. But the only problem with using fewer buffers is that we're more likely to wait for a fence to complete - - // vertex format: - // vertices 12 - // texcoords 8 - // normals 12 - // binormals 12 - // padding 4 - // total 48 - - // Rotate to the next buffer, round-robin. - gPipeline.bufferRotate(); - - // Wait until the hardware is done reading the last set of vertices from the buffer before writing the next set. - gPipeline.bufferWaitFence(); - - // Need to do this because we may be rendering without AGP even in AGP mode - U8* buffer_offset_start = gPipeline.bufferGetScratchMemory(); - glVertexPointer( 3, GL_FLOAT, AVATAR_VERTEX_BYTES, buffer_offset_start + AVATAR_OFFSET_POS); - glTexCoordPointer(2, GL_FLOAT, AVATAR_VERTEX_BYTES, buffer_offset_start + AVATAR_OFFSET_TEX0); - glNormalPointer( GL_FLOAT, AVATAR_VERTEX_BYTES, buffer_offset_start + AVATAR_OFFSET_NORMAL); - - } - - if ((mVertexShaderLevel > 0)) // for hardware blending - { - bindGLVertexPointer(); - bindGLNormalPointer(); - bindGLTexCoordPointer(0); - } - - if ((mVertexShaderLevel > 0)) - { //eyeballs render with the specular shader - gPipeline.mAvatarEyeballProgram.bind(); - gPipeline.mMaterialIndex = gPipeline.mAvatarEyeballProgram.mAttribute[LLPipeline::GLSL_MATERIAL_COLOR]; - gPipeline.mSpecularIndex = gPipeline.mAvatarEyeballProgram.mAttribute[LLPipeline::GLSL_SPECULAR_COLOR]; - - S32 index = gPipeline.mAvatarEyeballProgram.enableTexture(LLPipeline::GLSL_SCATTER_MAP); - gSky.mVOSkyp->getScatterMap()->bind(index); - - glActiveTextureARB(GL_TEXTURE0_ARB); - } - - if (avatarp->mSpecialRenderMode == 0) // normal - { - gPipeline.enableLightsAvatar(avatarp->mDrawable->getSunShadowFactor()); - } - else if (avatarp->mSpecialRenderMode == 1) // anim preview - { - gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f)); - } - else // 2=image preview, 3=morph view - { - gPipeline.enableLightsAvatarEdit(LLColor4(.5f, .5f, .5f, 1.f)); - } - - // render rigid meshes (eyeballs) first - mIndicesDrawn += avatarp->renderRigid(); - - if ((mVertexShaderLevel > 0)) - { - gPipeline.mAvatarEyeballProgram.disableTexture(LLPipeline::GLSL_SCATTER_MAP); - glActiveTextureARB(GL_TEXTURE0_ARB); - } - - if (!gRenderForSelect && avatarp->mIsSelf && LLVOAvatar::sAvatarLoadTest) - { - LLVector3 orig_pos_root = avatarp->mRoot.getPosition(); - LLVector3 next_pos_root = orig_pos_root; - for (S32 i = 0; i < NUM_TEST_AVATARS; i++) - { - next_pos_root.mV[VX] += 1.f; - if (i % 5 == 0) - { - next_pos_root.mV[VY] += 1.f; - next_pos_root.mV[VX] = orig_pos_root.mV[VX]; - } - - avatarp->mRoot.setPosition(next_pos_root); // avatar load test - avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test - - mIndicesDrawn += avatarp->renderRigid(); - } - avatarp->mRoot.setPosition(orig_pos_root); // avatar load test - avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test - } - - if ((mVertexShaderLevel > 0)) // for hardware blending - { - glClientActiveTextureARB(GL_TEXTURE1_ARB); - if ((mVertexShaderLevel >= SHADER_LEVEL_BUMP)) - { - bindGLTexCoordPointer(1); - - bindGLBinormalPointer(vertex_program->mAttribute[LLPipeline::GLSL_BINORMAL]); - gPipeline.mMaterialIndex = vertex_program->mAttribute[LLPipeline::GLSL_MATERIAL_COLOR]; - gPipeline.mSpecularIndex = vertex_program->mAttribute[LLPipeline::GLSL_SPECULAR_COLOR]; - } - glClientActiveTextureARB(GL_TEXTURE0_ARB); - bindGLTexCoordPointer(0); - vertex_program->bind(); - bindGLVertexWeightPointer(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]); - if ((mVertexShaderLevel >= SHADER_LEVEL_CLOTH)) - { - bindGLVertexClothingWeightPointer(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_CLOTHING]); - enable_cloth_weights(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_CLOTHING]); - } - enable_vertex_weighting(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]); - - if ((mVertexShaderLevel >= SHADER_LEVEL_BUMP)) - { - enable_binormals(vertex_program->mAttribute[LLPipeline::GLSL_BINORMAL]); - } - - vertex_program->enableTexture(LLPipeline::GLSL_BUMP_MAP); - S32 index = vertex_program->enableTexture(LLPipeline::GLSL_SCATTER_MAP); - gSky.mVOSkyp->getScatterMap()->bind(index); - glActiveTextureARB(GL_TEXTURE0_ARB); - } - - if ((mVertexShaderLevel >= SHADER_LEVEL_CLOTH)) - { - LLMatrix4 rot_mat; - gCamera->getMatrixToLocal(rot_mat); - LLMatrix4 cfr(OGL_TO_CFR_ROTATION); - rot_mat *= cfr; - - LLVector4 wind; - wind.setVec(avatarp->mWindVec); - wind.mV[VW] = 0; - wind = wind * rot_mat; - wind.mV[VW] = avatarp->mWindVec.mV[VW]; - - vertex_program->vertexAttrib4fv(LLPipeline::GLSL_AVATAR_WIND, wind.mV); - F32 phase = -1.f * (avatarp->mRipplePhase); - - F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); - LLVector4 sin_params(freq, freq, freq, phase); - vertex_program->vertexAttrib4fv(LLPipeline::GLSL_AVATAR_SINWAVE, sin_params.mV); - - LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f); - gravity = gravity * rot_mat; - vertex_program->vertexAttrib4fv(LLPipeline::GLSL_AVATAR_GRAVITY, gravity.mV); - } - mIndicesDrawn += avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); - + if (!gRenderForSelect && avatarp->mIsSelf && LLVOAvatar::sAvatarLoadTest) { LLVector3 orig_pos_root = avatarp->mRoot.getPosition(); @@ -434,31 +468,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, BOOL no_shaders) avatarp->mRoot.setPosition(orig_pos_root); // avatar load test avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test } - - // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done - if (!(mVertexShaderLevel > 0)) - { - // want for the previously bound fence to finish - gPipeline.bufferSendFence(); - } - else - { - vertex_program->disableTexture(LLPipeline::GLSL_BUMP_MAP); - vertex_program->disableTexture(LLPipeline::GLSL_SCATTER_MAP); - glActiveTextureARB(GL_TEXTURE0_ARB); - glClientActiveTextureARB(GL_TEXTURE0_ARB); - disable_vertex_weighting(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]); - if ((mVertexShaderLevel >= SHADER_LEVEL_BUMP)) - { - disable_binormals(vertex_program->mAttribute[LLPipeline::GLSL_BINORMAL]); - } - if ((mVertexShaderLevel >= SHADER_LEVEL_CLOTH)) - { - disable_cloth_weights(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_CLOTHING]); - } - - vertex_program->unbind(); - } } } @@ -471,14 +480,13 @@ void LLDrawPoolAvatar::renderForSelect() { return; } - //gGLSObjectSelectDepthAlpha.set(); - + if (!gRenderAvatar) { return; } - if (mDrawFace.empty() || !mMemory.count()) + if (mDrawFace.empty()) { return; } @@ -498,80 +506,38 @@ void LLDrawPoolAvatar::renderForSelect() glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - LLGLSLShader* vertex_program = &gPipeline.mAvatarPickProgram; - if (mVertexShaderLevel > 0) + glGetFloatv(GL_MODELVIEW_MATRIX, (F32*) sModelViewMatrix.mMatrix); + sVertexProgram = &gPipeline.mAvatarPickProgram; + if (sShaderLevel > 0) { - gPipeline.mAvatarMatrixParam = vertex_program->mUniform[LLPipeline::GLSL_AVATAR_MATRIX]; + gPipeline.mAvatarMatrixParam = sVertexProgram->mUniform[LLPipeline::GLSL_AVATAR_MATRIX]; } glAlphaFunc(GL_GEQUAL, 0.2f); glBlendFunc(GL_ONE, GL_ZERO); - //-------------------------------------------------------------------------------- - // this is where we first hit the software blending path - // if enabled, we need to set up the proper buffers and avoid setting other state - //-------------------------------------------------------------------------------- - if (!(mVertexShaderLevel > 0) || gUseGLPick) - { - - // Rotate to the next buffer, round-robin. - gPipeline.bufferRotate(); - - // Wait until the hardware is done reading the last set of vertices from the buffer before writing the next set. - gPipeline.bufferWaitFence(); - - // Need to do this because we may be rendering without AGP even in AGP mode - U8* buffer_offset_start = gPipeline.bufferGetScratchMemory(); - glVertexPointer( 3, GL_FLOAT, AVATAR_VERTEX_BYTES, buffer_offset_start + AVATAR_OFFSET_POS); - glTexCoordPointer(2, GL_FLOAT, AVATAR_VERTEX_BYTES, buffer_offset_start + AVATAR_OFFSET_TEX0); - glNormalPointer( GL_FLOAT, AVATAR_VERTEX_BYTES, buffer_offset_start + AVATAR_OFFSET_NORMAL); - } - S32 name = avatarp->mDrawable->getVObj()->mGLName; LLColor4U color((U8)(name >> 16), (U8)(name >> 8), (U8)name); glColor4ubv(color.mV); - if ((mVertexShaderLevel > 0) && !gUseGLPick) // for hardware blending - { - bindGLVertexPointer(); - bindGLNormalPointer(); - bindGLTexCoordPointer(0); - } - // render rigid meshes (eyeballs) first - mIndicesDrawn += avatarp->renderRigid(); + //mIndicesDrawn += avatarp->renderRigid(); - if ((mVertexShaderLevel > 0) && !gUseGLPick) // for hardware blending + if ((sShaderLevel > 0) && !gUseGLPick) // for hardware blending { glClientActiveTextureARB(GL_TEXTURE0_ARB); - bindGLTexCoordPointer(0); - vertex_program->bind(); - bindGLVertexWeightPointer(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]); - /*if ((mVertexShaderLevel >= SHADER_LEVEL_CLOTH)) - { - bindGLVertexClothingWeightPointer(); - enable_cloth_weights(); - }*/ - enable_vertex_weighting(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]); + sRenderingSkinned = TRUE; + sVertexProgram->bind(); + enable_vertex_weighting(sVertexProgram->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]); } - + mIndicesDrawn += avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done - if (!(mVertexShaderLevel > 0) || gUseGLPick) + if ((sShaderLevel > 0) && !gUseGLPick) { - // want for the previously bound fence to finish - gPipeline.bufferSendFence(); - } - else - { - vertex_program->unbind(); - disable_vertex_weighting(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]); - - /*if ((mVertexShaderLevel >= SHADER_LEVEL_CLOTH)) - { - disable_cloth_weights(); - }*/ + sRenderingSkinned = FALSE; + sVertexProgram->unbind(); + disable_vertex_weighting(sVertexProgram->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]); } glAlphaFunc(GL_GREATER, 0.01f); @@ -608,3 +574,46 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const { return LLColor3(0.f, 1.f, 0.f); } + +LLVertexBufferAvatar::LLVertexBufferAvatar() +: LLVertexBuffer(sDataMask, + gPipeline.getVertexShaderLevel(LLPipeline::SHADER_AVATAR) > 0 ? + GL_STATIC_DRAW_ARB : + GL_STREAM_DRAW_ARB) +{ + +} + + +void LLVertexBufferAvatar::setupVertexBuffer(U32 data_mask) const +{ + if (sRenderingSkinned) + { + U8* base = useVBOs() ? NULL : mMappedData; + + glVertexPointer(3,GL_FLOAT, mStride, (void*)(base + 0)); + glNormalPointer(GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_NORMAL])); + + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD2])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD])); + + set_vertex_weights(sVertexProgram->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT], mStride, (F32*)(base + mOffsets[TYPE_WEIGHT])); + + if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_BUMP) + { + set_binormals(sVertexProgram->mAttribute[LLPipeline::GLSL_BINORMAL], mStride, (LLVector3*)(base + mOffsets[TYPE_BINORMAL])); + } + + if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH) + { + set_vertex_clothing_weights(sVertexProgram->mAttribute[LLPipeline::GLSL_AVATAR_CLOTHING], mStride, (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT])); + } + } + else + { + LLVertexBuffer::setupVertexBuffer(data_mask); + } +} + |