aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llrender/llrender.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llrender/llrender.cpp')
-rw-r--r--linden/indra/llrender/llrender.cpp704
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
37LLRender gGL;
38
39static const U32 LL_NUM_TEXTURE_LAYERS = 8;
40
41static 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
53const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD;
54
55static 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
69LLTexUnit::LLTexUnit(U32 index)
70: mIsEnabled(false), mCurrBlendType(TB_MULT),
71mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
72mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
73mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
74mCurrColorScale(1), mCurrAlphaScale(1)
75{
76 llassert_always(index < LL_NUM_TEXTURE_LAYERS);
77 mIndex = index;
78}
79
80U32 LLTexUnit::getIndex(void)
81{
82 return mIndex;
83}
84
85void LLTexUnit::enable(void)
86{
87 if (!mIsEnabled)
88 {
89 activate();
90 glEnable(GL_TEXTURE_2D);
91 mIsEnabled = true;
92 }
93}
94
95void LLTexUnit::disable(void)
96{
97 if (mIsEnabled)
98 {
99 activate();
100 glDisable(GL_TEXTURE_2D);
101 mIsEnabled = false;
102 }
103}
104
105void 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.
116void 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
126void LLTexUnit::bindTexture(const LLImageGL* texture)
127{
128 if (texture != NULL)
129 {
130 activate();
131 texture->bind(mIndex);
132 }
133}
134
135void LLTexUnit::unbindTexture(void)
136{
137 activate();
138 glBindTexture(GL_TEXTURE_2D, 0);
139}
140
141void 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
181GLint 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
219GLint 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
257void 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
400void 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
409void 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
418LLRender::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
434LLRender::~LLRender()
435{
436 for (U32 i = 0; i < mTexUnits.size(); i++)
437 {
438 delete mTexUnits[i];
439 }
440}
441
442void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
443{
444 flush();
445 glTranslatef(x,y,z);
446}
447
448void LLRender::pushMatrix()
449{
450 flush();
451 glPushMatrix();
452}
453
454void LLRender::popMatrix()
455{
456 flush();
457 glPopMatrix();
458}
459
460void LLRender::setColorMask(bool writeColor, bool writeAlpha)
461{
462 setColorMask(writeColor, writeColor, writeColor, writeAlpha);
463}
464
465void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha)
466{
467 flush();
468 glColorMask(writeColorR, writeColorG, writeColorB, writeAlpha);
469}
470
471void 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
500void 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
513void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
514{
515 flush();
516 glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]);
517}
518
519LLTexUnit* 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
529void 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
549void 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}
566void 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}
621void 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}
638void LLRender::vertex2i(const GLint& x, const GLint& y)
639{
640 vertex3f((GLfloat) x, (GLfloat) y, 0);
641}
642
643void LLRender::vertex2f(const GLfloat& x, const GLfloat& y)
644{
645 vertex3f(x,y,0);
646}
647
648void LLRender::vertex2fv(const GLfloat* v)
649{
650 vertex3f(v[0], v[1], 0);
651}
652
653void LLRender::vertex3fv(const GLfloat* v)
654{
655 vertex3f(v[0], v[1], v[2]);
656}
657
658void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y)
659{
660 mTexcoordsp[mCount] = LLVector2(x,y);
661}
662
663void LLRender::texCoord2i(const GLint& x, const GLint& y)
664{
665 texCoord2f((GLfloat) x, (GLfloat) y);
666}
667
668void LLRender::texCoord2fv(const GLfloat* tc)
669{
670 texCoord2f(tc[0], tc[1]);
671}
672
673void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a)
674{
675 mColorsp[mCount] = LLColor4U(r,g,b,a);
676}
677void LLRender::color4ubv(const GLubyte* c)
678{
679 color4ub(c[0], c[1], c[2], c[3]);
680}
681
682void 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
690void LLRender::color4fv(const GLfloat* c)
691{
692 color4f(c[0],c[1],c[2],c[3]);
693}
694
695void LLRender::color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b)
696{
697 color4f(r,g,b,1);
698}
699
700void LLRender::color3fv(const GLfloat* c)
701{
702 color4f(c[0],c[1],c[2],1);
703}
704