diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llrender/llpostprocess.cpp | 109 |
1 files changed, 61 insertions, 48 deletions
diff --git a/linden/indra/llrender/llpostprocess.cpp b/linden/indra/llrender/llpostprocess.cpp index c884951..92a0854 100644 --- a/linden/indra/llrender/llpostprocess.cpp +++ b/linden/indra/llrender/llpostprocess.cpp | |||
@@ -4,7 +4,7 @@ | |||
4 | * | 4 | * |
5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | 5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ |
6 | * | 6 | * |
7 | * Copyright (c) 2007-2008, Linden Research, Inc. | 7 | * Copyright (c) 2007-2009, Linden Research, Inc. |
8 | * | 8 | * |
9 | * Second Life Viewer Source Code | 9 | * Second Life Viewer Source Code |
10 | * The source code in this file ("Source Code") is provided by Linden Lab | 10 | * The source code in this file ("Source Code") is provided by Linden Lab |
@@ -51,12 +51,14 @@ static const float LUMINANCE_B = 0.114f; | |||
51 | static const char * const XML_FILENAME = "postprocesseffects.xml"; | 51 | static const char * const XML_FILENAME = "postprocesseffects.xml"; |
52 | 52 | ||
53 | LLPostProcess::LLPostProcess(void) : | 53 | LLPostProcess::LLPostProcess(void) : |
54 | sceneRenderTexture(0), noiseTexture(0), | ||
55 | tempBloomTexture(0), | ||
56 | initialized(false), | 54 | initialized(false), |
57 | mAllEffects(LLSD::emptyMap()), | 55 | mAllEffects(LLSD::emptyMap()), |
58 | screenW(1), screenH(1) | 56 | screenW(1), screenH(1) |
59 | { | 57 | { |
58 | mSceneRenderTexture = NULL ; | ||
59 | mNoiseTexture = NULL ; | ||
60 | mTempBloomTexture = NULL ; | ||
61 | |||
60 | /* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender. | 62 | /* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender. |
61 | std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME)); | 63 | std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME)); |
62 | LL_DEBUGS2("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL; | 64 | LL_DEBUGS2("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL; |
@@ -110,9 +112,7 @@ LLPostProcess::LLPostProcess(void) : | |||
110 | 112 | ||
111 | LLPostProcess::~LLPostProcess(void) | 113 | LLPostProcess::~LLPostProcess(void) |
112 | { | 114 | { |
113 | glDeleteTextures(1, &sceneRenderTexture); | 115 | invalidate() ; |
114 | glDeleteTextures(1, &noiseTexture); | ||
115 | glDeleteTextures(1, &tempBloomTexture); | ||
116 | } | 116 | } |
117 | 117 | ||
118 | // static | 118 | // static |
@@ -157,6 +157,13 @@ void LLPostProcess::saveEffect(std::string const & effectName) | |||
157 | formatter->format(mAllEffects, effectsXML); | 157 | formatter->format(mAllEffects, effectsXML); |
158 | */ | 158 | */ |
159 | } | 159 | } |
160 | void LLPostProcess::invalidate() | ||
161 | { | ||
162 | mSceneRenderTexture = NULL ; | ||
163 | mNoiseTexture = NULL ; | ||
164 | mTempBloomTexture = NULL ; | ||
165 | initialized = FALSE ; | ||
166 | } | ||
160 | 167 | ||
161 | void LLPostProcess::apply(unsigned int width, unsigned int height) | 168 | void LLPostProcess::apply(unsigned int width, unsigned int height) |
162 | { | 169 | { |
@@ -172,7 +179,7 @@ void LLPostProcess::initialize(unsigned int width, unsigned int height) | |||
172 | { | 179 | { |
173 | screenW = width; | 180 | screenW = width; |
174 | screenH = height; | 181 | screenH = height; |
175 | createTexture(sceneRenderTexture, screenW, screenH); | 182 | createTexture(mSceneRenderTexture, screenW, screenH); |
176 | initialized = true; | 183 | initialized = true; |
177 | 184 | ||
178 | checkError(); | 185 | checkError(); |
@@ -198,16 +205,20 @@ void LLPostProcess::applyShaders(void) | |||
198 | } | 205 | } |
199 | if (tweaks.useNightVisionShader()){ | 206 | if (tweaks.useNightVisionShader()){ |
200 | /// If any of the above shaders have been called update the frame buffer; | 207 | /// If any of the above shaders have been called update the frame buffer; |
201 | if (tweaks.useColorFilter()){ | 208 | if (tweaks.useColorFilter()) |
202 | copyFrameBuffer(sceneRenderTexture, screenW, screenH); | 209 | { |
210 | GLuint tex = mSceneRenderTexture->getTexName() ; | ||
211 | copyFrameBuffer(tex, screenW, screenH); | ||
203 | } | 212 | } |
204 | applyNightVisionShader(); | 213 | applyNightVisionShader(); |
205 | checkError(); | 214 | checkError(); |
206 | } | 215 | } |
207 | if (tweaks.useBloomShader()){ | 216 | if (tweaks.useBloomShader()){ |
208 | /// If any of the above shaders have been called update the frame buffer; | 217 | /// If any of the above shaders have been called update the frame buffer; |
209 | if (tweaks.useColorFilter().asBoolean() || tweaks.useNightVisionShader().asBoolean()){ | 218 | if (tweaks.useColorFilter().asBoolean() || tweaks.useNightVisionShader().asBoolean()) |
210 | copyFrameBuffer(sceneRenderTexture, screenW, screenH); | 219 | { |
220 | GLuint tex = mSceneRenderTexture->getTexName() ; | ||
221 | copyFrameBuffer(tex, screenW, screenH); | ||
211 | } | 222 | } |
212 | applyBloomShader(); | 223 | applyBloomShader(); |
213 | checkError(); | 224 | checkError(); |
@@ -220,9 +231,9 @@ void LLPostProcess::applyColorFilterShader(void) | |||
220 | gPostColorFilterProgram.bind(); | 231 | gPostColorFilterProgram.bind(); |
221 | 232 | ||
222 | gGL.getTexUnit(0)->activate(); | 233 | gGL.getTexUnit(0)->activate(); |
223 | glEnable(GL_TEXTURE_RECTANGLE_ARB); | 234 | gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); |
224 | 235 | ||
225 | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, sceneRenderTexture); | 236 | gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, sceneRenderTexture); |
226 | 237 | ||
227 | getShaderUniforms(colorFilterUniforms, gPostColorFilterProgram.mProgramObject); | 238 | getShaderUniforms(colorFilterUniforms, gPostColorFilterProgram.mProgramObject); |
228 | glUniform1iARB(colorFilterUniforms["RenderTexture"], 0); | 239 | glUniform1iARB(colorFilterUniforms["RenderTexture"], 0); |
@@ -264,16 +275,16 @@ void LLPostProcess::applyNightVisionShader(void) | |||
264 | gPostNightVisionProgram.bind(); | 275 | gPostNightVisionProgram.bind(); |
265 | 276 | ||
266 | gGL.getTexUnit(0)->activate(); | 277 | gGL.getTexUnit(0)->activate(); |
267 | glEnable(GL_TEXTURE_RECTANGLE_ARB); | 278 | gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); |
268 | 279 | ||
269 | getShaderUniforms(nightVisionUniforms, gPostNightVisionProgram.mProgramObject); | 280 | getShaderUniforms(nightVisionUniforms, gPostNightVisionProgram.mProgramObject); |
270 | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, sceneRenderTexture); | 281 | gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, sceneRenderTexture); |
271 | glUniform1iARB(nightVisionUniforms["RenderTexture"], 0); | 282 | glUniform1iARB(nightVisionUniforms["RenderTexture"], 0); |
272 | 283 | ||
273 | gGL.getTexUnit(1)->activate(); | 284 | gGL.getTexUnit(1)->activate(); |
274 | glEnable(GL_TEXTURE_2D); | 285 | gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); |
275 | 286 | ||
276 | glBindTexture(GL_TEXTURE_2D, noiseTexture); | 287 | gGL.getTexUnit(1)->bindManual(LLTexUnit::TT_TEXTURE, noiseTexture); |
277 | glUniform1iARB(nightVisionUniforms["NoiseTexture"], 1); | 288 | glUniform1iARB(nightVisionUniforms["NoiseTexture"], 1); |
278 | 289 | ||
279 | 290 | ||
@@ -305,7 +316,7 @@ void LLPostProcess::createNightVisionShader(void) | |||
305 | nightVisionUniforms["noiseStrength"] = 0; | 316 | nightVisionUniforms["noiseStrength"] = 0; |
306 | nightVisionUniforms["lumWeights"] = 0; | 317 | nightVisionUniforms["lumWeights"] = 0; |
307 | 318 | ||
308 | createNoiseTexture(noiseTexture); | 319 | createNoiseTexture(mNoiseTexture); |
309 | } | 320 | } |
310 | 321 | ||
311 | void LLPostProcess::applyBloomShader(void) | 322 | void LLPostProcess::applyBloomShader(void) |
@@ -315,7 +326,7 @@ void LLPostProcess::applyBloomShader(void) | |||
315 | 326 | ||
316 | void LLPostProcess::createBloomShader(void) | 327 | void LLPostProcess::createBloomShader(void) |
317 | { | 328 | { |
318 | createTexture(tempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5)); | 329 | createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5)); |
319 | 330 | ||
320 | /// Create Bloom Extract Shader | 331 | /// Create Bloom Extract Shader |
321 | bloomExtractUniforms["RenderTexture"] = 0; | 332 | bloomExtractUniforms["RenderTexture"] = 0; |
@@ -347,7 +358,10 @@ void LLPostProcess::doEffects(void) | |||
347 | glPushClientAttrib(GL_ALL_ATTRIB_BITS); | 358 | glPushClientAttrib(GL_ALL_ATTRIB_BITS); |
348 | 359 | ||
349 | /// Copy the screen buffer to the render texture | 360 | /// Copy the screen buffer to the render texture |
350 | copyFrameBuffer(sceneRenderTexture, screenW, screenH); | 361 | { |
362 | GLuint tex = mSceneRenderTexture->getTexName() ; | ||
363 | copyFrameBuffer(tex, screenW, screenH); | ||
364 | } | ||
351 | 365 | ||
352 | /// Clear the frame buffer. | 366 | /// Clear the frame buffer. |
353 | glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | 367 | glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
@@ -373,7 +387,7 @@ void LLPostProcess::doEffects(void) | |||
373 | 387 | ||
374 | void LLPostProcess::copyFrameBuffer(GLuint & texture, unsigned int width, unsigned int height) | 388 | void LLPostProcess::copyFrameBuffer(GLuint & texture, unsigned int width, unsigned int height) |
375 | { | 389 | { |
376 | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); | 390 | gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture); |
377 | glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, width, height, 0); | 391 | glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, width, height, 0); |
378 | } | 392 | } |
379 | 393 | ||
@@ -478,43 +492,42 @@ void LLPostProcess::changeOrthogonal(unsigned int width, unsigned int height) | |||
478 | viewOrthogonal(width, height); | 492 | viewOrthogonal(width, height); |
479 | } | 493 | } |
480 | 494 | ||
481 | void LLPostProcess::createTexture(GLuint & texture, unsigned int width, unsigned int height) | 495 | void LLPostProcess::createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height) |
482 | { | 496 | { |
483 | if (texture != 0){ | 497 | std::vector<GLubyte> data(width * height * 4, 0) ; |
484 | glDeleteTextures(1, &texture); | ||
485 | } | ||
486 | 498 | ||
487 | std::vector<GLubyte> data(width * height * 4, 0); | 499 | texture = new LLImageGL(FALSE) ; |
488 | 500 | if(texture->createGLTexture()) | |
489 | glGenTextures(1, &texture); | 501 | { |
490 | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); | 502 | gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture->getTexName()); |
491 | glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0, | 503 | glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0, |
492 | GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); | 504 | GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); |
493 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_LINEAR); | 505 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_LINEAR); |
494 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,GL_LINEAR); | 506 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,GL_LINEAR); |
495 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 507 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
496 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 508 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
497 | } | ||
498 | |||
499 | void LLPostProcess::createNoiseTexture(GLuint & texture) | ||
500 | { | ||
501 | if (texture != 0){ | ||
502 | glDeleteTextures(1, &texture); | ||
503 | } | 509 | } |
504 | glGenTextures(1, &texture); | 510 | } |
505 | 511 | ||
512 | void LLPostProcess::createNoiseTexture(LLPointer<LLImageGL>& texture) | ||
513 | { | ||
506 | std::vector<GLubyte> buffer(NOISE_SIZE * NOISE_SIZE); | 514 | std::vector<GLubyte> buffer(NOISE_SIZE * NOISE_SIZE); |
507 | for (unsigned int i = 0; i < NOISE_SIZE; i++){ | 515 | for (unsigned int i = 0; i < NOISE_SIZE; i++){ |
508 | for (unsigned int k = 0; k < NOISE_SIZE; k++){ | 516 | for (unsigned int k = 0; k < NOISE_SIZE; k++){ |
509 | buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f); | 517 | buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f); |
510 | } | 518 | } |
511 | } | 519 | } |
512 | glBindTexture(GL_TEXTURE_2D, texture); | 520 | |
513 | glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]); | 521 | texture = new LLImageGL(FALSE) ; |
514 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); | 522 | if(texture->createGLTexture()) |
515 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR); | 523 | { |
516 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | 524 | gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName()); |
517 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | 525 | glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]); |
526 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); | ||
527 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR); | ||
528 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | ||
529 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | ||
530 | } | ||
518 | } | 531 | } |
519 | 532 | ||
520 | bool LLPostProcess::checkError(void) | 533 | bool LLPostProcess::checkError(void) |