Skip to content
Snippets Groups Projects
lldynamictexture.cpp 8.13 KiB
Newer Older
James Cook's avatar
James Cook committed
/** 
 * @file lldynamictexture.cpp
 * @brief Implementation of LLViewerDynamicTexture class
James Cook's avatar
James Cook committed
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
James Cook's avatar
James Cook committed
 */

#include "llviewerprecompiledheaders.h"

#include "lldynamictexture.h"
James Cook's avatar
James Cook committed
#include "llglheaders.h"
#include "llwindow.h"			// getPosition()

// Viewer includes
James Cook's avatar
James Cook committed
#include "llviewerwindow.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
#include "llviewertexture.h"
#include "llvertexbuffer.h"
#include "llrender.h"
#include "pipeline.h"
James Cook's avatar
James Cook committed

// static
LLViewerDynamicTexture::instance_list_t LLViewerDynamicTexture::sInstances[ LLViewerDynamicTexture::ORDER_COUNT ];
S32 LLViewerDynamicTexture::sNumRenders = 0;
James Cook's avatar
James Cook committed

//-----------------------------------------------------------------------------
// LLViewerDynamicTexture()
James Cook's avatar
James Cook committed
//-----------------------------------------------------------------------------
LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 components, EOrder order, BOOL clamp) : 
	LLViewerTexture(width, height, components, FALSE),
James Cook's avatar
James Cook committed
	mClamp(clamp)
{
	llassert((1 <= components) && (components <= 4));

	generateGLTexture();

	llassert( 0 <= order && order < ORDER_COUNT );
	LLViewerDynamicTexture::sInstances[ order ].insert(this);
James Cook's avatar
James Cook committed
}

