aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llrender/files.lst2
-rw-r--r--linden/indra/llrender/llfontgl.cpp41
-rw-r--r--linden/indra/llrender/llfontgl.h1
-rw-r--r--linden/indra/llrender/llglimmediate.cpp303
-rw-r--r--linden/indra/llrender/llglimmediate.h107
-rw-r--r--linden/indra/llrender/llimagegl.cpp152
-rw-r--r--linden/indra/llrender/llimagegl.h16
-rw-r--r--linden/indra/llrender/llrender.cpp704
-rw-r--r--linden/indra/llrender/llrender.h239
-rw-r--r--linden/indra/llrender/llrender.vcproj4
-rw-r--r--linden/indra/llrender/llrender_vc8.vcproj8
-rw-r--r--linden/indra/llrender/llrender_vc9.vcproj4
-rw-r--r--linden/indra/llrender/llrendertarget.cpp17
-rw-r--r--linden/indra/llrender/llvertexbuffer.cpp51
-rw-r--r--linden/indra/llrender/llvertexprogramgl.cpp125
-rw-r--r--linden/indra/newview/llanimstatelabels.h (renamed from linden/indra/llrender/llvertexprogramgl.h)33
16 files changed, 1180 insertions, 627 deletions
diff --git a/linden/indra/llrender/files.lst b/linden/indra/llrender/files.lst
index 3ada47b..5dc9579 100644
--- a/linden/indra/llrender/files.lst
+++ b/linden/indra/llrender/files.lst
@@ -1,7 +1,7 @@
1llrender/llfont.cpp 1llrender/llfont.cpp
2llrender/llfontgl.cpp 2llrender/llfontgl.cpp
3llrender/llgldbg.cpp 3llrender/llgldbg.cpp
4llrender/llglimmediate.cpp 4llrender/llrender.cpp
5llrender/llimagegl.cpp 5llrender/llimagegl.cpp
6llrender/llrendertarget.cpp 6llrender/llrendertarget.cpp
7llrender/llvertexbuffer.cpp 7llrender/llvertexbuffer.cpp
diff --git a/linden/indra/llrender/llfontgl.cpp b/linden/indra/llrender/llfontgl.cpp
index 938dd73..253bf50 100644
--- a/linden/indra/llrender/llfontgl.cpp
+++ b/linden/indra/llrender/llfontgl.cpp
@@ -36,7 +36,7 @@
36#include "llfont.h" 36#include "llfont.h"
37#include "llfontgl.h" 37#include "llfontgl.h"
38#include "llgl.h" 38#include "llgl.h"
39#include "llglimmediate.h" 39#include "llrender.h"
40#include "v4color.h" 40#include "v4color.h"
41#include "llstl.h" 41#include "llstl.h"
42 42
@@ -56,6 +56,7 @@ LLFontGL* LLFontGL::sSansSerif = NULL;
56LLFontGL* LLFontGL::sSansSerifBig = NULL; 56LLFontGL* LLFontGL::sSansSerifBig = NULL;
57LLFontGL* LLFontGL::sSansSerifHuge = NULL; 57LLFontGL* LLFontGL::sSansSerifHuge = NULL;
58LLFontGL* LLFontGL::sSansSerifBold = NULL; 58LLFontGL* LLFontGL::sSansSerifBold = NULL;
59LLFontList* LLFontGL::sMonospaceFallback = NULL;
59LLFontList* LLFontGL::sSSFallback = NULL; 60LLFontList* LLFontGL::sSSFallback = NULL;
60LLFontList* LLFontGL::sSSSmallFallback = NULL; 61LLFontList* LLFontGL::sSSSmallFallback = NULL;
61LLFontList* LLFontGL::sSSBigFallback = NULL; 62LLFontList* LLFontGL::sSSBigFallback = NULL;
@@ -240,7 +241,7 @@ bool LLFontGL::loadFaceFallback(LLFontList *fontlistp, const LLString& fontname,
240 font_path = sys_path + *token_iter; 241 font_path = sys_path + *token_iter;
241 if (!fontp->loadFace(font_path, point_size, sVertDPI, sHorizDPI, 2, TRUE)) 242 if (!fontp->loadFace(font_path, point_size, sVertDPI, sHorizDPI, 2, TRUE))
242 { 243 {
243 llwarns << "Couldn't load font " << *token_iter << llendl; 244 LL_INFOS_ONCE("ViewerImages") << "Couldn't load font " << *token_iter << LL_ENDL;
244 delete fontp; 245 delete fontp;
245 fontp = NULL; 246 fontp = NULL;
246 } 247 }
@@ -267,7 +268,7 @@ bool LLFontGL::loadFace(LLFontGL *fontp, const LLString& fontname, const F32 poi
267 font_path = sys_path + fontname; 268 font_path = sys_path + fontname;
268 if (!fontp->loadFace(font_path, point_size, sVertDPI, sHorizDPI, 2, FALSE)) 269 if (!fontp->loadFace(font_path, point_size, sVertDPI, sHorizDPI, 2, FALSE))
269 { 270 {
270 llwarns << "Couldn't load font " << fontname << llendl; 271 LL_WARNS("ViewerImages") << "Couldn't load font " << fontname << LL_ENDL;
271 return false; 272 return false;
272 } 273 }
273 } 274 }
@@ -279,12 +280,12 @@ bool LLFontGL::loadFace(LLFontGL *fontp, const LLString& fontname, const F32 poi
279 280
280// static 281// static
281BOOL LLFontGL::initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale, 282BOOL LLFontGL::initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale,
282 const LLString& monospace_file, F32 monospace_size, 283 const LLString& monospace_file, F32 monospace_size,
283 const LLString& sansserif_file, 284 const LLString& sansserif_file,
284 const LLString& sanserif_fallback_file, F32 ss_fallback_scale, 285 const LLString& sanserif_fallback_file, F32 ss_fallback_scale,
285 F32 small_size, F32 medium_size, F32 big_size, F32 huge_size, 286 F32 small_size, F32 medium_size, F32 big_size, F32 huge_size,
286 const LLString& sansserif_bold_file, F32 bold_size, 287 const LLString& sansserif_bold_file, F32 bold_size,
287 const LLString& app_dir) 288 const LLString& app_dir)
288{ 289{
289 BOOL failed = FALSE; 290 BOOL failed = FALSE;
290 sVertDPI = (F32)llfloor(screen_dpi * y_scale); 291 sVertDPI = (F32)llfloor(screen_dpi * y_scale);
@@ -306,7 +307,21 @@ BOOL LLFontGL::initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale,
306 sMonospace->reset(); 307 sMonospace->reset();
307 } 308 }
308 309
309 failed |= !loadFace(sMonospace, monospace_file, monospace_size, NULL); 310 if (sMonospaceFallback)
311 {
312 delete sMonospaceFallback;
313 }
314 sMonospaceFallback = new LLFontList();
315 if (!loadFaceFallback(
316 sMonospaceFallback,
317 sanserif_fallback_file,
318 monospace_size * ss_fallback_scale))
319 {
320 delete sMonospaceFallback;
321 sMonospaceFallback = NULL;
322 }
323
324 failed |= !loadFace(sMonospace, monospace_file, monospace_size, sMonospaceFallback);
310 325
311 // 326 //
312 // Sans-serif fonts 327 // Sans-serif fonts
@@ -466,6 +481,9 @@ void LLFontGL::destroyDefaultFonts()
466 delete sSansSerifBold; 481 delete sSansSerifBold;
467 sSansSerifBold = NULL; 482 sSansSerifBold = NULL;
468 483
484 delete sMonospaceFallback;
485 sMonospaceFallback = NULL;
486
469 delete sSSHugeFallback; 487 delete sSSHugeFallback;
470 sSSHugeFallback = NULL; 488 sSSHugeFallback = NULL;
471 489
@@ -647,7 +665,8 @@ S32 LLFontGL::render(const LLWString &wstr,
647 665
648 mImageGLp->bind(0); 666 mImageGLp->bind(0);
649 667
650 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Not guaranteed to be set correctly 668 // Not guaranteed to be set correctly
669 gGL.setSceneBlendType(LLRender::BT_ALPHA);
651 670
652 cur_x = ((F32)x * sScaleX); 671 cur_x = ((F32)x * sScaleX);
653 cur_y = ((F32)y * sScaleY); 672 cur_y = ((F32)y * sScaleY);
diff --git a/linden/indra/llrender/llfontgl.h b/linden/indra/llrender/llfontgl.h
index 4df1063..01046af 100644
--- a/linden/indra/llrender/llfontgl.h
+++ b/linden/indra/llrender/llfontgl.h
@@ -228,6 +228,7 @@ public:
228 static LLString sAppDir; // For loading fonts 228 static LLString sAppDir; // For loading fonts
229 229
230 static LLFontGL* sMonospace; // medium 230 static LLFontGL* sMonospace; // medium
231 static LLFontList* sMonospaceFallback;
231 232
232 static LLFontGL* sSansSerifSmall; // small 233 static LLFontGL* sSansSerifSmall; // small
233 static LLFontList* sSSSmallFallback; 234 static LLFontList* sSSSmallFallback;
diff --git a/linden/indra/llrender/llglimmediate.cpp b/linden/indra/llrender/llglimmediate.cpp
index edc694a..17c2182 100644
--- a/linden/indra/llrender/llglimmediate.cpp
+++ b/linden/indra/llrender/llglimmediate.cpp
@@ -1,302 +1 @@
1/** #error This file has been renamed llrender.cpp
2 * @file llglimmediate.cpp
3 * @brief LLGLImmediate 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 "llglimmediate.h"
35#include "llvertexbuffer.h"
36
37LLGLImmediate gGL;
38
39bool LLGLImmediate::sClever = false;
40
41const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD;
42
43LLGLImmediate::LLGLImmediate()
44{
45 mCount = 0;
46 mMode = LLVertexBuffer::TRIANGLES;
47 mBuffer = new LLVertexBuffer(immediate_mask, 0);
48 mBuffer->allocateBuffer(4096, 0, TRUE);
49 mBuffer->getVertexStrider(mVerticesp);
50 mBuffer->getTexCoordStrider(mTexcoordsp);
51 mBuffer->getColorStrider(mColorsp);
52}
53
54void LLGLImmediate::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
55{
56 flush();
57 glTranslatef(x,y,z);
58}
59
60void LLGLImmediate::pushMatrix()
61{
62 flush();
63 glPushMatrix();
64}
65
66void LLGLImmediate::popMatrix()
67{
68 flush();
69 glPopMatrix();
70}
71
72void LLGLImmediate::blendFunc(GLenum sfactor, GLenum dfactor)
73{
74 flush();
75 glBlendFunc(sfactor, dfactor);
76}
77
78void LLGLImmediate::begin(const GLuint& mode)
79{
80 if (sClever)
81 {
82 if (mode != mMode)
83 {
84 if (mMode == LLVertexBuffer::QUADS ||
85 mMode == LLVertexBuffer::LINES ||
86 mMode == LLVertexBuffer::TRIANGLES ||
87 mMode == LLVertexBuffer::POINTS)
88 {
89 flush();
90 }
91 else if (mCount != 0)
92 {
93 llerrs << "gGL.begin() called redundantly." << llendl;
94 }
95
96 mMode = mode;
97 }
98 }
99 else
100 {
101 glBegin(LLVertexBuffer::sGLMode[mode]);
102 }
103}
104
105void LLGLImmediate::end()
106{
107 if (sClever)
108 {
109 if (mCount == 0)
110 {
111 return;
112 //IMM_ERRS << "GL begin and end called with no vertices specified." << llendl;
113 }
114
115 if ((mMode != LLVertexBuffer::QUADS &&
116 mMode != LLVertexBuffer::LINES &&
117 mMode != LLVertexBuffer::TRIANGLES &&
118 mMode != LLVertexBuffer::POINTS) ||
119 mCount > 2048)
120 {
121 flush();
122 }
123 }
124 else
125 {
126 glEnd();
127 }
128}
129
130void LLGLImmediate::flush()
131{
132 if (sClever)
133 {
134 if (mCount > 0)
135 {
136#if 0
137 if (!glIsEnabled(GL_VERTEX_ARRAY))
138 {
139 llerrs << "foo 1" << llendl;
140 }
141
142 if (!glIsEnabled(GL_COLOR_ARRAY))
143 {
144 llerrs << "foo 2" << llendl;
145 }
146
147 if (!glIsEnabled(GL_TEXTURE_COORD_ARRAY))
148 {
149 llerrs << "foo 3" << llendl;
150 }
151
152 if (glIsEnabled(GL_NORMAL_ARRAY))
153 {
154 llerrs << "foo 7" << llendl;
155 }
156
157 GLvoid* pointer;
158
159 glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer);
160 if (pointer != &(mBuffer[0].v))
161 {
162 llerrs << "foo 4" << llendl;
163 }
164
165 glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer);
166 if (pointer != &(mBuffer[0].c))
167 {
168 llerrs << "foo 5" << llendl;
169 }
170
171 glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer);
172 if (pointer != &(mBuffer[0].uv))
173 {
174 llerrs << "foo 6" << llendl;
175 }
176#endif
177
178 mBuffer->setBuffer(immediate_mask);
179 mBuffer->drawArrays(mMode, 0, mCount);
180
181 mVerticesp[0] = mVerticesp[mCount];
182 mTexcoordsp[0] = mTexcoordsp[mCount];
183 mColorsp[0] = mColorsp[mCount];
184 mCount = 0;
185 }
186 }
187}
188
189void LLGLImmediate::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
190{
191 if (sClever)
192 {
193 if (mCount >= 4096)
194 {
195 // llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl;
196 return;
197 }
198
199 mVerticesp[mCount] = LLVector3(x,y,z);
200 mCount++;
201 if (mCount < 4096)
202 {
203 mVerticesp[mCount] = mVerticesp[mCount-1];
204 mColorsp[mCount] = mColorsp[mCount-1];
205 mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
206 }
207 }
208 else
209 {
210 glVertex3f(x,y,z);
211 }
212}
213
214void LLGLImmediate::vertex2i(const GLint& x, const GLint& y)
215{
216 vertex3f((GLfloat) x, (GLfloat) y, 0);
217}
218
219void LLGLImmediate::vertex2f(const GLfloat& x, const GLfloat& y)
220{
221 vertex3f(x,y,0);
222}
223
224void LLGLImmediate::vertex2fv(const GLfloat* v)
225{
226 vertex3f(v[0], v[1], 0);
227}
228
229void LLGLImmediate::vertex3fv(const GLfloat* v)
230{
231 vertex3f(v[0], v[1], v[2]);
232}
233
234void LLGLImmediate::texCoord2f(const GLfloat& x, const GLfloat& y)
235{
236 if (sClever)
237 {
238 mTexcoordsp[mCount] = LLVector2(x,y);
239 }
240 else
241 {
242 glTexCoord2f(x,y);
243 }
244}
245
246void LLGLImmediate::texCoord2i(const GLint& x, const GLint& y)
247{
248 texCoord2f((GLfloat) x, (GLfloat) y);
249}
250
251void LLGLImmediate::texCoord2fv(const GLfloat* tc)
252{
253 texCoord2f(tc[0], tc[1]);
254}
255
256void LLGLImmediate::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a)
257{
258 if (sClever)
259 {
260 mColorsp[mCount] = LLColor4U(r,g,b,a);
261 }
262 else
263 {
264 glColor4ub(r,g,b,a);
265 }
266}
267
268void LLGLImmediate::color4ubv(const GLubyte* c)
269{
270 color4ub(c[0], c[1], c[2], c[3]);
271}
272
273void LLGLImmediate::color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a)
274{
275 color4ub((GLubyte) (llclamp(r, 0.f, 1.f)*255),
276 (GLubyte) (llclamp(g, 0.f, 1.f)*255),
277 (GLubyte) (llclamp(b, 0.f, 1.f)*255),
278 (GLubyte) (llclamp(a, 0.f, 1.f)*255));
279}
280
281void LLGLImmediate::color4fv(const GLfloat* c)
282{
283 color4f(c[0],c[1],c[2],c[3]);
284}
285
286void LLGLImmediate::color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b)
287{
288 color4f(r,g,b,1);
289}
290
291void LLGLImmediate::color3fv(const GLfloat* c)
292{
293 color4f(c[0],c[1],c[2],1);
294}
295
296void LLGLImmediate::setClever(bool do_clever)
297{
298 llassert(mCount == 0);
299
300 sClever = do_clever;
301}
302
diff --git a/linden/indra/llrender/llglimmediate.h b/linden/indra/llrender/llglimmediate.h
index e0cddff..4a7a0eb 100644
--- a/linden/indra/llrender/llglimmediate.h
+++ b/linden/indra/llrender/llglimmediate.h
@@ -1,106 +1 @@
1/** #error This file has been renamed llrender.h
2 * @file llglimmediate.h
3 * @brief LLGLImmediate definition
4 *
5 * This class acts as a wrapper for OpenGL immediate calls concerning glBegin and glEnd.
6 * The goal of this class is to minimize the number of api calls due to legacy rendering
7 * code, and to define an interface for a multiple rendering API abstraction of the UI
8 * rendering.
9 *
10 * $LicenseInfo:firstyear=2001&license=viewergpl$
11 *
12 * Copyright (c) 2001-2008, Linden Research, Inc.
13 *
14 * Second Life Viewer Source Code
15 * The source code in this file ("Source Code") is provided by Linden Lab
16 * to you under the terms of the GNU General Public License, version 2.0
17 * ("GPL"), unless you have obtained a separate licensing agreement
18 * ("Other License"), formally executed by you and Linden Lab. Terms of
19 * the GPL can be found in doc/GPL-license.txt in this distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
21 *
22 * There are special exceptions to the terms and conditions of the GPL as
23 * it is applied to this Source Code. View the full text of the exception
24 * in the file doc/FLOSS-exception.txt in this software distribution, or
25 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
26 *
27 * By copying, modifying or distributing this software, you acknowledge
28 * that you have read and understood your obligations described above,
29 * and agree to abide by those obligations.
30 *
31 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
32 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
33 * COMPLETENESS OR PERFORMANCE.
34 * $/LicenseInfo$
35 */
36
37#ifndef LL_LLGLIMMEDIATE_H
38#define LL_LLGLIMMEDIATE_H
39
40#include "stdtypes.h"
41#include "llgltypes.h"
42#include "llglheaders.h"
43#include "llvertexbuffer.h"
44
45class LLGLImmediate
46{
47public:
48 LLGLImmediate();
49
50 void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
51 void pushMatrix();
52 void popMatrix();
53 void blendFunc(GLenum sfactor, GLenum dfactor);
54 void flush();
55
56 void begin(const GLuint& mode);
57 void end();
58 void vertex2i(const GLint& x, const GLint& y);
59 void vertex2f(const GLfloat& x, const GLfloat& y);
60 void vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z);
61 void vertex2fv(const GLfloat* v);
62 void vertex3fv(const GLfloat* v);
63
64 void texCoord2i(const GLint& x, const GLint& y);
65 void texCoord2f(const GLfloat& x, const GLfloat& y);
66 void texCoord2fv(const GLfloat* tc);
67
68 void color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a);
69 void color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a);
70 void color4fv(const GLfloat* c);
71 void color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b);
72 void color3fv(const GLfloat* c);
73 void color4ubv(const GLubyte* c);
74
75 // switch clever mode GL immediate rendering on or off. Setting to true builds
76 // client arrays manually, setting to false passes through the GL immediate mode
77 // commands to the GL implementation. Controllable by the RenderUseCleverUI
78 // debug setting.
79 // *NOTE: I have measured that this has about a 9% performance cost (0.6ms) for the
80 // Render/UI fasttimer vs the old #if CLEVER compile time switch. Dave Parks and I
81 // agreed that this was acceptable at the time due to it enabling better regression
82 // testing for QA.
83 // -Brad
84 void setClever(bool do_clever);
85
86 typedef struct Vertex
87 {
88 GLfloat v[3];
89 GLubyte c[4];
90 GLfloat uv[2];
91 };
92
93private:
94 static bool sClever;
95
96 U32 mCount;
97 U32 mMode;
98 LLPointer<LLVertexBuffer> mBuffer;
99 LLStrider<LLVector3> mVerticesp;
100 LLStrider<LLVector2> mTexcoordsp;
101 LLStrider<LLColor4U> mColorsp;
102};
103
104extern LLGLImmediate gGL;
105
106#endif
diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp
index 92d8eb4..fd934b9 100644
--- a/linden/indra/llrender/llimagegl.cpp
+++ b/linden/indra/llrender/llimagegl.cpp
@@ -41,7 +41,7 @@
41 41
42#include "llmath.h" 42#include "llmath.h"
43#include "llgl.h" 43#include "llgl.h"
44#include "llglimmediate.h" 44#include "llrender.h"
45 45
46 46
47//---------------------------------------------------------------------------- 47//----------------------------------------------------------------------------
@@ -130,13 +130,13 @@ void LLImageGL::bindExternalTexture(LLGLuint gl_name, S32 stage, LLGLenum bind_t
130 gGL.flush(); 130 gGL.flush();
131 if (stage > 0) 131 if (stage > 0)
132 { 132 {
133 glActiveTextureARB(GL_TEXTURE0_ARB + stage); 133 gGL.getTexUnit(stage)->activate();
134 } 134 }
135 glBindTexture(bind_target, gl_name); 135 glBindTexture(bind_target, gl_name);
136 sCurrentBoundTextures[stage] = gl_name; 136 sCurrentBoundTextures[stage] = gl_name;
137 if (stage > 0) 137 if (stage > 0)
138 { 138 {
139 glActiveTextureARB(GL_TEXTURE0_ARB); 139 gGL.getTexUnit(0)->activate();
140 } 140 }
141} 141}
142 142
@@ -149,9 +149,9 @@ void LLImageGL::unbindTexture(S32 stage, LLGLenum bind_target)
149 gGL.flush(); 149 gGL.flush();
150 if (stage > 0) 150 if (stage > 0)
151 { 151 {
152 glActiveTextureARB(GL_TEXTURE0_ARB + stage); 152 gGL.getTexUnit(stage)->activate();
153 glBindTexture(GL_TEXTURE_2D, 0); 153 glBindTexture(GL_TEXTURE_2D, 0);
154 glActiveTextureARB(GL_TEXTURE0_ARB); 154 gGL.getTexUnit(0)->activate();
155 } 155 }
156 else 156 else
157 { 157 {
@@ -304,7 +304,9 @@ void LLImageGL::init(BOOL usemipmaps)
304 mIsResident = 0; 304 mIsResident = 0;
305 mClampS = FALSE; 305 mClampS = FALSE;
306 mClampT = FALSE; 306 mClampT = FALSE;
307 mMipFilterNearest = FALSE; 307 mClampR = FALSE;
308 mMagFilterNearest = FALSE;
309 mMinFilterNearest = FALSE;
308 mWidth = 0; 310 mWidth = 0;
309 mHeight = 0; 311 mHeight = 0;
310 mComponents = 0; 312 mComponents = 0;
@@ -439,7 +441,7 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const
439 gGL.flush(); 441 gGL.flush();
440 if (stage > 0) 442 if (stage > 0)
441 { 443 {
442 glActiveTextureARB(GL_TEXTURE0_ARB + stage); 444 gGL.getTexUnit(stage)->activate();
443 } 445 }
444 446
445 glBindTexture(mBindTarget, mTexName); 447 glBindTexture(mBindTarget, mTexName);
@@ -448,7 +450,7 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const
448 450
449 if (stage > 0) 451 if (stage > 0)
450 { 452 {
451 glActiveTextureARB(GL_TEXTURE0_ARB); 453 gGL.getTexUnit(0)->activate();
452 } 454 }
453 455
454 if (mLastBindTime != sLastFrameTime) 456 if (mLastBindTime != sLastFrameTime)
@@ -466,12 +468,12 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const
466 gGL.flush(); 468 gGL.flush();
467 if (stage > 0) 469 if (stage > 0)
468 { 470 {
469 glActiveTextureARB(GL_TEXTURE0_ARB+stage); 471 gGL.getTexUnit(stage)->activate();
470 } 472 }
471 glBindTexture(mBindTarget, 0); 473 glBindTexture(mBindTarget, 0);
472 if (stage > 0) 474 if (stage > 0)
473 { 475 {
474 glActiveTextureARB(GL_TEXTURE0_ARB+stage); 476 gGL.getTexUnit(0)->activate();
475 } 477 }
476 sCurrentBoundTextures[stage] = 0; 478 sCurrentBoundTextures[stage] = 0;
477 return FALSE; 479 return FALSE;
@@ -628,7 +630,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
628 { 630 {
629 S32 bytes = w * h * mComponents; 631 S32 bytes = w * h * mComponents;
630 llassert(prev_mip_data); 632 llassert(prev_mip_data);
631 llassert(prev_mip_size == bytes); 633 llassert(prev_mip_size == bytes*4);
632 U8* new_data = new U8[bytes]; 634 U8* new_data = new U8[bytes];
633 llassert_always(new_data); 635 llassert_always(new_data);
634 LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents); 636 LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
@@ -941,7 +943,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
941 setImage(data_in, data_hasmips); 943 setImage(data_in, data_hasmips);
942 944
943 setClamp(mClampS, mClampT); 945 setClamp(mClampS, mClampT);
944 setMipFilterNearest(mMipFilterNearest); 946 setMipFilterNearest(mMagFilterNearest);
945 947
946 // things will break if we don't unbind after creation 948 // things will break if we don't unbind after creation
947 unbindTexture(0, mBindTarget); 949 unbindTexture(0, mBindTarget);
@@ -1044,8 +1046,23 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
1044 1046
1045 S32 gl_discard = discard_level - mCurrentDiscardLevel; 1047 S32 gl_discard = discard_level - mCurrentDiscardLevel;
1046 1048
1047 llverify(bindTextureInternal(0)); 1049 //explicitly unbind texture
1048 1050 LLImageGL::unbindTexture(0, mTarget);
1051 llverify(bindTextureInternal(0));
1052
1053 if (gDebugGL)
1054 {
1055 if (mTarget == GL_TEXTURE_2D)
1056 {
1057 GLint texname;
1058 glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
1059 if (texname != mTexName)
1060 {
1061 llerrs << "Invalid texture bound!" << llendl;
1062 }
1063 }
1064 }
1065
1049 LLGLint glwidth = 0; 1066 LLGLint glwidth = 0;
1050 glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth); 1067 glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth);
1051 if (glwidth == 0) 1068 if (glwidth == 0)
@@ -1067,40 +1084,63 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
1067 llerrs << llformat("LLImageGL::readBackRaw: bogus params: %d x %d x %d",width,height,ncomponents) << llendl; 1084 llerrs << llformat("LLImageGL::readBackRaw: bogus params: %d x %d x %d",width,height,ncomponents) << llendl;
1068 } 1085 }
1069 1086
1070 BOOL return_result = TRUE ;
1071 LLGLint is_compressed = 0; 1087 LLGLint is_compressed = 0;
1072 if (compressed_ok) 1088 if (compressed_ok)
1073 { 1089 {
1074 glGetTexLevelParameteriv(mTarget, is_compressed, GL_TEXTURE_COMPRESSED, (GLint*)&is_compressed); 1090 glGetTexLevelParameteriv(mTarget, is_compressed, GL_TEXTURE_COMPRESSED, (GLint*)&is_compressed);
1075 } 1091 }
1092
1093 //-----------------------------------------------------------------------------------------------
1094 GLenum error ;
1095 while((error = glGetError()) != GL_NO_ERROR)
1096 {
1097 llwarns << "GL Error happens before reading back texture. Error code: " << error << llendl ;
1098 }
1099 //-----------------------------------------------------------------------------------------------
1100
1076 if (is_compressed) 1101 if (is_compressed)
1077 { 1102 {
1078 LLGLint glbytes; 1103 LLGLint glbytes;
1079 glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint*)&glbytes); 1104 glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint*)&glbytes);
1080 imageraw->allocateDataSize(width, height, ncomponents, glbytes); 1105 if(!imageraw->allocateDataSize(width, height, ncomponents, glbytes))
1081 glGetCompressedTexImageARB(mTarget, gl_discard, (GLvoid*)(imageraw->getData()));
1082 if(glGetError() != GL_NO_ERROR)
1083 { 1106 {
1084 llwarns << "Error happens when reading back the compressed texture image." << llendl ; 1107 llwarns << "Memory allocation failed for reading back texture. Size is: " << glbytes << llendl ;
1085 imageraw->deleteData() ; 1108 llwarns << "width: " << width << "height: " << height << "components: " << ncomponents << llendl ;
1086 return_result = FALSE ; 1109 return FALSE ;
1087 } 1110 }
1088 stop_glerror(); 1111
1112 glGetCompressedTexImageARB(mTarget, gl_discard, (GLvoid*)(imageraw->getData()));
1113 //stop_glerror();
1089 } 1114 }
1090 else 1115 else
1091 { 1116 {
1092 imageraw->allocateDataSize(width, height, ncomponents); 1117 if(!imageraw->allocateDataSize(width, height, ncomponents))
1093 glGetTexImage(GL_TEXTURE_2D, gl_discard, mFormatPrimary, mFormatType, (GLvoid*)(imageraw->getData()));
1094 if(glGetError() != GL_NO_ERROR)
1095 { 1118 {
1096 llwarns << "Error happens when reading back the texture image." << llendl ; 1119 llwarns << "Memory allocation failed for reading back texture." << llendl ;
1097 imageraw->deleteData() ; 1120 llwarns << "width: " << width << "height: " << height << "components: " << ncomponents << llendl ;
1098 return_result = FALSE ; 1121 return FALSE ;
1099 } 1122 }
1100 stop_glerror(); 1123
1124 glGetTexImage(GL_TEXTURE_2D, gl_discard, mFormatPrimary, mFormatType, (GLvoid*)(imageraw->getData()));
1125 //stop_glerror();
1101 } 1126 }
1102 1127
1103 return return_result ; 1128 //-----------------------------------------------------------------------------------------------
1129 if((error = glGetError()) != GL_NO_ERROR)
1130 {
1131 llwarns << "GL Error happens after reading back texture. Error code: " << error << llendl ;
1132 imageraw->deleteData() ;
1133
1134 while((error = glGetError()) != GL_NO_ERROR)
1135 {
1136 llwarns << "GL Error happens after reading back texture. Error code: " << error << llendl ;
1137 }
1138
1139 return FALSE ;
1140 }
1141 //-----------------------------------------------------------------------------------------------
1142
1143 return TRUE ;
1104} 1144}
1105 1145
1106void LLImageGL::destroyGLTexture() 1146void LLImageGL::destroyGLTexture()
@@ -1130,25 +1170,55 @@ void LLImageGL::destroyGLTexture()
1130 1170
1131//---------------------------------------------------------------------------- 1171//----------------------------------------------------------------------------
1132 1172
1133void LLImageGL::setClamp(BOOL clamps, BOOL clampt) 1173void LLImageGL::glClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr)
1174{
1175 glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
1176 glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
1177 glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
1178}
1179
1180void LLImageGL::glClamp (BOOL clamps, BOOL clampt)
1134{ 1181{
1135 mClampS = clamps;
1136 mClampT = clampt;
1137 if (mTexName != 0) 1182 if (mTexName != 0)
1138 { 1183 {
1139 glTexParameteri(mBindTarget, GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); 1184 glTexParameteri (mBindTarget, GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
1140 glTexParameteri(mBindTarget, GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT); 1185 glTexParameteri (mBindTarget, GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT);
1141 } 1186 }
1142 stop_glerror();
1143} 1187}
1144 1188
1145void LLImageGL::setMipFilterNearest(BOOL nearest, BOOL min_nearest) 1189void LLImageGL::setClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr)
1190{
1191 mClampS = clamps;
1192 mClampT = clampt;
1193 mClampR = clampr;
1194 glClampCubemap (clamps, clampt, clampr);
1195}
1196
1197void LLImageGL::setClamp(BOOL clamps, BOOL clampt)
1198{
1199 mClampS = clamps;
1200 mClampT = clampt;
1201 glClamp (clamps, clampt);
1202}
1203
1204void LLImageGL::overrideClamp (BOOL clamps, BOOL clampt)
1205{
1206 glClamp (clamps, clampt);
1207}
1208
1209void LLImageGL::restoreClamp (void)
1210{
1211 glClamp (mClampS, mClampT);
1212}
1213
1214void LLImageGL::setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest)
1146{ 1215{
1147 mMipFilterNearest = nearest; 1216 mMagFilterNearest = mag_nearest;
1217 mMinFilterNearest = min_nearest;
1148 1218
1149 if (mTexName != 0) 1219 if (mTexName != 0)
1150 { 1220 {
1151 if (min_nearest) 1221 if (mMinFilterNearest)
1152 { 1222 {
1153 glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1223 glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1154 } 1224 }
@@ -1160,7 +1230,7 @@ void LLImageGL::setMipFilterNearest(BOOL nearest, BOOL min_nearest)
1160 { 1230 {
1161 glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1231 glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1162 } 1232 }
1163 if (mMipFilterNearest) 1233 if (mMagFilterNearest)
1164 { 1234 {
1165 glTexParameteri(mBindTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1235 glTexParameteri(mBindTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1166 } 1236 }
@@ -1170,7 +1240,7 @@ void LLImageGL::setMipFilterNearest(BOOL nearest, BOOL min_nearest)
1170 } 1240 }
1171 if (gGLManager.mHasAnisotropic) 1241 if (gGLManager.mHasAnisotropic)
1172 { 1242 {
1173 if (sGlobalUseAnisotropic && !mMipFilterNearest) 1243 if (sGlobalUseAnisotropic && !mMagFilterNearest)
1174 { 1244 {
1175 F32 largest_anisotropy; 1245 F32 largest_anisotropy;
1176 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_anisotropy); 1246 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_anisotropy);
diff --git a/linden/indra/llrender/llimagegl.h b/linden/indra/llrender/llimagegl.h
index b386294..3f231ee 100644
--- a/linden/indra/llrender/llimagegl.h
+++ b/linden/indra/llrender/llimagegl.h
@@ -81,6 +81,10 @@ protected:
81 virtual ~LLImageGL(); 81 virtual ~LLImageGL();
82 BOOL bindTextureInternal(const S32 stage = 0) const; 82 BOOL bindTextureInternal(const S32 stage = 0) const;
83 83
84private:
85 void glClamp (BOOL clamps, BOOL clampt);
86 void glClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr = FALSE);
87
84public: 88public:
85 virtual void dump(); // debugging info to llinfos 89 virtual void dump(); // debugging info to llinfos
86 virtual BOOL bind(const S32 stage = 0) const; 90 virtual BOOL bind(const S32 stage = 0) const;
@@ -99,8 +103,11 @@ public:
99 BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok); 103 BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok);
100 void destroyGLTexture(); 104 void destroyGLTexture();
101 105
106 void setClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr = FALSE);
102 void setClamp(BOOL clamps, BOOL clampt); 107 void setClamp(BOOL clamps, BOOL clampt);
103 void setMipFilterNearest(BOOL nearest, BOOL min_nearest = FALSE); 108 void overrideClamp (BOOL clamps, BOOL clampt);
109 void restoreClamp (void);
110 void setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest = FALSE);
104 void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); 111 void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
105 void dontDiscard() { mDontDiscard = 1; } 112 void dontDiscard() { mDontDiscard = 1; }
106 113
@@ -117,7 +124,8 @@ public:
117 124
118 BOOL getClampS() const { return mClampS; } 125 BOOL getClampS() const { return mClampS; }
119 BOOL getClampT() const { return mClampT; } 126 BOOL getClampT() const { return mClampT; }
120 BOOL getMipFilterNearest() const { return mMipFilterNearest; } 127 BOOL getClampR() const { return mClampR; }
128 BOOL getMipFilterNearest() const { return mMagFilterNearest; }
121 129
122 BOOL getHasGLTexture() const { return mTexName != 0; } 130 BOOL getHasGLTexture() const { return mTexName != 0; }
123 LLGLuint getTexName() const { return mTexName; } 131 LLGLuint getTexName() const { return mTexName; }
@@ -167,7 +175,9 @@ protected:
167 175
168 S8 mClampS; // Need to save clamp state 176 S8 mClampS; // Need to save clamp state
169 S8 mClampT; 177 S8 mClampT;
170 S8 mMipFilterNearest; // if TRUE, set magfilter to GL_NEAREST 178 S8 mClampR;
179 S8 mMagFilterNearest; // if TRUE, set magfilter to GL_NEAREST
180 S8 mMinFilterNearest; // if TRUE, set minfilter to GL_NEAREST
171 181
172 LLGLint mFormatInternal; // = GL internalformat 182 LLGLint mFormatInternal; // = GL internalformat
173 LLGLenum mFormatPrimary; // = GL format (pixel data format) 183 LLGLenum mFormatPrimary; // = GL format (pixel data format)
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
diff --git a/linden/indra/llrender/llrender.h b/linden/indra/llrender/llrender.h
new file mode 100644
index 0000000..03280fe
--- /dev/null
+++ b/linden/indra/llrender/llrender.h
@@ -0,0 +1,239 @@
1/**
2 * @file llrender.h
3 * @brief LLRender definition
4 *
5 * This class acts as a wrapper for OpenGL calls.
6 * The goal of this class is to minimize the number of api calls due to legacy rendering
7 * code, to define an interface for a multiple rendering API abstraction of the UI
8 * rendering, and to abstract out direct rendering calls in a way that is cleaner and easier to maintain.
9 *
10 * $LicenseInfo:firstyear=2001&license=viewergpl$
11 *
12 * Copyright (c) 2001-2008, Linden Research, Inc.
13 *
14 * Second Life Viewer Source Code
15 * The source code in this file ("Source Code") is provided by Linden Lab
16 * to you under the terms of the GNU General Public License, version 2.0
17 * ("GPL"), unless you have obtained a separate licensing agreement
18 * ("Other License"), formally executed by you and Linden Lab. Terms of
19 * the GPL can be found in doc/GPL-license.txt in this distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
21 *
22 * There are special exceptions to the terms and conditions of the GPL as
23 * it is applied to this Source Code. View the full text of the exception
24 * in the file doc/FLOSS-exception.txt in this software distribution, or
25 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
26 *
27 * By copying, modifying or distributing this software, you acknowledge
28 * that you have read and understood your obligations described above,
29 * and agree to abide by those obligations.
30 *
31 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
32 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
33 * COMPLETENESS OR PERFORMANCE.
34 * $/LicenseInfo$
35 */
36
37#ifndef LL_LLGLRENDER_H
38#define LL_LLGLRENDER_H
39
40#include "stdtypes.h"
41#include "llgltypes.h"
42#include "llglheaders.h"
43#include "llvertexbuffer.h"
44
45class LLTexUnit
46{
47public:
48 typedef enum
49 {
50 TB_REPLACE = 0,
51 TB_ADD,
52 TB_MULT,
53 TB_MULT_X2,
54 TB_ALPHA_BLEND,
55 TB_COMBINE // Doesn't need to be set directly, setTexture___Blend() set TB_COMBINE automatically
56 } eTextureBlendType;
57
58 typedef enum
59 {
60 TBO_REPLACE = 0, // Use Source 1
61 TBO_MULT, // Multiply: ( Source1 * Source2 )
62 TBO_MULT_X2, // Multiply then scale by 2: ( 2.0 * ( Source1 * Source2 ) )
63 TBO_MULT_X4, // Multiply then scale by 4: ( 4.0 * ( Source1 * Source2 ) )
64 TBO_ADD, // Add: ( Source1 + Source2 )
65 TBO_ADD_SIGNED, // Add then subtract 0.5: ( ( Source1 + Source2 ) - 0.5 )
66 TBO_SUBTRACT, // Subtract Source2 from Source1: ( Source1 - Source2 )
67 TBO_LERP_VERT_ALPHA, // Interpolate based on Vertex Alpha (VA): ( Source1 * VA + Source2 * (1-VA) )
68 TBO_LERP_TEX_ALPHA, // Interpolate based on Texture Alpha (TA): ( Source1 * TA + Source2 * (1-TA) )
69 TBO_LERP_PREV_ALPHA, // Interpolate based on Previous Alpha (PA): ( Source1 * PA + Source2 * (1-PA) )
70 TBO_LERP_CONST_ALPHA, // Interpolate based on Const Alpha (CA): ( Source1 * CA + Source2 * (1-CA) )
71 TBO_LERP_VERT_COLOR // Interpolate based on Vertex Col (VC): ( Source1 * VC + Source2 * (1-VC) )
72 // *Note* TBO_LERP_VERTEX_COLOR only works with setTextureColorBlend(),
73 // and falls back to TBO_LERP_VERTEX_ALPHA for setTextureAlphaBlend().
74 } eTextureBlendOp;
75
76 typedef enum
77 {
78 TBS_PREV_COLOR = 0, // Color from the previous texture stage
79 TBS_PREV_ALPHA,
80 TBS_ONE_MINUS_PREV_COLOR,
81 TBS_ONE_MINUS_PREV_ALPHA,
82 TBS_TEX_COLOR, // Color from the texture bound to this stage
83 TBS_TEX_ALPHA,
84 TBS_ONE_MINUS_TEX_COLOR,
85 TBS_ONE_MINUS_TEX_ALPHA,
86 TBS_VERT_COLOR, // The vertex color currently set
87 TBS_VERT_ALPHA,
88 TBS_ONE_MINUS_VERT_COLOR,
89 TBS_ONE_MINUS_VERT_ALPHA,
90 TBS_CONST_COLOR, // The constant color value currently set
91 TBS_CONST_ALPHA,
92 TBS_ONE_MINUS_CONST_COLOR,
93 TBS_ONE_MINUS_CONST_ALPHA
94 } eTextureBlendSrc;
95
96 LLTexUnit(U32 index);
97 U32 getIndex(void);
98
99 void enable(void);
100 void disable(void);
101 void activate(void);
102
103 void bindTexture(const LLImageGL* texture);
104 void unbindTexture(void);
105
106 void setTextureBlendType(eTextureBlendType type);
107
108 inline void setTextureColorBlend(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2 = TBS_PREV_COLOR)
109 { setTextureCombiner(op, src1, src2, false); }
110
111 // NOTE: If *_COLOR enums are passed to src1 or src2, the corresponding *_ALPHA enum will be used instead.
112 inline void setTextureAlphaBlend(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2 = TBS_PREV_ALPHA)
113 { setTextureCombiner(op, src1, src2, true); }
114
115private:
116 U32 mIndex;
117 bool mIsEnabled;
118 eTextureBlendType mCurrBlendType;
119 eTextureBlendOp mCurrColorOp;
120 eTextureBlendSrc mCurrColorSrc1;
121 eTextureBlendSrc mCurrColorSrc2;
122 eTextureBlendOp mCurrAlphaOp;
123 eTextureBlendSrc mCurrAlphaSrc1;
124 eTextureBlendSrc mCurrAlphaSrc2;
125 S32 mCurrColorScale;
126 S32 mCurrAlphaScale;
127
128 void debugTextureUnit(void);
129 void setColorScale(S32 scale);
130 void setAlphaScale(S32 scale);
131 GLint getTextureSource(eTextureBlendSrc src);
132 GLint getTextureSourceType(eTextureBlendSrc src, bool isAlpha = false);
133 void setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha = false);
134};
135
136class LLRender
137{
138 friend class LLTexUnit;
139public:
140 typedef enum
141 {
142 CF_NEVER = 0,
143 CF_ALWAYS,
144 CF_LESS,
145 CF_LESS_EQUAL,
146 CF_EQUAL,
147 CF_NOT_EQUAL,
148 CF_GREATER_EQUAL,
149 CF_GREATER,
150 CF_DEFAULT
151 } eCompareFunc;
152
153 typedef enum
154 {
155 BT_ALPHA = 0,
156 BT_ADD,
157 BT_ADD_WITH_ALPHA, // Additive blend modulated by the fragment's alpha.
158 BT_MULT,
159 BT_MULT_X2,
160 BT_REPLACE
161 } eBlendType;
162
163 typedef enum
164 {
165 BF_ONE = 0,
166 BF_ZERO,
167 BF_DEST_COLOR,
168 BF_SOURCE_COLOR,
169 BF_ONE_MINUS_DEST_COLOR,
170 BF_ONE_MINUS_SOURCE_COLOR,
171 BF_DEST_ALPHA,
172 BF_SOURCE_ALPHA,
173 BF_ONE_MINUS_DEST_ALPHA,
174 BF_ONE_MINUS_SOURCE_ALPHA
175 } eBlendFactor;
176
177 LLRender();
178 ~LLRender();
179
180 void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
181 void pushMatrix();
182 void popMatrix();
183
184 void flush();
185
186 void begin(const GLuint& mode);
187 void end();
188 void vertex2i(const GLint& x, const GLint& y);
189 void vertex2f(const GLfloat& x, const GLfloat& y);
190 void vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z);
191 void vertex2fv(const GLfloat* v);
192 void vertex3fv(const GLfloat* v);
193
194 void texCoord2i(const GLint& x, const GLint& y);
195 void texCoord2f(const GLfloat& x, const GLfloat& y);
196 void texCoord2fv(const GLfloat* tc);
197
198 void color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a);
199 void color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a);
200 void color4fv(const GLfloat* c);
201 void color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b);
202 void color3fv(const GLfloat* c);
203 void color4ubv(const GLubyte* c);
204
205 void setColorMask(bool writeColor, bool writeAlpha);
206 void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha);
207 void setSceneBlendType(eBlendType type);
208
209 void setAlphaRejectSettings(eCompareFunc func, F32 value = 0.01f);
210
211 void blendFunc(eBlendFactor sfactor, eBlendFactor dfactor);
212
213 LLTexUnit* getTexUnit(U32 index);
214
215 typedef struct Vertex
216 {
217 GLfloat v[3];
218 GLubyte c[4];
219 GLfloat uv[2];
220 };
221
222public:
223
224private:
225 U32 mCount;
226 U32 mMode;
227 U32 mCurrTextureUnitIndex;
228 LLPointer<LLVertexBuffer> mBuffer;
229 LLStrider<LLVector3> mVerticesp;
230 LLStrider<LLVector2> mTexcoordsp;
231 LLStrider<LLColor4U> mColorsp;
232 std::vector<LLTexUnit*> mTexUnits;
233};
234
235
236
237extern LLRender gGL;
238
239#endif
diff --git a/linden/indra/llrender/llrender.vcproj b/linden/indra/llrender/llrender.vcproj
index 2c6e2d2..d9144cb 100644
--- a/linden/indra/llrender/llrender.vcproj
+++ b/linden/indra/llrender/llrender.vcproj
@@ -165,7 +165,7 @@
165 RelativePath=".\llgldbg.cpp"> 165 RelativePath=".\llgldbg.cpp">
166 </File> 166 </File>
167 <File 167 <File
168 RelativePath=".\llglimmediate.cpp"> 168 RelativePath=".\llrender.cpp">
169 </File> 169 </File>
170 <File 170 <File
171 RelativePath=".\llimagegl.cpp"> 171 RelativePath=".\llimagegl.cpp">
@@ -206,7 +206,7 @@
206 RelativePath=".\llgldbg.h"> 206 RelativePath=".\llgldbg.h">
207 </File> 207 </File>
208 <File 208 <File
209 RelativePath=".\llglimmediate.h"> 209 RelativePath=".\llrender.h">
210 </File> 210 </File>
211 <File 211 <File
212 RelativePath=".\llimagegl.h"> 212 RelativePath=".\llimagegl.h">
diff --git a/linden/indra/llrender/llrender_vc8.vcproj b/linden/indra/llrender/llrender_vc8.vcproj
index 8c0f82a..2147cec 100644
--- a/linden/indra/llrender/llrender_vc8.vcproj
+++ b/linden/indra/llrender/llrender_vc8.vcproj
@@ -243,11 +243,11 @@
243 > 243 >
244 </File> 244 </File>
245 <File 245 <File
246 RelativePath=".\llglimmediate.cpp" 246 RelativePath=".\llimagegl.cpp"
247 > 247 >
248 </File> 248 </File>
249 <File 249 <File
250 RelativePath=".\llimagegl.cpp" 250 RelativePath=".\llrender.cpp"
251 > 251 >
252 </File> 252 </File>
253 <File 253 <File
@@ -297,11 +297,11 @@
297 > 297 >
298 </File> 298 </File>
299 <File 299 <File
300 RelativePath=".\llglimmediate.h" 300 RelativePath=".\llimagegl.h"
301 > 301 >
302 </File> 302 </File>
303 <File 303 <File
304 RelativePath=".\llimagegl.h" 304 RelativePath=".\llrender.h"
305 > 305 >
306 </File> 306 </File>
307 <File 307 <File
diff --git a/linden/indra/llrender/llrender_vc9.vcproj b/linden/indra/llrender/llrender_vc9.vcproj
index 08e3362..67385e6 100644
--- a/linden/indra/llrender/llrender_vc9.vcproj
+++ b/linden/indra/llrender/llrender_vc9.vcproj
@@ -244,7 +244,7 @@
244 > 244 >
245 </File> 245 </File>
246 <File 246 <File
247 RelativePath=".\llglimmediate.cpp" 247 RelativePath=".\llrender.cpp"
248 > 248 >
249 </File> 249 </File>
250 <File 250 <File
@@ -298,7 +298,7 @@
298 > 298 >
299 </File> 299 </File>
300 <File 300 <File
301 RelativePath=".\llglimmediate.h" 301 RelativePath=".\llrender.h"
302 > 302 >
303 </File> 303 </File>
304 <File 304 <File
diff --git a/linden/indra/llrender/llrendertarget.cpp b/linden/indra/llrender/llrendertarget.cpp
index e1f7703..708c582 100644
--- a/linden/indra/llrender/llrendertarget.cpp
+++ b/linden/indra/llrender/llrendertarget.cpp
@@ -32,17 +32,23 @@
32#include "linden_common.h" 32#include "linden_common.h"
33 33
34#include "llrendertarget.h" 34#include "llrendertarget.h"
35#include "llglimmediate.h" 35#include "llrender.h"
36#include "llgl.h" 36#include "llgl.h"
37 37
38 38
39BOOL LLRenderTarget::sUseFBO = FALSE; 39BOOL LLRenderTarget::sUseFBO = FALSE;
40 40
41LLRenderTarget::LLRenderTarget() 41LLRenderTarget::LLRenderTarget() :
42 mResX(0),
43 mResY(0),
44 mTex(0),
45 mFBO(0),
46 mDepth(0),
47 mStencil(0),
48 mUseDepth(FALSE),
49 mRenderDepth(FALSE),
50 mUsage(GL_TEXTURE_2D)
42{ 51{
43 mResX = mResY = mTex = mFBO = mDepth = 0;
44 mUseDepth = FALSE;
45 mUsage = GL_TEXTURE_2D;
46} 52}
47 53
48LLRenderTarget::~LLRenderTarget() 54LLRenderTarget::~LLRenderTarget()
@@ -175,6 +181,7 @@ void LLRenderTarget::clear()
175 { 181 {
176 LLGLEnable scissor(GL_SCISSOR_TEST); 182 LLGLEnable scissor(GL_SCISSOR_TEST);
177 glScissor(0, 0, mResX, mResY); 183 glScissor(0, 0, mResX, mResY);
184 stop_glerror();
178 glClear(mask); 185 glClear(mask);
179 } 186 }
180} 187}
diff --git a/linden/indra/llrender/llvertexbuffer.cpp b/linden/indra/llrender/llvertexbuffer.cpp
index 4c663e2..073fcbf 100644
--- a/linden/indra/llrender/llvertexbuffer.cpp
+++ b/linden/indra/llrender/llvertexbuffer.cpp
@@ -38,7 +38,7 @@
38#include "llglheaders.h" 38#include "llglheaders.h"
39#include "llmemory.h" 39#include "llmemory.h"
40#include "llmemtype.h" 40#include "llmemtype.h"
41#include "llglimmediate.h" 41#include "llrender.h"
42 42
43//============================================================================ 43//============================================================================
44 44
@@ -232,7 +232,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
232 llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; 232 llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl;
233 } 233 }
234 234
235 if (mGLBuffer != sGLRenderBuffer) 235 if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
236 { 236 {
237 llerrs << "Wrong vertex buffer bound." << llendl; 237 llerrs << "Wrong vertex buffer bound." << llendl;
238 } 238 }
@@ -768,11 +768,26 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
768 sMapped = TRUE;*/ 768 sMapped = TRUE;*/
769 if (!mMappedData) 769 if (!mMappedData)
770 { 770 {
771 GLint buff;
772 glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
773 if (buff != mGLBuffer)
774 {
775 llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
776 }
777
778
771 llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; 779 llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
772 } 780 }
773 781
774 if (!mMappedIndexData) 782 if (!mMappedIndexData)
775 { 783 {
784 GLint buff;
785 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
786 if (buff != mGLIndices)
787 {
788 llerrs << "Invalid GL index buffer bound: " << buff << llendl;
789 }
790
776 llerrs << "glMapBuffer returned NULL (no index data)" << llendl; 791 llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
777 } 792 }
778 793
@@ -952,8 +967,40 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
952 sIBOActive = TRUE; 967 sIBOActive = TRUE;
953 } 968 }
954 969
970 if (gDebugGL)
971 {
972 GLint buff;
973 glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
974 if (buff != mGLBuffer)
975 {
976 llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
977 }
978
979 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
980 if (buff != mGLIndices)
981 {
982 llerrs << "Invalid GL index buffer bound: " << buff << llendl;
983 }
984 }
985
955 if (mResized) 986 if (mResized)
956 { 987 {
988 if (gDebugGL)
989 {
990 GLint buff;
991 glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
992 if (buff != mGLBuffer)
993 {
994 llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
995 }
996
997 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
998 if (buff != mGLIndices)
999 {
1000 llerrs << "Invalid GL index buffer bound: " << buff << llendl;
1001 }
1002 }
1003
957 if (mGLBuffer) 1004 if (mGLBuffer)
958 { 1005 {
959 stop_glerror(); 1006 stop_glerror();
diff --git a/linden/indra/llrender/llvertexprogramgl.cpp b/linden/indra/llrender/llvertexprogramgl.cpp
deleted file mode 100644
index 9f25582..0000000
--- a/linden/indra/llrender/llvertexprogramgl.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
1/**
2 * @file llvertexprogramgl.cpp
3 * @brief LLVertexProgramGL base class
4 *
5 * $LicenseInfo:firstyear=2003&license=viewergpl$
6 *
7 * Copyright (c) 2003-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// This file contains the definition of LLVertexProgramGL,
33// for purposes of running vertex programs on GL hardware.
34
35#include "linden_common.h"
36
37#include "llvertexprogramgl.h"
38
39#include "llglheaders.h"
40
41LLVertexProgramGL::LLVertexProgramGL()
42{
43 mVertexProgramID = 0;
44}
45
46LLVertexProgramGL::~LLVertexProgramGL()
47{
48 glDeleteProgramsARB(1, (GLuint*) &mVertexProgramID);
49}
50
51BOOL LLVertexProgramGL::load(const char * filename)
52{
53 FILE *fp = fopen(filename, "r");
54 if (!fp)
55 {
56 llwarns << "Unable to open vertex program " << filename << llendl;
57 return FALSE;
58 }
59
60 fseek(fp,0,SEEK_END);
61 S32 file_size = ftell(fp);
62 fseek(fp,0,SEEK_SET);
63
64 char *text_buffer = new char[file_size + 1];
65
66 S32 num_read = (S32)fread(text_buffer, sizeof(char), file_size, fp);
67
68 if (ferror(fp) || num_read == 0)
69 {
70 llwarns << "Unable to read vertex program " << filename << llendl;
71 fclose(fp);
72 delete[] text_buffer;
73 return FALSE;
74 }
75 text_buffer[num_read] = '\0';
76 fclose(fp);
77
78 //Send program string to OpenGL
79 glGenProgramsARB(1, (GLuint*) &mVertexProgramID);
80 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, mVertexProgramID);
81 glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, num_read, text_buffer);
82
83 const GLubyte * program_error_string = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
84
85 GLint error_pos;
86 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos);
87
88 if(error_pos!=-1)
89 {
90 glGetError();
91 S32 line_num = 1;
92 char *next_token = strchr(text_buffer, '\n');
93 while(NULL != next_token && next_token < (text_buffer + error_pos))
94 {
95 next_token++;
96 line_num++;
97 next_token = strchr(next_token, '\n');
98 }
99 char bad_code[11];
100 strncpy(bad_code, text_buffer + error_pos, 10);
101 bad_code[10] = '\0';
102
103 llerrs << filename << "(" << line_num << "): Vertex Program Error: "
104 << program_error_string << " at (" << bad_code<< ")"
105 << llendl;
106 // clean up buffer
107 delete[] text_buffer;
108 return FALSE;
109 }
110
111 // clean up buffer
112 delete[] text_buffer;
113 return TRUE;
114}
115
116void LLVertexProgramGL::bind()
117{
118 glEnable(GL_VERTEX_PROGRAM_ARB);
119 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, mVertexProgramID);
120}
121
122void LLVertexProgramGL::unbind()
123{
124 glDisable(GL_VERTEX_PROGRAM_ARB);
125}
diff --git a/linden/indra/llrender/llvertexprogramgl.h b/linden/indra/newview/llanimstatelabels.h
index f9190f9..db1c1d8 100644
--- a/linden/indra/llrender/llvertexprogramgl.h
+++ b/linden/indra/newview/llanimstatelabels.h
@@ -1,10 +1,11 @@
1/** 1/**
2 * @file llvertexprogramgl.h 2 * @file llanimstatelabels.h
3 * @brief LLVertexProgramGL base class 3 * @brief Declaration of LLVOAvatar class which is a derivation fo
4 * LLViewerObject
4 * 5 *
5 * $LicenseInfo:firstyear=2003&license=viewergpl$ 6 * $LicenseInfo:firstyear=2001&license=viewergpl$
6 * 7 *
7 * Copyright (c) 2003-2008, Linden Research, Inc. 8 * Copyright (c) 2001-2008, Linden Research, Inc.
8 * 9 *
9 * Second Life Viewer Source Code 10 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab 11 * The source code in this file ("Source Code") is provided by Linden Lab
@@ -29,27 +30,13 @@
29 * $/LicenseInfo$ 30 * $/LicenseInfo$
30 */ 31 */
31 32
32#ifndef LL_LLVERTEXPROGRAMGL_H 33#ifndef LL_LLANIMSTATELABELS_H
33#define LL_LLVERTEXPROGRAMGL_H 34#define LL_LLANIMSTATELABELS_H
34 35
35// This file contains the definition of LLVertexProgramGL, 36class LLAnimStateLabels
36// for purposes of running vertex programs on GL hardware.
37
38#include "llgl.h"
39
40class LLVertexProgramGL
41{ 37{
42public: 38public:
43 LLVertexProgramGL(); 39 static std::string getStateLabel( const char *animName );
44 ~LLVertexProgramGL();
45
46 void bind();
47 void unbind();
48
49 BOOL load(const char * filename);
50
51private:
52 LLGLuint mVertexProgramID;
53}; 40};
54 41
55#endif // LL_LLVERTEXPROGRAMGL_H 42#endif // LL_ANIMSTATELABELS_H