aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lldrawpooltree.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/lldrawpooltree.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/lldrawpooltree.cpp361
1 files changed, 361 insertions, 0 deletions
diff --git a/linden/indra/newview/lldrawpooltree.cpp b/linden/indra/newview/lldrawpooltree.cpp
new file mode 100644
index 0000000..ad05d9a
--- /dev/null
+++ b/linden/indra/newview/lldrawpooltree.cpp
@@ -0,0 +1,361 @@
1/**
2 * @file lldrawpooltree.cpp
3 * @brief LLDrawPoolTree class implementation
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29
30#include "lldrawpooltree.h"
31
32#include "llagparray.h"
33#include "lldrawable.h"
34#include "llface.h"
35#include "llsky.h"
36#include "llviewerwindow.h"
37#include "llvotree.h"
38#include "pipeline.h"
39#include "llviewercamera.h"
40
41S32 LLDrawPoolTree::sDiffTex = 0;
42
43LLDrawPoolTree::LLDrawPoolTree(LLViewerImage *texturep) :
44 LLDrawPool(POOL_TREE, DATA_SIMPLE_IL_MASK, 0),
45 mTexturep(texturep)
46{
47 mTexturep->bind(0);
48 mTexturep->setClamp(FALSE, FALSE);
49}
50
51LLDrawPool *LLDrawPoolTree::instancePool()
52{
53 return new LLDrawPoolTree(mTexturep);
54}
55
56void LLDrawPoolTree::prerender()
57{
58 mVertexShaderLevel = gPipeline.getVertexShaderLevel(LLPipeline::SHADER_OBJECT);
59}
60
61void LLDrawPoolTree::beginRenderPass(S32 pass)
62{
63 glEnableClientState(GL_VERTEX_ARRAY);
64 glEnableClientState(GL_NORMAL_ARRAY);
65 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
66
67 if ((mVertexShaderLevel > 0))
68 {
69 S32 scatterTex = gPipeline.mObjectSimpleProgram.enableTexture(LLPipeline::GLSL_SCATTER_MAP);
70 LLViewerImage::bindTexture(gSky.mVOSkyp->getScatterMap(), scatterTex);
71 sDiffTex = gPipeline.mObjectSimpleProgram.enableTexture(LLPipeline::GLSL_DIFFUSE_MAP);
72 }
73}
74
75void LLDrawPoolTree::render(S32 pass)
76{
77 LLFastTimer t(LLFastTimer::FTM_RENDER_TREES);
78
79 if (mDrawFace.empty())
80 {
81 return;
82 }
83
84 gPipeline.enableLightsDynamic(1.f);
85 LLGLSPipelineAlpha gls_pipeline_alpha;
86
87 bindGLVertexPointer();
88 bindGLTexCoordPointer();
89 bindGLNormalPointer();
90
91 LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);
92
93 renderTree();
94
95}
96
97void LLDrawPoolTree::endRenderPass(S32 pass)
98{
99 if ((mVertexShaderLevel > 0))
100 {
101 gPipeline.mObjectSimpleProgram.disableTexture(LLPipeline::GLSL_SCATTER_MAP);
102 gPipeline.mObjectSimpleProgram.disableTexture(LLPipeline::GLSL_DIFFUSE_MAP);
103 glActiveTextureARB(GL_TEXTURE0_ARB);
104 glEnable(GL_TEXTURE_2D);
105 }
106
107 glDisableClientState(GL_NORMAL_ARRAY);
108 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
109}
110
111void LLDrawPoolTree::renderForSelect()
112{
113 if (mDrawFace.empty() || !mMemory.count())
114 {
115 return;
116 }
117
118 glEnableClientState (GL_VERTEX_ARRAY);
119 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
120
121 LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);
122
123 LLGLSObjectSelectAlpha gls_alpha;
124
125 glBlendFunc(GL_ONE, GL_ZERO);
126 glAlphaFunc(gPickTransparent ? GL_GEQUAL : GL_GREATER, 0.f);
127
128 bindGLVertexPointer();
129 bindGLTexCoordPointer();
130
131 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
132 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
133 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
134
135 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
136 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
137
138 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
139 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
140
141 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
142 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
143
144 renderTree(TRUE);
145
146 glAlphaFunc(GL_GREATER, 0.01f);
147 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
148
149 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
150 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
151}
152
153void LLDrawPoolTree::renderTree(BOOL selecting)
154{
155 LLGLState normalize(GL_NORMALIZE, TRUE);
156
157 // Bind the texture for this tree.
158 LLViewerImage::bindTexture(mTexturep,sDiffTex);
159 if (mTexturep)
160 {
161 if (mTexturep->getClampS()) {
162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
163 }
164 if (mTexturep->getClampT()) {
165 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
166 }
167 }
168
169 glMatrixMode(GL_MODELVIEW);
170
171 for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
172 iter != mDrawFace.end(); iter++)
173 {
174 LLFace *face = *iter;
175 LLDrawable *drawablep = face->getDrawable();
176
177 if (drawablep->isDead())
178 {
179 continue;
180 }
181
182 // Render each of the trees
183 LLVOTree *treep = (LLVOTree *)drawablep->getVObj();
184
185 LLColor4U color(255,255,255,255);
186
187 if (!selecting || treep->mGLName != 0)
188 {
189 if (selecting)
190 {
191 S32 name = treep->mGLName;
192
193 color = LLColor4U((U8)(name >> 16), (U8)(name >> 8), (U8)name, 255);
194 }
195
196 glPushMatrix();
197
198 // Translate to tree base HACK - adjustment in Z plants tree underground
199 const LLVector3 &pos_agent = treep->getPositionAgent();
200 glTranslatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
201
202 // Rotate to tree position
203 F32 angle_radians, x, y, z;
204 treep->getRotation().getAngleAxis(&angle_radians, &x, &y, &z);
205 glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
206
207 // Rotate and bend for current trunk/wind
208 // Note that trunk stiffness controls the amount of bend at the trunk as
209 // opposed to the crown of the tree
210 //
211 glRotatef(90.f, 0, 0, 1);
212 const F32 TRUNK_STIFF = 22.f;
213 glRotatef(treep->mTrunkBend.magVec()*TRUNK_STIFF, treep->mTrunkBend.mV[VX], treep->mTrunkBend.mV[VY], 0);
214
215 F32 radius = treep->getScale().magVec()*0.5f;
216 radius *= 0.1f;
217 glScalef(radius, radius, radius);
218
219 const F32 THRESH_ANGLE_FOR_BILLBOARD = 15.f;
220 const F32 BLEND_RANGE_FOR_BILLBOARD = 3.f;
221
222 F32 droop = treep->mDroop + 25.f*(1.f - treep->mTrunkBend.magVec());
223
224 S32 stop_depth = 0;
225 F32 app_angle = treep->getAppAngle()*LLVOTree::sTreeFactor;
226 F32 alpha = 1.0;
227 S32 trunk_LOD = 0;
228
229 for (S32 j = 0; j < 4; j++)
230 {
231
232 if (app_angle > LLVOTree::sLODAngles[j])
233 {
234 trunk_LOD = j;
235 break;
236 }
237 }
238
239 if (app_angle > (THRESH_ANGLE_FOR_BILLBOARD + BLEND_RANGE_FOR_BILLBOARD))
240 {
241 //
242 // Draw only the full geometry tree
243 //
244 //stop_depth = (app_angle < THRESH_ANGLE_FOR_RECURSION_REDUCTION);
245 glAlphaFunc(GL_GREATER, 0.5f);
246 LLDrawPool::LLOverrideFaceColor clr(this, color);
247 treep->drawBranchPipeline(this, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha);
248 }
249 else if (app_angle < (THRESH_ANGLE_FOR_BILLBOARD - BLEND_RANGE_FOR_BILLBOARD))
250 {
251 //
252 // Draw only the billboard
253 //
254 // Only the billboard, can use closer to normal alpha func.
255 stop_depth = -1;
256 glAlphaFunc(GL_GREATER, 0.4f);
257 LLDrawPool::LLOverrideFaceColor clr(this, color);
258 treep->drawBranchPipeline(this, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha);
259 }
260 else
261 {
262 //
263 // Draw a blended version including both billboard and full tree
264 //
265 alpha = (app_angle - THRESH_ANGLE_FOR_BILLBOARD)/BLEND_RANGE_FOR_BILLBOARD;
266 BOOL billboard_depth = TRUE; // billboard gets alpha
267 if (alpha > 0.5f)
268 {
269 billboard_depth = FALSE;
270 }
271 alpha = alpha/2.f + 0.5f;
272
273 glAlphaFunc(GL_GREATER, alpha*0.5f);
274 {
275 LLGLDepthTest gls_depth(GL_TRUE, billboard_depth ? GL_FALSE : GL_TRUE);
276 color.mV[3] = (U8) (llclamp(alpha, 0.0f, 1.0f) * 255);
277 LLDrawPool::LLOverrideFaceColor clr(this, color);
278 treep->drawBranchPipeline(this, trunk_LOD, 0, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha);
279 }
280 {
281 LLGLDepthTest gls_depth(GL_TRUE, billboard_depth ? GL_TRUE : GL_FALSE);
282 glAlphaFunc(GL_GREATER, (1.f - alpha)*0.1f);
283 color.mV[3] = (U8) (llclamp(1.f-alpha, 0.0f, 1.0f) * 255);
284 LLDrawPool::LLOverrideFaceColor clr(this, color);
285 treep->drawBranchPipeline(this, trunk_LOD, -1, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, 1.f - alpha);
286 }
287 }
288 glPopMatrix();
289 }
290 }
291
292 if (mTexturep)
293 {
294 if (mTexturep->getClampS()) {
295 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
296 }
297 if (mTexturep->getClampT()) {
298 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
299 }
300 }
301 glAlphaFunc(GL_GREATER, 0.01f);
302}
303
304
305S32 LLDrawPoolTree::rebuild()
306{
307 mRebuildTime++;
308 if (mRebuildTime > mRebuildFreq)
309 {
310 // Flush AGP to force an AGP realloc and reduce AGP fragmentation
311 flushAGP();
312 mRebuildTime = 0;
313 }
314
315 return 0;
316}
317
318BOOL LLDrawPoolTree::verify() const
319{
320 BOOL ok = TRUE;
321
322 // shared geometry. Just verify that it's there and correct.
323
324 // Verify all indices in the pool are in the right range
325 const U32 *indicesp = getRawIndices();
326 for (U32 i = 0; i < getIndexCount(); i++)
327 {
328 if (indicesp[i] > getVertexCount())
329 {
330 ok = FALSE;
331 llinfos << "Bad index in tree pool!" << llendl;
332 }
333 }
334
335 if (!ok)
336 {
337 printDebugInfo();
338 }
339 return ok;
340}
341
342LLViewerImage *LLDrawPoolTree::getTexture()
343{
344 return mTexturep;
345}
346
347LLViewerImage *LLDrawPoolTree::getDebugTexture()
348{
349 return mTexturep;
350}
351
352
353LLColor3 LLDrawPoolTree::getDebugColor() const
354{
355 return LLColor3(1.f, 0.f, 1.f);
356}
357
358S32 LLDrawPoolTree::getMaterialAttribIndex()
359{
360 return gPipeline.mObjectSimpleProgram.mAttribute[LLPipeline::GLSL_MATERIAL_COLOR];
361}