diff options
author | Jacek Antonelli | 2008-08-15 23:44:54 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:54 -0500 |
commit | b2afb8800bb033a04bb3ecdf0363068d56648ef1 (patch) | |
tree | 3568129b5bbddb47cd39d622b4137a8fbff4abaf /linden/indra/newview/pipeline.cpp | |
parent | Second Life viewer sources 1.14.0.1 (diff) | |
download | meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.zip meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.gz meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.bz2 meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.xz |
Second Life viewer sources 1.15.0.2
Diffstat (limited to 'linden/indra/newview/pipeline.cpp')
-rw-r--r-- | linden/indra/newview/pipeline.cpp | 1558 |
1 files changed, 364 insertions, 1194 deletions
diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index 1a5b4f1..5d4618e 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp | |||
@@ -4,6 +4,7 @@ | |||
4 | * | 4 | * |
5 | * Copyright (c) 2005-2007, Linden Research, Inc. | 5 | * Copyright (c) 2005-2007, Linden Research, Inc. |
6 | * | 6 | * |
7 | * Second Life Viewer Source Code | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | 8 | * The source code in this file ("Source Code") is provided by Linden Lab |
8 | * to you under the terms of the GNU General Public License, version 2.0 | 9 | * to you under the terms of the GNU General Public License, version 2.0 |
9 | * ("GPL"), unless you have obtained a separate licensing agreement | 10 | * ("GPL"), unless you have obtained a separate licensing agreement |
@@ -44,7 +45,7 @@ | |||
44 | #include "material_codes.h" | 45 | #include "material_codes.h" |
45 | #include "timing.h" | 46 | #include "timing.h" |
46 | #include "v3color.h" | 47 | #include "v3color.h" |
47 | #include "llui.h" | 48 | #include "llui.h" |
48 | #include "llglheaders.h" | 49 | #include "llglheaders.h" |
49 | 50 | ||
50 | // newview includes | 51 | // newview includes |
@@ -89,6 +90,9 @@ | |||
89 | #include "llworld.h" | 90 | #include "llworld.h" |
90 | #include "viewer.h" | 91 | #include "viewer.h" |
91 | #include "llcubemap.h" | 92 | #include "llcubemap.h" |
93 | #include "lldebugmessagebox.h" | ||
94 | #include "llglslshader.h" | ||
95 | #include "llviewerjoystick.h" | ||
92 | 96 | ||
93 | #ifdef _DEBUG | 97 | #ifdef _DEBUG |
94 | // Debug indices is disabled for now for debug performance - djs 4/24/02 | 98 | // Debug indices is disabled for now for debug performance - djs 4/24/02 |
@@ -128,77 +132,6 @@ S32 gTrivialAccepts = 0; | |||
128 | 132 | ||
129 | BOOL gRenderForSelect = FALSE; | 133 | BOOL gRenderForSelect = FALSE; |
130 | 134 | ||
131 | //glsl parameter tables | ||
132 | const char* LLPipeline::sReservedAttribs[] = | ||
133 | { | ||
134 | "materialColor", | ||
135 | "specularColor", | ||
136 | "binormal" | ||
137 | }; | ||
138 | |||
139 | U32 LLPipeline::sReservedAttribCount = LLPipeline::GLSL_END_RESERVED_ATTRIBS; | ||
140 | |||
141 | const char* LLPipeline::sAvatarAttribs[] = | ||
142 | { | ||
143 | "weight", | ||
144 | "clothing", | ||
145 | "gWindDir", | ||
146 | "gSinWaveParams", | ||
147 | "gGravity" | ||
148 | }; | ||
149 | |||
150 | U32 LLPipeline::sAvatarAttribCount = sizeof(LLPipeline::sAvatarAttribs)/sizeof(char*); | ||
151 | |||
152 | const char* LLPipeline::sAvatarUniforms[] = | ||
153 | { | ||
154 | "matrixPalette" | ||
155 | }; | ||
156 | |||
157 | U32 LLPipeline::sAvatarUniformCount = 1; | ||
158 | |||
159 | const char* LLPipeline::sReservedUniforms[] = | ||
160 | { | ||
161 | "diffuseMap", | ||
162 | "specularMap", | ||
163 | "bumpMap", | ||
164 | "environmentMap", | ||
165 | "scatterMap" | ||
166 | }; | ||
167 | |||
168 | U32 LLPipeline::sReservedUniformCount = LLPipeline::GLSL_END_RESERVED_UNIFORMS; | ||
169 | |||
170 | const char* LLPipeline::sTerrainUniforms[] = | ||
171 | { | ||
172 | "detail0", | ||
173 | "detail1", | ||
174 | "alphaRamp" | ||
175 | }; | ||
176 | |||
177 | U32 LLPipeline::sTerrainUniformCount = sizeof(LLPipeline::sTerrainUniforms)/sizeof(char*); | ||
178 | |||
179 | const char* LLPipeline::sShinyUniforms[] = | ||
180 | { | ||
181 | "origin" | ||
182 | }; | ||
183 | |||
184 | U32 LLPipeline::sShinyUniformCount = sizeof(LLPipeline::sShinyUniforms)/sizeof(char*); | ||
185 | |||
186 | const char* LLPipeline::sWaterUniforms[] = | ||
187 | { | ||
188 | "screenTex", | ||
189 | "eyeVec", | ||
190 | "time", | ||
191 | "d1", | ||
192 | "d2", | ||
193 | "lightDir", | ||
194 | "specular", | ||
195 | "lightExp", | ||
196 | "fbScale", | ||
197 | "refScale" | ||
198 | }; | ||
199 | |||
200 | U32 LLPipeline::sWaterUniformCount = sizeof(LLPipeline::sWaterUniforms)/sizeof(char*); | ||
201 | |||
202 | //---------------------------------------- | 135 | //---------------------------------------- |
203 | 136 | ||
204 | void stamp(F32 x, F32 y, F32 xs, F32 ys) | 137 | void stamp(F32 x, F32 y, F32 xs, F32 ys) |
@@ -215,6 +148,14 @@ void stamp(F32 x, F32 y, F32 xs, F32 ys) | |||
215 | glEnd(); | 148 | glEnd(); |
216 | } | 149 | } |
217 | 150 | ||
151 | U32 nhpo2(U32 v) | ||
152 | { | ||
153 | U32 r = 1; | ||
154 | while (r < v) { | ||
155 | r *= 2; | ||
156 | } | ||
157 | return r; | ||
158 | } | ||
218 | 159 | ||
219 | 160 | ||
220 | //---------------------------------------- | 161 | //---------------------------------------- |
@@ -229,10 +170,13 @@ BOOL LLPipeline::sRenderSoundBeacons = FALSE; | |||
229 | BOOL LLPipeline::sUseOcclusion = FALSE; | 170 | BOOL LLPipeline::sUseOcclusion = FALSE; |
230 | BOOL LLPipeline::sSkipUpdate = FALSE; | 171 | BOOL LLPipeline::sSkipUpdate = FALSE; |
231 | BOOL LLPipeline::sDynamicReflections = FALSE; | 172 | BOOL LLPipeline::sDynamicReflections = FALSE; |
173 | BOOL LLPipeline::sRenderGlow = FALSE; | ||
232 | 174 | ||
233 | LLPipeline::LLPipeline() : | 175 | LLPipeline::LLPipeline() : |
176 | mScreenTex(0), | ||
234 | mCubeBuffer(NULL), | 177 | mCubeBuffer(NULL), |
235 | mCubeList(0), | 178 | mGlowMap(0), |
179 | mGlowBuffer(0), | ||
236 | mVertexShadersEnabled(FALSE), | 180 | mVertexShadersEnabled(FALSE), |
237 | mVertexShadersLoaded(0), | 181 | mVertexShadersLoaded(0), |
238 | mLastRebuildPool(NULL), | 182 | mLastRebuildPool(NULL), |
@@ -244,16 +188,21 @@ LLPipeline::LLPipeline() : | |||
244 | mWaterPool(NULL), | 188 | mWaterPool(NULL), |
245 | mGroundPool(NULL), | 189 | mGroundPool(NULL), |
246 | mSimplePool(NULL), | 190 | mSimplePool(NULL), |
191 | mGlowPool(NULL), | ||
247 | mBumpPool(NULL), | 192 | mBumpPool(NULL), |
248 | mLightMask(0), | 193 | mLightMask(0), |
249 | mLightMovingMask(0) | 194 | mLightMovingMask(0) |
250 | { | 195 | { |
251 | 196 | mFramebuffer[0] = mFramebuffer[1] = 0; | |
197 | mCubeFrameBuffer = 0; | ||
198 | mCubeDepth = 0; | ||
252 | } | 199 | } |
253 | 200 | ||
254 | void LLPipeline::init() | 201 | void LLPipeline::init() |
255 | { | 202 | { |
256 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 203 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
204 | |||
205 | mInitialized = TRUE; | ||
257 | 206 | ||
258 | stop_glerror(); | 207 | stop_glerror(); |
259 | 208 | ||
@@ -275,6 +224,7 @@ void LLPipeline::init() | |||
275 | getPool(LLDrawPool::POOL_ALPHA_POST_WATER); | 224 | getPool(LLDrawPool::POOL_ALPHA_POST_WATER); |
276 | getPool(LLDrawPool::POOL_SIMPLE); | 225 | getPool(LLDrawPool::POOL_SIMPLE); |
277 | getPool(LLDrawPool::POOL_BUMP); | 226 | getPool(LLDrawPool::POOL_BUMP); |
227 | getPool(LLDrawPool::POOL_GLOW); | ||
278 | 228 | ||
279 | mTrianglesDrawnStat.reset(); | 229 | mTrianglesDrawnStat.reset(); |
280 | resetFrameStats(); | 230 | resetFrameStats(); |
@@ -293,14 +243,7 @@ void LLPipeline::init() | |||
293 | // Enable features | 243 | // Enable features |
294 | stop_glerror(); | 244 | stop_glerror(); |
295 | 245 | ||
296 | setShaders(); | 246 | LLShaderMgr::setShaders(); |
297 | } | ||
298 | |||
299 | void LLPipeline::LLScatterShader::init(GLhandleARB shader, int map_stage) | ||
300 | { | ||
301 | glUseProgramObjectARB(shader); | ||
302 | glUniform1iARB(glGetUniformLocationARB(shader, "scatterMap"), map_stage); | ||
303 | glUseProgramObjectARB(0); | ||
304 | } | 247 | } |
305 | 248 | ||
306 | LLPipeline::~LLPipeline() | 249 | LLPipeline::~LLPipeline() |
@@ -358,20 +301,12 @@ void LLPipeline::cleanup() | |||
358 | mGroundPool = NULL; | 301 | mGroundPool = NULL; |
359 | delete mSimplePool; | 302 | delete mSimplePool; |
360 | mSimplePool = NULL; | 303 | mSimplePool = NULL; |
304 | delete mGlowPool; | ||
305 | mGlowPool = NULL; | ||
361 | delete mBumpPool; | 306 | delete mBumpPool; |
362 | mBumpPool = NULL; | 307 | mBumpPool = NULL; |
363 | 308 | ||
364 | if (mCubeBuffer) | 309 | releaseGLBuffers(); |
365 | { | ||
366 | delete mCubeBuffer; | ||
367 | mCubeBuffer = NULL; | ||
368 | } | ||
369 | |||
370 | if (mCubeList) | ||
371 | { | ||
372 | glDeleteLists(mCubeList, 1); | ||
373 | mCubeList = 0; | ||
374 | } | ||
375 | 310 | ||
376 | mBloomImagep = NULL; | 311 | mBloomImagep = NULL; |
377 | mBloomImage2p = NULL; | 312 | mBloomImage2p = NULL; |
@@ -412,376 +347,68 @@ void LLPipeline::destroyGL() | |||
412 | clearRenderMap(); | 347 | clearRenderMap(); |
413 | resetVertexBuffers(); | 348 | resetVertexBuffers(); |
414 | 349 | ||
415 | if (mCubeBuffer) | 350 | releaseGLBuffers(); |
416 | { | ||
417 | delete mCubeBuffer; | ||
418 | mCubeBuffer = NULL; | ||
419 | } | ||
420 | |||
421 | if (mCubeList) | ||
422 | { | ||
423 | glDeleteLists(mCubeList, 1); | ||
424 | mCubeList = 0; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | void LLPipeline::restoreGL() | ||
429 | { | ||
430 | resetVertexBuffers(); | ||
431 | |||
432 | if (mVertexShadersEnabled) | ||
433 | { | ||
434 | setShaders(); | ||
435 | } | ||
436 | |||
437 | for (U32 i = 0; i < mObjectPartition.size()-1; i++) | ||
438 | { | ||
439 | if (mObjectPartition[i]) | ||
440 | { | ||
441 | mObjectPartition[i]->restoreGL(); | ||
442 | } | ||
443 | } | ||
444 | } | ||
445 | |||
446 | //============================================================================ | ||
447 | // Load Shader | ||
448 | |||
449 | static LLString get_object_log(GLhandleARB ret) | ||
450 | { | ||
451 | LLString res; | ||
452 | |||
453 | //get log length | ||
454 | GLint length; | ||
455 | glGetObjectParameterivARB(ret, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); | ||
456 | if (length > 0) | ||
457 | { | ||
458 | //the log could be any size, so allocate appropriately | ||
459 | GLcharARB* log = new GLcharARB[length]; | ||
460 | glGetInfoLogARB(ret, length, &length, log); | ||
461 | res = LLString(log); | ||
462 | delete[] log; | ||
463 | } | ||
464 | return res; | ||
465 | } | ||
466 | |||
467 | void LLPipeline::dumpObjectLog(GLhandleARB ret, BOOL warns) | ||
468 | { | ||
469 | LLString log = get_object_log(ret); | ||
470 | if (warns) | ||
471 | { | ||
472 | llwarns << log << llendl; | ||
473 | } | ||
474 | else | ||
475 | { | ||
476 | llinfos << log << llendl; | ||
477 | } | ||
478 | } | 351 | } |
479 | 352 | ||
480 | GLhandleARB LLPipeline::loadShader(const LLString& filename, S32 cls, GLenum type) | 353 | void LLPipeline::releaseGLBuffers() |
481 | { | 354 | { |
482 | GLenum error; | 355 | if (mGlowMap) |
483 | error = glGetError(); | ||
484 | if (error != GL_NO_ERROR) | ||
485 | { | ||
486 | llwarns << "GL ERROR entering loadShader(): " << error << llendl; | ||
487 | } | ||
488 | |||
489 | llinfos << "Loading shader file: " << filename << llendl; | ||
490 | |||
491 | if (filename.empty()) | ||
492 | { | ||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | |||
497 | //read in from file | ||
498 | FILE* file = NULL; | ||
499 | |||
500 | S32 try_gpu_class = mVertexShaderLevel[cls]; | ||
501 | S32 gpu_class; | ||
502 | |||
503 | //find the most relevant file | ||
504 | for (gpu_class = try_gpu_class; gpu_class > 0; gpu_class--) | ||
505 | { //search from the current gpu class down to class 1 to find the most relevant shader | ||
506 | std::stringstream fname; | ||
507 | fname << gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); | ||
508 | fname << gpu_class << "/" << filename; | ||
509 | |||
510 | // llinfos << "Looking in " << fname.str().c_str() << llendl; | ||
511 | file = fopen(fname.str().c_str(), "r"); /* Flawfinder: ignore */ | ||
512 | if (file) | ||
513 | { | ||
514 | break; // done | ||
515 | } | ||
516 | } | ||
517 | |||
518 | if (file == NULL) | ||
519 | { | 356 | { |
520 | llinfos << "GLSL Shader file not found: " << filename << llendl; | 357 | glDeleteTextures(1, &mGlowMap); |
521 | return 0; | 358 | mGlowMap = 0; |
522 | } | 359 | } |
523 | 360 | ||
524 | //we can't have any lines longer than 1024 characters | 361 | if (mGlowBuffer) |
525 | //or any shaders longer than 1024 lines... deal - DaveP | ||
526 | GLcharARB buff[1024]; | ||
527 | GLcharARB* text[1024]; | ||
528 | GLuint count = 0; | ||
529 | |||
530 | //copy file into memory | ||
531 | while(fgets(buff, 1024, file) != NULL) | ||
532 | { | ||
533 | text[count++] = strdup(buff); | ||
534 | } | ||
535 | fclose(file); | ||
536 | |||
537 | //create shader object | ||
538 | GLhandleARB ret = glCreateShaderObjectARB(type); | ||
539 | error = glGetError(); | ||
540 | if (error != GL_NO_ERROR) | ||
541 | { | ||
542 | llwarns << "GL ERROR in glCreateShaderObjectARB: " << error << llendl; | ||
543 | } | ||
544 | else | ||
545 | { | ||
546 | //load source | ||
547 | glShaderSourceARB(ret, count, (const GLcharARB**) text, NULL); | ||
548 | error = glGetError(); | ||
549 | if (error != GL_NO_ERROR) | ||
550 | { | ||
551 | llwarns << "GL ERROR in glShaderSourceARB: " << error << llendl; | ||
552 | } | ||
553 | else | ||
554 | { | ||
555 | //compile source | ||
556 | glCompileShaderARB(ret); | ||
557 | error = glGetError(); | ||
558 | if (error != GL_NO_ERROR) | ||
559 | { | ||
560 | llwarns << "GL ERROR in glCompileShaderARB: " << error << llendl; | ||
561 | } | ||
562 | } | ||
563 | } | ||
564 | //free memory | ||
565 | for (GLuint i = 0; i < count; i++) | ||
566 | { | ||
567 | free(text[i]); | ||
568 | } | ||
569 | if (error == GL_NO_ERROR) | ||
570 | { | ||
571 | //check for errors | ||
572 | GLint success = GL_TRUE; | ||
573 | glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success); | ||
574 | error = glGetError(); | ||
575 | if (error != GL_NO_ERROR || success == GL_FALSE) | ||
576 | { | ||
577 | //an error occured, print log | ||
578 | llwarns << "GLSL Compilation Error: (" << error << ") in " << filename << llendl; | ||
579 | dumpObjectLog(ret); | ||
580 | ret = 0; | ||
581 | } | ||
582 | } | ||
583 | else | ||
584 | { | 362 | { |
585 | ret = 0; | 363 | glDeleteTextures(1, &mGlowBuffer); |
364 | mGlowBuffer = 0; | ||
586 | } | 365 | } |
587 | stop_glerror(); | ||
588 | 366 | ||
589 | //successfully loaded, save results | 367 | if (mScreenTex) |
590 | #if 1 // 1.9.1 | ||
591 | if (ret) | ||
592 | { | ||
593 | mVertexShaderLevel[cls] = try_gpu_class; | ||
594 | } | ||
595 | else | ||
596 | { | ||
597 | if (mVertexShaderLevel[cls] > 1) | ||
598 | { | ||
599 | mVertexShaderLevel[cls] = mVertexShaderLevel[cls] - 1; | ||
600 | ret = loadShader(filename,cls,type); | ||
601 | if (ret && mMaxVertexShaderLevel[cls] > mVertexShaderLevel[cls]) | ||
602 | { | ||
603 | mMaxVertexShaderLevel[cls] = mVertexShaderLevel[cls]; | ||
604 | } | ||
605 | } | ||
606 | } | ||
607 | #else | ||
608 | if (ret) | ||
609 | { | ||
610 | S32 max = -1; | ||
611 | /*if (try_gpu_class == mMaxVertexShaderLevel[cls]) | ||
612 | { | ||
613 | max = gpu_class; | ||
614 | }*/ | ||
615 | saveVertexShaderLevel(cls,try_gpu_class,max); | ||
616 | } | ||
617 | else | ||
618 | { | 368 | { |
619 | if (mVertexShaderLevel[cls] > 1) | 369 | glDeleteTextures(1, &mScreenTex); |
620 | { | 370 | mScreenTex = 0; |
621 | mVertexShaderLevel[cls] = mVertexShaderLevel[cls] - 1; | ||
622 | ret = loadShader(f,cls,type); | ||
623 | if (ret && mMaxVertexShaderLevel[cls] > mVertexShaderLevel[cls]) | ||
624 | { | ||
625 | saveVertexShaderLevel(cls, mVertexShaderLevel[cls], mVertexShaderLevel[cls]); | ||
626 | } | ||
627 | } | ||
628 | } | 371 | } |
629 | #endif | ||
630 | return ret; | ||
631 | } | ||
632 | 372 | ||
633 | BOOL LLPipeline::linkProgramObject(GLhandleARB obj, BOOL suppress_errors) | 373 | if (mCubeBuffer) |
634 | { | ||
635 | //check for errors | ||
636 | glLinkProgramARB(obj); | ||
637 | GLint success = GL_TRUE; | ||
638 | glGetObjectParameterivARB(obj, GL_OBJECT_LINK_STATUS_ARB, &success); | ||
639 | if (!suppress_errors && success == GL_FALSE) | ||
640 | { | 374 | { |
641 | //an error occured, print log | 375 | delete mCubeBuffer; |
642 | llwarns << "GLSL Linker Error:" << llendl; | 376 | mCubeBuffer = NULL; |
643 | } | 377 | } |
644 | 378 | ||
645 | LLString log = get_object_log(obj); | 379 | if (mCubeFrameBuffer) |
646 | LLString::toLower(log); | ||
647 | if (log.find("software") != LLString::npos) | ||
648 | { | 380 | { |
649 | llwarns << "GLSL Linker: Running in Software:" << llendl; | 381 | glDeleteFramebuffersEXT(1, &mCubeFrameBuffer); |
650 | success = GL_FALSE; | 382 | glDeleteRenderbuffersEXT(1, &mCubeDepth); |
651 | suppress_errors = FALSE; | 383 | mCubeDepth = mCubeFrameBuffer = 0; |
652 | } | 384 | } |
653 | if (!suppress_errors) | ||
654 | { | ||
655 | dumpObjectLog(obj, !success); | ||
656 | } | ||
657 | |||
658 | return success; | ||
659 | } | ||
660 | 385 | ||
661 | BOOL LLPipeline::validateProgramObject(GLhandleARB obj) | 386 | if (mFramebuffer[0]) |
662 | { | ||
663 | //check program validity against current GL | ||
664 | glValidateProgramARB(obj); | ||
665 | GLint success = GL_TRUE; | ||
666 | glGetObjectParameterivARB(obj, GL_OBJECT_VALIDATE_STATUS_ARB, &success); | ||
667 | if (success == GL_FALSE) | ||
668 | { | ||
669 | llwarns << "GLSL program not valid: " << llendl; | ||
670 | dumpObjectLog(obj); | ||
671 | } | ||
672 | else | ||
673 | { | 387 | { |
674 | dumpObjectLog(obj, FALSE); | 388 | glDeleteFramebuffersEXT(2, mFramebuffer); |
389 | mFramebuffer[0] = mFramebuffer[1] = 0; | ||
675 | } | 390 | } |
676 | |||
677 | return success; | ||
678 | } | 391 | } |
679 | 392 | ||
680 | //============================================================================ | 393 | void LLPipeline::restoreGL() |
681 | // Shader Management | ||
682 | |||
683 | void LLPipeline::setShaders() | ||
684 | { | 394 | { |
685 | sDynamicReflections = gSavedSettings.getBOOL("RenderDynamicReflections"); | ||
686 | |||
687 | //hack to reset buffers that change behavior with shaders | ||
688 | resetVertexBuffers(); | 395 | resetVertexBuffers(); |
689 | 396 | ||
690 | if (gViewerWindow) | 397 | if (mVertexShadersEnabled) |
691 | { | ||
692 | gViewerWindow->setCursor(UI_CURSOR_WAIT); | ||
693 | } | ||
694 | |||
695 | // Lighting | ||
696 | setLightingDetail(-1); | ||
697 | |||
698 | // Shaders | ||
699 | for (S32 i=0; i<SHADER_COUNT; i++) | ||
700 | { | 398 | { |
701 | mVertexShaderLevel[i] = 0; | 399 | LLShaderMgr::setShaders(); |
702 | mMaxVertexShaderLevel[i] = 0; | ||
703 | } | 400 | } |
704 | if (canUseVertexShaders()) | 401 | |
402 | for (U32 i = 0; i < mObjectPartition.size()-1; i++) | ||
705 | { | 403 | { |
706 | S32 light_class = 2; | 404 | if (mObjectPartition[i]) |
707 | S32 env_class = 2; | ||
708 | S32 obj_class = 0; | ||
709 | |||
710 | if (getLightingDetail() == 0) | ||
711 | { | ||
712 | light_class = 1; | ||
713 | } | ||
714 | // Load lighting shaders | ||
715 | mVertexShaderLevel[SHADER_LIGHTING] = light_class; | ||
716 | mMaxVertexShaderLevel[SHADER_LIGHTING] = light_class; | ||
717 | mVertexShaderLevel[SHADER_ENVIRONMENT] = env_class; | ||
718 | mMaxVertexShaderLevel[SHADER_ENVIRONMENT] = env_class; | ||
719 | mVertexShaderLevel[SHADER_OBJECT] = obj_class; | ||
720 | mMaxVertexShaderLevel[SHADER_OBJECT] = obj_class; | ||
721 | |||
722 | BOOL loaded = loadShadersLighting(); | ||
723 | |||
724 | if (loaded) | ||
725 | { | ||
726 | mVertexShadersEnabled = TRUE; | ||
727 | mVertexShadersLoaded = 1; | ||
728 | |||
729 | // Load all shaders to set max levels | ||
730 | loadShadersEnvironment(); | ||
731 | loadShadersObject(); | ||
732 | // Load max avatar shaders to set the max level | ||
733 | mVertexShaderLevel[SHADER_AVATAR] = 3; | ||
734 | mMaxVertexShaderLevel[SHADER_AVATAR] = 3; | ||
735 | loadShadersAvatar(); | ||
736 | |||
737 | // Load shaders to correct levels | ||
738 | if (!gSavedSettings.getBOOL("RenderRippleWater")) | ||
739 | { | ||
740 | mVertexShaderLevel[SHADER_ENVIRONMENT] = 0; | ||
741 | loadShadersEnvironment(); // unloads | ||
742 | } | ||
743 | |||
744 | #if LL_DARWIN // force avatar shaders off for mac | ||
745 | mVertexShaderLevel[SHADER_AVATAR] = 0; | ||
746 | mMaxVertexShaderLevel[SHADER_AVATAR] = 0; | ||
747 | #else | ||
748 | if (gSavedSettings.getBOOL("RenderAvatarVP")) | ||
749 | { | ||
750 | S32 avatar = gSavedSettings.getS32("RenderAvatarMode"); | ||
751 | S32 avatar_class = 1 + avatar; | ||
752 | // Set the actual level | ||
753 | mVertexShaderLevel[SHADER_AVATAR] = avatar_class; | ||
754 | loadShadersAvatar(); | ||
755 | if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class) | ||
756 | { | ||
757 | if (mVertexShaderLevel[SHADER_AVATAR] == 0) | ||
758 | { | ||
759 | gSavedSettings.setBOOL("RenderAvatarVP", FALSE); | ||
760 | } | ||
761 | avatar = llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0); | ||
762 | gSavedSettings.setS32("RenderAvatarMode", avatar); | ||
763 | } | ||
764 | } | ||
765 | else | ||
766 | { | ||
767 | mVertexShaderLevel[SHADER_AVATAR] = 0; | ||
768 | gSavedSettings.setS32("RenderAvatarMode", 0); | ||
769 | loadShadersAvatar(); // unloads | ||
770 | } | ||
771 | #endif | ||
772 | } | ||
773 | else | ||
774 | { | 405 | { |
775 | mVertexShadersEnabled = FALSE; | 406 | mObjectPartition[i]->restoreGL(); |
776 | mVertexShadersLoaded = 0; | ||
777 | } | 407 | } |
778 | } | 408 | } |
779 | if (gViewerWindow) | ||
780 | { | ||
781 | gViewerWindow->setCursor(UI_CURSOR_ARROW); | ||
782 | } | ||
783 | } | 409 | } |
784 | 410 | ||
411 | |||
785 | BOOL LLPipeline::canUseVertexShaders() | 412 | BOOL LLPipeline::canUseVertexShaders() |
786 | { | 413 | { |
787 | if (!gGLManager.mHasVertexShader || | 414 | if (!gGLManager.mHasVertexShader || |
@@ -799,468 +426,10 @@ BOOL LLPipeline::canUseVertexShaders() | |||
799 | 426 | ||
800 | void LLPipeline::unloadShaders() | 427 | void LLPipeline::unloadShaders() |
801 | { | 428 | { |
802 | mObjectSimpleProgram.unload(); | 429 | LLShaderMgr::unloadShaders(); |
803 | mObjectShinyProgram.unload(); | ||
804 | mObjectBumpProgram.unload(); | ||
805 | mObjectAlphaProgram.unload(); | ||
806 | mWaterProgram.unload(); | ||
807 | mTerrainProgram.unload(); | ||
808 | mGroundProgram.unload(); | ||
809 | mAvatarProgram.unload(); | ||
810 | mAvatarEyeballProgram.unload(); | ||
811 | mAvatarPickProgram.unload(); | ||
812 | mHighlightProgram.unload(); | ||
813 | |||
814 | mVertexShaderLevel[SHADER_LIGHTING] = 0; | ||
815 | mVertexShaderLevel[SHADER_OBJECT] = 0; | ||
816 | mVertexShaderLevel[SHADER_AVATAR] = 0; | ||
817 | mVertexShaderLevel[SHADER_ENVIRONMENT] = 0; | ||
818 | mVertexShaderLevel[SHADER_INTERFACE] = 0; | ||
819 | |||
820 | mLightVertex = mLightFragment = mScatterVertex = mScatterFragment = 0; | ||
821 | mVertexShadersLoaded = 0; | 430 | mVertexShadersLoaded = 0; |
822 | } | 431 | } |
823 | 432 | ||
824 | #if 0 // 1.9.2 | ||
825 | // Any time shader options change | ||
826 | BOOL LLPipeline::loadShaders() | ||
827 | { | ||
828 | unloadShaders(); | ||
829 | |||
830 | if (!canUseVertexShaders()) | ||
831 | { | ||
832 | return FALSE; | ||
833 | } | ||
834 | |||
835 | S32 light_class = mMaxVertexShaderLevel[SHADER_LIGHTING]; | ||
836 | if (getLightingDetail() == 0) | ||
837 | { | ||
838 | light_class = 1; // Use minimum lighting shader | ||
839 | } | ||
840 | else if (getLightingDetail() == 1) | ||
841 | { | ||
842 | light_class = 2; // Use medium lighting shader | ||
843 | } | ||
844 | mVertexShaderLevel[SHADER_LIGHTING] = light_class; | ||
845 | //mVertexShaderLevel[SHADER_OBJECT] = llmin(mMaxVertexShaderLevel[SHADER_OBJECT], gSavedSettings.getS32("VertexShaderLevelObject")); | ||
846 | mVertexShaderLevel[SHADER_OBJECT] = 0; | ||
847 | mVertexShaderLevel[SHADER_AVATAR] = llmin(mMaxVertexShaderLevel[SHADER_AVATAR], gSavedSettings.getS32("VertexShaderLevelAvatar")); | ||
848 | mVertexShaderLevel[SHADER_ENVIRONMENT] = llmin(mMaxVertexShaderLevel[SHADER_ENVIRONMENT], gSavedSettings.getS32("VertexShaderLevelEnvironment")); | ||
849 | mVertexShaderLevel[SHADER_INTERFACE] = mMaxVertexShaderLevel[SHADER_INTERFACE]; | ||
850 | |||
851 | BOOL loaded = loadShadersLighting(); | ||
852 | if (loaded) | ||
853 | { | ||
854 | loadShadersEnvironment(); // Must load this before object/avatar for scatter | ||
855 | loadShadersObject(); | ||
856 | loadShadersAvatar(); | ||
857 | loadShadersInterface(); | ||
858 | mVertexShadersLoaded = 1; | ||
859 | } | ||
860 | else | ||
861 | { | ||
862 | unloadShaders(); | ||
863 | mVertexShadersEnabled = FALSE; | ||
864 | mVertexShadersLoaded = 0; //-1; // -1 = failed | ||
865 | setLightingDetail(-1); | ||
866 | } | ||
867 | |||
868 | return loaded; | ||
869 | } | ||
870 | #endif | ||
871 | |||
872 | BOOL LLPipeline::loadShadersLighting() | ||
873 | { | ||
874 | // Load light dependency shaders first | ||
875 | // All of these have to load for any shaders to function | ||
876 | |||
877 | std::string lightvertex = "lighting/lightV.glsl"; | ||
878 | //get default light function implementation | ||
879 | mLightVertex = loadShader(lightvertex, SHADER_LIGHTING, GL_VERTEX_SHADER_ARB); | ||
880 | if( !mLightVertex ) | ||
881 | { | ||
882 | llwarns << "Failed to load " << lightvertex << llendl; | ||
883 | return FALSE; | ||
884 | } | ||
885 | |||
886 | std::string lightfragment = "lighting/lightF.glsl"; | ||
887 | mLightFragment = loadShader(lightfragment, SHADER_LIGHTING, GL_FRAGMENT_SHADER_ARB); | ||
888 | if ( !mLightFragment ) | ||
889 | { | ||
890 | llwarns << "Failed to load " << lightfragment << llendl; | ||
891 | return FALSE; | ||
892 | } | ||
893 | |||
894 | // NOTE: Scatter shaders use the ENVIRONMENT detail level | ||
895 | |||
896 | std::string scattervertex = "environment/scatterV.glsl"; | ||
897 | mScatterVertex = loadShader(scattervertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB); | ||
898 | if ( !mScatterVertex ) | ||
899 | { | ||
900 | llwarns << "Failed to load " << scattervertex << llendl; | ||
901 | return FALSE; | ||
902 | } | ||
903 | |||
904 | std::string scatterfragment = "environment/scatterF.glsl"; | ||
905 | mScatterFragment = loadShader(scatterfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB); | ||
906 | if ( !mScatterFragment ) | ||
907 | { | ||
908 | llwarns << "Failed to load " << scatterfragment << llendl; | ||
909 | return FALSE; | ||
910 | } | ||
911 | |||
912 | return TRUE; | ||
913 | } | ||
914 | |||
915 | BOOL LLPipeline::loadShadersEnvironment() | ||
916 | { | ||
917 | GLhandleARB baseObjects[] = | ||
918 | { | ||
919 | mLightFragment, | ||
920 | mLightVertex, | ||
921 | mScatterFragment, | ||
922 | mScatterVertex | ||
923 | }; | ||
924 | S32 baseCount = 4; | ||
925 | |||
926 | BOOL success = TRUE; | ||
927 | |||
928 | if (mVertexShaderLevel[SHADER_ENVIRONMENT] == 0) | ||
929 | { | ||
930 | mWaterProgram.unload(); | ||
931 | mGroundProgram.unload(); | ||
932 | mTerrainProgram.unload(); | ||
933 | return FALSE; | ||
934 | } | ||
935 | |||
936 | if (success) | ||
937 | { | ||
938 | //load water vertex shader | ||
939 | std::string waterfragment = "environment/waterF.glsl"; | ||
940 | std::string watervertex = "environment/waterV.glsl"; | ||
941 | mWaterProgram.mProgramObject = glCreateProgramObjectARB(); | ||
942 | mWaterProgram.attachObjects(baseObjects, baseCount); | ||
943 | mWaterProgram.attachObject(loadShader(watervertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB)); | ||
944 | mWaterProgram.attachObject(loadShader(waterfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB)); | ||
945 | |||
946 | success = mWaterProgram.mapAttributes(); | ||
947 | if (success) | ||
948 | { | ||
949 | success = mWaterProgram.mapUniforms(sWaterUniforms, sWaterUniformCount); | ||
950 | } | ||
951 | if (!success) | ||
952 | { | ||
953 | llwarns << "Failed to load " << watervertex << llendl; | ||
954 | } | ||
955 | } | ||
956 | if (success) | ||
957 | { | ||
958 | //load ground vertex shader | ||
959 | std::string groundvertex = "environment/groundV.glsl"; | ||
960 | std::string groundfragment = "environment/groundF.glsl"; | ||
961 | mGroundProgram.mProgramObject = glCreateProgramObjectARB(); | ||
962 | mGroundProgram.attachObjects(baseObjects, baseCount); | ||
963 | mGroundProgram.attachObject(loadShader(groundvertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB)); | ||
964 | mGroundProgram.attachObject(loadShader(groundfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB)); | ||
965 | |||
966 | success = mGroundProgram.mapAttributes(); | ||
967 | if (success) | ||
968 | { | ||
969 | success = mGroundProgram.mapUniforms(); | ||
970 | } | ||
971 | if (!success) | ||
972 | { | ||
973 | llwarns << "Failed to load " << groundvertex << llendl; | ||
974 | } | ||
975 | } | ||
976 | |||
977 | if (success) | ||
978 | { | ||
979 | //load terrain vertex shader | ||
980 | std::string terrainvertex = "environment/terrainV.glsl"; | ||
981 | std::string terrainfragment = "environment/terrainF.glsl"; | ||
982 | mTerrainProgram.mProgramObject = glCreateProgramObjectARB(); | ||
983 | mTerrainProgram.attachObjects(baseObjects, baseCount); | ||
984 | mTerrainProgram.attachObject(loadShader(terrainvertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB)); | ||
985 | mTerrainProgram.attachObject(loadShader(terrainfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB)); | ||
986 | success = mTerrainProgram.mapAttributes(); | ||
987 | if (success) | ||
988 | { | ||
989 | success = mTerrainProgram.mapUniforms(sTerrainUniforms, sTerrainUniformCount); | ||
990 | } | ||
991 | if (!success) | ||
992 | { | ||
993 | llwarns << "Failed to load " << terrainvertex << llendl; | ||
994 | } | ||
995 | } | ||
996 | |||
997 | if( !success ) | ||
998 | { | ||
999 | mVertexShaderLevel[SHADER_ENVIRONMENT] = 0; | ||
1000 | mMaxVertexShaderLevel[SHADER_ENVIRONMENT] = 0; | ||
1001 | return FALSE; | ||
1002 | } | ||
1003 | |||
1004 | if (gWorldPointer) | ||
1005 | { | ||
1006 | gWorldPointer->updateWaterObjects(); | ||
1007 | } | ||
1008 | |||
1009 | return TRUE; | ||
1010 | } | ||
1011 | |||
1012 | BOOL LLPipeline::loadShadersObject() | ||
1013 | { | ||
1014 | GLhandleARB baseObjects[] = | ||
1015 | { | ||
1016 | mLightFragment, | ||
1017 | mLightVertex, | ||
1018 | mScatterFragment, | ||
1019 | mScatterVertex | ||
1020 | }; | ||
1021 | S32 baseCount = 4; | ||
1022 | |||
1023 | BOOL success = TRUE; | ||
1024 | |||
1025 | if (mVertexShaderLevel[SHADER_OBJECT] == 0) | ||
1026 | { | ||
1027 | mObjectShinyProgram.unload(); | ||
1028 | mObjectSimpleProgram.unload(); | ||
1029 | mObjectBumpProgram.unload(); | ||
1030 | mObjectAlphaProgram.unload(); | ||
1031 | return FALSE; | ||
1032 | } | ||
1033 | |||
1034 | #if 0 | ||
1035 | if (success) | ||
1036 | { | ||
1037 | //load object (volume/tree) vertex shader | ||
1038 | std::string simplevertex = "objects/simpleV.glsl"; | ||
1039 | std::string simplefragment = "objects/simpleF.glsl"; | ||
1040 | mObjectSimpleProgram.mProgramObject = glCreateProgramObjectARB(); | ||
1041 | mObjectSimpleProgram.attachObjects(baseObjects, baseCount); | ||
1042 | mObjectSimpleProgram.attachObject(loadShader(simplevertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB)); | ||
1043 | mObjectSimpleProgram.attachObject(loadShader(simplefragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB)); | ||
1044 | success = mObjectSimpleProgram.mapAttributes(); | ||
1045 | if (success) | ||
1046 | { | ||
1047 | success = mObjectSimpleProgram.mapUniforms(); | ||
1048 | } | ||
1049 | if( !success ) | ||
1050 | { | ||
1051 | llwarns << "Failed to load " << simplevertex << llendl; | ||
1052 | } | ||
1053 | } | ||
1054 | |||
1055 | if (success) | ||
1056 | { | ||
1057 | //load object bumpy vertex shader | ||
1058 | std::string bumpshinyvertex = "objects/bumpshinyV.glsl"; | ||
1059 | std::string bumpshinyfragment = "objects/bumpshinyF.glsl"; | ||
1060 | mObjectBumpProgram.mProgramObject = glCreateProgramObjectARB(); | ||
1061 | mObjectBumpProgram.attachObjects(baseObjects, baseCount); | ||
1062 | mObjectBumpProgram.attachObject(loadShader(bumpshinyvertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB)); | ||
1063 | mObjectBumpProgram.attachObject(loadShader(bumpshinyfragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB)); | ||
1064 | success = mObjectBumpProgram.mapAttributes(); | ||
1065 | if (success) | ||
1066 | { | ||
1067 | success = mObjectBumpProgram.mapUniforms(); | ||
1068 | } | ||
1069 | if( !success ) | ||
1070 | { | ||
1071 | llwarns << "Failed to load " << bumpshinyvertex << llendl; | ||
1072 | } | ||
1073 | } | ||
1074 | |||
1075 | if (success) | ||
1076 | { | ||
1077 | //load object alpha vertex shader | ||
1078 | std::string alphavertex = "objects/alphaV.glsl"; | ||
1079 | std::string alphafragment = "objects/alphaF.glsl"; | ||
1080 | mObjectAlphaProgram.mProgramObject = glCreateProgramObjectARB(); | ||
1081 | mObjectAlphaProgram.attachObjects(baseObjects, baseCount); | ||
1082 | mObjectAlphaProgram.attachObject(loadShader(alphavertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB)); | ||
1083 | mObjectAlphaProgram.attachObject(loadShader(alphafragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB)); | ||
1084 | |||
1085 | success = mObjectAlphaProgram.mapAttributes(); | ||
1086 | if (success) | ||
1087 | { | ||
1088 | success = mObjectAlphaProgram.mapUniforms(); | ||
1089 | } | ||
1090 | if( !success ) | ||
1091 | { | ||
1092 | llwarns << "Failed to load " << alphavertex << llendl; | ||
1093 | } | ||
1094 | } | ||
1095 | #endif | ||
1096 | |||
1097 | if (success) | ||
1098 | { | ||
1099 | //load shiny vertex shader | ||
1100 | std::string shinyvertex = "objects/shinyV.glsl"; | ||
1101 | std::string shinyfragment = "objects/shinyF.glsl"; | ||
1102 | mObjectShinyProgram.mProgramObject = glCreateProgramObjectARB(); | ||
1103 | mObjectShinyProgram.attachObjects(baseObjects, baseCount); | ||
1104 | mObjectShinyProgram.attachObject(loadShader(shinyvertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB)); | ||
1105 | mObjectShinyProgram.attachObject(loadShader(shinyfragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB)); | ||
1106 | |||
1107 | success = mObjectShinyProgram.mapAttributes(); | ||
1108 | if (success) | ||
1109 | { | ||
1110 | success = mObjectShinyProgram.mapUniforms(LLPipeline::sShinyUniforms, LLPipeline::sShinyUniformCount); | ||
1111 | } | ||
1112 | if( !success ) | ||
1113 | { | ||
1114 | llwarns << "Failed to load " << shinyvertex << llendl; | ||
1115 | } | ||
1116 | } | ||
1117 | |||
1118 | if( !success ) | ||
1119 | { | ||
1120 | mVertexShaderLevel[SHADER_OBJECT] = 0; | ||
1121 | mMaxVertexShaderLevel[SHADER_OBJECT] = 0; | ||
1122 | return FALSE; | ||
1123 | } | ||
1124 | |||
1125 | return TRUE; | ||
1126 | } | ||
1127 | |||
1128 | BOOL LLPipeline::loadShadersAvatar() | ||
1129 | { | ||
1130 | GLhandleARB baseObjects[] = | ||
1131 | { | ||
1132 | mLightFragment, | ||
1133 | mLightVertex, | ||
1134 | mScatterFragment, | ||
1135 | mScatterVertex | ||
1136 | }; | ||
1137 | S32 baseCount = 4; | ||
1138 | |||
1139 | BOOL success = TRUE; | ||
1140 | |||
1141 | if (mVertexShaderLevel[SHADER_AVATAR] == 0) | ||
1142 | { | ||
1143 | mAvatarProgram.unload(); | ||
1144 | mAvatarEyeballProgram.unload(); | ||
1145 | mAvatarPickProgram.unload(); | ||
1146 | return FALSE; | ||
1147 | } | ||
1148 | |||
1149 | if (success) | ||
1150 | { | ||
1151 | //load specular (eyeball) vertex program | ||
1152 | std::string eyeballvertex = "avatar/eyeballV.glsl"; | ||
1153 | std::string eyeballfragment = "avatar/eyeballF.glsl"; | ||
1154 | mAvatarEyeballProgram.mProgramObject = glCreateProgramObjectARB(); | ||
1155 | mAvatarEyeballProgram.attachObjects(baseObjects, baseCount); | ||
1156 | mAvatarEyeballProgram.attachObject(loadShader(eyeballvertex, SHADER_AVATAR, GL_VERTEX_SHADER_ARB)); | ||
1157 | mAvatarEyeballProgram.attachObject(loadShader(eyeballfragment, SHADER_AVATAR, GL_FRAGMENT_SHADER_ARB)); | ||
1158 | success = mAvatarEyeballProgram.mapAttributes(); | ||
1159 | if (success) | ||
1160 | { | ||
1161 | success = mAvatarEyeballProgram.mapUniforms(); | ||
1162 | } | ||
1163 | if( !success ) | ||
1164 | { | ||
1165 | llwarns << "Failed to load " << eyeballvertex << llendl; | ||
1166 | } | ||
1167 | } | ||
1168 | |||
1169 | if (success) | ||
1170 | { | ||
1171 | mAvatarSkinVertex = loadShader("avatar/avatarSkinV.glsl", SHADER_AVATAR, GL_VERTEX_SHADER_ARB); | ||
1172 | //load avatar vertex shader | ||
1173 | std::string avatarvertex = "avatar/avatarV.glsl"; | ||
1174 | std::string avatarfragment = "avatar/avatarF.glsl"; | ||
1175 | |||
1176 | mAvatarProgram.mProgramObject = glCreateProgramObjectARB(); | ||
1177 | mAvatarProgram.attachObjects(baseObjects, baseCount); | ||
1178 | mAvatarProgram.attachObject(mAvatarSkinVertex); | ||
1179 | mAvatarProgram.attachObject(loadShader(avatarvertex, SHADER_AVATAR, GL_VERTEX_SHADER_ARB)); | ||
1180 | mAvatarProgram.attachObject(loadShader(avatarfragment, SHADER_AVATAR, GL_FRAGMENT_SHADER_ARB)); | ||
1181 | |||
1182 | success = mAvatarProgram.mapAttributes(sAvatarAttribs, sAvatarAttribCount); | ||
1183 | if (success) | ||
1184 | { | ||
1185 | success = mAvatarProgram.mapUniforms(sAvatarUniforms, sAvatarUniformCount); | ||
1186 | } | ||
1187 | if( !success ) | ||
1188 | { | ||
1189 | llwarns << "Failed to load " << avatarvertex << llendl; | ||
1190 | } | ||
1191 | } | ||
1192 | |||
1193 | if (success) | ||
1194 | { | ||
1195 | //load avatar picking shader | ||
1196 | std::string pickvertex = "avatar/pickAvatarV.glsl"; | ||
1197 | std::string pickfragment = "avatar/pickAvatarF.glsl"; | ||
1198 | mAvatarPickProgram.mProgramObject = glCreateProgramObjectARB(); | ||
1199 | mAvatarPickProgram.attachObject(loadShader(pickvertex, SHADER_AVATAR, GL_VERTEX_SHADER_ARB)); | ||
1200 | mAvatarPickProgram.attachObject(loadShader(pickfragment, SHADER_AVATAR, GL_FRAGMENT_SHADER_ARB)); | ||
1201 | mAvatarPickProgram.attachObject(mAvatarSkinVertex); | ||
1202 | |||
1203 | success = mAvatarPickProgram.mapAttributes(sAvatarAttribs, sAvatarAttribCount); | ||
1204 | if (success) | ||
1205 | { | ||
1206 | success = mAvatarPickProgram.mapUniforms(sAvatarUniforms, sAvatarUniformCount); | ||
1207 | } | ||
1208 | if( !success ) | ||
1209 | { | ||
1210 | llwarns << "Failed to load " << pickvertex << llendl; | ||
1211 | } | ||
1212 | } | ||
1213 | |||
1214 | if( !success ) | ||
1215 | { | ||
1216 | mVertexShaderLevel[SHADER_AVATAR] = 0; | ||
1217 | mMaxVertexShaderLevel[SHADER_AVATAR] = 0; | ||
1218 | return FALSE; | ||
1219 | } | ||
1220 | |||
1221 | return TRUE; | ||
1222 | } | ||
1223 | |||
1224 | BOOL LLPipeline::loadShadersInterface() | ||
1225 | { | ||
1226 | BOOL success = TRUE; | ||
1227 | |||
1228 | if (mVertexShaderLevel[SHADER_INTERFACE] == 0) | ||
1229 | { | ||
1230 | mHighlightProgram.unload(); | ||
1231 | return FALSE; | ||
1232 | } | ||
1233 | |||
1234 | if (success) | ||
1235 | { | ||
1236 | //load highlighting shader | ||
1237 | std::string highlightvertex = "interface/highlightV.glsl"; | ||
1238 | std::string highlightfragment = "interface/highlightF.glsl"; | ||
1239 | mHighlightProgram.mProgramObject = glCreateProgramObjectARB(); | ||
1240 | mHighlightProgram.attachObject(loadShader(highlightvertex, SHADER_INTERFACE, GL_VERTEX_SHADER_ARB)); | ||
1241 | mHighlightProgram.attachObject(loadShader(highlightfragment, SHADER_INTERFACE, GL_FRAGMENT_SHADER_ARB)); | ||
1242 | |||
1243 | success = mHighlightProgram.mapAttributes(); | ||
1244 | if (success) | ||
1245 | { | ||
1246 | success = mHighlightProgram.mapUniforms(); | ||
1247 | } | ||
1248 | if( !success ) | ||
1249 | { | ||
1250 | llwarns << "Failed to load " << highlightvertex << llendl; | ||
1251 | } | ||
1252 | } | ||
1253 | |||
1254 | if( !success ) | ||
1255 | { | ||
1256 | mVertexShaderLevel[SHADER_INTERFACE] = 0; | ||
1257 | mMaxVertexShaderLevel[SHADER_INTERFACE] = 0; | ||
1258 | return FALSE; | ||
1259 | } | ||
1260 | |||
1261 | return TRUE; | ||
1262 | } | ||
1263 | |||
1264 | //============================================================================ | 433 | //============================================================================ |
1265 | 434 | ||
1266 | void LLPipeline::enableShadows(const BOOL enable_shadows) | 435 | void LLPipeline::enableShadows(const BOOL enable_shadows) |
@@ -1298,7 +467,7 @@ S32 LLPipeline::setLightingDetail(S32 level) | |||
1298 | 467 | ||
1299 | if (mVertexShadersLoaded == 1) | 468 | if (mVertexShadersLoaded == 1) |
1300 | { | 469 | { |
1301 | gPipeline.setShaders(); | 470 | LLShaderMgr::setShaders(); |
1302 | } | 471 | } |
1303 | } | 472 | } |
1304 | return mLightingDetail; | 473 | return mLightingDetail; |
@@ -1372,6 +541,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) | |||
1372 | poolp = mSimplePool; | 541 | poolp = mSimplePool; |
1373 | break; | 542 | break; |
1374 | 543 | ||
544 | case LLDrawPool::POOL_GLOW: | ||
545 | poolp = mGlowPool; | ||
546 | break; | ||
547 | |||
1375 | case LLDrawPool::POOL_TREE: | 548 | case LLDrawPool::POOL_TREE: |
1376 | poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 ); | 549 | poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 ); |
1377 | break; | 550 | break; |
@@ -2315,7 +1488,7 @@ void renderScriptedBeacons(LLDrawable* drawablep) | |||
2315 | && !vobj->getParent() | 1488 | && !vobj->getParent() |
2316 | && vobj->flagScripted()) | 1489 | && vobj->flagScripted()) |
2317 | { | 1490 | { |
2318 | gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f)); | 1491 | gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); |
2319 | } | 1492 | } |
2320 | } | 1493 | } |
2321 | 1494 | ||
@@ -2327,7 +1500,7 @@ void renderPhysicalBeacons(LLDrawable* drawablep) | |||
2327 | && !vobj->getParent() | 1500 | && !vobj->getParent() |
2328 | && vobj->usePhysics()) | 1501 | && vobj->usePhysics()) |
2329 | { | 1502 | { |
2330 | gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f)); | 1503 | gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); |
2331 | } | 1504 | } |
2332 | } | 1505 | } |
2333 | 1506 | ||
@@ -2339,7 +1512,7 @@ void renderParticleBeacons(LLDrawable* drawablep) | |||
2339 | && vobj->isParticleSource()) | 1512 | && vobj->isParticleSource()) |
2340 | { | 1513 | { |
2341 | LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f); | 1514 | LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f); |
2342 | gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f)); | 1515 | gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); |
2343 | } | 1516 | } |
2344 | } | 1517 | } |
2345 | 1518 | ||
@@ -2560,7 +1733,7 @@ void LLPipeline::postSort(LLCamera& camera) | |||
2560 | LLVector3d pos_global = sourcep->getPositionGlobal(); | 1733 | LLVector3d pos_global = sourcep->getPositionGlobal(); |
2561 | LLVector3 pos = gAgent.getPosAgentFromGlobal(pos_global); | 1734 | LLVector3 pos = gAgent.getPosAgentFromGlobal(pos_global); |
2562 | //pos += LLVector3(0.f, 0.f, 0.2f); | 1735 | //pos += LLVector3(0.f, 0.f, 0.2f); |
2563 | gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f)); | 1736 | gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); |
2564 | } | 1737 | } |
2565 | } | 1738 | } |
2566 | 1739 | ||
@@ -2641,10 +1814,10 @@ void LLPipeline::renderHighlights() | |||
2641 | LLGLEnable color_mat(GL_COLOR_MATERIAL); | 1814 | LLGLEnable color_mat(GL_COLOR_MATERIAL); |
2642 | disableLights(); | 1815 | disableLights(); |
2643 | 1816 | ||
2644 | if ((mVertexShaderLevel[SHADER_INTERFACE] > 0)) | 1817 | if ((LLShaderMgr::sVertexShaderLevel[LLShaderMgr::SHADER_INTERFACE] > 0)) |
2645 | { | 1818 | { |
2646 | mHighlightProgram.bind(); | 1819 | gHighlightProgram.bind(); |
2647 | gPipeline.mHighlightProgram.vertexAttrib4f(LLPipeline::GLSL_MATERIAL_COLOR,1,0,0,0.5f); | 1820 | gHighlightProgram.vertexAttrib4f(LLShaderMgr::MATERIAL_COLOR,1,0,0,0.5f); |
2648 | } | 1821 | } |
2649 | 1822 | ||
2650 | if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) | 1823 | if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) |
@@ -2683,9 +1856,9 @@ void LLPipeline::renderHighlights() | |||
2683 | // have touch-handlers. | 1856 | // have touch-handlers. |
2684 | mHighlightFaces.clear(); | 1857 | mHighlightFaces.clear(); |
2685 | 1858 | ||
2686 | if (mVertexShaderLevel[SHADER_INTERFACE] > 0) | 1859 | if (LLShaderMgr::sVertexShaderLevel[LLShaderMgr::SHADER_INTERFACE] > 0) |
2687 | { | 1860 | { |
2688 | mHighlightProgram.unbind(); | 1861 | gHighlightProgram.unbind(); |
2689 | } | 1862 | } |
2690 | } | 1863 | } |
2691 | 1864 | ||
@@ -2765,11 +1938,13 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
2765 | // | 1938 | // |
2766 | // | 1939 | // |
2767 | stop_glerror(); | 1940 | stop_glerror(); |
2768 | BOOL did_hud_elements = FALSE; | 1941 | BOOL did_hud_elements = LLDrawPoolWater::sSkipScreenCopy; |
2769 | BOOL occlude = sUseOcclusion; | 1942 | BOOL occlude = sUseOcclusion; |
2770 | 1943 | ||
2771 | U32 cur_type = 0; | 1944 | U32 cur_type = 0; |
2772 | 1945 | ||
1946 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); | ||
1947 | |||
2773 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING)) | 1948 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING)) |
2774 | { | 1949 | { |
2775 | gObjectList.renderObjectsForSelect(camera); | 1950 | gObjectList.renderObjectsForSelect(camera); |
@@ -2777,8 +1952,7 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
2777 | else | 1952 | else |
2778 | { | 1953 | { |
2779 | LLFastTimer t(LLFastTimer::FTM_POOLS); | 1954 | LLFastTimer t(LLFastTimer::FTM_POOLS); |
2780 | calcNearbyLights(); | 1955 | calcNearbyLights(camera); |
2781 | |||
2782 | pool_set_t::iterator iter1 = mPools.begin(); | 1956 | pool_set_t::iterator iter1 = mPools.begin(); |
2783 | while ( iter1 != mPools.end() ) | 1957 | while ( iter1 != mPools.end() ) |
2784 | { | 1958 | { |
@@ -2824,6 +1998,7 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
2824 | } | 1998 | } |
2825 | poolp->endRenderPass(i); | 1999 | poolp->endRenderPass(i); |
2826 | #ifndef LL_RELEASE_FOR_DOWNLOAD | 2000 | #ifndef LL_RELEASE_FOR_DOWNLOAD |
2001 | #if LL_DEBUG_GL | ||
2827 | GLint depth; | 2002 | GLint depth; |
2828 | glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); | 2003 | glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); |
2829 | if (depth > 3) | 2004 | if (depth > 3) |
@@ -2834,6 +2009,7 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
2834 | LLGLState::checkTextureChannels(); | 2009 | LLGLState::checkTextureChannels(); |
2835 | LLGLState::checkClientArrays(); | 2010 | LLGLState::checkClientArrays(); |
2836 | #endif | 2011 | #endif |
2012 | #endif | ||
2837 | } | 2013 | } |
2838 | } | 2014 | } |
2839 | else | 2015 | else |
@@ -2854,9 +2030,9 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
2854 | } | 2030 | } |
2855 | 2031 | ||
2856 | #ifndef LL_RELEASE_FOR_DOWNLOAD | 2032 | #ifndef LL_RELEASE_FOR_DOWNLOAD |
2857 | LLGLState::checkStates(); | 2033 | LLGLState::checkStates(); |
2858 | LLGLState::checkTextureChannels(); | 2034 | LLGLState::checkTextureChannels(); |
2859 | LLGLState::checkClientArrays(); | 2035 | LLGLState::checkClientArrays(); |
2860 | #endif | 2036 | #endif |
2861 | 2037 | ||
2862 | if (occlude) | 2038 | if (occlude) |
@@ -2886,6 +2062,40 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
2886 | // Contains a list of the faces of objects that are physical or | 2062 | // Contains a list of the faces of objects that are physical or |
2887 | // have touch-handlers. | 2063 | // have touch-handlers. |
2888 | mHighlightFaces.clear(); | 2064 | mHighlightFaces.clear(); |
2065 | |||
2066 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | ||
2067 | |||
2068 | if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD) && | ||
2069 | !LLDrawPoolWater::sSkipScreenCopy && | ||
2070 | sRenderGlow && | ||
2071 | gGLManager.mHasFramebufferObject) | ||
2072 | { | ||
2073 | const U32 glow_res = nhpo2(gSavedSettings.getS32("RenderGlowResolution")); | ||
2074 | if (mGlowMap == 0) | ||
2075 | { | ||
2076 | glGenTextures(1, &mGlowMap); | ||
2077 | glBindTexture(GL_TEXTURE_2D, mGlowMap); | ||
2078 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
2079 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
2080 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
2081 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
2082 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glow_res, glow_res, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); | ||
2083 | } | ||
2084 | |||
2085 | if (mGlowBuffer == 0) | ||
2086 | { | ||
2087 | glGenTextures(1, &mGlowBuffer); | ||
2088 | glBindTexture(GL_TEXTURE_2D, mGlowBuffer); | ||
2089 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
2090 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
2091 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
2092 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
2093 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glow_res, glow_res, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); | ||
2094 | } | ||
2095 | |||
2096 | bindScreenToTexture(); | ||
2097 | renderBloom(mScreenTex, mGlowMap, mGlowBuffer, glow_res, LLVector2(0,0), mScreenScale); | ||
2098 | } | ||
2889 | } | 2099 | } |
2890 | 2100 | ||
2891 | void LLPipeline::processOcclusion(LLCamera& camera) | 2101 | void LLPipeline::processOcclusion(LLCamera& camera) |
@@ -3241,6 +2451,18 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) | |||
3241 | } | 2451 | } |
3242 | break; | 2452 | break; |
3243 | 2453 | ||
2454 | case LLDrawPool::POOL_GLOW: | ||
2455 | if (mGlowPool) | ||
2456 | { | ||
2457 | llassert(0); | ||
2458 | llwarns << "Ignoring duplicate glow pool." << llendl; | ||
2459 | } | ||
2460 | else | ||
2461 | { | ||
2462 | mGlowPool = (LLRenderPass*) new_poolp; | ||
2463 | } | ||
2464 | break; | ||
2465 | |||
3244 | case LLDrawPool::POOL_TREE: | 2466 | case LLDrawPool::POOL_TREE: |
3245 | mTreePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; | 2467 | mTreePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; |
3246 | break; | 2468 | break; |
@@ -3360,6 +2582,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | |||
3360 | mSimplePool = NULL; | 2582 | mSimplePool = NULL; |
3361 | break; | 2583 | break; |
3362 | 2584 | ||
2585 | case LLDrawPool::POOL_GLOW: | ||
2586 | llassert(mGlowPool == poolp); | ||
2587 | mGlowPool = NULL; | ||
2588 | break; | ||
2589 | |||
3363 | case LLDrawPool::POOL_TREE: | 2590 | case LLDrawPool::POOL_TREE: |
3364 | #ifdef _DEBUG | 2591 | #ifdef _DEBUG |
3365 | { | 2592 | { |
@@ -3545,7 +2772,7 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_ | |||
3545 | return dist; | 2772 | return dist; |
3546 | } | 2773 | } |
3547 | 2774 | ||
3548 | void LLPipeline::calcNearbyLights() | 2775 | void LLPipeline::calcNearbyLights(LLCamera& camera) |
3549 | { | 2776 | { |
3550 | if (mLightingDetail >= 1) | 2777 | if (mLightingDetail >= 1) |
3551 | { | 2778 | { |
@@ -3553,34 +2780,39 @@ void LLPipeline::calcNearbyLights() | |||
3553 | // begin() == the closest light and rbegin() == the farthest light | 2780 | // begin() == the closest light and rbegin() == the farthest light |
3554 | const S32 MAX_LOCAL_LIGHTS = 6; | 2781 | const S32 MAX_LOCAL_LIGHTS = 6; |
3555 | // LLVector3 cam_pos = gAgent.getCameraPositionAgent(); | 2782 | // LLVector3 cam_pos = gAgent.getCameraPositionAgent(); |
3556 | LLVector3 cam_pos = gAgent.getPositionAgent(); | 2783 | LLVector3 cam_pos = LLPipeline::sSkipUpdate || LLViewerJoystick::sOverrideCamera ? |
2784 | camera.getOrigin() : | ||
2785 | gAgent.getPositionAgent(); | ||
3557 | 2786 | ||
3558 | F32 max_dist = LIGHT_MAX_RADIUS * 4.f; // ignore enitrely lights > 4 * max light rad | 2787 | F32 max_dist = LIGHT_MAX_RADIUS * 4.f; // ignore enitrely lights > 4 * max light rad |
3559 | 2788 | ||
3560 | // UPDATE THE EXISTING NEARBY LIGHTS | 2789 | // UPDATE THE EXISTING NEARBY LIGHTS |
3561 | light_set_t cur_nearby_lights; | 2790 | if (!LLPipeline::sSkipUpdate) |
3562 | for (light_set_t::iterator iter = mNearbyLights.begin(); | ||
3563 | iter != mNearbyLights.end(); iter++) | ||
3564 | { | 2791 | { |
3565 | const Light* light = &(*iter); | 2792 | light_set_t cur_nearby_lights; |
3566 | LLDrawable* drawable = light->drawable; | 2793 | for (light_set_t::iterator iter = mNearbyLights.begin(); |
3567 | LLVOVolume* volight = drawable->getVOVolume(); | 2794 | iter != mNearbyLights.end(); iter++) |
3568 | if (!volight || !drawable->isState(LLDrawable::LIGHT)) | ||
3569 | { | ||
3570 | drawable->clearState(LLDrawable::NEARBY_LIGHT); | ||
3571 | continue; | ||
3572 | } | ||
3573 | if (light->fade <= -LIGHT_FADE_TIME) | ||
3574 | { | ||
3575 | drawable->clearState(LLDrawable::NEARBY_LIGHT); | ||
3576 | } | ||
3577 | else | ||
3578 | { | 2795 | { |
3579 | F32 dist = calc_light_dist(volight, cam_pos, max_dist); | 2796 | const Light* light = &(*iter); |
3580 | cur_nearby_lights.insert(Light(drawable, dist, light->fade)); | 2797 | LLDrawable* drawable = light->drawable; |
2798 | LLVOVolume* volight = drawable->getVOVolume(); | ||
2799 | if (!volight || !drawable->isState(LLDrawable::LIGHT)) | ||
2800 | { | ||
2801 | drawable->clearState(LLDrawable::NEARBY_LIGHT); | ||
2802 | continue; | ||
2803 | } | ||
2804 | if (light->fade <= -LIGHT_FADE_TIME) | ||
2805 | { | ||
2806 | drawable->clearState(LLDrawable::NEARBY_LIGHT); | ||
2807 | } | ||
2808 | else | ||
2809 | { | ||
2810 | F32 dist = calc_light_dist(volight, cam_pos, max_dist); | ||
2811 | cur_nearby_lights.insert(Light(drawable, dist, light->fade)); | ||
2812 | } | ||
3581 | } | 2813 | } |
2814 | mNearbyLights = cur_nearby_lights; | ||
3582 | } | 2815 | } |
3583 | mNearbyLights = cur_nearby_lights; | ||
3584 | 2816 | ||
3585 | // FIND NEW LIGHTS THAT ARE IN RANGE | 2817 | // FIND NEW LIGHTS THAT ARE IN RANGE |
3586 | light_set_t new_nearby_lights; | 2818 | light_set_t new_nearby_lights; |
@@ -3715,7 +2947,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) | |||
3715 | LLColor4 light_color = light->getLightColor(); | 2947 | LLColor4 light_color = light->getLightColor(); |
3716 | light_color.mV[3] = 0.0f; | 2948 | light_color.mV[3] = 0.0f; |
3717 | 2949 | ||
3718 | F32 fade = iter->fade; | 2950 | F32 fade = LLPipeline::sSkipUpdate ? 1.f : iter->fade; |
3719 | if (fade < LIGHT_FADE_TIME) | 2951 | if (fade < LIGHT_FADE_TIME) |
3720 | { | 2952 | { |
3721 | // fade in/out light | 2953 | // fade in/out light |
@@ -4261,257 +3493,6 @@ BOOL LLPipeline::getRenderSoundBeacons(void*) | |||
4261 | return sRenderSoundBeacons; | 3493 | return sRenderSoundBeacons; |
4262 | } | 3494 | } |
4263 | 3495 | ||
4264 | //=============================== | ||
4265 | // LLGLSL Shader implementation | ||
4266 | //=============================== | ||
4267 | LLGLSLShader::LLGLSLShader() | ||
4268 | : mProgramObject(0) | ||
4269 | { } | ||
4270 | |||
4271 | void LLGLSLShader::unload() | ||
4272 | { | ||
4273 | stop_glerror(); | ||
4274 | mAttribute.clear(); | ||
4275 | mTexture.clear(); | ||
4276 | mUniform.clear(); | ||
4277 | |||
4278 | if (mProgramObject) | ||
4279 | { | ||
4280 | GLhandleARB obj[1024]; | ||
4281 | GLsizei count; | ||
4282 | |||
4283 | glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj); | ||
4284 | for (GLsizei i = 0; i < count; i++) | ||
4285 | { | ||
4286 | glDeleteObjectARB(obj[i]); | ||
4287 | } | ||
4288 | |||
4289 | glDeleteObjectARB(mProgramObject); | ||
4290 | |||
4291 | mProgramObject = 0; | ||
4292 | } | ||
4293 | |||
4294 | //hack to make apple not complain | ||
4295 | glGetError(); | ||
4296 | |||
4297 | stop_glerror(); | ||
4298 | } | ||
4299 | |||
4300 | void LLGLSLShader::attachObject(GLhandleARB object) | ||
4301 | { | ||
4302 | if (object != 0) | ||
4303 | { | ||
4304 | stop_glerror(); | ||
4305 | glAttachObjectARB(mProgramObject, object); | ||
4306 | stop_glerror(); | ||
4307 | } | ||
4308 | else | ||
4309 | { | ||
4310 | llwarns << "Attempting to attach non existing shader object. " << llendl; | ||
4311 | } | ||
4312 | } | ||
4313 | |||
4314 | void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count) | ||
4315 | { | ||
4316 | for (S32 i = 0; i < count; i++) | ||
4317 | { | ||
4318 | attachObject(objects[i]); | ||
4319 | } | ||
4320 | } | ||
4321 | |||
4322 | BOOL LLGLSLShader::mapAttributes(const char** attrib_names, S32 count) | ||
4323 | { | ||
4324 | //link the program | ||
4325 | BOOL res = link(); | ||
4326 | |||
4327 | mAttribute.clear(); | ||
4328 | mAttribute.resize(LLPipeline::sReservedAttribCount + count, -1); | ||
4329 | |||
4330 | if (res) | ||
4331 | { //read back channel locations | ||
4332 | |||
4333 | //read back reserved channels first | ||
4334 | for (S32 i = 0; i < (S32) LLPipeline::sReservedAttribCount; i++) | ||
4335 | { | ||
4336 | const char* name = LLPipeline::sReservedAttribs[i]; | ||
4337 | S32 index = glGetAttribLocationARB(mProgramObject, name); | ||
4338 | if (index != -1) | ||
4339 | { | ||
4340 | mAttribute[i] = index; | ||
4341 | llinfos << "Attribute " << name << " assigned to channel " << index << llendl; | ||
4342 | } | ||
4343 | } | ||
4344 | |||
4345 | for (S32 i = 0; i < count; i++) | ||
4346 | { | ||
4347 | const char* name = attrib_names[i]; | ||
4348 | S32 index = glGetAttribLocationARB(mProgramObject, name); | ||
4349 | if (index != -1) | ||
4350 | { | ||
4351 | mAttribute[LLPipeline::sReservedAttribCount + i] = index; | ||
4352 | llinfos << "Attribute " << name << " assigned to channel " << index << llendl; | ||
4353 | } | ||
4354 | } | ||
4355 | |||
4356 | return TRUE; | ||
4357 | } | ||
4358 | |||
4359 | return FALSE; | ||
4360 | } | ||
4361 | |||
4362 | void LLGLSLShader::mapUniform(GLint index, const char** uniform_names, S32 count) | ||
4363 | { | ||
4364 | if (index == -1) | ||
4365 | { | ||
4366 | return; | ||
4367 | } | ||
4368 | |||
4369 | GLenum type; | ||
4370 | GLsizei length; | ||
4371 | GLint size; | ||
4372 | char name[1024]; /* Flawfinder: ignore */ | ||
4373 | name[0] = 0; | ||
4374 | |||
4375 | glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, name); | ||
4376 | |||
4377 | //find the index of this uniform | ||
4378 | for (S32 i = 0; i < (S32) LLPipeline::sReservedUniformCount; i++) | ||
4379 | { | ||
4380 | if (mUniform[i] == -1 && !strncmp(LLPipeline::sReservedUniforms[i],name, strlen(LLPipeline::sReservedUniforms[i]))) /* Flawfinder: ignore */ | ||
4381 | { | ||
4382 | //found it | ||
4383 | S32 location = glGetUniformLocationARB(mProgramObject, name); | ||
4384 | mUniform[i] = location; | ||
4385 | llinfos << "Uniform " << name << " is at location " << location << llendl; | ||
4386 | mTexture[i] = mapUniformTextureChannel(location, type); | ||
4387 | return; | ||
4388 | } | ||
4389 | } | ||
4390 | |||
4391 | for (S32 i = 0; i < count; i++) | ||
4392 | { | ||
4393 | if (mUniform[i+LLPipeline::sReservedUniformCount] == -1 && | ||
4394 | !strncmp(uniform_names[i],name, strlen(uniform_names[i]))) /* Flawfinder: ignore */ | ||
4395 | { | ||
4396 | //found it | ||
4397 | S32 location = glGetUniformLocationARB(mProgramObject, name); | ||
4398 | mUniform[i+LLPipeline::sReservedUniformCount] = location; | ||
4399 | llinfos << "Uniform " << name << " is at location " << location << " stored in index " << | ||
4400 | (i+LLPipeline::sReservedUniformCount) << llendl; | ||
4401 | mTexture[i+LLPipeline::sReservedUniformCount] = mapUniformTextureChannel(location, type); | ||
4402 | return; | ||
4403 | } | ||
4404 | } | ||
4405 | |||
4406 | //llinfos << "Unknown uniform: " << name << llendl; | ||
4407 | } | ||
4408 | |||
4409 | GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) | ||
4410 | { | ||
4411 | if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) | ||
4412 | { //this here is a texture | ||
4413 | glUniform1iARB(location, mActiveTextureChannels); | ||
4414 | llinfos << "Assigned to texture channel " << mActiveTextureChannels << llendl; | ||
4415 | return mActiveTextureChannels++; | ||
4416 | } | ||
4417 | return -1; | ||
4418 | } | ||
4419 | |||
4420 | BOOL LLGLSLShader::mapUniforms(const char** uniform_names, S32 count) | ||
4421 | { | ||
4422 | BOOL res = TRUE; | ||
4423 | |||
4424 | mActiveTextureChannels = 0; | ||
4425 | mUniform.clear(); | ||
4426 | mTexture.clear(); | ||
4427 | |||
4428 | //initialize arrays | ||
4429 | mUniform.resize(count + LLPipeline::sReservedUniformCount, -1); | ||
4430 | mTexture.resize(count + LLPipeline::sReservedUniformCount, -1); | ||
4431 | |||
4432 | |||
4433 | |||
4434 | bind(); | ||
4435 | |||
4436 | //get the number of active uniforms | ||
4437 | GLint activeCount; | ||
4438 | glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount); | ||
4439 | |||
4440 | for (S32 i = 0; i < activeCount; i++) | ||
4441 | { | ||
4442 | mapUniform(i, uniform_names, count); | ||
4443 | } | ||
4444 | |||
4445 | unbind(); | ||
4446 | |||
4447 | return res; | ||
4448 | } | ||
4449 | |||
4450 | BOOL LLGLSLShader::link(BOOL suppress_errors) | ||
4451 | { | ||
4452 | return gPipeline.linkProgramObject(mProgramObject, suppress_errors); | ||
4453 | } | ||
4454 | |||
4455 | void LLGLSLShader::bind() | ||
4456 | { | ||
4457 | glUseProgramObjectARB(mProgramObject); | ||
4458 | if (mAttribute.size() > 0) | ||
4459 | { | ||
4460 | gPipeline.mMaterialIndex = mAttribute[0]; | ||
4461 | } | ||
4462 | } | ||
4463 | |||
4464 | void LLGLSLShader::unbind() | ||
4465 | { | ||
4466 | for (U32 i = 0; i < mAttribute.size(); ++i) | ||
4467 | { | ||
4468 | vertexAttrib4f(i, 0,0,0,1); | ||
4469 | } | ||
4470 | glUseProgramObjectARB(0); | ||
4471 | } | ||
4472 | |||
4473 | S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode) | ||
4474 | { | ||
4475 | if (uniform < 0 || uniform >= (S32)mTexture.size()) | ||
4476 | { | ||
4477 | llerrs << "LLGLSLShader::enableTexture: uniform out of range: " << uniform << llendl; | ||
4478 | } | ||
4479 | S32 index = mTexture[uniform]; | ||
4480 | if (index != -1) | ||
4481 | { | ||
4482 | glActiveTextureARB(GL_TEXTURE0_ARB+index); | ||
4483 | glEnable(mode); | ||
4484 | } | ||
4485 | return index; | ||
4486 | } | ||
4487 | |||
4488 | S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode) | ||
4489 | { | ||
4490 | S32 index = mTexture[uniform]; | ||
4491 | if (index != -1) | ||
4492 | { | ||
4493 | glActiveTextureARB(GL_TEXTURE0_ARB+index); | ||
4494 | glDisable(mode); | ||
4495 | } | ||
4496 | return index; | ||
4497 | } | ||
4498 | |||
4499 | void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) | ||
4500 | { | ||
4501 | if (mAttribute[index] > 0) | ||
4502 | { | ||
4503 | glVertexAttrib4fARB(mAttribute[index], x, y, z, w); | ||
4504 | } | ||
4505 | } | ||
4506 | |||
4507 | void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v) | ||
4508 | { | ||
4509 | if (mAttribute[index] > 0) | ||
4510 | { | ||
4511 | glVertexAttrib4fvARB(mAttribute[index], v); | ||
4512 | } | ||
4513 | } | ||
4514 | |||
4515 | LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision) | 3496 | LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision) |
4516 | { | 3497 | { |
4517 | LLDrawable* drawable = mObjectPartition[PARTITION_VOLUME]->pickDrawable(start, end, collision); | 3498 | LLDrawable* drawable = mObjectPartition[PARTITION_VOLUME]->pickDrawable(start, end, collision); |
@@ -4647,6 +3628,14 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, | |||
4647 | glGenTextures(1, &blur_tex); | 3628 | glGenTextures(1, &blur_tex); |
4648 | } | 3629 | } |
4649 | 3630 | ||
3631 | BOOL reattach = FALSE; | ||
3632 | if (mCubeFrameBuffer == 0) | ||
3633 | { | ||
3634 | glGenFramebuffersEXT(1, &mCubeFrameBuffer); | ||
3635 | glGenRenderbuffersEXT(1, &mCubeDepth); | ||
3636 | reattach = TRUE; | ||
3637 | } | ||
3638 | |||
4650 | BOOL toggle_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); | 3639 | BOOL toggle_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); |
4651 | if (toggle_ui) | 3640 | if (toggle_ui) |
4652 | { | 3641 | { |
@@ -4663,6 +3652,7 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, | |||
4663 | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | | 3652 | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | |
4664 | //(1 << LLPipeline::RENDER_TYPE_STARS) | | 3653 | //(1 << LLPipeline::RENDER_TYPE_STARS) | |
4665 | //(1 << LLPipeline::RENDER_TYPE_AVATAR) | | 3654 | //(1 << LLPipeline::RENDER_TYPE_AVATAR) | |
3655 | (1 << LLPipeline::RENDER_TYPE_GLOW) | | ||
4666 | (1 << LLPipeline::RENDER_TYPE_GRASS) | | 3656 | (1 << LLPipeline::RENDER_TYPE_GRASS) | |
4667 | (1 << LLPipeline::RENDER_TYPE_VOLUME) | | 3657 | (1 << LLPipeline::RENDER_TYPE_VOLUME) | |
4668 | (1 << LLPipeline::RENDER_TYPE_TERRAIN) | | 3658 | (1 << LLPipeline::RENDER_TYPE_TERRAIN) | |
@@ -4694,11 +3684,45 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, | |||
4694 | 3684 | ||
4695 | LLVector3 origin = cube_cam.getOrigin(); | 3685 | LLVector3 origin = cube_cam.getOrigin(); |
4696 | 3686 | ||
4697 | gPipeline.calcNearbyLights(); | 3687 | gPipeline.calcNearbyLights(cube_cam); |
4698 | 3688 | ||
3689 | cube_map->bind(); | ||
4699 | for (S32 i = 0; i < 6; i++) | 3690 | for (S32 i = 0; i < 6; i++) |
4700 | { | 3691 | { |
3692 | GLint res_x, res_y; | ||
3693 | glGetTexLevelParameteriv(cube_face[i], 0, GL_TEXTURE_WIDTH, &res_x); | ||
3694 | glGetTexLevelParameteriv(cube_face[i], 0, GL_TEXTURE_HEIGHT, &res_y); | ||
3695 | |||
3696 | if (res_x != res || res_y != res) | ||
3697 | { | ||
3698 | glTexImage2D(cube_face[i],0,GL_RGBA,res,res,0,GL_RGBA,GL_FLOAT,NULL); | ||
3699 | reattach = TRUE; | ||
3700 | } | ||
3701 | } | ||
3702 | cube_map->disable(); | ||
3703 | |||
3704 | if (reattach) | ||
3705 | { | ||
3706 | glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mCubeDepth); | ||
3707 | GLint res_x, res_y; | ||
3708 | glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &res_x); | ||
3709 | glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_HEIGHT_EXT, &res_y); | ||
3710 | |||
3711 | if (res_x != res || res_y != res) | ||
3712 | { | ||
3713 | glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT24,res,res); | ||
3714 | } | ||
4701 | 3715 | ||
3716 | glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); | ||
3717 | } | ||
3718 | |||
3719 | for (S32 i = 0; i < 6; i++) | ||
3720 | { | ||
3721 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer); | ||
3722 | glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, | ||
3723 | cube_face[i], cube_map->getGLName(), 0); | ||
3724 | glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, | ||
3725 | GL_RENDERBUFFER_EXT, mCubeDepth); | ||
4702 | glMatrixMode(GL_PROJECTION); | 3726 | glMatrixMode(GL_PROJECTION); |
4703 | glLoadIdentity(); | 3727 | glLoadIdentity(); |
4704 | gluPerspective(90.f, 1.f, 0.1f, 1024.f); | 3728 | gluPerspective(90.f, 1.f, 0.1f, 1024.f); |
@@ -4707,7 +3731,6 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, | |||
4707 | 3731 | ||
4708 | apply_cube_face_rotation(i); | 3732 | apply_cube_face_rotation(i); |
4709 | 3733 | ||
4710 | |||
4711 | glTranslatef(-origin.mV[0], -origin.mV[1], -origin.mV[2]); | 3734 | glTranslatef(-origin.mV[0], -origin.mV[1], -origin.mV[2]); |
4712 | cube_cam.setOrigin(origin); | 3735 | cube_cam.setOrigin(origin); |
4713 | LLViewerCamera::updateFrustumPlanes(cube_cam); | 3736 | LLViewerCamera::updateFrustumPlanes(cube_cam); |
@@ -4715,18 +3738,15 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, | |||
4715 | gPipeline.updateCull(cube_cam); | 3738 | gPipeline.updateCull(cube_cam); |
4716 | gPipeline.stateSort(cube_cam); | 3739 | gPipeline.stateSort(cube_cam); |
4717 | 3740 | ||
4718 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 3741 | glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); |
4719 | gPipeline.renderGeom(cube_cam); | 3742 | gPipeline.renderGeom(cube_cam); |
4720 | |||
4721 | cube_map->enable(0); | ||
4722 | cube_map->bind(); | ||
4723 | glCopyTexImage2D(cube_face[i], 0, GL_RGB, 0, 0, res, res, 0); | ||
4724 | cube_map->disable(); | ||
4725 | } | 3743 | } |
4726 | 3744 | ||
3745 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | ||
3746 | |||
4727 | cube_cam.setOrigin(origin); | 3747 | cube_cam.setOrigin(origin); |
4728 | gPipeline.resetDrawOrders(); | 3748 | gPipeline.resetDrawOrders(); |
4729 | gPipeline.mShinyOrigin.setVec(cube_cam.getOrigin(), cube_cam.getFar()*2.f); | 3749 | gShinyOrigin.setVec(cube_cam.getOrigin(), cube_cam.getFar()*2.f); |
4730 | glMatrixMode(GL_PROJECTION); | 3750 | glMatrixMode(GL_PROJECTION); |
4731 | glPopMatrix(); | 3751 | glPopMatrix(); |
4732 | glMatrixMode(GL_MODELVIEW); | 3752 | glMatrixMode(GL_MODELVIEW); |
@@ -4740,14 +3760,12 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, | |||
4740 | { | 3760 | { |
4741 | gPipeline.toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); | 3761 | gPipeline.toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); |
4742 | } | 3762 | } |
4743 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||
4744 | LLDrawPoolWater::sSkipScreenCopy = FALSE; | 3763 | LLDrawPoolWater::sSkipScreenCopy = FALSE; |
4745 | } | 3764 | } |
4746 | 3765 | ||
4747 | //send cube map vertices and texture coordinates | 3766 | //send cube map vertices and texture coordinates |
4748 | void render_cube_map() | 3767 | void render_cube_map() |
4749 | { | 3768 | { |
4750 | |||
4751 | U32 idx[36]; | 3769 | U32 idx[36]; |
4752 | 3770 | ||
4753 | idx[0] = 1; idx[1] = 0; idx[2] = 2; //front | 3771 | idx[0] = 1; idx[1] = 0; idx[2] = 2; //front |
@@ -4794,7 +3812,7 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 | |||
4794 | { | 3812 | { |
4795 | LLGLEnable cube(GL_TEXTURE_CUBE_MAP_ARB); | 3813 | LLGLEnable cube(GL_TEXTURE_CUBE_MAP_ARB); |
4796 | LLGLDepthTest depth(GL_FALSE); | 3814 | LLGLDepthTest depth(GL_FALSE); |
4797 | 3815 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
4798 | glMatrixMode(GL_PROJECTION); | 3816 | glMatrixMode(GL_PROJECTION); |
4799 | glPushMatrix(); | 3817 | glPushMatrix(); |
4800 | glLoadIdentity(); | 3818 | glLoadIdentity(); |
@@ -4807,9 +3825,9 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 | |||
4807 | 3825 | ||
4808 | S32 kernel = 2; | 3826 | S32 kernel = 2; |
4809 | F32 step = 90.f/res; | 3827 | F32 step = 90.f/res; |
4810 | F32 alpha = 1.f/((kernel*2+1)); | 3828 | F32 alpha = 1.f/((kernel*2)+1); |
4811 | 3829 | ||
4812 | glColor4f(1,1,1,alpha); | 3830 | glColor4f(alpha,alpha,alpha,alpha*1.25f); |
4813 | 3831 | ||
4814 | S32 x = 0; | 3832 | S32 x = 0; |
4815 | 3833 | ||
@@ -4831,7 +3849,7 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 | |||
4831 | }; | 3849 | }; |
4832 | 3850 | ||
4833 | 3851 | ||
4834 | glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE); | 3852 | glBlendFunc(GL_ONE, GL_ONE); |
4835 | //3-axis blur | 3853 | //3-axis blur |
4836 | for (U32 j = 0; j < 3; j++) | 3854 | for (U32 j = 0; j < 3; j++) |
4837 | { | 3855 | { |
@@ -4863,7 +3881,7 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 | |||
4863 | } | 3881 | } |
4864 | for (U32 i = 0; i < 6; i++) | 3882 | for (U32 i = 0; i < 6; i++) |
4865 | { | 3883 | { |
4866 | glCopyTexImage2D(cube_face[i], 0, GL_RGB, 0, i*res, res, res, 0); | 3884 | glCopyTexImage2D(cube_face[i], 0, GL_RGBA, 0, i*res, res, res, 0); |
4867 | } | 3885 | } |
4868 | } | 3886 | } |
4869 | 3887 | ||
@@ -4873,6 +3891,158 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 | |||
4873 | glPopMatrix(); | 3891 | glPopMatrix(); |
4874 | 3892 | ||
4875 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 3893 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
3894 | glClear(GL_COLOR_BUFFER_BIT); | ||
3895 | } | ||
3896 | |||
3897 | void LLPipeline::bindScreenToTexture() | ||
3898 | { | ||
3899 | LLGLEnable gl_texture_2d(GL_TEXTURE_2D); | ||
3900 | |||
3901 | GLint* viewport = (GLint*) gGLViewport; | ||
3902 | GLuint resX = nhpo2(viewport[2]); | ||
3903 | GLuint resY = nhpo2(viewport[3]); | ||
3904 | |||
3905 | if (mScreenTex == 0) | ||
3906 | { | ||
3907 | glGenTextures(1, &mScreenTex); | ||
3908 | glBindTexture(GL_TEXTURE_2D, mScreenTex); | ||
3909 | |||
3910 | gImageList.updateMaxResidentTexMem(-1, resX*resY*3); | ||
3911 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, resX, resY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); | ||
3912 | |||
3913 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
3914 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
3915 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
3916 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
3917 | } | ||
3918 | |||
3919 | glBindTexture(GL_TEXTURE_2D, mScreenTex); | ||
3920 | GLint cResX; | ||
3921 | GLint cResY; | ||
3922 | glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &cResX); | ||
3923 | glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &cResY); | ||
3924 | |||
3925 | if (cResX != (GLint)resX || cResY != (GLint)resY) | ||
3926 | { | ||
3927 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, resX, resY, 0, GL_RGB, GL_FLOAT, NULL); | ||
3928 | gImageList.updateMaxResidentTexMem(-1, resX*resY*3); | ||
3929 | } | ||
3930 | |||
3931 | glCopyTexSubImage2D(GL_TEXTURE_2D, 0, viewport[0], viewport[1], 0, 0, viewport[2], viewport[3]); | ||
3932 | |||
3933 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
3934 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
3935 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
3936 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
3937 | |||
3938 | |||
3939 | mScreenScale.mV[0] = (float) viewport[2]/resX; | ||
3940 | mScreenScale.mV[1] = (float) viewport[3]/resY; | ||
3941 | |||
3942 | LLImageGL::sBoundTextureMemory += resX * resY * 3; | ||
4876 | } | 3943 | } |
4877 | 3944 | ||
3945 | void LLPipeline::renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res, LLVector2 tc1, LLVector2 tc2) | ||
3946 | { | ||
3947 | gGlowProgram.bind(); | ||
3948 | |||
3949 | LLGLEnable tex(GL_TEXTURE_2D); | ||
3950 | LLGLDepthTest depth(GL_FALSE); | ||
3951 | LLGLDisable blend(GL_BLEND); | ||
3952 | LLGLDisable cull(GL_CULL_FACE); | ||
3953 | |||
3954 | if (mFramebuffer[0] == 0) | ||
3955 | { | ||
3956 | glGenFramebuffersEXT(2, mFramebuffer); | ||
3957 | } | ||
3958 | |||
3959 | GLint viewport[4]; | ||
3960 | glGetIntegerv(GL_VIEWPORT, viewport); | ||
3961 | glViewport(0,0,res,res); | ||
3962 | |||
3963 | glMatrixMode(GL_PROJECTION); | ||
3964 | glPushMatrix(); | ||
3965 | glLoadIdentity(); | ||
3966 | glMatrixMode(GL_MODELVIEW); | ||
3967 | glPushMatrix(); | ||
3968 | glLoadIdentity(); | ||
3969 | |||
3970 | glBindTexture(GL_TEXTURE_2D, source); | ||
3971 | |||
3972 | S32 kernel = gSavedSettings.getS32("RenderGlowSize")*2; | ||
3973 | |||
3974 | LLGLDisable test(GL_ALPHA_TEST); | ||
3975 | |||
3976 | F32 delta = 1.f/(res*gSavedSettings.getF32("RenderGlowStrength")); | ||
3977 | |||
3978 | for (S32 i = 0; i < kernel; i++) | ||
3979 | { | ||
3980 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFramebuffer[i%2]); | ||
3981 | glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | ||
3982 | GL_COLOR_ATTACHMENT0_EXT, | ||
3983 | GL_TEXTURE_2D, | ||
3984 | i%2 == 0 ? buffer : dest, 0); | ||
3985 | |||
3986 | glBindTexture(GL_TEXTURE_2D, i == 0 ? source : | ||
3987 | i%2==0 ? dest : | ||
3988 | buffer); | ||
3989 | |||
3990 | glUniform1fARB(gGlowProgram.mUniform[LLShaderMgr::GLOW_DELTA],delta); | ||
3991 | |||
3992 | glBegin(GL_TRIANGLE_STRIP); | ||
3993 | glTexCoord2f(tc1.mV[0], tc1.mV[1]); | ||
3994 | glVertex2f(-1,-1); | ||
3995 | |||
3996 | glTexCoord2f(tc1.mV[0], tc2.mV[1]); | ||
3997 | glVertex2f(-1,1); | ||
3998 | |||
3999 | glTexCoord2f(tc2.mV[0], tc1.mV[1]); | ||
4000 | glVertex2f(1,-1); | ||
4001 | |||
4002 | glTexCoord2f(tc2.mV[0], tc2.mV[1]); | ||
4003 | glVertex2f(1,1); | ||
4004 | glEnd(); | ||
4005 | |||
4006 | tc1.setVec(0,0); | ||
4007 | tc2.setVec(1,1); | ||
4008 | |||
4009 | } | ||
4010 | |||
4011 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | ||
4012 | gGlowProgram.unbind(); | ||
4013 | |||
4014 | glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); | ||
4015 | |||
4016 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_GLOW)) | ||
4017 | { | ||
4018 | glClear(GL_COLOR_BUFFER_BIT); | ||
4019 | } | ||
4020 | |||
4021 | glBindTexture(GL_TEXTURE_2D, dest); | ||
4022 | { | ||
4023 | LLGLEnable blend(GL_BLEND); | ||
4024 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | ||
4025 | |||
4026 | glBegin(GL_TRIANGLE_STRIP); | ||
4027 | glColor4f(1,1,1,1); | ||
4028 | glTexCoord2f(tc1.mV[0], tc1.mV[1]); | ||
4029 | glVertex2f(-1,-1); | ||
4030 | |||
4031 | glTexCoord2f(tc1.mV[0], tc2.mV[1]); | ||
4032 | glVertex2f(-1,1); | ||
4033 | |||
4034 | glTexCoord2f(tc2.mV[0], tc1.mV[1]); | ||
4035 | glVertex2f(1,-1); | ||
4036 | |||
4037 | glTexCoord2f(tc2.mV[0], tc2.mV[1]); | ||
4038 | glVertex2f(1,1); | ||
4039 | glEnd(); | ||
4040 | |||
4041 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
4042 | } | ||
4878 | 4043 | ||
4044 | glMatrixMode(GL_PROJECTION); | ||
4045 | glPopMatrix(); | ||
4046 | glMatrixMode(GL_MODELVIEW); | ||
4047 | glPopMatrix(); | ||
4048 | } \ No newline at end of file | ||