PageRenderTime 444ms CodeModel.GetById 167ms app.highlight 67ms RepoModel.GetById 155ms app.codeStats 50ms

/indra/newview/lldynamictexture.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 284 lines | 189 code | 31 blank | 64 comment | 33 complexity | c7c215b7361e29949df57d5f07107261 MD5 | raw file
  1/** 
  2 * @file lldynamictexture.cpp
  3 * @brief Implementation of LLViewerDynamicTexture class
  4 *
  5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "lldynamictexture.h"
 30
 31// Linden library includes
 32#include "llglheaders.h"
 33#include "llwindow.h"			// getPosition()
 34
 35// Viewer includes
 36#include "llviewerwindow.h"
 37#include "llviewercamera.h"
 38#include "llviewercontrol.h"
 39#include "llviewertexture.h"
 40#include "llvertexbuffer.h"
 41#include "llviewerdisplay.h"
 42#include "llrender.h"
 43#include "pipeline.h"
 44#include "llglslshader.h"
 45
 46// static
 47LLViewerDynamicTexture::instance_list_t LLViewerDynamicTexture::sInstances[ LLViewerDynamicTexture::ORDER_COUNT ];
 48S32 LLViewerDynamicTexture::sNumRenders = 0;
 49
 50//-----------------------------------------------------------------------------
 51// LLViewerDynamicTexture()
 52//-----------------------------------------------------------------------------
 53LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 components, EOrder order, BOOL clamp) : 
 54	LLViewerTexture(width, height, components, FALSE),
 55	mClamp(clamp)
 56{
 57	llassert((1 <= components) && (components <= 4));
 58
 59	if(gGLManager.mDebugGPU)
 60	{
 61		if(components == 3)
 62		{
 63			mComponents = 4 ; //convert to 32bits.
 64		}
 65	}
 66	generateGLTexture();
 67
 68	llassert( 0 <= order && order < ORDER_COUNT );
 69	LLViewerDynamicTexture::sInstances[ order ].insert(this);
 70}
 71
 72//-----------------------------------------------------------------------------
 73// LLViewerDynamicTexture()
 74//-----------------------------------------------------------------------------
 75LLViewerDynamicTexture::~LLViewerDynamicTexture()
 76{
 77	for( S32 order = 0; order < ORDER_COUNT; order++ )
 78	{
 79		LLViewerDynamicTexture::sInstances[order].erase(this);  // will fail in all but one case.
 80	}
 81}
 82
 83//virtual 
 84S8 LLViewerDynamicTexture::getType() const
 85{
 86	return LLViewerTexture::DYNAMIC_TEXTURE ;
 87}
 88
 89//-----------------------------------------------------------------------------
 90// generateGLTexture()
 91//-----------------------------------------------------------------------------
 92void LLViewerDynamicTexture::generateGLTexture()
 93{
 94	LLViewerTexture::generateGLTexture() ;
 95	generateGLTexture(-1, 0, 0, FALSE);
 96}
 97
 98void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
 99{
100	if (mComponents < 1 || mComponents > 4)
101	{
102		llerrs << "Bad number of components in dynamic texture: " << mComponents << llendl;
103	}
104	
105	LLPointer<LLImageRaw> raw_image = new LLImageRaw(mFullWidth, mFullHeight, mComponents);
106	if (internal_format >= 0)
107	{
108		setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
109	}
110	createGLTexture(0, raw_image, 0, TRUE, LLViewerTexture::DYNAMIC_TEX);
111	setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);
112	mGLTexturep->setGLTextureCreated(false);
113}
114
115//-----------------------------------------------------------------------------
116// render()
117//-----------------------------------------------------------------------------
118BOOL LLViewerDynamicTexture::render()
119{
120	return FALSE;
121}
122
123//-----------------------------------------------------------------------------
124// preRender()
125//-----------------------------------------------------------------------------
126void LLViewerDynamicTexture::preRender(BOOL clear_depth)
127{
128	{
129		// force rendering to on-screen portion of frame buffer
130		LLCoordScreen window_pos;
131		gViewerWindow->getWindow()->getPosition( &window_pos );
132		mOrigin.set(0, gViewerWindow->getWindowHeightRaw() - mFullHeight);  // top left corner
133
134		if (window_pos.mX < 0)
135		{
136			mOrigin.mX = -window_pos.mX;
137		}
138		if (window_pos.mY < 0)
139		{
140			mOrigin.mY += window_pos.mY;
141			mOrigin.mY = llmax(mOrigin.mY, 0) ;
142		}
143
144		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
145	}
146	// Set up camera
147	LLViewerCamera* camera = LLViewerCamera::getInstance();
148	mCamera.setOrigin(*camera);
149	mCamera.setAxes(*camera);
150	mCamera.setAspect(camera->getAspect());
151	mCamera.setView(camera->getView());
152	mCamera.setNear(camera->getNear());
153
154	glViewport(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
155	if (clear_depth)
156	{
157		glClear(GL_DEPTH_BUFFER_BIT);
158	}
159}
160
161//-----------------------------------------------------------------------------
162// postRender()
163//-----------------------------------------------------------------------------
164void LLViewerDynamicTexture::postRender(BOOL success)
165{
166	{
167		if (success)
168		{
169			if(mGLTexturep.isNull())
170			{
171				generateGLTexture() ;
172			}
173			else if(!mGLTexturep->getHasGLTexture())
174			{
175				generateGLTexture() ;
176			}			
177			else if(mGLTexturep->getDiscardLevel() != 0)//do not know how it happens, but regenerate one if it does.
178			{
179				generateGLTexture() ;
180			}
181
182			success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
183		}
184	}
185
186	// restore viewport
187	gViewerWindow->setup2DViewport();
188
189	// restore camera
190	LLViewerCamera* camera = LLViewerCamera::getInstance();
191	camera->setOrigin(mCamera);
192	camera->setAxes(mCamera);
193	camera->setAspect(mCamera.getAspect());
194	camera->setView(mCamera.getView());
195	camera->setNear(mCamera.getNear());
196}
197
198//-----------------------------------------------------------------------------
199// static
200// updateDynamicTextures()
201// Calls update on each dynamic texture.  Calls each group in order: "first," then "middle," then "last."
202//-----------------------------------------------------------------------------
203BOOL LLViewerDynamicTexture::updateAllInstances()
204{
205	sNumRenders = 0;
206	if (gGLManager.mIsDisabled || LLPipeline::sMemAllocationThrottled)
207	{
208		return TRUE;
209	}
210
211	LLGLSLShader::bindNoShader();
212	LLVertexBuffer::unbind();
213	
214	BOOL result = FALSE;
215	BOOL ret = FALSE ;
216	for( S32 order = 0; order < ORDER_COUNT; order++ )
217	{
218		for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
219			 iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
220		{
221			LLViewerDynamicTexture *dynamicTexture = *iter;
222			if (dynamicTexture->needsRender())
223			{				
224				glClear(GL_DEPTH_BUFFER_BIT);
225				gDepthDirty = TRUE;
226								
227				gGL.color4f(1,1,1,1);
228				dynamicTexture->preRender();	// Must be called outside of startRender()
229				result = FALSE;
230				if (dynamicTexture->render())
231				{
232					ret = TRUE ;
233					result = TRUE;
234					sNumRenders++;
235				}
236				gGL.flush();
237				LLVertexBuffer::unbind();
238				
239				dynamicTexture->postRender(result);
240			}
241		}
242	}
243
244	return ret;
245}
246
247//-----------------------------------------------------------------------------
248// static
249// destroyGL()
250//-----------------------------------------------------------------------------
251void LLViewerDynamicTexture::destroyGL()
252{
253	for( S32 order = 0; order < ORDER_COUNT; order++ )
254	{
255		for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
256			 iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
257		{
258			LLViewerDynamicTexture *dynamicTexture = *iter;
259			dynamicTexture->destroyGLTexture() ;
260		}
261	}
262}
263
264//-----------------------------------------------------------------------------
265// static
266// restoreGL()
267//-----------------------------------------------------------------------------
268void LLViewerDynamicTexture::restoreGL()
269{
270	if (gGLManager.mIsDisabled)
271	{
272		return ;
273	}			
274	
275	for( S32 order = 0; order < ORDER_COUNT; order++ )
276	{
277		for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
278			 iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
279		{
280			LLViewerDynamicTexture *dynamicTexture = *iter;
281			dynamicTexture->restoreGLTexture() ;
282		}
283	}
284}