Ejemplo n.º 1
0
WINGDIAPI HDC APIENTRY
wglGetCurrentDC( VOID )
{
   return stw_get_current_dc();
}
BOOL WINAPI
wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
{
   HDC prevDrawable = stw_get_current_dc();
   HDC prevReadable = stw_get_current_read_dc();
   HDC dc;
   struct stw_context *curctx = stw_current_context();
   struct stw_framebuffer *fb;
   GLenum texFormat, srcBuffer, target;
   boolean retVal;
   int pixelFormatSave;

   /*
    * Implementation notes:
    * Ideally, we'd implement this function with the
    * st_context_iface::teximage() function which replaces a specific
    * texture image with a different resource (the pbuffer).
    * The main problem however, is the pbuffer image is upside down relative
    * to the texture image.
    * Window system drawing surfaces (windows & pbuffers) are "top to bottom"
    * while OpenGL texture images are "bottom to top".  One possible solution
    * to this is to invert rendering to pbuffers (as we do for renderbuffers)
    * but that could lead to other issues (and would require extensive
    * testing).
    *
    * The simple alternative is to use a copy-based approach which copies the
    * pbuffer image into the texture via glCopyTex[Sub]Image.  That's what
    * we do here.
    */

   if (!curctx) {
      debug_printf("No rendering context in wglBindTexImageARB()\n");
      SetLastError(ERROR_INVALID_OPERATION);
      return FALSE;
   }

   fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
   if (!fb) {
      debug_printf("Invalid pbuffer handle in wglBindTexImageARB()\n");
      SetLastError(ERROR_INVALID_HANDLE);
      return FALSE;
   }

   srcBuffer = translate_ibuffer(iBuffer);
   if (srcBuffer == GL_NONE) {
      debug_printf("Invalid buffer 0x%x in wglBindTexImageARB()\n", iBuffer);
      SetLastError(ERROR_INVALID_DATA);
      return FALSE;
   }

   target = translate_target(fb->textureTarget);
   if (target == GL_NONE) {
      debug_printf("no texture target in wglBindTexImageARB()\n");
      return FALSE;
   }

   texFormat = translate_texture_format(fb->textureFormat);
   if (texFormat == GL_NONE) {
      debug_printf("no texture format in wglBindTexImageARB()\n");
      return FALSE;
   }

   /*
    * Bind the pbuffer surface so we can read/copy from it.
    *
    * Before we can call stw_make_current() we have to temporarily
    * change the pbuffer's pixel format to match the context to avoid
    * an error condition.  After the stw_make_current() we restore the
    * buffer's pixel format.
    */
   pixelFormatSave = fb->iPixelFormat;
   fb->iPixelFormat = curctx->iPixelFormat;
   dc = wglGetPbufferDCARB(hPbuffer);
   retVal = stw_make_current(dc, dc, curctx->dhglrc);
   fb->iPixelFormat = pixelFormatSave;
   if (!retVal) {
      debug_printf("stw_make_current(#1) failed in wglBindTexImageARB()\n");
      wglReleasePbufferDCARB(hPbuffer, dc);
      return FALSE;
   }

   st_copy_framebuffer_to_texture(srcBuffer, fb->width, fb->height,
                                  target, fb->textureLevel,
                                  fb->textureFace, texFormat);

   /* rebind previous drawing surface */
   retVal = stw_make_current(prevDrawable, prevReadable, curctx->dhglrc);
   if (!retVal) {
      debug_printf("stw_make_current(#2) failed in wglBindTexImageARB()\n");
   }

   wglReleasePbufferDCARB(hPbuffer, dc);

   return retVal;
}