diff options
Diffstat (limited to 'indra/llrender/llrendertarget.cpp')
-rw-r--r-- | indra/llrender/llrendertarget.cpp | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp new file mode 100644 index 0000000000..c082b93164 --- /dev/null +++ b/indra/llrender/llrendertarget.cpp @@ -0,0 +1,185 @@ +/** + * @file llrendertarget.cpp + * @brief LLRenderTarget implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llrendertarget.h" +#include "llglimmediate.h" + + +BOOL LLRenderTarget::sUseFBO = FALSE; + +LLRenderTarget::LLRenderTarget() +{ + mResX = mResY = mTex = mFBO = mDepth = 0; + mUseDepth = FALSE; + mUsage = GL_TEXTURE_2D; +} + +LLRenderTarget::~LLRenderTarget() +{ + release(); +} + +void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage, BOOL force_fbo) +{ + mResX = resx; + mResY = resy; + + mUsage = usage; + mUseDepth = depth; + release(); + + glGenTextures(1, (GLuint *) &mTex); + glBindTexture(mUsage, mTex); + glTexImage2D(mUsage, 0, color_fmt, mResX, mResY, 0, color_fmt, GL_UNSIGNED_BYTE, NULL); + + glTexParameteri(mUsage, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(mUsage, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + if (mUsage != GL_TEXTURE_RECTANGLE_ARB) + { + glTexParameteri(mUsage, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTexParameteri(mUsage, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + } + else + { + // ATI doesn't support mirrored repeat for rectangular textures. + glTexParameteri(mUsage, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(mUsage, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + stop_glerror(); + + if (sUseFBO || force_fbo) + { + if (depth) + { + glGenRenderbuffersEXT(1, (GLuint *) &mDepth); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepth); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT,mResX,mResY); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + + glGenFramebuffersEXT(1, (GLuint *) &mFBO); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); + + if (mDepth) + { + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, mDepth); + } + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + mUsage, mTex, 0); + + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } +} + +void LLRenderTarget::release() +{ + if (mFBO) + { + glDeleteFramebuffersEXT(1, (GLuint *) &mFBO); + mFBO = 0; + } + + if (mTex) + { + glDeleteTextures(1, (GLuint *) &mTex); + mTex = 0; + } + + if (mDepth) + { + glDeleteRenderbuffersEXT(1, (GLuint *) &mDepth); + mDepth = 0; + } +} + +void LLRenderTarget::bindTarget() +{ + if (mFBO) + { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); + } + + glViewport(0, 0, mResX, mResY); +} + +void LLRenderTarget::clear() +{ + U32 mask = GL_COLOR_BUFFER_BIT; + if (mUseDepth) + { + mask |= GL_DEPTH_BUFFER_BIT; + } + if (mFBO) + { + glClear(mask); + } + else + { + LLGLEnable scissor(GL_SCISSOR_TEST); + glScissor(0, 0, mResX, mResY); + glClear(mask); + } +} + +void LLRenderTarget::bindTexture() +{ + glBindTexture(mUsage, mTex); +} + +void LLRenderTarget::flush() +{ + gGL.flush(); + if (!mFBO) + { + bindTexture(); + glCopyTexSubImage2D(mUsage, 0, 0, 0, 0, 0, mResX, mResY); + } +} + +BOOL LLRenderTarget::isComplete() const +{ + return (mTex || mDepth) ? TRUE : FALSE; +} + +void LLRenderTarget::getViewport(S32* viewport) +{ + viewport[0] = 0; + viewport[1] = 0; + viewport[2] = mResX; + viewport[3] = mResY; +} + |