//-----------------------------------------------------------------------------
// LLViewerDynamicTexture()
James Cook's avatar
James Cook committed
//-----------------------------------------------------------------------------
LLViewerDynamicTexture::~LLViewerDynamicTexture()
James Cook's avatar
James Cook committed
{
	for( S32 order = 0; order < ORDER_COUNT; order++ )
	{
		LLViewerDynamicTexture::sInstances[order].erase(this);  // will fail in all but one case.
//virtual 
S8 LLViewerDynamicTexture::getType() const
James Cook's avatar
James Cook committed
{
	return LLViewerTexture::DYNAMIC_TEXTURE ;
James Cook's avatar
James Cook committed

//-----------------------------------------------------------------------------
// generateGLTexture()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::generateGLTexture()
	LLViewerTexture::generateGLTexture() ;
James Cook's avatar
James Cook committed
}

void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
James Cook's avatar
James Cook committed
{
	if (mComponents < 1 || mComponents > 4)
	{
		LL_ERRS() << "Bad number of components in dynamic texture: " << mComponents << LL_ENDL;
James Cook's avatar
James Cook committed
	}
	
	LLPointer<LLImageRaw> raw_image = new LLImageRaw(mFullWidth, mFullHeight, mComponents);
		setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
	createGLTexture(0, raw_image, 0, TRUE, LLGLTexture::DYNAMIC_TEX);
	setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);
	mGLTexturep->setGLTextureCreated(false);
James Cook's avatar
James Cook committed
}

//-----------------------------------------------------------------------------
// render()
//-----------------------------------------------------------------------------
BOOL LLViewerDynamicTexture::render()
James Cook's avatar
James Cook committed
{
	return FALSE;
}

//-----------------------------------------------------------------------------
// preRender()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::preRender(BOOL clear_depth)
James Cook's avatar
James Cook committed
{
     //use the bottom left corner
	mOrigin.set(0, 0);
    gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
James Cook's avatar
James Cook committed
	// Set up camera
Rye Mutt's avatar
Rye Mutt committed
	LLViewerCamera* camera = LLViewerCamera::getInstance();
	mCamera.setOrigin(*camera);
	mCamera.setAxes(*camera);
	mCamera.setAspect(camera->getAspect());
	mCamera.setView(camera->getView());
	mCamera.setNear(camera->getNear());
James Cook's avatar
James Cook committed

	glViewport(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
James Cook's avatar
James Cook committed
	if (clear_depth)
	{
		glClear(GL_DEPTH_BUFFER_BIT);
	}
}

//-----------------------------------------------------------------------------
// postRender()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::postRender(BOOL success)
James Cook's avatar
James Cook committed
{
	{
		if (success)
		{
			if(mGLTexturep.isNull())
			{
				generateGLTexture() ;
			}
			else if(!mGLTexturep->getHasGLTexture())
			else if(mGLTexturep->getDiscardLevel() != 0)//do not know how it happens, but regenerate one if it does.
			success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
James Cook's avatar
James Cook committed
		}
	}

	// restore viewport
	gViewerWindow->setup2DViewport();
James Cook's avatar
James Cook committed

	// restore camera
Rye Mutt's avatar
Rye Mutt committed
	LLViewerCamera* camera = LLViewerCamera::getInstance();
	camera->setOrigin(mCamera);
	camera->setAxes(mCamera);
	camera->setAspect(mCamera.getAspect());
	camera->setViewNoBroadcast(mCamera.getView());
James Cook's avatar
James Cook committed
}

//-----------------------------------------------------------------------------
// static
// updateDynamicTextures()
// Calls update on each dynamic texture.  Calls each group in order: "first," then "middle," then "last."
//-----------------------------------------------------------------------------
BOOL LLViewerDynamicTexture::updateAllInstances()
James Cook's avatar
James Cook committed
{
Rye Mutt's avatar
Rye Mutt committed
    LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;

James Cook's avatar
James Cook committed
	sNumRenders = 0;
	if (gGLManager.mIsDisabled)
James Cook's avatar
James Cook committed
	{
Graham Linden's avatar
Graham Linden committed
		return TRUE;
    LLRenderTarget& bake_target = gPipeline.mBake;
Rye Mutt's avatar
Rye Mutt committed
	if (!bake_target.isComplete())
    {
        llassert(false);
		return FALSE;
    }
    llassert(bake_target.getWidth() >= LLPipeline::MAX_BAKE_WIDTH);
    llassert(bake_target.getHeight() >= LLPipeline::MAX_BAKE_WIDTH);

    bake_target.bindTarget();
    bake_target.clear();
James Cook's avatar
James Cook committed
	BOOL result = FALSE;
James Cook's avatar
James Cook committed
	for( S32 order = 0; order < ORDER_COUNT; order++ )
	{
		for (LLViewerDynamicTexture* dynamicTexture : LLViewerDynamicTexture::sInstances[order])
James Cook's avatar
James Cook committed
		{
			if (dynamicTexture->needsRender())
Rye Mutt's avatar
Rye Mutt committed
                llassert(dynamicTexture->getFullWidth() <= LLPipeline::MAX_BAKE_WIDTH);
                llassert(dynamicTexture->getFullHeight() <= LLPipeline::MAX_BAKE_WIDTH);

				gGL.color4f(1,1,1,1);
Rye Mutt's avatar
Rye Mutt committed
                dynamicTexture->setBoundTarget(&bake_target);
				dynamicTexture->preRender();	// Must be called outside of startRender()
James Cook's avatar
James Cook committed
				if (dynamicTexture->render())
				{
James Cook's avatar
James Cook committed
					result = TRUE;
					sNumRenders++;
				}
Graham Linden's avatar
Graham Linden committed
				gGL.flush();
				LLVertexBuffer::unbind();
Graham Linden's avatar
Graham Linden committed
				dynamicTexture->setBoundTarget(nullptr);
James Cook's avatar
James Cook committed
				dynamicTexture->postRender(result);
			}
		}
	}

Rye Mutt's avatar
Rye Mutt committed
	bake_target.flush();
Graham Linden's avatar
Graham Linden committed
    gGL.flush();

James Cook's avatar
James Cook committed
//-----------------------------------------------------------------------------
// static
// destroyGL()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::destroyGL()
James Cook's avatar
James Cook committed
{
	for( S32 order = 0; order < ORDER_COUNT; order++ )
	{
		for (LLViewerDynamicTexture* dynamicTexture : LLViewerDynamicTexture::sInstances[order])
James Cook's avatar
James Cook committed
}

//-----------------------------------------------------------------------------
// static
// restoreGL()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::restoreGL()
James Cook's avatar
James Cook committed
{
	if (gGLManager.mIsDisabled)
	{
		return ;
	}			
	
	for( S32 order = 0; order < ORDER_COUNT; order++ )
	{
		for (LLViewerDynamicTexture* dynamicTexture : LLViewerDynamicTexture::sInstances[order])
James Cook's avatar
James Cook committed
}