📄 rendertexture.cpp
字号:
wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_WIDTH_ARB, &_iWidth );
wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &_iHeight );
_bInitialized = true;
// get the actual number of bits allocated:
int attrib = WGL_RED_BITS_ARB;
int value;
_iBits[0] = (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) ? value : iRBits;
attrib = WGL_GREEN_BITS_ARB;
_iBits[1] = (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) ? value : iGBits;
attrib = WGL_BLUE_BITS_ARB;
_iBits[2] = (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) ? value : iBBits;
attrib = WGL_ALPHA_BITS_ARB;
_iBits[3] = (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) ? value : iABits;
attrib = WGL_DEPTH_BITS_ARB;
_iBits[4] = (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) ? value : 0;
attrib = WGL_STENCIL_BITS_ARB;
_iBits[5] = (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) ? value : 0;
#if defined(_DEBUG) | defined(DEBUG)
fprintf(stderr, "Created a %dx%d RenderTexture with BPP(%d, %d, %d, %d)",
_iWidth, _iHeight, _iBits[0], _iBits[1], _iBits[2], _iBits[3]);
if (_iBits[4]) fprintf(stderr, " depth=%d", _iBits[4]);
if (_iBits[5]) fprintf(stderr, " stencil=%d", _iBits[5]);
fprintf(stderr, "\n");
#endif
#else
_pDpy = glXGetCurrentDisplay();
GLXContext context = glXGetCurrentContext();
int screen = DefaultScreen(_pDpy);
XVisualInfo *visInfo;
int iFormat = 0;
int iNumFormats;
int fbAttribs[50];
int attrib = 0;
fbAttribs[attrib++] = GLX_RENDER_TYPE_SGIX;
fbAttribs[attrib++] = GLX_RGBA_BIT_SGIX;
fbAttribs[attrib++] = GLX_DRAWABLE_TYPE_SGIX;
fbAttribs[attrib++] = GLX_PBUFFER_BIT_SGIX;
fbAttribs[attrib++] = GLX_STENCIL_SIZE;
fbAttribs[attrib++] = (bStencil) ? 8 : 0;
fbAttribs[attrib++] = GLX_DEPTH_SIZE;
fbAttribs[attrib++] = (bDepth) ? 24 : 0;
if (_bFloat)
{
fbAttribs[attrib++] = GLX_RED_SIZE;
fbAttribs[attrib++] = iRBits;
fbAttribs[attrib++] = GLX_GREEN_SIZE;
fbAttribs[attrib++] = iGBits;
fbAttribs[attrib++] = GLX_BLUE_SIZE;
fbAttribs[attrib++] = iBBits;
fbAttribs[attrib++] = GLX_ALPHA_SIZE;
fbAttribs[attrib++] = iABits;
fbAttribs[attrib++] = GLX_FLOAT_COMPONENTS_NV;
fbAttribs[attrib++] = 1;
}
fbAttribs[attrib++] = None;
GLXFBConfigSGIX *fbConfigs;
int nConfigs;
fbConfigs = glXChooseFBConfigSGIX(_pDpy, screen, fbAttribs, &nConfigs);
if (nConfigs == 0 || !fbConfigs) {
fprintf(stderr,
"RenderTexture::Initialize() creation error: Couldn't find a suitable pixel format\n");
return false;
}
// Pick the first returned format that will return a pbuffer
for (int i=0;i<nConfigs;i++)
{
_hPBuffer = glXCreateGLXPbufferSGIX(_pDpy, fbConfigs[i], _iWidth, _iHeight, NULL);
if (_hPBuffer) {
_hGLContext = glXCreateContextWithConfigSGIX(_pDpy, fbConfigs[i], GLX_RGBA_TYPE, bShare?context:NULL, True);
break;
}
}
if (!_hPBuffer)
{
fprintf(stderr, "RenderTexture::Initialize() pbuffer creation error: glXCreateGLXPbufferSGIX() failed\n");
return false;
}
if(!_hGLContext)
{
// Try indirect
_hGLContext = glXCreateContext(_pDpy, visInfo, bShare?context:NULL, False);
if ( !_hGLContext )
{
fprintf(stderr, "RenderTexture::Initialize() creation error: glXCreateContext() failed\n");
return false;
}
}
glXQueryGLXPbufferSGIX(_pDpy, _hPBuffer, GLX_WIDTH_SGIX, (GLuint*)&_iWidth);
glXQueryGLXPbufferSGIX(_pDpy, _hPBuffer, GLX_HEIGHT_SGIX, (GLuint*)&_iHeight);
_bInitialized = true;
// XXX Query the color format
#endif
return true;
}
//------------------------------------------------------------------------------
// Function : RenderTexture::_Invalidate
// Description :
//------------------------------------------------------------------------------
/**
* @fn RenderTexture::_Invalidate()
* @brief Returns the pbuffer memory to the graphics device.
*
*/
bool RenderTexture::_Invalidate()
{
_bFloat = false;
_bRectangle = false;
_bInitialized = false;
_bHasDepth = false;
_bHasStencil = false;
_bMipmap = false;
_bAnisoFilter = false;
_iBits[0] = _iBits[1] = _iBits[2] = _iBits[3] = 0;
if (_bIsTexture)
glDeleteTextures(1, &_iTextureID);
if (_bIsDepthTexture) {
// [Redge]
if (!_bHasArbDepthTexture) delete[] _pPoorDepthTexture;
// [/Redge]
glDeleteTextures(1, &_iDepthTextureID);
}
#if _WIN32
if ( _hPBuffer )
{
// Check if we are currently rendering in the pbuffer
if (wglGetCurrentContext() == _hGLContext)
wglMakeCurrent(0,0);
wglDeleteContext( _hGLContext);
wglReleasePbufferDCARB( _hPBuffer, _hDC);
wglDestroyPbufferARB( _hPBuffer );
_hPBuffer = 0;
return true;
}
#else
if ( _hPBuffer )
{
if(glXGetCurrentContext() == _hGLContext)
// XXX I don't know if this is right at all
glXMakeCurrent(_pDpy, _hPBuffer, 0);
glXDestroyGLXPbufferSGIX(_pDpy, _hPBuffer);
_hPBuffer = 0;
return true;
}
#endif
return false;
}
//------------------------------------------------------------------------------
// Function : RenderTexture::Reset
// Description :
//------------------------------------------------------------------------------
/**
* @fn RenderTexture::Reset(int iWidth, int iHeight, unsigned int iMode, bool bIsTexture, bool bIsDepthTexture)
* @brief Resets the resolution of the offscreen buffer.
*
* Causes the buffer to delete itself. User must call Initialize() again
* before use.
*/
bool RenderTexture::Reset(int iWidth, int iHeight, bool bIsTexture /* = true */,
bool bIsDepthTexture /* = false */)
{
if (!_Invalidate())
{
fprintf(stderr, "RenderTexture::Reset(): failed to invalidate.\n");
return false;
}
_iWidth = iWidth;
_iHeight = iHeight;
_bIsTexture = bIsTexture;
_bIsDepthTexture = bIsDepthTexture;
return true;
}
//------------------------------------------------------------------------------
// Function : RenderTexture::BeginCapture
// Description :
//------------------------------------------------------------------------------
/**
* @fn RenderTexture::BeginCapture()
* @brief Activates rendering to the RenderTexture.
*/
bool RenderTexture::BeginCapture()
{
if (!_bInitialized)
{
fprintf(stderr, "RenderTexture::BeginCapture(): Texture is not initialized!\n");
exit(1);
return false;
}
#ifdef _WIN32
// cache the current context so we can reset it when EndCapture() is called.
_hPreviousDC = wglGetCurrentDC();
if (NULL == _hPreviousDC)
_wglGetLastError();
_hPreviousContext = wglGetCurrentContext();
if (NULL == _hPreviousContext)
_wglGetLastError();
if (_bIsTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
{
glBindTexture(_iTextureTarget, _iTextureID);
// release the pbuffer from the render texture object
if (FALSE == wglReleaseTexImageARB(_hPBuffer, WGL_FRONT_LEFT_ARB))
{
_wglGetLastError();
return false;
}
}
if (_bIsDepthTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
{
glBindTexture(_iTextureTarget, _iDepthTextureID);
// release the pbuffer from the render texture object
if (FALSE == wglReleaseTexImageARB(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
{
_wglGetLastError();
return false;
}
}
// make the pbuffer's rendering context current.
if (FALSE == wglMakeCurrent( _hDC, _hGLContext))
{
_wglGetLastError();
return false;
}
#else
_hPreviousContext = glXGetCurrentContext();
_hPreviousDrawable = glXGetCurrentDrawable();
if (False == glXMakeCurrent(_pDpy, _hPBuffer, _hGLContext)) {
return false;
}
#endif
return true;
}
//------------------------------------------------------------------------------
// Function : RenderTexture::EndCapture
// Description :
//------------------------------------------------------------------------------
/**
* @fn RenderTexture::EndCapture()
* @brief Ends rendering to the RenderTexture.
*/
bool RenderTexture::EndCapture()
{
bool bContextReset = false;
if (!_bInitialized)
{
fprintf(stderr, "RenderTexture::EndCapture(): Texture is not initialized!\n");
return false;
}
#ifdef _WIN32
if (_bIsTexture)
{
if (RT_RENDER_TO_TEXTURE == _eUpdateMode)
{
// make the previous rendering context current
if (FALSE == wglMakeCurrent( _hPreviousDC, _hPreviousContext))
{
_wglGetLastError();
return false;
}
bContextReset = true;
// [Redge] moved binding completely to Bind()
// [Mark] Can't do that, because it makes things difficult for Cg users.
// bind the pbuffer to the render texture object
glBindTexture(_iTextureTarget, _iTextureID);
if (FALSE == wglBindTexImageARB(_hPBuffer, WGL_FRONT_LEFT_ARB))
{
_wglGetLastError();
return false;
}
}
else
{
glBindTexture(_iTextureTarget, _iTextureID);
glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
}
}
if (_bIsDepthTexture)
{
if (RT_RENDER_TO_TEXTURE == _eUpdateMode)
{
// make the previous rendering context current
if(!bContextReset)
{
if (FALSE == wglMakeCurrent( _hPreviousDC, _hPreviousContext))
{
_wglGetLastError();
return false;
}
bContextReset = true;
}
// [Redge] moved binding completely to Bind()
// [Mark] Can't do that, because it makes things difficult for Cg users.
// bind the pbuffer to the render texture object
glBindTexture(_iTextureTarget, _iDepthTextureID);
if (FALSE == wglBindTexImageARB(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
{
_wglGetLastError();
return false;
}
}
else
{
glBindTexture(_iTextureTarget, _iDepthTextureID);
// HOW TO COPY DEPTH TEXTURE??? Supposedly this just magically works...
// [Redge]
if (_bHasArbDepthTexture)
{
glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
}
else
{
// no 'real' depth texture available, so behavior has to be emulated
// using glReadPixels (beware, this is (naturally) slow ...)
glReadPixels(0, 0, _iWidth, _iHeight,
GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, _pPoorDepthTexture);
glTexImage2D(_iTextureTarget, 0, GL_LUMINANCE16,
_iWidth, _iHeight,
0, GL_LUMINANCE, GL_UNSIGNED_SHORT, _pPoorDepthTexture);
}
// [/Redge]
}
}
if(!bContextReset)
{
// make the previous rendering context current
if (FALSE == wglMakeCurrent( _hPreviousDC, _hPreviousContext))
{
_wglGetLastError();
return false;
}
}
#else
assert(_bIsTexture);
glBindTexture(_iTextureTarget, _iTextureID);
glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
if(!bContextReset)
{
if (False == glXMakeCurrent(_pDpy, _hPreviousDrawable, _hPreviousContext))
{
return false;
}
}
#endif
return true;
}
//------------------------------------------------------------------------------
// Function : RenderTexture::Bind
// Description :
//------------------------------------------------------------------------------
/**
* @fn RenderTexture::Bind()
* @brief Binds RGB texture.
*/
void RenderTexture::Bind() const
{
if (_bInitialized) {
glBindTexture(_iTextureTarget, _iTextureID);
}
}
//------------------------------------------------------------------------------
// Function : RenderTexture::BindDepth
// Description :
//------------------------------------------------------------------------------
/**
* @fn RenderTexture::BindDepth()
* @brief Binds depth texture.
*/
void RenderTexture::BindDepth() const
{
if (_bInitialized && _bIsDepthTexture) {
glBindTexture(_iTextureTarget, _iDepthTextureID);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -