lldynamictexture.cpp 8.45 KB
Newer Older
James Cook's avatar
James Cook committed
1
2
/** 
 * @file lldynamictexture.cpp
3
 * @brief Implementation of LLViewerDynamicTexture class
James Cook's avatar
James Cook committed
4
 *
5
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
6
 * Second Life Viewer Source Code
7
8
9
10
11
12
 * 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.
13
 * 
14
15
16
17
 * 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.
18
 * 
19
20
21
 * 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
22
 * 
23
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
24
 * $/LicenseInfo$
James Cook's avatar
James Cook committed
25
26
27
28
29
 */

#include "llviewerprecompiledheaders.h"

#include "lldynamictexture.h"
30
31

// Linden library includes
James Cook's avatar
James Cook committed
32
#include "llglheaders.h"
33
34
35
#include "llwindow.h"			// getPosition()

// Viewer includes
James Cook's avatar
James Cook committed
36
37
38
#include "llviewerwindow.h"
#include "llviewercamera.h"
#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"
James Cook's avatar
James Cook committed
45
46

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

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

59
60
61
62
63
64
65
	if(gGLManager.mDebugGPU)
	{
		if(components == 3)
		{
			mComponents = 4 ; //convert to 32bits.
		}
	}
James Cook's avatar
James Cook committed
66
67
68
	generateGLTexture();

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

//-----------------------------------------------------------------------------
73
// LLViewerDynamicTexture()
James Cook's avatar
James Cook committed
74
//-----------------------------------------------------------------------------
75
LLViewerDynamicTexture::~LLViewerDynamicTexture()
James Cook's avatar
James Cook committed
76
{
77
78
79
	for (auto& sInstance : LLViewerDynamicTexture::sInstances)
    {
        sInstance.erase(this);  // will fail in all but one case.
James Cook's avatar
James Cook committed
80
81
82
	}
}

83
84
//virtual 
S8 LLViewerDynamicTexture::getType() const
James Cook's avatar
James Cook committed
85
{
86
	return LLViewerTexture::DYNAMIC_TEXTURE ;
87
}
James Cook's avatar
James Cook committed
88

89
90
91
//-----------------------------------------------------------------------------
// generateGLTexture()
//-----------------------------------------------------------------------------
92
void LLViewerDynamicTexture::generateGLTexture()
93
{
94
	LLViewerTexture::generateGLTexture() ;
95
	generateGLTexture(-1, 0, 0, FALSE);
James Cook's avatar
James Cook committed
96
97
}

98
void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
James Cook's avatar
James Cook committed
99
100
101
{
	if (mComponents < 1 || mComponents > 4)
	{
Richard Linden's avatar
Richard Linden committed
102
		LL_ERRS() << "Bad number of components in dynamic texture: " << mComponents << LL_ENDL;
James Cook's avatar
James Cook committed
103
	}
104
105
	
	LLPointer<LLImageRaw> raw_image = new LLImageRaw(mFullWidth, mFullHeight, mComponents);
106
107
	if (internal_format >= 0)
	{
108
		setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
109
	}
110
	createGLTexture(0, raw_image, 0, TRUE, LLGLTexture::DYNAMIC_TEX);
111
112
	setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);
	mGLTexturep->setGLTextureCreated(false);
James Cook's avatar
James Cook committed
113
114
115
116
117
}

//-----------------------------------------------------------------------------
// render()
//-----------------------------------------------------------------------------
118
BOOL LLViewerDynamicTexture::render()
James Cook's avatar
James Cook committed
119
120
121
122
123
124
125
{
	return FALSE;
}

//-----------------------------------------------------------------------------
// preRender()
//-----------------------------------------------------------------------------
126
void LLViewerDynamicTexture::preRender(BOOL clear_depth)
James Cook's avatar
James Cook committed
127
{
128
129
130
	gPipeline.allocatePhysicsBuffer();
	llassert(mFullWidth <= static_cast<S32>(gPipeline.mPhysicsDisplay.getWidth()));
	llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
131

132
	if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI)
133
134
135
136
137
	{ //using offscreen render target, just use the bottom left corner
		mOrigin.set(0, 0);
	}
	else
	{ // force rendering to on-screen portion of frame buffer
James Cook's avatar
James Cook committed
138
139
		LLCoordScreen window_pos;
		gViewerWindow->getWindow()->getPosition( &window_pos );
140
		mOrigin.set(0, gViewerWindow->getWindowHeightRaw() - mFullHeight);  // top left corner
James Cook's avatar
James Cook committed
141
142
143
144
145
146
147
148

		if (window_pos.mX < 0)
		{
			mOrigin.mX = -window_pos.mX;
		}
		if (window_pos.mY < 0)
		{
			mOrigin.mY += window_pos.mY;
Steven Bennetts's avatar
Steven Bennetts committed
149
			mOrigin.mY = llmax(mOrigin.mY, 0) ;
James Cook's avatar
James Cook committed
150
151
		}
	}
152
153

	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
