diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/lldrawpoolbump.cpp | 662 |
1 files changed, 225 insertions, 437 deletions
diff --git a/linden/indra/newview/lldrawpoolbump.cpp b/linden/indra/newview/lldrawpoolbump.cpp index befcc70..916454c 100644 --- a/linden/indra/newview/lldrawpoolbump.cpp +++ b/linden/indra/newview/lldrawpoolbump.cpp | |||
@@ -37,12 +37,10 @@ | |||
37 | #include "m4math.h" | 37 | #include "m4math.h" |
38 | 38 | ||
39 | #include "llagent.h" | 39 | #include "llagent.h" |
40 | #include "llagparray.h" | ||
41 | #include "llcubemap.h" | 40 | #include "llcubemap.h" |
42 | #include "lldrawable.h" | 41 | #include "lldrawable.h" |
43 | #include "lldrawpoolsimple.h" | 42 | #include "lldrawpoolsimple.h" |
44 | #include "llface.h" | 43 | #include "llface.h" |
45 | #include "llgl.h" | ||
46 | #include "llsky.h" | 44 | #include "llsky.h" |
47 | #include "lltextureentry.h" | 45 | #include "lltextureentry.h" |
48 | #include "llviewercamera.h" | 46 | #include "llviewercamera.h" |
@@ -64,9 +62,11 @@ LLBumpImageList gBumpImageList; | |||
64 | 62 | ||
65 | const S32 STD_BUMP_LATEST_FILE_VERSION = 1; | 63 | const S32 STD_BUMP_LATEST_FILE_VERSION = 1; |
66 | 64 | ||
67 | S32 LLDrawPoolBump::sBumpTex = -1; | 65 | const U32 VERTEX_MASK_SHINY = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; |
68 | S32 LLDrawPoolBump::sDiffTex = -1; | 66 | const U32 VERTEX_MASK_BUMP = LLVertexBuffer::MAP_VERTEX |LLVertexBuffer::MAP_TEXCOORD | LLVertexBuffer::MAP_TEXCOORD2; |
69 | S32 LLDrawPoolBump::sEnvTex = -1; | 67 | |
68 | U32 LLDrawPoolBump::sVertexMask = VERTEX_MASK_SHINY; | ||
69 | static LLCubeMap* sCubeMap = NULL; | ||
70 | 70 | ||
71 | // static | 71 | // static |
72 | void LLStandardBumpmap::init() | 72 | void LLStandardBumpmap::init() |
@@ -89,7 +89,7 @@ void LLStandardBumpmap::restoreGL() | |||
89 | gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Darkness"); // BE_DARKNESS | 89 | gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Darkness"); // BE_DARKNESS |
90 | 90 | ||
91 | std::string file_name = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "std_bump.ini" ); | 91 | std::string file_name = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "std_bump.ini" ); |
92 | FILE* file = LLFile::fopen( file_name.c_str(), "rt" ); | 92 | FILE* file = LLFile::fopen( file_name.c_str(), "rt" ); /*Flawfinder: ignore*/ |
93 | if( !file ) | 93 | if( !file ) |
94 | { | 94 | { |
95 | llwarns << "Could not open std_bump <" << file_name << ">" << llendl; | 95 | llwarns << "Could not open std_bump <" << file_name << ">" << llendl; |
@@ -114,9 +114,10 @@ void LLStandardBumpmap::restoreGL() | |||
114 | while( !feof(file) && (LLStandardBumpmap::sStandardBumpmapCount < (U32)TEM_BUMPMAP_COUNT) ) | 114 | while( !feof(file) && (LLStandardBumpmap::sStandardBumpmapCount < (U32)TEM_BUMPMAP_COUNT) ) |
115 | { | 115 | { |
116 | // *NOTE: This buffer size is hard coded into scanf() below. | 116 | // *NOTE: This buffer size is hard coded into scanf() below. |
117 | char label[2048] = ""; | 117 | char label[2048] = ""; /* Flawfinder: ignore */ |
118 | char bump_file[2048] = ""; | 118 | char bump_file[2048] = ""; /* Flawfinder: ignore */ |
119 | fields_read = fscanf( file, "\n%2047s %2047s", label, bump_file); | 119 | fields_read = fscanf( /* Flawfinder: ignore */ |
120 | file, "\n%2047s %2047s", label, bump_file); | ||
120 | if( EOF == fields_read ) | 121 | if( EOF == fields_read ) |
121 | { | 122 | { |
122 | break; | 123 | break; |
@@ -127,7 +128,7 @@ void LLStandardBumpmap::restoreGL() | |||
127 | return; | 128 | return; |
128 | } | 129 | } |
129 | 130 | ||
130 | llinfos << "Loading bumpmap: " << bump_file << " from viewerart" << llendl; | 131 | // llinfos << "Loading bumpmap: " << bump_file << " from viewerart" << llendl; |
131 | gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; | 132 | gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; |
132 | gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = gImageList.getImage( LLUUID(gViewerArt.getString(bump_file)) ); | 133 | gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = gImageList.getImage( LLUUID(gViewerArt.getString(bump_file)) ); |
133 | LLStandardBumpmap::sStandardBumpmapCount++; | 134 | LLStandardBumpmap::sStandardBumpmapCount++; |
@@ -151,15 +152,9 @@ void LLStandardBumpmap::destroyGL() | |||
151 | 152 | ||
152 | //////////////////////////////////////////////////////////////// | 153 | //////////////////////////////////////////////////////////////// |
153 | 154 | ||
154 | LLDrawPoolBump::LLDrawPoolBump(LLViewerImage *texturep) : | 155 | LLDrawPoolBump::LLDrawPoolBump() |
155 | LLDrawPool(POOL_BUMP, DATA_BUMP_IL_MASK | DATA_COLORS_MASK, DATA_SIMPLE_NIL_MASK), | 156 | : LLRenderPass(LLDrawPool::POOL_BUMP) |
156 | mTexturep(texturep) | ||
157 | { | ||
158 | } | ||
159 | |||
160 | LLDrawPool *LLDrawPoolBump::instancePool() | ||
161 | { | 157 | { |
162 | return new LLDrawPoolBump(mTexturep); | ||
163 | } | 158 | } |
164 | 159 | ||
165 | 160 | ||
@@ -168,51 +163,16 @@ void LLDrawPoolBump::prerender() | |||
168 | mVertexShaderLevel = gPipeline.getVertexShaderLevel(LLPipeline::SHADER_OBJECT); | 163 | mVertexShaderLevel = gPipeline.getVertexShaderLevel(LLPipeline::SHADER_OBJECT); |
169 | } | 164 | } |
170 | 165 | ||
171 | BOOL LLDrawPoolBump::match(LLFace* last_face, LLFace* facep) | ||
172 | { | ||
173 | if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_CHAIN_FACES) && | ||
174 | !last_face->isState(LLFace::LIGHT | LLFace::FULLBRIGHT) && | ||
175 | !facep->isState(LLFace::LIGHT | LLFace::FULLBRIGHT) && | ||
176 | facep->getIndicesStart() == last_face->getIndicesStart()+last_face->getIndicesCount() && | ||
177 | facep->getRenderColor() == last_face->getRenderColor() && | ||
178 | facep->getTextureEntry()->getShiny() == last_face->getTextureEntry()->getShiny() && | ||
179 | facep->getTextureEntry()->getBumpmap() == last_face->getTextureEntry()->getBumpmap()) | ||
180 | { | ||
181 | if (facep->isState(LLFace::GLOBAL)) | ||
182 | { | ||
183 | if (last_face->isState(LLFace::GLOBAL)) | ||
184 | { | ||
185 | return TRUE; | ||
186 | } | ||
187 | } | ||
188 | else | ||
189 | { | ||
190 | if (!last_face->isState(LLFace::GLOBAL)) | ||
191 | { | ||
192 | if (last_face->getRenderMatrix() == facep->getRenderMatrix()) | ||
193 | { | ||
194 | return TRUE; | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | |||
200 | return FALSE; | ||
201 | } | ||
202 | |||
203 | // static | 166 | // static |
204 | S32 LLDrawPoolBump::numBumpPasses() | 167 | S32 LLDrawPoolBump::numBumpPasses() |
205 | { | 168 | { |
206 | if (gPipeline.getVertexShaderLevel(LLPipeline::SHADER_OBJECT) > 0) | 169 | if (gSavedSettings.getBOOL("RenderObjectBump")) |
207 | { | 170 | { |
208 | return 1; // single pass for shaders | 171 | return 2; |
209 | } | 172 | } |
210 | else | 173 | else |
211 | { | 174 | { |
212 | if (gSavedSettings.getBOOL("RenderObjectBump")) | 175 | return 0; |
213 | return 3; | ||
214 | else | ||
215 | return 1; | ||
216 | } | 176 | } |
217 | } | 177 | } |
218 | 178 | ||
@@ -226,13 +186,10 @@ void LLDrawPoolBump::beginRenderPass(S32 pass) | |||
226 | switch( pass ) | 186 | switch( pass ) |
227 | { | 187 | { |
228 | case 0: | 188 | case 0: |
229 | beginPass0(this); | 189 | beginShiny(); |
230 | break; | 190 | break; |
231 | case 1: | 191 | case 1: |
232 | beginPass1(); | 192 | beginBump(); |
233 | break; | ||
234 | case 2: | ||
235 | beginPass2(); | ||
236 | break; | 193 | break; |
237 | default: | 194 | default: |
238 | llassert(0); | 195 | llassert(0); |
@@ -243,66 +200,17 @@ void LLDrawPoolBump::beginRenderPass(S32 pass) | |||
243 | void LLDrawPoolBump::render(S32 pass) | 200 | void LLDrawPoolBump::render(S32 pass) |
244 | { | 201 | { |
245 | LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP); | 202 | LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP); |
246 | if (!mTexturep) | ||
247 | { | ||
248 | return; | ||
249 | } | ||
250 | |||
251 | if (mDrawFace.empty()) | ||
252 | { | ||
253 | return; | ||
254 | } | ||
255 | |||
256 | const U32* index_array = getRawIndices(); | ||
257 | 203 | ||
258 | S32 indices = 0; | ||
259 | switch( pass ) | 204 | switch( pass ) |
260 | { | 205 | { |
261 | case 0: | 206 | case 0: |
262 | { | 207 | { |
263 | stop_glerror(); | 208 | renderShiny(); |
264 | |||
265 | bindGLVertexPointer(); | ||
266 | bindGLTexCoordPointer(); | ||
267 | bindGLNormalPointer(); | ||
268 | if (gPipeline.getLightingDetail() >= 2) | ||
269 | { | ||
270 | bindGLColorPointer(); | ||
271 | } | ||
272 | |||
273 | stop_glerror(); | ||
274 | |||
275 | LLGLState alpha_test(GL_ALPHA_TEST, FALSE); | ||
276 | LLGLState blend(GL_BLEND, FALSE); | ||
277 | LLViewerImage* tex = getTexture(); | ||
278 | if (tex && tex->getPrimaryFormat() == GL_ALPHA) | ||
279 | { | ||
280 | // Enable Invisibility Hack | ||
281 | alpha_test.enable(); | ||
282 | blend.enable(); | ||
283 | } | ||
284 | indices += renderPass0(this, mDrawFace, index_array, mTexturep); | ||
285 | break; | 209 | break; |
286 | } | 210 | } |
287 | case 1: | 211 | case 1: |
288 | { | 212 | { |
289 | bindGLVertexPointer(); | 213 | renderBump(); |
290 | bindGLNormalPointer(); | ||
291 | indices += renderPass1(mDrawFace, index_array, mTexturep); | ||
292 | break; | ||
293 | } | ||
294 | case 2: | ||
295 | { | ||
296 | bindGLVertexPointer(); | ||
297 | // Texture unit 0 | ||
298 | glActiveTextureARB(GL_TEXTURE0_ARB); | ||
299 | glClientActiveTextureARB(GL_TEXTURE0_ARB); | ||
300 | bindGLTexCoordPointer(); | ||
301 | // Texture unit 1 | ||
302 | glActiveTextureARB(GL_TEXTURE1_ARB); | ||
303 | glClientActiveTextureARB(GL_TEXTURE1_ARB); | ||
304 | bindGLTexCoordPointer(1); | ||
305 | indices += renderPass2(mDrawFace, index_array, mTexturep); | ||
306 | break; | 214 | break; |
307 | } | 215 | } |
308 | default: | 216 | default: |
@@ -311,7 +219,6 @@ void LLDrawPoolBump::render(S32 pass) | |||
311 | break; | 219 | break; |
312 | } | 220 | } |
313 | } | 221 | } |
314 | mIndicesDrawn += indices; | ||
315 | } | 222 | } |
316 | 223 | ||
317 | void LLDrawPoolBump::endRenderPass(S32 pass) | 224 | void LLDrawPoolBump::endRenderPass(S32 pass) |
@@ -319,13 +226,10 @@ void LLDrawPoolBump::endRenderPass(S32 pass) | |||
319 | switch( pass ) | 226 | switch( pass ) |
320 | { | 227 | { |
321 | case 0: | 228 | case 0: |
322 | endPass0(this); | 229 | endShiny(); |
323 | break; | 230 | break; |
324 | case 1: | 231 | case 1: |
325 | endPass1(); | 232 | endBump(); |
326 | break; | ||
327 | case 2: | ||
328 | endPass2(); | ||
329 | break; | 233 | break; |
330 | default: | 234 | default: |
331 | llassert(0); | 235 | llassert(0); |
@@ -334,252 +238,171 @@ void LLDrawPoolBump::endRenderPass(S32 pass) | |||
334 | } | 238 | } |
335 | 239 | ||
336 | //static | 240 | //static |
337 | void LLDrawPoolBump::beginPass0(LLDrawPool* pool) | 241 | void LLDrawPoolBump::beginShiny() |
338 | { | 242 | { |
339 | stop_glerror(); | 243 | sVertexMask = VERTEX_MASK_SHINY; |
340 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | 244 | // Second pass: environment map |
341 | glEnableClientState(GL_VERTEX_ARRAY); | 245 | glEnableClientState(GL_VERTEX_ARRAY); |
342 | glEnableClientState(GL_NORMAL_ARRAY); | 246 | glEnableClientState(GL_NORMAL_ARRAY); |
343 | if (gPipeline.getLightingDetail() >= 2) | 247 | glEnableClientState(GL_COLOR_ARRAY); |
344 | { | ||
345 | glEnableClientState(GL_COLOR_ARRAY); | ||
346 | } | ||
347 | 248 | ||
348 | if (pool->getVertexShaderLevel() > 0) | 249 | LLCubeMap* cube_map = gSky.mVOSkyp->getCubeMap(); |
250 | if( cube_map ) | ||
349 | { | 251 | { |
350 | enable_binormals(gPipeline.mObjectBumpProgram.mAttribute[LLPipeline::GLSL_BINORMAL]); | 252 | cube_map->enable(0); |
253 | cube_map->setMatrix(0); | ||
254 | cube_map->bind(); | ||
351 | 255 | ||
352 | sEnvTex = gPipeline.mObjectBumpProgram.enableTexture(LLPipeline::GLSL_ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); | 256 | if (gPipeline.getVertexShaderLevel(LLPipeline::SHADER_OBJECT) > 0) |
353 | LLCubeMap* cube_map = gSky.mVOSkyp->getCubeMap(); | ||
354 | if (sEnvTex >= 0 && cube_map) | ||
355 | { | 257 | { |
356 | cube_map->bind(); | 258 | LLMatrix4 mat; |
357 | cube_map->setMatrix(1); | 259 | glGetFloatv(GL_MODELVIEW_MATRIX, (F32*) mat.mMatrix); |
260 | gPipeline.mObjectShinyProgram.bind(); | ||
261 | LLVector3 vec = LLVector3(gPipeline.mShinyOrigin) * mat; | ||
262 | LLVector4 vec4(vec, gPipeline.mShinyOrigin.mV[3]); | ||
263 | glUniform4fvARB(gPipeline.mObjectShinyProgram.mUniform[LLPipeline::GLSL_SHINY_ORIGIN], 1, | ||
264 | vec4.mV); | ||
265 | } | ||
266 | else | ||
267 | { | ||
268 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); | ||
269 | |||
270 | //use RGB from texture | ||
271 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); | ||
272 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); | ||
273 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); | ||
274 | |||
275 | // use alpha from color | ||
276 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); | ||
277 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR); | ||
278 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); | ||
358 | } | 279 | } |
359 | |||
360 | sBumpTex = gPipeline.mObjectBumpProgram.enableTexture(LLPipeline::GLSL_BUMP_MAP); | ||
361 | sDiffTex = gPipeline.mObjectBumpProgram.enableTexture(LLPipeline::GLSL_DIFFUSE_MAP); | ||
362 | S32 scatterTex = gPipeline.mObjectBumpProgram.enableTexture(LLPipeline::GLSL_SCATTER_MAP); | ||
363 | LLViewerImage::bindTexture(gSky.mVOSkyp->getScatterMap(), scatterTex); | ||
364 | } | 280 | } |
365 | stop_glerror(); | ||
366 | } | 281 | } |
367 | 282 | ||
368 | //static | 283 | void LLDrawPoolBump::renderShiny() |
369 | S32 LLDrawPoolBump::renderPass0(LLDrawPool* pool, face_array_t& face_list, const U32* index_array, LLViewerImage* tex) | ||
370 | { | 284 | { |
371 | if (!tex) | 285 | LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); |
372 | { | ||
373 | return 0; | ||
374 | } | ||
375 | 286 | ||
376 | if (face_list.empty()) | 287 | sCubeMap = NULL; |
288 | |||
289 | if( gSky.mVOSkyp->getCubeMap() ) | ||
377 | { | 290 | { |
378 | return 0; | 291 | LLGLEnable blend_enable(GL_BLEND); |
292 | renderStatic(LLRenderPass::PASS_SHINY, sVertexMask); | ||
293 | renderActive(LLRenderPass::PASS_SHINY, sVertexMask); | ||
379 | } | 294 | } |
295 | } | ||
380 | 296 | ||
381 | stop_glerror(); | 297 | void LLDrawPoolBump::renderActive(U32 type, U32 mask, BOOL texture) |
298 | { | ||
299 | #if !LL_RELEASE_FOR_DOWNLOAD | ||
300 | LLGLState::checkClientArrays(mask); | ||
301 | #endif | ||
382 | 302 | ||
383 | S32 res = 0; | 303 | LLSpatialBridge* last_bridge = NULL; |
384 | if (pool->getVertexShaderLevel() > 0) | 304 | glPushMatrix(); |
305 | |||
306 | for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mActiveGroups.begin(); i != gPipeline.mActiveGroups.end(); ++i) | ||
385 | { | 307 | { |
386 | LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP); | 308 | LLSpatialGroup* group = *i; |
387 | pool->bindGLBinormalPointer(gPipeline.mObjectBumpProgram.mAttribute[LLPipeline::GLSL_BINORMAL]); | 309 | if (!group->isDead() && |
388 | 310 | gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && | |
389 | LLViewerImage::bindTexture(tex, sDiffTex); | 311 | group->mDrawMap.find(type) != group->mDrawMap.end()) |
390 | |||
391 | //single pass shader driven shiny/bump | ||
392 | LLGLDisable(GL_ALPHA_TEST); | ||
393 | |||
394 | LLViewerImage::sWhiteImagep->bind(sBumpTex); | ||
395 | |||
396 | GLfloat alpha[4] = | ||
397 | { | 312 | { |
398 | 0.00f, | 313 | LLSpatialBridge* bridge = (LLSpatialBridge*) group->mSpatialPartition; |
399 | 0.25f, | 314 | if (bridge != last_bridge) |
400 | 0.5f, | ||
401 | 0.75f | ||
402 | }; | ||
403 | |||
404 | LLImageGL* last_bump = NULL; | ||
405 | |||
406 | for (std::vector<LLFace*>::iterator iter = face_list.begin(); | ||
407 | iter != face_list.end(); iter++) | ||
408 | { | ||
409 | LLFace *facep = *iter; | ||
410 | if (facep->mSkipRender) | ||
411 | { | ||
412 | continue; | ||
413 | } | ||
414 | |||
415 | const LLTextureEntry* te = facep->getTextureEntry(); | ||
416 | if (te) | ||
417 | { | 315 | { |
418 | U8 index = te->getShiny(); | 316 | glPopMatrix(); |
419 | LLColor4 col = te->getColor(); | 317 | glPushMatrix(); |
420 | 318 | glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); | |
421 | gPipeline.mObjectBumpProgram.vertexAttrib4f(LLPipeline::GLSL_MATERIAL_COLOR, | 319 | last_bridge = bridge; |
422 | col.mV[0], col.mV[1], col.mV[2], alpha[index]); | 320 | |
423 | gPipeline.mObjectBumpProgram.vertexAttrib4f(LLPipeline::GLSL_SPECULAR_COLOR, | 321 | if (LLPipeline::sDynamicReflections) |
424 | alpha[index], alpha[index], alpha[index], alpha[index]); | ||
425 | |||
426 | LLImageGL* bump = getBumpMap(te, tex); | ||
427 | if (bump != last_bump) | ||
428 | { | 322 | { |
429 | if (bump) | 323 | LLSpatialPartition* part = gPipeline.getSpatialPartition(LLPipeline::PARTITION_VOLUME); |
324 | LLSpatialGroup::OctreeNode* node = part->mOctree->getNodeAt(LLVector3d(bridge->mDrawable->getPositionAgent()), 32.0); | ||
325 | if (node) | ||
430 | { | 326 | { |
431 | bump->bind(sBumpTex); | 327 | sCubeMap = ((LLSpatialGroup*) node->getListener(0))->mReflectionMap; |
432 | } | ||
433 | else | ||
434 | { | ||
435 | LLViewerImage::sWhiteImagep->bind(sBumpTex); | ||
436 | } | 328 | } |
437 | } | 329 | } |
438 | last_bump = bump; | ||
439 | |||
440 | // Draw the geometry | ||
441 | facep->enableLights(); | ||
442 | res += facep->renderIndexed(index_array); | ||
443 | stop_glerror(); | ||
444 | } | ||
445 | else | ||
446 | { | ||
447 | llwarns << "DrawPoolBump has face with invalid texture entry." << llendl; | ||
448 | } | 330 | } |
449 | } | ||
450 | } | ||
451 | else | ||
452 | { | ||
453 | LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); | ||
454 | LLViewerImage::bindTexture(tex); | ||
455 | res = LLDrawPool::drawLoop(face_list, index_array); | ||
456 | } | ||
457 | return res; | ||
458 | } | ||
459 | |||
460 | //static | ||
461 | void LLDrawPoolBump::endPass0(LLDrawPool* pool) | ||
462 | { | ||
463 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
464 | glDisableClientState(GL_NORMAL_ARRAY); | ||
465 | glDisableClientState(GL_COLOR_ARRAY); | ||
466 | 331 | ||
467 | if (pool->getVertexShaderLevel() > 0) | 332 | renderGroup(group,type,mask,texture); |
468 | { | ||
469 | gPipeline.mObjectBumpProgram.disableTexture(LLPipeline::GLSL_ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); | ||
470 | LLCubeMap* cube_map = gSky.mVOSkyp->getCubeMap(); | ||
471 | if (sEnvTex >= 0 && cube_map) | ||
472 | { | ||
473 | cube_map->restoreMatrix(); | ||
474 | } | 333 | } |
475 | |||
476 | gPipeline.mObjectBumpProgram.disableTexture(LLPipeline::GLSL_SCATTER_MAP); | ||
477 | gPipeline.mObjectBumpProgram.disableTexture(LLPipeline::GLSL_BUMP_MAP); | ||
478 | gPipeline.mObjectBumpProgram.disableTexture(LLPipeline::GLSL_DIFFUSE_MAP); | ||
479 | |||
480 | disable_binormals(gPipeline.mObjectBumpProgram.mAttribute[LLPipeline::GLSL_BINORMAL]); | ||
481 | |||
482 | glActiveTextureARB(GL_TEXTURE0_ARB); | ||
483 | glEnable(GL_TEXTURE_2D); | ||
484 | } | 334 | } |
335 | |||
336 | glPopMatrix(); | ||
485 | } | 337 | } |
486 | 338 | ||
487 | 339 | ||
488 | //static | ||
489 | void LLDrawPoolBump::beginPass1() | ||
490 | { | ||
491 | // Second pass: environment map | ||
492 | glEnableClientState(GL_VERTEX_ARRAY); | ||
493 | glEnableClientState(GL_NORMAL_ARRAY); | ||
494 | 340 | ||
495 | LLCubeMap* cube_map = gSky.mVOSkyp->getCubeMap(); | 341 | void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE) |
496 | if( cube_map ) | 342 | { |
497 | { | 343 | std::vector<LLDrawInfo*>& draw_info = group->mDrawMap[type]; |
498 | cube_map->enable(0); | 344 | |
499 | cube_map->setMatrix(0); | 345 | for (std::vector<LLDrawInfo*>::const_iterator k = draw_info.begin(); k != draw_info.end(); ++k) |
500 | cube_map->bind(); | ||
501 | } | ||
502 | } | ||
503 | |||
504 | //static | ||
505 | S32 LLDrawPoolBump::renderPass1(face_array_t& face_list, const U32* index_array, LLViewerImage* tex) | ||
506 | { | ||
507 | LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); | ||
508 | if (gPipeline.getVertexShaderLevel(LLPipeline::SHADER_OBJECT) > 0) //everything happens in pass0 | ||
509 | { | ||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | S32 res = 0; | ||
514 | if( gSky.mVOSkyp->getCubeMap() ) | ||
515 | { | 346 | { |
516 | //LLGLSPipelineAlpha gls; | 347 | LLDrawInfo& params = **k; |
517 | //LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_EQUAL); | 348 | if (LLPipeline::sDynamicReflections) |
518 | LLGLEnable blend_enable(GL_BLEND); | ||
519 | |||
520 | GLfloat alpha[4] = | ||
521 | { | 349 | { |
522 | 0.00f, | 350 | if (params.mReflectionMap.notNull()) |
523 | 0.25f, | ||
524 | 0.5f, | ||
525 | 0.75f | ||
526 | }; | ||
527 | |||
528 | for (std::vector<LLFace*>::iterator iter = face_list.begin(); | ||
529 | iter != face_list.end(); iter++) | ||
530 | { | ||
531 | LLFace *facep = *iter; | ||
532 | if (facep->mSkipRender) | ||
533 | { | 351 | { |
534 | continue; | 352 | params.mReflectionMap->bind(); |
535 | } | 353 | } |
536 | 354 | else | |
537 | const LLTextureEntry* te = facep->getTextureEntry(); | ||
538 | if (te) | ||
539 | { | 355 | { |
540 | U8 index = te->getShiny(); | 356 | if (sCubeMap) |
541 | if( index > 0 ) | ||
542 | { | 357 | { |
543 | LLOverrideFaceColor override_color(facep->getPool(), 1, 1, 1, alpha[index]); | 358 | sCubeMap->bind(); |
544 | 359 | } | |
545 | // Draw the geometry | 360 | else |
546 | facep->enableLights(); | 361 | { |
547 | res += facep->renderIndexed(index_array); | 362 | gSky.mVOSkyp->getCubeMap()->bind(); |
548 | stop_glerror(); | ||
549 | } | 363 | } |
550 | } | ||
551 | else | ||
552 | { | ||
553 | llwarns << "DrawPoolBump has face with invalid texture entry." << llendl; | ||
554 | } | 364 | } |
555 | } | 365 | } |
366 | |||
367 | params.mVertexBuffer->setBuffer(mask); | ||
368 | U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer(); | ||
369 | glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount, | ||
370 | GL_UNSIGNED_INT, indices_pointer+params.mOffset); | ||
371 | gPipeline.mTrianglesDrawn += params.mCount/3; | ||
556 | } | 372 | } |
557 | return res; | ||
558 | } | 373 | } |
559 | 374 | ||
560 | //static | 375 | void LLDrawPoolBump::endShiny() |
561 | void LLDrawPoolBump::endPass1() | ||
562 | { | 376 | { |
563 | LLCubeMap* cube_map = gSky.mVOSkyp->getCubeMap(); | 377 | LLCubeMap* cube_map = gSky.mVOSkyp->getCubeMap(); |
564 | if( cube_map ) | 378 | if( cube_map ) |
565 | { | 379 | { |
566 | cube_map->disable(); | 380 | cube_map->disable(); |
567 | cube_map->restoreMatrix(); | 381 | cube_map->restoreMatrix(); |
382 | |||
383 | if (gPipeline.getVertexShaderLevel(LLPipeline::SHADER_OBJECT) > 0) | ||
384 | { | ||
385 | gPipeline.mObjectShinyProgram.unbind(); | ||
386 | } | ||
387 | |||
568 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | 388 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
569 | } | 389 | } |
570 | 390 | ||
571 | LLImageGL::unbindTexture(0, GL_TEXTURE_2D); | 391 | LLImageGL::unbindTexture(0, GL_TEXTURE_2D); |
572 | 392 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | |
573 | glDisableClientState(GL_NORMAL_ARRAY); | 393 | glDisableClientState(GL_NORMAL_ARRAY); |
394 | glDisableClientState(GL_COLOR_ARRAY); | ||
574 | } | 395 | } |
575 | 396 | ||
576 | 397 | ||
577 | // static | 398 | // static |
578 | LLImageGL* LLDrawPoolBump::getBumpMap(const LLTextureEntry* te, LLViewerImage* tex) | 399 | BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params) |
579 | { | 400 | { |
580 | U32 bump_code = te->getBumpmap(); | ||
581 | LLImageGL* bump = NULL; | 401 | LLImageGL* bump = NULL; |
582 | 402 | ||
403 | U8 bump_code = params.mBump; | ||
404 | LLViewerImage* tex = params.mTexture; | ||
405 | |||
583 | switch( bump_code ) | 406 | switch( bump_code ) |
584 | { | 407 | { |
585 | case BE_NO_BUMP: | 408 | case BE_NO_BUMP: |
@@ -597,28 +420,33 @@ LLImageGL* LLDrawPoolBump::getBumpMap(const LLTextureEntry* te, LLViewerImage* t | |||
597 | if( bump_code < LLStandardBumpmap::sStandardBumpmapCount ) | 420 | if( bump_code < LLStandardBumpmap::sStandardBumpmapCount ) |
598 | { | 421 | { |
599 | bump = gStandardBumpmapList[bump_code].mImage; | 422 | bump = gStandardBumpmapList[bump_code].mImage; |
423 | gBumpImageList.addTextureStats(bump_code, tex->getID(), params.mVSize, 1, 1); | ||
600 | } | 424 | } |
601 | break; | 425 | break; |
602 | } | 426 | } |
603 | 427 | ||
604 | return bump; | 428 | if (bump) |
429 | { | ||
430 | bump->bind(1); | ||
431 | bump->bind(0); | ||
432 | return TRUE; | ||
433 | } | ||
434 | return FALSE; | ||
605 | } | 435 | } |
606 | 436 | ||
607 | //static | 437 | //static |
608 | void LLDrawPoolBump::beginPass2() | 438 | void LLDrawPoolBump::beginBump() |
609 | { | 439 | { |
440 | sVertexMask = VERTEX_MASK_BUMP; | ||
610 | LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP); | 441 | LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP); |
611 | // Optional third pass: emboss bump map | 442 | // Optional second pass: emboss bump map |
612 | stop_glerror(); | 443 | stop_glerror(); |
613 | 444 | ||
614 | // TEXTURE UNIT 0 | 445 | // TEXTURE UNIT 0 |
615 | // Output.rgb = texture at texture coord 0 | 446 | // Output.rgb = texture at texture coord 0 |
616 | glActiveTextureARB(GL_TEXTURE0_ARB); | 447 | glActiveTextureARB(GL_TEXTURE0_ARB); |
617 | glClientActiveTextureARB(GL_TEXTURE0_ARB); | 448 | glClientActiveTextureARB(GL_TEXTURE0_ARB); |
618 | |||
619 | glEnableClientState(GL_VERTEX_ARRAY); | ||
620 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | 449 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
621 | glDisableClientState(GL_NORMAL_ARRAY); | ||
622 | 450 | ||
623 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); | 451 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); |
624 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); | 452 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); |
@@ -631,14 +459,10 @@ void LLDrawPoolBump::beginPass2() | |||
631 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); | 459 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); |
632 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); | 460 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); |
633 | 461 | ||
634 | |||
635 | // TEXTURE UNIT 1 | 462 | // TEXTURE UNIT 1 |
636 | glActiveTextureARB(GL_TEXTURE1_ARB); | 463 | glActiveTextureARB(GL_TEXTURE1_ARB); |
637 | glClientActiveTextureARB(GL_TEXTURE1_ARB); | 464 | glClientActiveTextureARB(GL_TEXTURE1_ARB); |
638 | |||
639 | glEnableClientState(GL_VERTEX_ARRAY); | ||
640 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | 465 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
641 | glDisableClientState(GL_NORMAL_ARRAY); | ||
642 | 466 | ||
643 | glEnable(GL_TEXTURE_2D); // Texture unit 1 | 467 | glEnable(GL_TEXTURE_2D); // Texture unit 1 |
644 | 468 | ||
@@ -668,68 +492,25 @@ void LLDrawPoolBump::beginPass2() | |||
668 | // = dst.rgb + dst.rgb * (bump0 - bump1) | 492 | // = dst.rgb + dst.rgb * (bump0 - bump1) |
669 | glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); | 493 | glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); |
670 | // glBlendFunc(GL_ONE, GL_ZERO); // temp | 494 | // glBlendFunc(GL_ONE, GL_ZERO); // temp |
671 | 495 | glActiveTextureARB(GL_TEXTURE0_ARB); | |
672 | stop_glerror(); | 496 | stop_glerror(); |
673 | } | 497 | } |
674 | 498 | ||
675 | //static | 499 | //static |
676 | S32 LLDrawPoolBump::renderPass2(face_array_t& face_list, const U32* index_array, LLViewerImage* tex) | 500 | void LLDrawPoolBump::renderBump() |
677 | { | 501 | { |
678 | if (gPipeline.getVertexShaderLevel(LLPipeline::SHADER_OBJECT) > 0) //everything happens in pass0 | 502 | LLFastTimer ftm(LLFastTimer::FTM_RENDER_BUMP); |
679 | { | ||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | LLGLDisable fog(GL_FOG); | 503 | LLGLDisable fog(GL_FOG); |
684 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_EQUAL); | 504 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_EQUAL); |
685 | LLGLEnable tex2d(GL_TEXTURE_2D); | 505 | LLGLEnable tex2d(GL_TEXTURE_2D); |
686 | LLGLEnable blend(GL_BLEND); | 506 | LLGLEnable blend(GL_BLEND); |
687 | S32 res = 0; | 507 | glColor4f(1,1,1,1); |
688 | 508 | renderBump(LLRenderPass::PASS_BUMP, sVertexMask); | |
689 | LLImageGL* last_bump = NULL; | 509 | renderBumpActive(LLRenderPass::PASS_BUMP, sVertexMask); |
690 | |||
691 | for (std::vector<LLFace*>::iterator iter = face_list.begin(); | ||
692 | iter != face_list.end(); iter++) | ||
693 | { | ||
694 | LLFace *facep = *iter; | ||
695 | if (facep->mSkipRender) | ||
696 | { | ||
697 | continue; | ||
698 | } | ||
699 | LLOverrideFaceColor override_color(facep->getPool(), 1,1,1,1); | ||
700 | |||
701 | const LLTextureEntry* te = facep->getTextureEntry(); | ||
702 | LLImageGL* bump = getBumpMap(te, tex); | ||
703 | |||
704 | if( bump ) | ||
705 | { | ||
706 | if( bump != last_bump ) | ||
707 | { | ||
708 | last_bump = bump; | ||
709 | |||
710 | // Texture unit 0 | ||
711 | bump->bind(0); | ||
712 | stop_glerror(); | ||
713 | |||
714 | // Texture unit 1 | ||
715 | bump->bind(1); | ||
716 | stop_glerror(); | ||
717 | } | ||
718 | |||
719 | // Draw the geometry | ||
720 | res += facep->renderIndexed(index_array); | ||
721 | stop_glerror(); | ||
722 | } | ||
723 | else | ||
724 | { | ||
725 | // llwarns << "Skipping invalid bump code " << (S32) te->getBumpmap() << llendl; | ||
726 | } | ||
727 | } | ||
728 | return res; | ||
729 | } | 510 | } |
730 | 511 | ||
731 | //static | 512 | //static |
732 | void LLDrawPoolBump::endPass2() | 513 | void LLDrawPoolBump::endBump() |
733 | { | 514 | { |
734 | // Disable texture unit 1 | 515 | // Disable texture unit 1 |
735 | glActiveTextureARB(GL_TEXTURE1_ARB); | 516 | glActiveTextureARB(GL_TEXTURE1_ARB); |
@@ -747,67 +528,6 @@ void LLDrawPoolBump::endPass2() | |||
747 | glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); | 528 | glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); |
748 | } | 529 | } |
749 | 530 | ||
750 | |||
751 | void LLDrawPoolBump::renderForSelect() | ||
752 | { | ||
753 | if (mDrawFace.empty() || !mMemory.count()) | ||
754 | { | ||
755 | return; | ||
756 | } | ||
757 | |||
758 | glEnableClientState ( GL_VERTEX_ARRAY ); | ||
759 | |||
760 | bindGLVertexPointer(); | ||
761 | |||
762 | for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); | ||
763 | iter != mDrawFace.end(); iter++) | ||
764 | { | ||
765 | LLFace *facep = *iter; | ||
766 | if (facep->getDrawable() && !facep->getDrawable()->isDead() && (facep->getViewerObject()->mGLName)) | ||
767 | { | ||
768 | facep->renderForSelect(); | ||
769 | } | ||
770 | } | ||
771 | } | ||
772 | |||
773 | |||
774 | void LLDrawPoolBump::renderFaceSelected(LLFace *facep, | ||
775 | LLImageGL *image, | ||
776 | const LLColor4 &color, | ||
777 | const S32 index_offset, const S32 index_count) | ||
778 | { | ||
779 | facep->renderSelected(image, color, index_offset, index_count); | ||
780 | } | ||
781 | |||
782 | |||
783 | void LLDrawPoolBump::dirtyTexture(const LLViewerImage *texturep) | ||
784 | { | ||
785 | if (mTexturep == texturep) | ||
786 | { | ||
787 | for (std::vector<LLFace*>::iterator iter = mReferences.begin(); | ||
788 | iter != mReferences.end(); iter++) | ||
789 | { | ||
790 | LLFace *facep = *iter; | ||
791 | gPipeline.markTextured(facep->getDrawable()); | ||
792 | } | ||
793 | } | ||
794 | } | ||
795 | |||
796 | LLViewerImage *LLDrawPoolBump::getTexture() | ||
797 | { | ||
798 | return mTexturep; | ||
799 | } | ||
800 | |||
801 | LLViewerImage *LLDrawPoolBump::getDebugTexture() | ||
802 | { | ||
803 | return mTexturep; | ||
804 | } | ||
805 | |||
806 | LLColor3 LLDrawPoolBump::getDebugColor() const | ||
807 | { | ||
808 | return LLColor3(1.f, 1.f, 0.f); | ||
809 | } | ||
810 | |||
811 | //////////////////////////////////////////////////////////////// | 531 | //////////////////////////////////////////////////////////////// |
812 | // List of one-component bump-maps created from other texures. | 532 | // List of one-component bump-maps created from other texures. |
813 | 533 | ||
@@ -1131,25 +851,93 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerImage *src_vi, LLIma | |||
1131 | } | 851 | } |
1132 | } | 852 | } |
1133 | 853 | ||
1134 | S32 LLDrawPoolBump::getMaterialAttribIndex() | 854 | void LLDrawPoolBump::renderBumpActive(U32 type, U32 mask) |
1135 | { | 855 | { |
1136 | return gPipeline.mObjectBumpProgram.mAttribute[LLPipeline::GLSL_MATERIAL_COLOR]; | 856 | #if !LL_RELEASE_FOR_DOWNLOAD |
857 | LLGLState::checkClientArrays(mask); | ||
858 | #endif | ||
859 | |||
860 | LLSpatialBridge* last_bridge = NULL; | ||
861 | glPushMatrix(); | ||
862 | |||
863 | for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mActiveGroups.begin(); i != gPipeline.mActiveGroups.end(); ++i) | ||
864 | { | ||
865 | LLSpatialGroup* group = *i; | ||
866 | if (!group->isDead() && | ||
867 | group->mSpatialPartition->mRenderByGroup && | ||
868 | group->mDrawMap.find(type) != group->mDrawMap.end()) | ||
869 | { | ||
870 | LLSpatialBridge* bridge = (LLSpatialBridge*) group->mSpatialPartition; | ||
871 | if (bridge != last_bridge) | ||
872 | { | ||
873 | glPopMatrix(); | ||
874 | glPushMatrix(); | ||
875 | glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); | ||
876 | last_bridge = bridge; | ||
877 | } | ||
878 | |||
879 | renderGroupBump(group,type,mask); | ||
880 | } | ||
881 | } | ||
882 | |||
883 | glPopMatrix(); | ||
1137 | } | 884 | } |
1138 | 885 | ||
1139 | // virtual | 886 | void LLDrawPoolBump::renderBump(U32 type, U32 mask) |
1140 | void LLDrawPoolBump::enableShade() | 887 | { |
1141 | { | 888 | #if !LL_RELEASE_FOR_DOWNLOAD |
1142 | glDisableClientState(GL_COLOR_ARRAY); | 889 | LLGLState::checkClientArrays(mask); |
890 | #endif | ||
891 | |||
892 | std::vector<LLDrawInfo*>& draw_info = gPipeline.mRenderMap[type]; | ||
893 | |||
894 | for (std::vector<LLDrawInfo*>::iterator i = draw_info.begin(); i != draw_info.end(); ++i) | ||
895 | { | ||
896 | LLDrawInfo& params = **i; | ||
897 | |||
898 | if (LLDrawPoolBump::bindBumpMap(params)) | ||
899 | { | ||
900 | pushBatch(params, mask, FALSE); | ||
901 | } | ||
902 | } | ||
1143 | } | 903 | } |
1144 | 904 | ||
1145 | // virtual | 905 | void LLDrawPoolBump::renderGroupBump(LLSpatialGroup* group, U32 type, U32 mask) |
1146 | void LLDrawPoolBump::disableShade() | 906 | { |
1147 | { | 907 | const std::vector<LLDrawInfo*>& draw_info = group->mDrawMap[type]; |
1148 | glEnableClientState(GL_COLOR_ARRAY); | 908 | |
909 | for (std::vector<LLDrawInfo*>::const_iterator k = draw_info.begin(); k != draw_info.end(); ++k) | ||
910 | { | ||
911 | LLDrawInfo& params = **k; | ||
912 | |||
913 | if (LLDrawPoolBump::bindBumpMap(params)) | ||
914 | { | ||
915 | pushBatch(params, mask, FALSE); | ||
916 | } | ||
917 | } | ||
1149 | } | 918 | } |
1150 | 919 | ||
1151 | // virtual | 920 | void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) |
1152 | void LLDrawPoolBump::setShade(F32 shade) | ||
1153 | { | 921 | { |
1154 | glColor4f(0,0,0,shade); | 922 | if (params.mTextureMatrix) |
923 | { | ||
924 | glActiveTextureARB(GL_TEXTURE1_ARB); | ||
925 | glMatrixMode(GL_TEXTURE); | ||
926 | glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); | ||
927 | glActiveTextureARB(GL_TEXTURE0_ARB); | ||
928 | glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); | ||
929 | } | ||
930 | params.mVertexBuffer->setBuffer(mask); | ||
931 | U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer(); | ||
932 | glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount, | ||
933 | GL_UNSIGNED_INT, indices_pointer+params.mOffset); | ||
934 | gPipeline.mTrianglesDrawn += params.mCount/3; | ||
935 | if (params.mTextureMatrix) | ||
936 | { | ||
937 | glActiveTextureARB(GL_TEXTURE1_ARB); | ||
938 | glLoadIdentity(); | ||
939 | glActiveTextureARB(GL_TEXTURE0_ARB); | ||
940 | glLoadIdentity(); | ||
941 | glMatrixMode(GL_MODELVIEW); | ||
942 | } | ||
1155 | } | 943 | } |