Files
SingularityViewer/indra/newview/lldrawpoolterrain.cpp
Shyotl e756140e1d Innitial commit of experimental v2 texture system port work. Compiles and runs on windows, at least. Fixing bugs as they come.
Need to test:
localassetbrowser
preview related floaters
hgfloatertexteditor
maps
media textures! Currently very hacky
web browser
alpha masks on avatars
bumpmaps
Are all sky components appearing?
LLViewerDynamicTexture (texture baking, browser, animated textures, anim previews, etc)
Snapshot related features
Customize avatar
vfs floater
UI textures in general
Texture priority issues
2011-03-31 03:22:01 -05:00

957 lines
28 KiB
C++

/**
* @file lldrawpoolterrain.cpp
* @brief LLDrawPoolTerrain class implementation
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "lldrawpoolterrain.h"
#include "llfasttimer.h"
#include "llagent.h"
#include "llviewercontrol.h"
#include "lldrawable.h"
#include "llface.h"
#include "llsky.h"
#include "llsurface.h"
#include "llsurfacepatch.h"
#include "llviewerregion.h"
#include "llvlcomposition.h"
#include "llviewerparcelmgr.h" // for gRenderParcelOwnership
#include "llviewerparceloverlay.h"
#include "llvosurfacepatch.h"
#include "llviewercamera.h"
#include "llviewertexturelist.h" // To get alpha gradients
#include "llworld.h"
#include "pipeline.h"
#include "llviewershadermgr.h"
#include "llrender.h"
const F32 DETAIL_SCALE = 1.f/16.f;
int DebugDetailMap = 0;
S32 LLDrawPoolTerrain::sDetailMode = 1;
F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE;
static LLGLSLShader* sShader = NULL;
LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
LLFacePool(POOL_TERRAIN),
mTexturep(texturep)
{
// Hack!
sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale");
sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
mAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga",
TRUE, LLViewerTexture::BOOST_UI,
LLViewerTexture::FETCHED_TEXTURE,
GL_ALPHA8, GL_ALPHA,
LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb"));
//gGL.getTexUnit(0)->bind(mAlphaRampImagep.get());
mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c",
TRUE, LLViewerTexture::BOOST_UI,
LLViewerTexture::FETCHED_TEXTURE,
GL_ALPHA8, GL_ALPHA,
LLUUID("38b86f85-2575-52a9-a531-23108d8da837"));
//gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
mTexturep->setBoostLevel(LLViewerTexture::BOOST_TERRAIN);
//gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
LLDrawPoolTerrain::~LLDrawPoolTerrain()
{
llassert( gPipeline.findPool( getType(), getTexture() ) == NULL );
}
LLDrawPool *LLDrawPoolTerrain::instancePool()
{
return new LLDrawPoolTerrain(mTexturep);
}
U32 LLDrawPoolTerrain::getVertexDataMask()
{
if (LLPipeline::sShadowRender)
{
return LLVertexBuffer::MAP_VERTEX;
}
else
{
return VERTEX_DATA_MASK;
}
}
void LLDrawPoolTerrain::prerender()
{
mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
if (mVertexShaderLevel > 0)
{
sDetailMode = 1;
}
else
{
sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
}
}
void LLDrawPoolTerrain::beginRenderPass( S32 pass )
{
LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN);
LLFacePool::beginRenderPass(pass);
sShader = LLPipeline::sUnderWaterRender ?
&gTerrainWaterProgram :
&gTerrainProgram;
if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0)
{
sShader->bind();
}
}
void LLDrawPoolTerrain::endRenderPass( S32 pass )
{
LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN);
LLFacePool::endRenderPass(pass);
if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0) {
sShader->unbind();
}
}
//static
S32 LLDrawPoolTerrain::getDetailMode()
{
return sDetailMode;
}
void LLDrawPoolTerrain::render(S32 pass)
{
LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN);
if (mDrawFace.empty())
{
return;
}
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
for (S32 i = 0; i < 4; i++)
{
compp->mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN);
compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
}
if (!gGLManager.mHasMultitexture)
{
// No multitexture, render simple land.
renderSimple(); // Render without multitexture
return;
}
// Render simplified land if video card can't do sufficient multitexturing
if (!gGLManager.mHasARBEnvCombine || (gGLManager.mNumTextureUnits < 2))
{
renderSimple(); // Render without multitexture
return;
}
LLGLSPipeline gls;
LLOverrideFaceColor override(this, 1.f, 1.f, 1.f, 1.f);
if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0)
{
gPipeline.enableLightsDynamic();
renderFullShader();
}
else
{
gPipeline.enableLightsStatic();
if (sDetailMode == 0){
renderSimple();
} else if (gGLManager.mNumTextureUnits < 4){
renderFull2TU();
} else {
renderFull4TU();
}
}
// Special-case for land ownership feedback
static const LLCachedControl<bool> show_parcel_owners("ShowParcelOwners",false);
if (show_parcel_owners)
{
if (mVertexShaderLevel > 1)
{ //use fullbright shader for highlighting
LLGLSLShader* old_shader = sShader;
sShader->unbind();
sShader = &gObjectFullbrightProgram;
sShader->bind();
renderOwnership();
sShader = old_shader;
sShader->bind();
}
else
{
gPipeline.disableLights();
renderOwnership();
}
}
}
void LLDrawPoolTerrain::beginDeferredPass(S32 pass)
{
LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN);
LLFacePool::beginRenderPass(pass);
sShader = &gDeferredTerrainProgram;
sShader->bind();
}
void LLDrawPoolTerrain::endDeferredPass(S32 pass)
{
LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN);
LLFacePool::endRenderPass(pass);
sShader->unbind();
}
void LLDrawPoolTerrain::renderDeferred(S32 pass)
{
LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN);
if (mDrawFace.empty())
{
return;
}
renderFullShader();
}
void LLDrawPoolTerrain::beginShadowPass(S32 pass)
{
LLFastTimer t(LLFastTimer::FTM_SHADOW_TERRAIN);
LLFacePool::beginRenderPass(pass);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gDeferredShadowProgram.bind();
}
void LLDrawPoolTerrain::endShadowPass(S32 pass)
{
LLFastTimer t(LLFastTimer::FTM_SHADOW_TERRAIN);
LLFacePool::endRenderPass(pass);
gDeferredShadowProgram.unbind();
}
void LLDrawPoolTerrain::renderShadow(S32 pass)
{
LLFastTimer t(LLFastTimer::FTM_SHADOW_TERRAIN);
if (mDrawFace.empty())
{
return;
}
//LLGLEnable offset(GL_POLYGON_OFFSET);
//glCullFace(GL_FRONT);
drawLoop();
//glCullFace(GL_BACK);
}
void LLDrawPoolTerrain::renderFullShader()
{
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale;
LLVector4 tp0, tp1;
tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x);
tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y);
//
// detail texture 0
//
S32 detail0 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0);
gGL.getTexUnit(detail0)->bind(detail_texture0p);
gGL.getTexUnit(0)->activate();
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
//
// detail texture 1
//
S32 detail1 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1);
gGL.getTexUnit(detail1)->bind(detail_texture1p);
/// ALPHA TEXTURE COORDS 0:
gGL.getTexUnit(1)->activate();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
// detail texture 2
//
S32 detail2 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2);
gGL.getTexUnit(detail2)->bind(detail_texture2p);
gGL.getTexUnit(2)->activate();
/// ALPHA TEXTURE COORDS 1:
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(-2.f, 0.f, 0.f);
glMatrixMode(GL_MODELVIEW);
//
// detail texture 3
//
S32 detail3 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
gGL.getTexUnit(detail3)->bind(detail_texture3p);
/// ALPHA TEXTURE COORDS 2:
gGL.getTexUnit(3)->activate();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(-1.f, 0.f, 0.f);
glMatrixMode(GL_MODELVIEW);
//
// Alpha Ramp
//
S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep);
// GL_BLEND disabled by default
drawLoop();
// Disable multitexture
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0);
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1);
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2);
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(4)->disable();
gGL.getTexUnit(4)->activate();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
gGL.getTexUnit(detail3)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(3)->disable();
gGL.getTexUnit(3)->activate();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
gGL.getTexUnit(detail2)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(2)->disable();
gGL.getTexUnit(2)->activate();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
gGL.getTexUnit(detail1)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->disable();
gGL.getTexUnit(1)->activate();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
//----------------------------------------------------------------------------
// Restore Texture Unit 0 defaults
gGL.getTexUnit(detail0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(0)->activate();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
}
void LLDrawPoolTerrain::renderFull4TU()
{
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale;
LLVector4 tp0, tp1;
tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x);
tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y);
gGL.blendFunc(LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_SOURCE_ALPHA);
//----------------------------------------------------------------------------
// Pass 1/1
//
// Stage 0: detail texture 0
//
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->bind(detail_texture0p);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
//
// Stage 1: Generate alpha ramp for detail0/detail1 transition
//
gGL.getTexUnit(1)->bind(m2DAlphaRampImagep.get());
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->activate();
// Care about alpha only
gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
//
// Stage 2: Interpolate detail1 with existing based on ramp
//
gGL.getTexUnit(2)->bind(detail_texture1p);
gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(2)->activate();
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
gGL.getTexUnit(2)->setTextureColorBlend(LLTexUnit::TBO_LERP_PREV_ALPHA, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_TEX_COLOR);
//
// Stage 3: Modulate with primary (vertex) color for lighting
//
gGL.getTexUnit(3)->bind(detail_texture1p);
gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(3)->activate();
// Set alpha texture and do lighting modulation
gGL.getTexUnit(3)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_VERT_COLOR);
gGL.getTexUnit(0)->activate();
// GL_BLEND disabled by default
drawLoop();
//----------------------------------------------------------------------------
// Second pass
// Stage 0: Write detail3 into base
//
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->bind(detail_texture3p);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
//
// Stage 1: Generate alpha ramp for detail2/detail3 transition
//
gGL.getTexUnit(1)->bind(m2DAlphaRampImagep);
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->activate();
// Set the texture matrix
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(-2.f, 0.f, 0.f);
// Care about alpha only
gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
//
// Stage 2: Interpolate detail2 with existing based on ramp
//
gGL.getTexUnit(2)->bind(detail_texture2p);
gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(2)->activate();
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
gGL.getTexUnit(2)->setTextureColorBlend(LLTexUnit::TBO_LERP_PREV_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
//
// Stage 3: Generate alpha ramp for detail1/detail2 transition
//
gGL.getTexUnit(3)->bind(m2DAlphaRampImagep);
gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(3)->activate();
// Set the texture matrix
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(-1.f, 0.f, 0.f);
// Set alpha texture and do lighting modulation
gGL.getTexUnit(3)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_VERT_COLOR);
gGL.getTexUnit(3)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
gGL.getTexUnit(0)->activate();
{
LLGLEnable blend(GL_BLEND);
drawLoop();
}
LLVertexBuffer::unbind();
// Disable multitexture
gGL.getTexUnit(3)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(3)->disable();
gGL.getTexUnit(3)->activate();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(2)->disable();
gGL.getTexUnit(2)->activate();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->disable();
gGL.getTexUnit(1)->activate();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
// Restore blend state
gGL.setSceneBlendType(LLRender::BT_ALPHA);
//----------------------------------------------------------------------------
// Restore Texture Unit 0 defaults
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
void LLDrawPoolTerrain::renderFull2TU()
{
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale;
LLVector4 tp0, tp1;
tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x);
tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y);
gGL.blendFunc(LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_SOURCE_ALPHA);
//----------------------------------------------------------------------------
// Pass 1/4
//
// Stage 0: Render detail 0 into base
//
gGL.getTexUnit(0)->bind(detail_texture0p);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
drawLoop();
//----------------------------------------------------------------------------
// Pass 2/4
//
// Stage 0: Generate alpha ramp for detail0/detail1 transition
//
gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
// Care about alpha only
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
//
// Stage 1: Write detail1
//
gGL.getTexUnit(1)->bind(detail_texture1p);
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->activate();
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
gGL.getTexUnit(0)->activate();
{
LLGLEnable blend(GL_BLEND);
drawLoop();
}
//----------------------------------------------------------------------------
// Pass 3/4
//
// Stage 0: Generate alpha ramp for detail1/detail2 transition
//
gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
// Set the texture matrix
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(-1.f, 0.f, 0.f);
// Care about alpha only
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
//
// Stage 1: Write detail2
//
gGL.getTexUnit(1)->bind(detail_texture2p);
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->activate();
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
{
LLGLEnable blend(GL_BLEND);
drawLoop();
}
//----------------------------------------------------------------------------
// Pass 4/4
//
// Stage 0: Generate alpha ramp for detail2/detail3 transition
//
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
// Set the texture matrix
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(-2.f, 0.f, 0.f);
// Care about alpha only
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
// Stage 1: Write detail3
gGL.getTexUnit(1)->bind(detail_texture3p);
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->activate();
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
gGL.getTexUnit(0)->activate();
{
LLGLEnable blend(GL_BLEND);
drawLoop();
}
// Restore blend state
gGL.setSceneBlendType(LLRender::BT_ALPHA);
// Disable multitexture
gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->disable();
gGL.getTexUnit(1)->activate();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
//----------------------------------------------------------------------------
// Restore Texture Unit 0 defaults
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
void LLDrawPoolTerrain::renderSimple()
{
LLVector4 tp0, tp1;
//----------------------------------------------------------------------------
// Pass 1/1
// Stage 0: Base terrain texture pass
mTexturep->addTextureStats(1024.f*1024.f);
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(0)->bind(mTexturep);
LLVector3 origin_agent = mDrawFace[0]->getDrawable()->getVObj()->getRegion()->getOriginAgent();
F32 tscale = 1.f/256.f;
tp0.setVec(tscale, 0.f, 0.0f, -1.f*(origin_agent.mV[0]/256.f));
tp1.setVec(0.f, tscale, 0.0f, -1.f*(origin_agent.mV[1]/256.f));
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
drawLoop();
//----------------------------------------------------------------------------
// Restore Texture Unit 0 defaults
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
//============================================================================
void LLDrawPoolTerrain::renderOwnership()
{
LLGLSPipelineAlpha gls_pipeline_alpha;
llassert(!mDrawFace.empty());
// Each terrain pool is associated with a single region.
// We need to peek back into the viewer's data to find out
// which ownership overlay texture to use.
LLFace *facep = mDrawFace[0];
LLDrawable *drawablep = facep->getDrawable();
const LLViewerObject *objectp = drawablep->getVObj();
const LLVOSurfacePatch *vo_surface_patchp = (LLVOSurfacePatch *)objectp;
LLSurfacePatch *surface_patchp = vo_surface_patchp->getPatch();
LLSurface *surfacep = surface_patchp->getSurface();
LLViewerRegion *regionp = surfacep->getRegion();
LLViewerParcelOverlay *overlayp = regionp->getParcelOverlay();
LLViewerTexture *texturep = overlayp->getTexture();
gGL.getTexUnit(0)->bind(texturep);
// *NOTE: Because the region is 256 meters wide, but has 257 pixels, the
// texture coordinates for pixel 256x256 is not 1,1. This makes the
// ownership map not line up with the selection. We address this with
// a texture matrix multiply.
glMatrixMode(GL_TEXTURE);
glPushMatrix();
const F32 TEXTURE_FUDGE = 257.f / 256.f;
glScalef( TEXTURE_FUDGE, TEXTURE_FUDGE, 1.f );
for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
iter != mDrawFace.end(); iter++)
{
LLFace *facep = *iter;
facep->renderIndexed(LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0);
}
glMatrixMode(GL_TEXTURE);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void LLDrawPoolTerrain::renderForSelect()
{
if (mDrawFace.empty())
{
return;
}
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
iter != mDrawFace.end(); iter++)
{
LLFace *facep = *iter;
if (!facep->getDrawable()->isDead() && (facep->getDrawable()->getVObj()->mGLName))
{
facep->renderForSelect(LLVertexBuffer::MAP_VERTEX);
}
}
}
void LLDrawPoolTerrain::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures)
{
LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(mTexturep) ;
if (tex && textures.find(tex) != textures.end())
{
for (std::vector<LLFace*>::iterator iter = mReferences.begin();
iter != mReferences.end(); iter++)
{
LLFace *facep = *iter;
gPipeline.markTextured(facep->getDrawable());
}
}
}
LLViewerTexture *LLDrawPoolTerrain::getTexture()
{
return mTexturep;
}
LLViewerTexture *LLDrawPoolTerrain::getDebugTexture()
{
return mTexturep;
}
LLColor3 LLDrawPoolTerrain::getDebugColor() const
{
return LLColor3(0.f, 0.f, 1.f);
}