aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lldrawpoolavatar.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/lldrawpoolavatar.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/lldrawpoolavatar.cpp629
1 files changed, 629 insertions, 0 deletions
diff --git a/linden/indra/newview/lldrawpoolavatar.cpp b/linden/indra/newview/lldrawpoolavatar.cpp
new file mode 100644
index 0000000..abf154c
--- /dev/null
+++ b/linden/indra/newview/lldrawpoolavatar.cpp
@@ -0,0 +1,629 @@
1/**
2 * @file lldrawpoolavatar.cpp
3 * @brief LLDrawPoolAvatar 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 "lldrawpoolavatar.h"
31
32#include "llvoavatar.h"
33#include "m3math.h"
34
35#include "llagparray.h"
36#include "llagent.h"
37#include "lldrawable.h"
38#include "llface.h"
39#include "llsky.h"
40#include "llviewercamera.h"
41#include "llviewerregion.h"
42#include "noise.h"
43#include "pipeline.h"
44
45extern F32 gFrameDTClamped;
46extern BOOL gUseGLPick;
47
48F32 CLOTHING_GRAVITY_EFFECT = 0.7f;
49F32 CLOTHING_ACCEL_FORCE_FACTOR = 0.2f;
50const S32 NUM_TEST_AVATARS = 30;
51const S32 MIN_PIXEL_AREA_2_PASS_SKINNING = 500000000;
52
53// Format for gAGPVertices
54// vertex format for bumpmapping:
55// vertices 12
56// pad 4
57// normals 12
58// pad 4
59// texcoords0 8
60// texcoords1 8
61// total 48
62//
63// for no bumpmapping
64// vertices 12
65// texcoords 8
66// normals 12
67// total 32
68//
69
70S32 AVATAR_OFFSET_POS = 0;
71S32 AVATAR_OFFSET_NORMAL = 16;
72S32 AVATAR_OFFSET_TEX0 = 32;
73S32 AVATAR_OFFSET_TEX1 = 40;
74S32 AVATAR_VERTEX_BYTES = 48;
75
76
77BOOL gAvatarEmbossBumpMap = FALSE;
78
79LLDrawPoolAvatar::LLDrawPoolAvatar() :
80LLDrawPool(POOL_AVATAR,
81 DATA_SIMPLE_IL_MASK,
82 DATA_VERTEX_WEIGHTS_MASK | DATA_CLOTHING_WEIGHTS_MASK )
83{
84 mCleanupUnused = FALSE;
85
86 // Overide the data layout
87 mDataMaskIL = 0;
88 mStride = 0;
89 for (S32 i = 0; i < DATA_MAX_TYPES; i++)
90 {
91 mDataOffsets[i] = 0;
92 }
93
94 // Note: padding is to speed up SSE code
95 mDataMaskIL |= DATA_VERTICES_MASK;
96 mDataOffsets[DATA_VERTICES] = mStride;
97 mStride += sDataSizes[DATA_VERTICES];
98
99 mStride += 4;
100
101 mDataMaskIL |= DATA_NORMALS_MASK;
102 mDataOffsets[DATA_NORMALS] = mStride;
103 mStride += sDataSizes[DATA_NORMALS];
104
105 mStride += 4;
106
107 // Note: binormals are stripped off in software blending
108 mDataMaskIL |= DATA_BINORMALS_MASK;
109 mDataOffsets[DATA_BINORMALS] = mStride;
110 mStride += sDataSizes[DATA_BINORMALS];
111
112 mStride += 4; // To keep the structure 16-byte aligned (for SSE happiness)
113
114 mDataMaskIL |= DATA_TEX_COORDS0_MASK;
115 mDataOffsets[DATA_TEX_COORDS0] = mStride;
116 mStride += sDataSizes[DATA_TEX_COORDS0];
117
118 mDataMaskIL |= DATA_TEX_COORDS1_MASK;
119 mDataOffsets[DATA_TEX_COORDS1] = mStride;
120 mStride += sDataSizes[DATA_TEX_COORDS1];
121
122 //LLDebugVarMessageBox::show("acceleration", &CLOTHING_ACCEL_FORCE_FACTOR, 10.f, 0.1f);
123 //LLDebugVarMessageBox::show("gravity", &CLOTHING_GRAVITY_EFFECT, 10.f, 0.1f);
124
125}
126
127//-----------------------------------------------------------------------------
128// instancePool()
129//-----------------------------------------------------------------------------
130LLDrawPool *LLDrawPoolAvatar::instancePool()
131{
132 return new LLDrawPoolAvatar();
133}
134
135
136S32 LLDrawPoolAvatar::rebuild()
137{
138 mRebuildTime++;
139 if (mRebuildTime > mRebuildFreq)
140 {
141 flushAGP();
142
143 mRebuildTime = 0;
144 }
145
146 return 0;
147}
148
149BOOL gRenderAvatar = TRUE;
150
151void LLDrawPoolAvatar::prerender()
152{
153 mVertexShaderLevel = gPipeline.getVertexShaderLevel(LLPipeline::SHADER_AVATAR);
154}
155
156//-----------------------------------------------------------------------------
157// render()
158//-----------------------------------------------------------------------------
159void LLDrawPoolAvatar::render(S32 pass)
160{
161 LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS);
162 renderAvatars(NULL); // render all avatars
163}
164
165void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, BOOL no_shaders)
166{
167 if (no_shaders)
168 {
169 mVertexShaderLevel = 0;
170 }
171
172 if (!gRenderAvatar)
173 {
174 return;
175 }
176
177 if (mDrawFace.empty() && !single_avatar)
178 {
179 return;
180 }
181
182 LLVOAvatar *avatarp;
183
184 if (single_avatar)
185 {
186 avatarp = single_avatar;
187 }
188 else
189 {
190 const LLFace *facep = mDrawFace[0];
191 if (!facep->getDrawable())
192 {
193 return;
194 }
195 avatarp = (LLVOAvatar *)(facep->getDrawable()->getVObj());
196 }
197
198 if (avatarp->isDead() || avatarp->mDrawable.isNull())
199 {
200 return;
201 }
202
203 LLOverrideFaceColor color(this, 1.0f, 1.0f, 1.0f, 1.0f);
204
205 if( !single_avatar || (avatarp == single_avatar) )
206 {
207 if (LLVOAvatar::sShowCollisionVolumes)
208 {
209 LLGLSNoTexture no_texture;
210 avatarp->renderCollisionVolumes();
211 }
212
213 LLGLEnable normalize(GL_NORMALIZE);
214
215 if (avatarp->mIsSelf && LLAgent::sDebugDisplayTarget)
216 {
217 LLGLSNoTexture gls_no_texture;
218 LLVector3 pos = avatarp->getPositionAgent();
219
220 color.setColor(1.0f, 0.0f, 0.0f, 0.8f);
221 glBegin(GL_LINES);
222 {
223 glVertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV);
224 glVertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV);
225 glVertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV);
226 glVertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV);
227 glVertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV);
228 glVertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV);
229 }glEnd();
230
231 pos = avatarp->mDrawable->getPositionAgent();
232 color.setColor(1.0f, 0.0f, 0.0f, 0.8f);
233 glBegin(GL_LINES);
234 {
235 glVertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV);
236 glVertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV);
237 glVertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV);
238 glVertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV);
239 glVertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV);
240 glVertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV);
241 }glEnd();
242
243 pos = avatarp->mRoot.getWorldPosition();
244 color.setColor(1.0f, 1.0f, 1.0f, 0.8f);
245 glBegin(GL_LINES);
246 {
247 glVertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV);
248 glVertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV);
249 glVertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV);
250 glVertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV);
251 glVertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV);
252 glVertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV);
253 }glEnd();
254
255 pos = avatarp->mPelvisp->getWorldPosition();
256 color.setColor(0.0f, 0.0f, 1.0f, 0.8f);
257 glBegin(GL_LINES);
258 {
259 glVertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV);
260 glVertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV);
261 glVertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV);
262 glVertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV);
263 glVertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV);
264 glVertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV);
265 }glEnd();
266
267 color.setColor(1.0f, 1.0f, 1.0f, 1.0f);
268 }
269
270 glEnableClientState(GL_VERTEX_ARRAY);
271 glEnableClientState(GL_NORMAL_ARRAY);
272 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
273
274 LLGLSLShader* vertex_program = &gPipeline.mAvatarProgram;
275 if (mVertexShaderLevel > 0)
276 {
277 gPipeline.mAvatarMatrixParam = vertex_program->mUniform[LLPipeline::GLSL_AVATAR_MATRIX];
278 }
279
280 //--------------------------------------------------------------------------------
281 // this is where we first hit the software blending path
282 // if enabled, we need to set up the proper buffers and avoid setting other state
283 //--------------------------------------------------------------------------------
284 if (!(mVertexShaderLevel > 0))
285 {
286
287 // performance could be increased by better utilizing the buffers, for example, only using 1k buffers for lo-res
288 // avatars. But the only problem with using fewer buffers is that we're more likely to wait for a fence to complete
289
290 // vertex format:
291 // vertices 12
292 // texcoords 8
293 // normals 12
294 // binormals 12
295 // padding 4
296 // total 48
297
298 // Rotate to the next buffer, round-robin.
299 gPipeline.bufferRotate();
300
301 // Wait until the hardware is done reading the last set of vertices from the buffer before writing the next set.
302 gPipeline.bufferWaitFence();
303
304 // Need to do this because we may be rendering without AGP even in AGP mode
305 U8* buffer_offset_start = gPipeline.bufferGetScratchMemory();
306 glVertexPointer( 3, GL_FLOAT, AVATAR_VERTEX_BYTES, buffer_offset_start + AVATAR_OFFSET_POS);
307 glTexCoordPointer(2, GL_FLOAT, AVATAR_VERTEX_BYTES, buffer_offset_start + AVATAR_OFFSET_TEX0);
308 glNormalPointer( GL_FLOAT, AVATAR_VERTEX_BYTES, buffer_offset_start + AVATAR_OFFSET_NORMAL);
309
310 }
311
312 if ((mVertexShaderLevel > 0)) // for hardware blending
313 {
314 bindGLVertexPointer();
315 bindGLNormalPointer();
316 bindGLTexCoordPointer(0);
317 }
318
319 if ((mVertexShaderLevel > 0))
320 { //eyeballs render with the specular shader
321 gPipeline.mAvatarEyeballProgram.bind();
322 gPipeline.mMaterialIndex = gPipeline.mAvatarEyeballProgram.mAttribute[LLPipeline::GLSL_MATERIAL_COLOR];
323 gPipeline.mSpecularIndex = gPipeline.mAvatarEyeballProgram.mAttribute[LLPipeline::GLSL_SPECULAR_COLOR];
324
325 S32 index = gPipeline.mAvatarEyeballProgram.enableTexture(LLPipeline::GLSL_SCATTER_MAP);
326 gSky.mVOSkyp->getScatterMap()->bind(index);
327
328 glActiveTextureARB(GL_TEXTURE0_ARB);
329 }
330
331 if (avatarp->mSpecialRenderMode == 0) // normal
332 {
333 gPipeline.enableLightsAvatar(avatarp->mDrawable->getSunShadowFactor());
334 }
335 else if (avatarp->mSpecialRenderMode == 1) // anim preview
336 {
337 gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f));
338 }
339 else // 2=image preview, 3=morph view
340 {
341 gPipeline.enableLightsAvatarEdit(LLColor4(.5f, .5f, .5f, 1.f));
342 }
343
344 // render rigid meshes (eyeballs) first
345 mIndicesDrawn += avatarp->renderRigid();
346
347 if ((mVertexShaderLevel > 0))
348 {
349 gPipeline.mAvatarEyeballProgram.disableTexture(LLPipeline::GLSL_SCATTER_MAP);
350 glActiveTextureARB(GL_TEXTURE0_ARB);
351 }
352
353 if (!gRenderForSelect && avatarp->mIsSelf && LLVOAvatar::sAvatarLoadTest)
354 {
355 LLVector3 orig_pos_root = avatarp->mRoot.getPosition();
356 LLVector3 next_pos_root = orig_pos_root;
357 for (S32 i = 0; i < NUM_TEST_AVATARS; i++)
358 {
359 next_pos_root.mV[VX] += 1.f;
360 if (i % 5 == 0)
361 {
362 next_pos_root.mV[VY] += 1.f;
363 next_pos_root.mV[VX] = orig_pos_root.mV[VX];
364 }
365
366 avatarp->mRoot.setPosition(next_pos_root); // avatar load test
367 avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test
368
369 mIndicesDrawn += avatarp->renderRigid();
370 }
371 avatarp->mRoot.setPosition(orig_pos_root); // avatar load test
372 avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test
373 }
374
375 if ((mVertexShaderLevel > 0)) // for hardware blending
376 {
377 glClientActiveTextureARB(GL_TEXTURE1_ARB);
378 if ((mVertexShaderLevel >= SHADER_LEVEL_BUMP))
379 {
380 bindGLTexCoordPointer(1);
381
382 bindGLBinormalPointer(vertex_program->mAttribute[LLPipeline::GLSL_BINORMAL]);
383 gPipeline.mMaterialIndex = vertex_program->mAttribute[LLPipeline::GLSL_MATERIAL_COLOR];
384 gPipeline.mSpecularIndex = vertex_program->mAttribute[LLPipeline::GLSL_SPECULAR_COLOR];
385 }
386 glClientActiveTextureARB(GL_TEXTURE0_ARB);
387 bindGLTexCoordPointer(0);
388 vertex_program->bind();
389 bindGLVertexWeightPointer(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]);
390 if ((mVertexShaderLevel >= SHADER_LEVEL_CLOTH))
391 {
392 bindGLVertexClothingWeightPointer(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_CLOTHING]);
393 enable_cloth_weights(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_CLOTHING]);
394 }
395 enable_vertex_weighting(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]);
396
397 if ((mVertexShaderLevel >= SHADER_LEVEL_BUMP))
398 {
399 enable_binormals(vertex_program->mAttribute[LLPipeline::GLSL_BINORMAL]);
400 }
401
402 vertex_program->enableTexture(LLPipeline::GLSL_BUMP_MAP);
403 S32 index = vertex_program->enableTexture(LLPipeline::GLSL_SCATTER_MAP);
404 gSky.mVOSkyp->getScatterMap()->bind(index);
405 glActiveTextureARB(GL_TEXTURE0_ARB);
406 }
407
408 if ((mVertexShaderLevel >= SHADER_LEVEL_CLOTH))
409 {
410 LLMatrix4 rot_mat;
411 gCamera->getMatrixToLocal(rot_mat);
412 LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
413 rot_mat *= cfr;
414
415 LLVector4 wind;
416 wind.setVec(avatarp->mWindVec);
417 wind.mV[VW] = 0;
418 wind = wind * rot_mat;
419 wind.mV[VW] = avatarp->mWindVec.mV[VW];
420
421 vertex_program->vertexAttrib4fv(LLPipeline::GLSL_AVATAR_WIND, wind.mV);
422 F32 phase = -1.f * (avatarp->mRipplePhase);
423
424 F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f);
425 LLVector4 sin_params(freq, freq, freq, phase);
426 vertex_program->vertexAttrib4fv(LLPipeline::GLSL_AVATAR_SINWAVE, sin_params.mV);
427
428 LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f);
429 gravity = gravity * rot_mat;
430 vertex_program->vertexAttrib4fv(LLPipeline::GLSL_AVATAR_GRAVITY, gravity.mV);
431 }
432
433 mIndicesDrawn += avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);
434
435 if (!gRenderForSelect && avatarp->mIsSelf && LLVOAvatar::sAvatarLoadTest)
436 {
437 LLVector3 orig_pos_root = avatarp->mRoot.getPosition();
438 LLVector3 next_pos_root = orig_pos_root;
439 for (S32 i = 0; i < NUM_TEST_AVATARS; i++)
440 {
441 next_pos_root.mV[VX] += 1.f;
442 if (i % 5 == 0)
443 {
444 next_pos_root.mV[VY] += 1.f;
445 next_pos_root.mV[VX] = orig_pos_root.mV[VX];
446 }
447
448 avatarp->mRoot.setPosition(next_pos_root); // avatar load test
449 avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test
450
451 mIndicesDrawn += avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);
452 }
453 avatarp->mRoot.setPosition(orig_pos_root); // avatar load test
454 avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test
455 }
456
457 // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done
458 if (!(mVertexShaderLevel > 0))
459 {
460 // want for the previously bound fence to finish
461 gPipeline.bufferSendFence();
462 }
463 else
464 {
465 vertex_program->disableTexture(LLPipeline::GLSL_BUMP_MAP);
466 vertex_program->disableTexture(LLPipeline::GLSL_SCATTER_MAP);
467 glActiveTextureARB(GL_TEXTURE0_ARB);
468 glClientActiveTextureARB(GL_TEXTURE0_ARB);
469 disable_vertex_weighting(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]);
470 if ((mVertexShaderLevel >= SHADER_LEVEL_BUMP))
471 {
472 disable_binormals(vertex_program->mAttribute[LLPipeline::GLSL_BINORMAL]);
473 }
474 if ((mVertexShaderLevel >= SHADER_LEVEL_CLOTH))
475 {
476 disable_cloth_weights(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_CLOTHING]);
477 }
478
479 vertex_program->unbind();
480 }
481 }
482}
483
484//-----------------------------------------------------------------------------
485// renderForSelect()
486//-----------------------------------------------------------------------------
487void LLDrawPoolAvatar::renderForSelect()
488{
489 if (gUseGLPick)
490 {
491 return;
492 }
493 //gGLSObjectSelectDepthAlpha.set();
494
495 if (!gRenderAvatar)
496 {
497 return;
498 }
499
500 if (mDrawFace.empty() || !mMemory.count())
501 {
502 return;
503 }
504
505 const LLFace *facep = mDrawFace[0];
506 if (!facep->getDrawable())
507 {
508 return;
509 }
510 LLVOAvatar *avatarp = (LLVOAvatar *)(facep->getDrawable()->getVObj());
511
512 if (avatarp->isDead() || avatarp->mIsDummy || avatarp->mDrawable.isNull())
513 {
514 return;
515 }
516
517 glEnableClientState(GL_VERTEX_ARRAY);
518 glEnableClientState(GL_NORMAL_ARRAY);
519 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
520
521 LLGLSLShader* vertex_program = &gPipeline.mAvatarPickProgram;
522 if (mVertexShaderLevel > 0)
523 {
524 gPipeline.mAvatarMatrixParam = vertex_program->mUniform[LLPipeline::GLSL_AVATAR_MATRIX];
525 }
526 glAlphaFunc(GL_GEQUAL, 0.2f);
527 glBlendFunc(GL_ONE, GL_ZERO);
528
529 //--------------------------------------------------------------------------------
530 // this is where we first hit the software blending path
531 // if enabled, we need to set up the proper buffers and avoid setting other state
532 //--------------------------------------------------------------------------------
533 if (!(mVertexShaderLevel > 0) || gUseGLPick)
534 {
535
536 // Rotate to the next buffer, round-robin.
537 gPipeline.bufferRotate();
538
539 // Wait until the hardware is done reading the last set of vertices from the buffer before writing the next set.
540 gPipeline.bufferWaitFence();
541
542 // Need to do this because we may be rendering without AGP even in AGP mode
543 U8* buffer_offset_start = gPipeline.bufferGetScratchMemory();
544 glVertexPointer( 3, GL_FLOAT, AVATAR_VERTEX_BYTES, buffer_offset_start + AVATAR_OFFSET_POS);
545 glTexCoordPointer(2, GL_FLOAT, AVATAR_VERTEX_BYTES, buffer_offset_start + AVATAR_OFFSET_TEX0);
546 glNormalPointer( GL_FLOAT, AVATAR_VERTEX_BYTES, buffer_offset_start + AVATAR_OFFSET_NORMAL);
547 }
548
549 S32 name = avatarp->mDrawable->getVObj()->mGLName;
550 LLColor4U color((U8)(name >> 16), (U8)(name >> 8), (U8)name);
551 glColor4ubv(color.mV);
552
553 if ((mVertexShaderLevel > 0) && !gUseGLPick) // for hardware blending
554 {
555 bindGLVertexPointer();
556 bindGLNormalPointer();
557 bindGLTexCoordPointer(0);
558 }
559
560 // render rigid meshes (eyeballs) first
561 mIndicesDrawn += avatarp->renderRigid();
562
563 if ((mVertexShaderLevel > 0) && !gUseGLPick) // for hardware blending
564 {
565 glClientActiveTextureARB(GL_TEXTURE0_ARB);
566 bindGLTexCoordPointer(0);
567 vertex_program->bind();
568 bindGLVertexWeightPointer(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]);
569 /*if ((mVertexShaderLevel >= SHADER_LEVEL_CLOTH))
570 {
571 bindGLVertexClothingWeightPointer();
572 enable_cloth_weights();
573 }*/
574 enable_vertex_weighting(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]);
575 }
576
577 mIndicesDrawn += avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);
578
579 // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done
580 if (!(mVertexShaderLevel > 0) || gUseGLPick)
581 {
582 // want for the previously bound fence to finish
583 gPipeline.bufferSendFence();
584 }
585 else
586 {
587 vertex_program->unbind();
588 disable_vertex_weighting(vertex_program->mAttribute[LLPipeline::GLSL_AVATAR_WEIGHT]);
589
590 /*if ((mVertexShaderLevel >= SHADER_LEVEL_CLOTH))
591 {
592 disable_cloth_weights();
593 }*/
594 }
595
596 glAlphaFunc(GL_GREATER, 0.01f);
597 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
598
599 // restore texture mode
600 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
601 glDisableClientState(GL_NORMAL_ARRAY);
602 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
603}
604
605//-----------------------------------------------------------------------------
606// getDebugTexture()
607//-----------------------------------------------------------------------------
608LLViewerImage *LLDrawPoolAvatar::getDebugTexture()
609{
610 if (mReferences.empty())
611 {
612 return NULL;
613 }
614 LLFace *face = mReferences[0];
615 if (!face->getDrawable())
616 {
617 return NULL;
618 }
619 const LLViewerObject *objectp = face->getDrawable()->getVObj();
620
621 // Avatar should always have at least 1 (maybe 3?) TE's.
622 return objectp->getTEImage(0);
623}
624
625
626LLColor3 LLDrawPoolAvatar::getDebugColor() const
627{
628 return LLColor3(0.f, 1.f, 0.f);
629}