James Cook's avatar
James Cook committed
154
	// Set up camera
155
156
157
158
159
160
	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
161

162
	glViewport(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
James Cook's avatar
James Cook committed
163
164
165
166
167
168
169
170
171
	if (clear_depth)
	{
		glClear(GL_DEPTH_BUFFER_BIT);
	}
}

//-----------------------------------------------------------------------------
// postRender()
//-----------------------------------------------------------------------------
172
void LLViewerDynamicTexture::postRender(BOOL success)
James Cook's avatar
James Cook committed
173
174
175
176
{
	{
		if (success)
		{
177
178
179
180
			if(mGLTexturep.isNull())
			{
				generateGLTexture() ;
			}
181
			else if(!mGLTexturep->getHasGLTexture())
182
183
			{
				generateGLTexture() ;
184
			}			
185
			else if(mGLTexturep->getDiscardLevel() != 0)//do not know how it happens, but regenerate one if it does.
186
187
188
			{
				generateGLTexture() ;
			}
189

190
			success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
James Cook's avatar
James Cook committed
191
192
193
194
		}
	}

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

	// restore camera
198
199
200
201
202
203
	LLViewerCamera* camera = LLViewerCamera::getInstance();
	camera->setOrigin(mCamera);
	camera->setAxes(mCamera);
	camera->setAspect(mCamera.getAspect());
	camera->setView(mCamera.getView());
	camera->setNear(mCamera.getNear());
James Cook's avatar
James Cook committed
204
205
206
207
208
209
210
}

//-----------------------------------------------------------------------------
// static
// updateDynamicTextures()
// Calls update on each dynamic texture.  Calls each group in order: "first," then "middle," then "last."
//-----------------------------------------------------------------------------
211
BOOL LLViewerDynamicTexture::updateAllInstances()
James Cook's avatar
James Cook committed
212
213
{
	sNumRenders = 0;
214
	if (gGLManager.mIsDisabled || LLPipeline::sMemAllocationThrottled)
James Cook's avatar
James Cook committed
215
216
217
218
	{
		return TRUE;
	}

219
	bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI;
220
221
	if (use_fbo)
	{
222
		gPipeline.mPhysicsDisplay.bindTarget();
223
224
	}

225
226
	LLGLSLShader::bindNoShader();
	LLVertexBuffer::unbind();
227
	
James Cook's avatar
James Cook committed
228
	BOOL result = FALSE;
229
	BOOL ret = FALSE ;
230
231
	for (auto& sInstance : LLViewerDynamicTexture::sInstances)
    {
Cinder's avatar
Cinder committed
232
233
234
		for (auto dynamicTexture : sInstance)
        {
            if (dynamicTexture->needsRender())
235
			{				
236
				glClear(GL_DEPTH_BUFFER_BIT);
237
				gDepthDirty = TRUE;
238
								
Steven Bennetts's avatar
Steven Bennetts committed
239
				gGL.color4f(1,1,1,1);
240
				dynamicTexture->preRender();	// Must be called outside of startRender()
241
				result = FALSE;
James Cook's avatar
James Cook committed
242
243
				if (dynamicTexture->render())
				{
244
					ret = TRUE ;
James Cook's avatar
James Cook committed
245
246
247
					result = TRUE;
					sNumRenders++;
				}
Steven Bennetts's avatar
Steven Bennetts committed
248
249
250
				gGL.flush();
				LLVertexBuffer::unbind();
				
James Cook's avatar
James Cook committed
251
252
253
254
255
				dynamicTexture->postRender(result);
			}
		}
	}

256
257
	if (use_fbo)
	{
258
		gPipeline.mPhysicsDisplay.flush();
259
260
	}

261
262
263
	return ret;
}

James Cook's avatar
James Cook committed
264
265
266
267
//-----------------------------------------------------------------------------
// static
// destroyGL()
//-----------------------------------------------------------------------------
268
void LLViewerDynamicTexture::destroyGL()
James Cook's avatar
James Cook committed
269
{
270
271
	for (auto& sInstance : LLViewerDynamicTexture::sInstances)
    {
Cinder's avatar
Cinder committed
272
273
274
		for (auto dynamicTexture : sInstance)
        {
            dynamicTexture->destroyGLTexture() ;
275
276
		}
	}
James Cook's avatar
James Cook committed
277
278
279
280
281
282
}

//-----------------------------------------------------------------------------
// static
// restoreGL()
//-----------------------------------------------------------------------------
283
void LLViewerDynamicTexture::restoreGL()
James Cook's avatar
James Cook committed
284
{
285
286
287
288
289
	if (gGLManager.mIsDisabled)
	{
		return ;
	}			
	
290
291
	for (auto& sInstance : LLViewerDynamicTexture::sInstances)
    {
Cinder's avatar
Cinder committed
292
293
294
		for (auto dynamicTexture : sInstance)
        {
            dynamicTexture->restoreGLTexture() ;
295
296
		}
	}
James Cook's avatar
James Cook committed
297
}