⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rendertexture.cpp

📁 PDE simulator on GPU.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  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 + -