Huge renderer update (WIP). Still plenty to do, especially pertaining to UI.

-Nametag bubble visbility is oddly inconsistent. May vanish with future planned UI merges...
-VBOs are PAINFULLY slow on ATI hardware. This repos self-compiled davep/shining-fixes branch, so I'll leave the ball in LL's court for now regarding that.
This commit is contained in:
Shyotl
2011-12-09 14:02:29 -06:00
parent 8e7733b2ce
commit ffb285c6ff
499 changed files with 22321 additions and 12356 deletions

View File

@@ -47,12 +47,14 @@
#include "llviewerregion.h"
#include "llcamera.h"
#include "pipeline.h"
#if MESH_ENABLED
#include "llmeshrepository.h"
#endif //MESH_ENABLED
#include "llrender.h"
#include "lloctree.h"
#include "llvoavatar.h"
#include "llvoavatar.h"
#include "llvolumemgr.h"
#include "llglslshader.h"
#include "llviewershadermgr.h"
const F32 SG_OCCLUSION_FUDGE = 0.25f;
#define SG_DISCARD_TOLERANCE 0.01f
@@ -218,7 +220,7 @@ typedef enum
//contact Runitai Linden for a copy of the SL object used to write this table
//basically, you give the table a bitmask of the look-at vector to a node and it
//gives you a triangle fan index array
static U8 sOcclusionIndices[] =
static U16 sOcclusionIndices[] =
{
//000
b111, b110, b010, b011, b001, b101, b100, b110,
@@ -255,7 +257,7 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7;
return sOcclusionIndices+cypher*8;
return (U8*) (sOcclusionIndices+cypher*8);
}
void LLSpatialGroup::buildOcclusion()
@@ -322,7 +324,8 @@ void LLSpatialGroup::buildOcclusion()
}
{
mOcclusionVerts->setBuffer(0);
mOcclusionVerts->flush();
LLVertexBuffer::unbind();
}
clearState(LLSpatialGroup::OCCLUSION_DIRTY);
@@ -2323,8 +2326,7 @@ void pushVerts(LLVolume* volume)
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{
const LLVolumeFace& face = volume->getVolumeFace(i);
glVertexPointer(3, GL_FLOAT, 16, face.mPositions);
glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices);
}
}
@@ -2333,7 +2335,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
if (buffer)
{
buffer->setBuffer(mask);
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getRequestedVerts()-1, buffer->getRequestedIndices(), 0);
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
}
}
@@ -2555,11 +2557,11 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
!group->getData().empty();
if (render_objects)
{
LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
gGL.diffuseColor4f(0, 0.5f, 0, 0.5f);
gGL.color4f(0, 0.5f, 0, 0.5f); //???
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
}
@@ -2569,7 +2571,6 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
if (render_objects)
{
gGL.diffuseColor4f(0.f, 0.5f, 0.f,1.f);
gGL.color4f(0.f, 0.5f, 0.f, 1.f); //???
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
}
@@ -2578,7 +2579,6 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
if (render_objects)
{
gGL.diffuseColor4f(0.f, 0.75f, 0.f,0.5f);
gGL.color4f(0.f, 0.75f, 0.f, 0.5f);
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
}
/*else if (camera && group->mOcclusionVerts)
@@ -2662,17 +2662,17 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
{
if (drawable->isSpatialBridge())
{
gGL.color4f(1,0.5f,0,1);
gGL.diffuseColor4f(1,0.5f,0,1);
}
else if (drawable->getVOVolume())
{
if (drawable->isRoot())
{
gGL.color4f(1,1,0,1);
gGL.diffuseColor4f(1,1,0,1);
}
else
{
gGL.color4f(0,1,0,1);
gGL.diffuseColor4f(0,1,0,1);
}
}
else if (drawable->getVObj())
@@ -2680,30 +2680,30 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
switch (drawable->getVObj()->getPCode())
{
case LLViewerObject::LL_VO_SURFACE_PATCH:
gGL.color4f(0,1,1,1);
gGL.diffuseColor4f(0,1,1,1);
break;
case LLViewerObject::LL_VO_CLOUDS:
gGL.color4f(0.5f,0.5f,0.5f,1.0f);
gGL.diffuseColor4f(0.5f,0.5f,0.5f,1.0f);
break;
case LLViewerObject::LL_VO_PART_GROUP:
case LLViewerObject::LL_VO_HUD_PART_GROUP:
gGL.color4f(0,0,1,1);
gGL.diffuseColor4f(0,0,1,1);
break;
case LLViewerObject::LL_VO_VOID_WATER:
case LLViewerObject::LL_VO_WATER:
gGL.color4f(0,0.5f,1,1);
gGL.diffuseColor4f(0,0.5f,1,1);
break;
case LL_PCODE_LEGACY_TREE:
gGL.color4f(0,0.5f,0,1);
gGL.diffuseColor4f(0,0.5f,0,1);
break;
default:
gGL.color4f(1,0,1,1);
gGL.diffuseColor4f(1,0,1,1);
break;
}
}
else
{
gGL.color4f(1,0,0,1);
gGL.diffuseColor4f(1,0,0,1);
}
}
@@ -2780,7 +2780,7 @@ void renderTexturePriority(LLDrawable* drawable)
F32 t = vsize/sLastMaxTexPriority;
LLVector4 col = lerp(cold, hot, t);
gGL.color4fv(col.mV);
gGL.diffuseColor4fv(col.mV);
}
//else
//{
@@ -2816,7 +2816,7 @@ void renderPoints(LLDrawable* drawablep)
if (drawablep->getNumFaces())
{
gGL.begin(LLRender::POINTS);
gGL.color3f(1,1,1);
gGL.diffuseColor3f(1,1,1);
for (S32 i = 0; i < drawablep->getNumFaces(); i++)
{
gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV);
@@ -2841,7 +2841,7 @@ void renderBatchSize(LLDrawInfo* params)
{
LLGLEnable offset(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.f, 1.f);
glColor3ubv((GLubyte*) &(params->mDebugColor));
gGL.diffuseColor4ubv((GLubyte*) &(params->mDebugColor));
pushVerts(params, LLVertexBuffer::MAP_VERTEX);
}
@@ -2873,60 +2873,198 @@ void renderLights(LLDrawable* drawablep)
{
LLGLDepthTest depth(GL_FALSE, GL_TRUE);
gGL.color4f(1,1,1,1);
gGL.diffuseColor4f(1,1,1,1);
drawBoxOutline(pos, size);
}
gGL.color4f(1,1,0,1);
gGL.diffuseColor4f(1,1,0,1);
F32 rad = drawablep->getVOVolume()->getLightRadius();
drawBoxOutline(pos, LLVector4a(rad));
}
}
class LLRenderOctreeRaycast : public LLOctreeTriangleRayIntersect
{
public:
LLRenderOctreeRaycast(const LLVector4a& start, const LLVector4a& dir, F32* closest_t)
: LLOctreeTriangleRayIntersect(start, dir, NULL, closest_t, NULL, NULL, NULL, NULL)
{
}
void visit(const LLOctreeNode<LLVolumeTriangle>* branch)
{
LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0);
LLVector3 center, size;
if (branch->getData().empty())
{
gGL.diffuseColor3f(1.f,0.2f,0.f);
center.set(branch->getCenter().getF32ptr());
size.set(branch->getSize().getF32ptr());
}
else
{
gGL.diffuseColor3f(0.75f, 1.f, 0.f);
center.set(vl->mBounds[0].getF32ptr());
size.set(vl->mBounds[1].getF32ptr());
}
drawBoxOutline(center, size);
for (U32 i = 0; i < 2; i++)
{
LLGLDepthTest depth(GL_TRUE, GL_FALSE, i == 1 ? GL_LEQUAL : GL_GREATER);
if (i == 1)
{
gGL.diffuseColor4f(0,1,1,0.5f);
}
else
{
gGL.diffuseColor4f(0,0.5f,0.5f, 0.25f);
drawBoxOutline(center, size);
}
if (i == 1)
{
gGL.flush();
glLineWidth(3.f);
}
gGL.begin(LLRender::TRIANGLES);
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getData().begin();
iter != branch->getData().end();
++iter)
{
const LLVolumeTriangle* tri = *iter;
gGL.vertex3fv(tri->mV[0]->getF32ptr());
gGL.vertex3fv(tri->mV[1]->getF32ptr());
gGL.vertex3fv(tri->mV[2]->getF32ptr());
}
gGL.end();
if (i == 1)
{
gGL.flush();
glLineWidth(1.f);
}
}
}
};
void renderRaycast(LLDrawable* drawablep)
{
if (drawablep->getVObj() != gDebugRaycastObject)
{
return;
}
if (drawablep->getNumFaces())
{
LLGLEnable blend(GL_BLEND);
gGL.color4f(0,1,1,0.5f);
gGL.diffuseColor4f(0,1,1,0.5f);
if (drawablep->getVOVolume() && gDebugRaycastFaceHit != -1)
if (drawablep->getVOVolume())
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
pushVerts(drawablep->getFace(gDebugRaycastFaceHit), LLVertexBuffer::MAP_VERTEX);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
//pushVerts(drawablep->getFace(gDebugRaycastFaceHit), LLVertexBuffer::MAP_VERTEX);
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
LLVOVolume* vobj = drawablep->getVOVolume();
LLVolume* volume = vobj->getVolume();
bool transform = true;
if (drawablep->isState(LLDrawable::RIGGED))
{
volume = vobj->getRiggedVolume();
transform = false;
}
if (volume)
{
LLVector3 trans = drawablep->getRegion()->getOriginAgent();
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{
const LLVolumeFace& face = volume->getVolumeFace(i);
if (!face.mOctree)
{
((LLVolumeFace*) &face)->createOctree();
}
gGL.pushMatrix();
gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
LLVector3 start, end;
if (transform)
{
start = vobj->agentPositionToVolume(gDebugRaycastStart);
end = vobj->agentPositionToVolume(gDebugRaycastEnd);
}
else
{
start = gDebugRaycastStart;
end = gDebugRaycastEnd;
}
LLVector4a starta, enda;
starta.load3(start.mV);
enda.load3(end.mV);
LLVector4a dir;
dir.setSub(enda, starta);
F32 t = 1.f;
LLRenderOctreeRaycast render(starta, dir, &t);
gGL.flush();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
{
//render face positions
LLVertexBuffer::unbind();
gGL.diffuseColor4f(0,1,1,0.5f);
glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions);
gGL.syncMatrices();
glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
}
render.traverse(face.mOctree);
gGL.popMatrix();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
}
}
else if (drawablep->isAvatar())
{
LLGLDepthTest depth(GL_FALSE);
LLVOAvatar* av = (LLVOAvatar*) drawablep->getVObj().get();
av->renderCollisionVolumes();
if (drawablep->getVObj() == gDebugRaycastObject)
{
LLGLDepthTest depth(GL_FALSE);
LLVOAvatar* av = (LLVOAvatar*) drawablep->getVObj().get();
av->renderCollisionVolumes();
}
}
// draw intersection point
gGL.pushMatrix();
gGL.loadMatrix(gGLModelView);
LLVector3 translate = gDebugRaycastIntersection;
gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]);
LLCoordFrame orient;
orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal);
LLMatrix4 rotation;
orient.getRotMatrixToParent(rotation);
gGL.multMatrix((float*)rotation.mMatrix);
gGL.color4f(1,0,0,0.5f);
drawBox(LLVector3(0, 0, 0), LLVector3(0.1f, 0.022f, 0.022f));
gGL.color4f(0,1,0,0.5f);
drawBox(LLVector3(0, 0, 0), LLVector3(0.021f, 0.1f, 0.021f));
gGL.color4f(0,0,1,0.5f);
drawBox(LLVector3(0, 0, 0), LLVector3(0.02f, 0.02f, 0.1f));
gGL.popMatrix();
if (drawablep->getVObj() == gDebugRaycastObject)
{
// draw intersection point
gGL.pushMatrix();
gGL.loadMatrix(gGLModelView);
LLVector3 translate = gDebugRaycastIntersection;
gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]);
LLCoordFrame orient;
orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal);
LLMatrix4 rotation;
orient.getRotMatrixToParent(rotation);
gGL.multMatrix((float*)rotation.mMatrix);
gGL.diffuseColor4f(1,0,0,0.5f);
drawBox(LLVector3(0, 0, 0), LLVector3(0.1f, 0.022f, 0.022f));
gGL.diffuseColor4f(0,1,0,0.5f);
drawBox(LLVector3(0, 0, 0), LLVector3(0.021f, 0.1f, 0.021f));
gGL.diffuseColor4f(0,0,1,0.5f);
drawBox(LLVector3(0, 0, 0), LLVector3(0.02f, 0.02f, 0.1f));
gGL.popMatrix();
// draw bounding box of prim
const LLVector4a* ext = drawablep->getSpatialExtents();
@@ -2938,10 +3076,10 @@ void renderRaycast(LLDrawable* drawablep)
size.setSub(ext[1], ext[0]);
size.mul(0.5f);
LLGLDepthTest depth(GL_FALSE, GL_TRUE);
gGL.color4f(0,0.5f,0.5f,1);
drawBoxOutline(pos, size);
LLGLDepthTest depth(GL_FALSE, GL_TRUE);
gGL.diffuseColor4f(0,0.5f,0.5f,1);
drawBoxOutline(pos, size);
}
}
}
@@ -3009,7 +3147,7 @@ public:
stop_glerror();
gGLLastMatrix = NULL;
gGL.popMatrix();
gGL.color4f(1,1,1,1);
gGL.diffuseColor4f(1,1,1,1);
}
}
}
@@ -3033,7 +3171,7 @@ public:
{
if (!group->getData().empty())
{
gGL.color3f(0,0,1);
gGL.diffuseColor3f(0,0,1);
drawBoxOutline(group->mObjectBounds[0],
group->mObjectBounds[1]);
}
@@ -3052,7 +3190,7 @@ public:
{
if (drawable->isState(LLDrawable::IN_REBUILD_Q2))
{
gGL.color4f(0.6f, 0.6f, 0.1f, 1.f);
gGL.diffuseColor4f(0.6f, 0.6f, 0.1f, 1.f);
const LLVector4a* ext = drawable->getSpatialExtents();
LLVector4a center;
center.setAdd(ext[0], ext[1]);
@@ -3280,6 +3418,11 @@ void LLSpatialPartition::renderDebug()
return;
}
if (LLGLSLShader::sNoFixedFunction)
{
gDebugProgram.bind();
}
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
{
//sLastMaxTexPriority = lerp(sLastMaxTexPriority, sCurMaxTexPriority, gFrameIntervalSeconds);
@@ -3308,11 +3451,16 @@ void LLSpatialPartition::renderDebug()
LLOctreeRenderNonOccluded render_debug(camera);
render_debug.traverse(mOctree);
if (LLGLSLShader::sNoFixedFunction)
{
gDebugProgram.unbind();
}
}
void LLSpatialGroup::drawObjectBox(LLColor4 col)
{
gGL.color4fv(col.mV);
gGL.diffuseColor4fv(col.mV);
LLVector4a size;
size = mObjectBounds[1];
size.mul(1.01f);
@@ -3417,7 +3565,7 @@ public:
LLVector3 local_start = mStart;
LLVector3 local_end = mEnd;
if (!gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())
if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())
{
return false;
}
@@ -3439,7 +3587,6 @@ public:
{
LLVector3 intersection;
bool skip_check = false;
#if MESH_ENABLED
if (vobj->isAvatar())
{
LLVOAvatar* avatar = (LLVOAvatar*) vobj;
@@ -3460,7 +3607,6 @@ public:
}
}
#endif //MESH_ENABLED
if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal))
{
@@ -3514,7 +3660,8 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
mVSize(0.f),
mGroup(NULL),
mFace(NULL),
mDistance(0.f)
mDistance(0.f),
mDrawMode(LLRender::TRIANGLES)
{
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);