diff options
Diffstat (limited to 'linden/indra/llrender/llrender.cpp')
-rw-r--r-- | linden/indra/llrender/llrender.cpp | 704 |
1 files changed, 704 insertions, 0 deletions
diff --git a/linden/indra/llrender/llrender.cpp b/linden/indra/llrender/llrender.cpp new file mode 100644 index 0000000..e9c1227 --- /dev/null +++ b/linden/indra/llrender/llrender.cpp | |||
@@ -0,0 +1,704 @@ | |||
1 | /** | ||
2 | * @file llrender.cpp | ||
3 | * @brief LLRender implementation | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2001-2008, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | * $/LicenseInfo$ | ||
30 | */ | ||
31 | |||
32 | #include "linden_common.h" | ||
33 | |||
34 | #include "llrender.h" | ||
35 | #include "llvertexbuffer.h" | ||
36 | |||
37 | LLRender gGL; | ||
38 | |||
39 | static const U32 LL_NUM_TEXTURE_LAYERS = 8; | ||
40 | |||
41 | static GLenum sGLCompareFunc[] = | ||
42 | { | ||
43 | GL_NEVER, | ||
44 | GL_ALWAYS, | ||
45 | GL_LESS, | ||
46 | GL_LEQUAL, | ||
47 | GL_EQUAL, | ||
48 | GL_NOTEQUAL, | ||
49 | GL_GEQUAL, | ||
50 | GL_GREATER | ||
51 | }; | ||
52 | |||
53 | const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD; | ||
54 | |||
55 | static GLenum sGLBlendFactor[] = | ||
56 | { | ||
57 | GL_ONE, | ||
58 | GL_ZERO, | ||
59 | GL_DST_COLOR, | ||
60 | GL_SRC_COLOR, | ||
61 | GL_ONE_MINUS_DST_COLOR, | ||
62 | GL_ONE_MINUS_SRC_COLOR, | ||
63 | GL_DST_ALPHA, | ||
64 | GL_SRC_ALPHA, | ||
65 | GL_ONE_MINUS_DST_ALPHA, | ||
66 | GL_ONE_MINUS_SRC_ALPHA | ||
67 | }; | ||
68 | |||
69 | LLTexUnit::LLTexUnit(U32 index) | ||
70 | : mIsEnabled(false), mCurrBlendType(TB_MULT), | ||
71 | mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT), | ||
72 | mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR), | ||
73 | mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA), | ||
74 | mCurrColorScale(1), mCurrAlphaScale(1) | ||
75 | { | ||
76 | llassert_always(index < LL_NUM_TEXTURE_LAYERS); | ||
77 | mIndex = index; | ||
78 | } | ||
79 | |||
80 | U32 LLTexUnit::getIndex(void) | ||
81 | { | ||
82 | return mIndex; | ||
83 | } | ||
84 | |||
85 | void LLTexUnit::enable(void) | ||
86 | { | ||
87 | if (!mIsEnabled) | ||
88 | { | ||
89 | activate(); | ||
90 | glEnable(GL_TEXTURE_2D); | ||
91 | mIsEnabled = true; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | void LLTexUnit::disable(void) | ||
96 | { | ||
97 | if (mIsEnabled) | ||
98 | { | ||
99 | activate(); | ||
100 | glDisable(GL_TEXTURE_2D); | ||
101 | mIsEnabled = false; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | void LLTexUnit::activate(void) | ||
106 | { | ||
107 | //if (gGL.mCurrTextureUnitIndex != mIndex) | ||
108 | { | ||
109 | glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); | ||
110 | gGL.mCurrTextureUnitIndex = mIndex; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | // Useful for debugging that you've manually assigned a texture operation to the correct | ||
115 | // texture unit based on the currently set active texture in opengl. | ||
116 | void LLTexUnit::debugTextureUnit(void) | ||
117 | { | ||
118 | GLint activeTexture; | ||
119 | glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture); | ||
120 | if ((GL_TEXTURE0_ARB + mIndex) != activeTexture) | ||
121 | { | ||
122 | llerrs << "Incorrect Texture Unit! Expected: " << (activeTexture - GL_TEXTURE0_ARB) << " Actual: " << mIndex << llendl; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | void LLTexUnit::bindTexture(const LLImageGL* texture) | ||
127 | { | ||
128 | if (texture != NULL) | ||
129 | { | ||
130 | activate(); | ||
131 | texture->bind(mIndex); | ||
132 | } | ||
133 | } | ||
134 | |||
135 | void LLTexUnit::unbindTexture(void) | ||
136 | { | ||
137 | activate(); | ||
138 | glBindTexture(GL_TEXTURE_2D, 0); | ||
139 | } | ||
140 | |||
141 | void LLTexUnit::setTextureBlendType(eTextureBlendType type) | ||
142 | { | ||
143 | // Do nothing if it's already correctly set. | ||
144 | if (mCurrBlendType == type) | ||
145 | { | ||
146 | return; | ||
147 | } | ||
148 | |||
149 | activate(); | ||
150 | mCurrBlendType = type; | ||
151 | S32 scale_amount = 1; | ||
152 | switch (type) | ||
153 | { | ||
154 | case TB_REPLACE: | ||
155 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | ||
156 | break; | ||
157 | case TB_ADD: | ||
158 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); | ||
159 | break; | ||
160 | case TB_MULT: | ||
161 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | ||
162 | break; | ||
163 | case TB_MULT_X2: | ||
164 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | ||
165 | scale_amount = 2; | ||
166 | break; | ||
167 | case TB_ALPHA_BLEND: | ||
168 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); | ||
169 | break; | ||
170 | case TB_COMBINE: | ||
171 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); | ||
172 | break; | ||
173 | default: | ||
174 | llerrs << "Unknown Texture Blend Type: " << type << llendl; | ||
175 | break; | ||
176 | } | ||
177 | setColorScale(scale_amount); | ||
178 | setAlphaScale(1); | ||
179 | } | ||
180 | |||
181 | GLint LLTexUnit::getTextureSource(eTextureBlendSrc src) | ||
182 | { | ||
183 | switch(src) | ||
184 | { | ||
185 | // All four cases should return the same value. | ||
186 | case TBS_PREV_COLOR: | ||
187 | case TBS_PREV_ALPHA: | ||
188 | case TBS_ONE_MINUS_PREV_COLOR: | ||
189 | case TBS_ONE_MINUS_PREV_ALPHA: | ||
190 | return GL_PREVIOUS_ARB; | ||
191 | |||
192 | // All four cases should return the same value. | ||
193 | case TBS_TEX_COLOR: | ||
194 | case TBS_TEX_ALPHA: | ||
195 | case TBS_ONE_MINUS_TEX_COLOR: | ||
196 | case TBS_ONE_MINUS_TEX_ALPHA: | ||
197 | return GL_TEXTURE; | ||
198 | |||
199 | // All four cases should return the same value. | ||
200 | case TBS_VERT_COLOR: | ||
201 | case TBS_VERT_ALPHA: | ||
202 | case TBS_ONE_MINUS_VERT_COLOR: | ||
203 | case TBS_ONE_MINUS_VERT_ALPHA: | ||
204 | return GL_PRIMARY_COLOR_ARB; | ||
205 | |||
206 | // All four cases should return the same value. | ||
207 | case TBS_CONST_COLOR: | ||
208 | case TBS_CONST_ALPHA: | ||
209 | case TBS_ONE_MINUS_CONST_COLOR: | ||
210 | case TBS_ONE_MINUS_CONST_ALPHA: | ||
211 | return GL_CONSTANT_ARB; | ||
212 | |||
213 | default: | ||
214 | llwarns << "Unknown eTextureBlendSrc: " << src << ". Using Vertex Color instead." << llendl; | ||
215 | return GL_PRIMARY_COLOR_ARB; | ||
216 | } | ||
217 | } | ||
218 | |||
219 | GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha) | ||
220 | { | ||
221 | switch(src) | ||
222 | { | ||
223 | // All four cases should return the same value. | ||
224 | case TBS_PREV_COLOR: | ||
225 | case TBS_TEX_COLOR: | ||
226 | case TBS_VERT_COLOR: | ||
227 | case TBS_CONST_COLOR: | ||
228 | return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR; | ||
229 | |||
230 | // All four cases should return the same value. | ||
231 | case TBS_PREV_ALPHA: | ||
232 | case TBS_TEX_ALPHA: | ||
233 | case TBS_VERT_ALPHA: | ||
234 | case TBS_CONST_ALPHA: | ||
235 | return GL_SRC_ALPHA; | ||
236 | |||
237 | // All four cases should return the same value. | ||
238 | case TBS_ONE_MINUS_PREV_COLOR: | ||
239 | case TBS_ONE_MINUS_TEX_COLOR: | ||
240 | case TBS_ONE_MINUS_VERT_COLOR: | ||
241 | case TBS_ONE_MINUS_CONST_COLOR: | ||
242 | return (isAlpha) ? GL_ONE_MINUS_SRC_ALPHA : GL_ONE_MINUS_SRC_COLOR; | ||
243 | |||
244 | // All four cases should return the same value. | ||
245 | case TBS_ONE_MINUS_PREV_ALPHA: | ||
246 | case TBS_ONE_MINUS_TEX_ALPHA: | ||
247 | case TBS_ONE_MINUS_VERT_ALPHA: | ||
248 | case TBS_ONE_MINUS_CONST_ALPHA: | ||
249 | return GL_ONE_MINUS_SRC_ALPHA; | ||
250 | |||
251 | default: | ||
252 | llwarns << "Unknown eTextureBlendSrc: " << src << ". Using Source Color or Alpha instead." << llendl; | ||
253 | return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha) | ||
258 | { | ||
259 | activate(); | ||
260 | if (mCurrBlendType != TB_COMBINE) | ||
261 | { | ||
262 | mCurrBlendType = TB_COMBINE; | ||
263 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); | ||
264 | } | ||
265 | |||
266 | // We want an early out, because this function does a LOT of stuff. | ||
267 | if ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2) ) | ||
268 | || (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2) )) | ||
269 | { | ||
270 | return; | ||
271 | } | ||
272 | |||
273 | // Get the gl source enums according to the eTextureBlendSrc sources passed in | ||
274 | GLint source1 = getTextureSource(src1); | ||
275 | GLint source2 = getTextureSource(src2); | ||
276 | // Get the gl operand enums according to the eTextureBlendSrc sources passed in | ||
277 | GLint operand1 = getTextureSourceType(src1, isAlpha); | ||
278 | GLint operand2 = getTextureSourceType(src2, isAlpha); | ||
279 | // Default the scale amount to 1 | ||
280 | S32 scale_amount = 1; | ||
281 | GLenum comb_enum, src0_enum, src1_enum, src2_enum, operand0_enum, operand1_enum, operand2_enum; | ||
282 | |||
283 | if (isAlpha) | ||
284 | { | ||
285 | // Set enums to ALPHA ones | ||
286 | comb_enum = GL_COMBINE_ALPHA_ARB; | ||
287 | src0_enum = GL_SOURCE0_ALPHA_ARB; | ||
288 | src1_enum = GL_SOURCE1_ALPHA_ARB; | ||
289 | src2_enum = GL_SOURCE2_ALPHA_ARB; | ||
290 | operand0_enum = GL_OPERAND0_ALPHA_ARB; | ||
291 | operand1_enum = GL_OPERAND1_ALPHA_ARB; | ||
292 | operand2_enum = GL_OPERAND2_ALPHA_ARB; | ||
293 | |||
294 | // cache current combiner | ||
295 | mCurrAlphaOp = op; | ||
296 | mCurrAlphaSrc1 = src1; | ||
297 | mCurrAlphaSrc2 = src2; | ||
298 | } | ||
299 | else | ||
300 | { | ||
301 | // Set enums to ALPHA ones | ||
302 | comb_enum = GL_COMBINE_RGB_ARB; | ||
303 | src0_enum = GL_SOURCE0_RGB_ARB; | ||
304 | src1_enum = GL_SOURCE1_RGB_ARB; | ||
305 | src2_enum = GL_SOURCE2_RGB_ARB; | ||
306 | operand0_enum = GL_OPERAND0_RGB_ARB; | ||
307 | operand1_enum = GL_OPERAND1_RGB_ARB; | ||
308 | operand2_enum = GL_OPERAND2_RGB_ARB; | ||
309 | |||
310 | // cache current combiner | ||
311 | mCurrColorOp = op; | ||
312 | mCurrColorSrc1 = src1; | ||
313 | mCurrColorSrc2 = src2; | ||
314 | } | ||
315 | |||
316 | switch(op) | ||
317 | { | ||
318 | case TBO_REPLACE: | ||
319 | // Slightly special syntax (no second sources), just set all and return. | ||
320 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE); | ||
321 | glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1); | ||
322 | glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1); | ||
323 | (isAlpha) ? setAlphaScale(1) : setColorScale(1); | ||
324 | return; | ||
325 | |||
326 | case TBO_MULT: | ||
327 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE); | ||
328 | break; | ||
329 | |||
330 | case TBO_MULT_X2: | ||
331 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE); | ||
332 | scale_amount = 2; | ||
333 | break; | ||
334 | |||
335 | case TBO_MULT_X4: | ||
336 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE); | ||
337 | scale_amount = 4; | ||
338 | break; | ||
339 | |||
340 | case TBO_ADD: | ||
341 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD); | ||
342 | break; | ||
343 | |||
344 | case TBO_ADD_SIGNED: | ||
345 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD_SIGNED_ARB); | ||
346 | break; | ||
347 | |||
348 | case TBO_SUBTRACT: | ||
349 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_SUBTRACT_ARB); | ||
350 | break; | ||
351 | |||
352 | case TBO_LERP_VERT_ALPHA: | ||
353 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); | ||
354 | glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR_ARB); | ||
355 | glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); | ||
356 | break; | ||
357 | |||
358 | case TBO_LERP_TEX_ALPHA: | ||
359 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); | ||
360 | glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_TEXTURE); | ||
361 | glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); | ||
362 | break; | ||
363 | |||
364 | case TBO_LERP_PREV_ALPHA: | ||
365 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); | ||
366 | glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PREVIOUS_ARB); | ||
367 | glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); | ||
368 | break; | ||
369 | |||
370 | case TBO_LERP_CONST_ALPHA: | ||
371 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); | ||
372 | glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_CONSTANT_ARB); | ||
373 | glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); | ||
374 | break; | ||
375 | |||
376 | case TBO_LERP_VERT_COLOR: | ||
377 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); | ||
378 | glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR_ARB); | ||
379 | glTexEnvi(GL_TEXTURE_ENV, operand2_enum, (isAlpha) ? GL_SRC_ALPHA : GL_SRC_COLOR); | ||
380 | break; | ||
381 | |||
382 | default: | ||
383 | llwarns << "Unknown eTextureBlendOp: " << op << ". Setting op to replace." << llendl; | ||
384 | // Slightly special syntax (no second sources), just set all and return. | ||
385 | glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE); | ||
386 | glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1); | ||
387 | glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1); | ||
388 | (isAlpha) ? setAlphaScale(1) : setColorScale(1); | ||
389 | return; | ||
390 | } | ||
391 | |||
392 | // Set sources, operands, and scale accordingly | ||
393 | glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1); | ||
394 | glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1); | ||
395 | glTexEnvi(GL_TEXTURE_ENV, src1_enum, source2); | ||
396 | glTexEnvi(GL_TEXTURE_ENV, operand1_enum, operand2); | ||
397 | (isAlpha) ? setAlphaScale(scale_amount) : setColorScale(scale_amount); | ||
398 | } | ||
399 | |||
400 | void LLTexUnit::setColorScale(S32 scale) | ||
401 | { | ||
402 | if (mCurrColorScale != scale) | ||
403 | { | ||
404 | mCurrColorScale = scale; | ||
405 | glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | void LLTexUnit::setAlphaScale(S32 scale) | ||
410 | { | ||
411 | if (mCurrAlphaScale != scale) | ||
412 | { | ||
413 | mCurrAlphaScale = scale; | ||
414 | glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); | ||
415 | } | ||
416 | } | ||
417 | |||
418 | LLRender::LLRender() | ||
419 | { | ||
420 | mCount = 0; | ||
421 | mMode = LLVertexBuffer::TRIANGLES; | ||
422 | mBuffer = new LLVertexBuffer(immediate_mask, 0); | ||
423 | mBuffer->allocateBuffer(4096, 0, TRUE); | ||
424 | mBuffer->getVertexStrider(mVerticesp); | ||
425 | mBuffer->getTexCoordStrider(mTexcoordsp); | ||
426 | mBuffer->getColorStrider(mColorsp); | ||
427 | |||
428 | for (unsigned int i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) | ||
429 | { | ||
430 | mTexUnits.push_back(new LLTexUnit(i)); | ||
431 | } | ||
432 | } | ||
433 | |||
434 | LLRender::~LLRender() | ||
435 | { | ||
436 | for (U32 i = 0; i < mTexUnits.size(); i++) | ||
437 | { | ||
438 | delete mTexUnits[i]; | ||
439 | } | ||
440 | } | ||
441 | |||
442 | void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) | ||
443 | { | ||
444 | flush(); | ||
445 | glTranslatef(x,y,z); | ||
446 | } | ||
447 | |||
448 | void LLRender::pushMatrix() | ||
449 | { | ||
450 | flush(); | ||
451 | glPushMatrix(); | ||
452 | } | ||
453 | |||
454 | void LLRender::popMatrix() | ||
455 | { | ||
456 | flush(); | ||
457 | glPopMatrix(); | ||
458 | } | ||
459 | |||
460 | void LLRender::setColorMask(bool writeColor, bool writeAlpha) | ||
461 | { | ||
462 | setColorMask(writeColor, writeColor, writeColor, writeAlpha); | ||
463 | } | ||
464 | |||
465 | void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha) | ||
466 | { | ||
467 | flush(); | ||
468 | glColorMask(writeColorR, writeColorG, writeColorB, writeAlpha); | ||
469 | } | ||
470 | |||
471 | void LLRender::setSceneBlendType(eBlendType type) | ||
472 | { | ||
473 | flush(); | ||
474 | switch (type) | ||
475 | { | ||
476 | case BT_ALPHA: | ||
477 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
478 | break; | ||
479 | case BT_ADD: | ||
480 | glBlendFunc(GL_ONE, GL_ONE); | ||
481 | break; | ||
482 | case BT_ADD_WITH_ALPHA: | ||
483 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | ||
484 | break; | ||
485 | case BT_MULT: | ||
486 | glBlendFunc(GL_DST_COLOR, GL_ZERO); | ||
487 | break; | ||
488 | case BT_MULT_X2: | ||
489 | glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); | ||
490 | break; | ||
491 | case BT_REPLACE: | ||
492 | glBlendFunc(GL_ONE, GL_ZERO); | ||
493 | break; | ||
494 | default: | ||
495 | llerrs << "Unknown Scene Blend Type: " << type << llendl; | ||
496 | break; | ||
497 | } | ||
498 | } | ||
499 | |||
500 | void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) | ||
501 | { | ||
502 | flush(); | ||
503 | if (func == CF_DEFAULT) | ||
504 | { | ||
505 | glAlphaFunc(GL_GREATER, 0.01f); | ||
506 | } | ||
507 | else | ||
508 | { | ||
509 | glAlphaFunc(sGLCompareFunc[func], value); | ||
510 | } | ||
511 | } | ||
512 | |||
513 | void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor) | ||
514 | { | ||
515 | flush(); | ||
516 | glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]); | ||
517 | } | ||
518 | |||
519 | LLTexUnit* LLRender::getTexUnit(U32 index) | ||
520 | { | ||
521 | if (index < mTexUnits.size()) | ||
522 | { | ||
523 | return mTexUnits[index]; | ||
524 | } | ||
525 | llerrs << "Non-existing texture unit layer requested: " << index << llendl; | ||
526 | return NULL; | ||
527 | } | ||
528 | |||
529 | void LLRender::begin(const GLuint& mode) | ||
530 | { | ||
531 | if (mode != mMode) | ||
532 | { | ||
533 | if (mMode == LLVertexBuffer::QUADS || | ||
534 | mMode == LLVertexBuffer::LINES || | ||
535 | mMode == LLVertexBuffer::TRIANGLES || | ||
536 | mMode == LLVertexBuffer::POINTS) | ||
537 | { | ||
538 | flush(); | ||
539 | } | ||
540 | else if (mCount != 0) | ||
541 | { | ||
542 | llerrs << "gGL.begin() called redundantly." << llendl; | ||
543 | } | ||
544 | |||
545 | mMode = mode; | ||
546 | } | ||
547 | } | ||
548 | |||
549 | void LLRender::end() | ||
550 | { | ||
551 | if (mCount == 0) | ||
552 | { | ||
553 | return; | ||
554 | //IMM_ERRS << "GL begin and end called with no vertices specified." << llendl; | ||
555 | } | ||
556 | |||
557 | if ((mMode != LLVertexBuffer::QUADS && | ||
558 | mMode != LLVertexBuffer::LINES && | ||
559 | mMode != LLVertexBuffer::TRIANGLES && | ||
560 | mMode != LLVertexBuffer::POINTS) || | ||
561 | mCount > 2048) | ||
562 | { | ||
563 | flush(); | ||
564 | } | ||
565 | } | ||
566 | void LLRender::flush() | ||
567 | { | ||
568 | if (mCount > 0) | ||
569 | { | ||
570 | #if 0 | ||
571 | if (!glIsEnabled(GL_VERTEX_ARRAY)) | ||
572 | { | ||
573 | llerrs << "foo 1" << llendl; | ||
574 | } | ||
575 | |||
576 | if (!glIsEnabled(GL_COLOR_ARRAY)) | ||
577 | { | ||
578 | llerrs << "foo 2" << llendl; | ||
579 | } | ||
580 | |||
581 | if (!glIsEnabled(GL_TEXTURE_COORD_ARRAY)) | ||
582 | { | ||
583 | llerrs << "foo 3" << llendl; | ||
584 | } | ||
585 | |||
586 | if (glIsEnabled(GL_NORMAL_ARRAY)) | ||
587 | { | ||
588 | llerrs << "foo 7" << llendl; | ||
589 | } | ||
590 | |||
591 | GLvoid* pointer; | ||
592 | |||
593 | glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer); | ||
594 | if (pointer != &(mBuffer[0].v)) | ||
595 | { | ||
596 | llerrs << "foo 4" << llendl; | ||
597 | } | ||
598 | |||
599 | glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer); | ||
600 | if (pointer != &(mBuffer[0].c)) | ||
601 | { | ||
602 | llerrs << "foo 5" << llendl; | ||
603 | } | ||
604 | |||
605 | glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer); | ||
606 | if (pointer != &(mBuffer[0].uv)) | ||
607 | { | ||
608 | llerrs << "foo 6" << llendl; | ||
609 | } | ||
610 | #endif | ||
611 | |||
612 | mBuffer->setBuffer(immediate_mask); | ||
613 | mBuffer->drawArrays(mMode, 0, mCount); | ||
614 | |||
615 | mVerticesp[0] = mVerticesp[mCount]; | ||
616 | mTexcoordsp[0] = mTexcoordsp[mCount]; | ||
617 | mColorsp[0] = mColorsp[mCount]; | ||
618 | mCount = 0; | ||
619 | } | ||
620 | } | ||
621 | void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) | ||
622 | { | ||
623 | if (mCount >= 4096) | ||
624 | { | ||
625 | // llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl; | ||
626 | return; | ||
627 | } | ||
628 | |||
629 | mVerticesp[mCount] = LLVector3(x,y,z); | ||
630 | mCount++; | ||
631 | if (mCount < 4096) | ||
632 | { | ||
633 | mVerticesp[mCount] = mVerticesp[mCount-1]; | ||
634 | mColorsp[mCount] = mColorsp[mCount-1]; | ||
635 | mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; | ||
636 | } | ||
637 | } | ||
638 | void LLRender::vertex2i(const GLint& x, const GLint& y) | ||
639 | { | ||
640 | vertex3f((GLfloat) x, (GLfloat) y, 0); | ||
641 | } | ||
642 | |||
643 | void LLRender::vertex2f(const GLfloat& x, const GLfloat& y) | ||
644 | { | ||
645 | vertex3f(x,y,0); | ||
646 | } | ||
647 | |||
648 | void LLRender::vertex2fv(const GLfloat* v) | ||
649 | { | ||
650 | vertex3f(v[0], v[1], 0); | ||
651 | } | ||
652 | |||
653 | void LLRender::vertex3fv(const GLfloat* v) | ||
654 | { | ||
655 | vertex3f(v[0], v[1], v[2]); | ||
656 | } | ||
657 | |||
658 | void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y) | ||
659 | { | ||
660 | mTexcoordsp[mCount] = LLVector2(x,y); | ||
661 | } | ||
662 | |||
663 | void LLRender::texCoord2i(const GLint& x, const GLint& y) | ||
664 | { | ||
665 | texCoord2f((GLfloat) x, (GLfloat) y); | ||
666 | } | ||
667 | |||
668 | void LLRender::texCoord2fv(const GLfloat* tc) | ||
669 | { | ||
670 | texCoord2f(tc[0], tc[1]); | ||
671 | } | ||
672 | |||
673 | void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a) | ||
674 | { | ||
675 | mColorsp[mCount] = LLColor4U(r,g,b,a); | ||
676 | } | ||
677 | void LLRender::color4ubv(const GLubyte* c) | ||
678 | { | ||
679 | color4ub(c[0], c[1], c[2], c[3]); | ||
680 | } | ||
681 | |||
682 | void LLRender::color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a) | ||
683 | { | ||
684 | color4ub((GLubyte) (llclamp(r, 0.f, 1.f)*255), | ||
685 | (GLubyte) (llclamp(g, 0.f, 1.f)*255), | ||
686 | (GLubyte) (llclamp(b, 0.f, 1.f)*255), | ||
687 | (GLubyte) (llclamp(a, 0.f, 1.f)*255)); | ||
688 | } | ||
689 | |||
690 | void LLRender::color4fv(const GLfloat* c) | ||
691 | { | ||
692 | color4f(c[0],c[1],c[2],c[3]); | ||
693 | } | ||
694 | |||
695 | void LLRender::color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b) | ||
696 | { | ||
697 | color4f(r,g,b,1); | ||
698 | } | ||
699 | |||
700 | void LLRender::color3fv(const GLfloat* c) | ||
701 | { | ||
702 | color4f(c[0],c[1],c[2],1); | ||
703 | } | ||
704 | |||