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