Implemented IWineD3DDevice_GetRenderTargetData.
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index a820c72..90a9597 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4579,8 +4579,78 @@
}
HRESULT WINAPI IWineD3DDeviceImpl_GetRenderTargetData(IWineD3DDevice *iface, IWineD3DSurface *pRenderTarget, IWineD3DSurface *pSurface) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+ /** TODO: remove remove casts to IWineD3DSurfaceImpl *
+ * NOTE It may be best to move the code into surface to occomplish this
+ ****************************************/
- TRACE("(%p) : stub\n", This);
+ WINED3DSURFACE_DESC surfaceDesc;
+ unsigned int surfaceWidth, surfaceHeight;
+ glDescriptor *targetGlDescription = NULL;
+ glDescriptor *surfaceGlDescription = NULL;
+ IWineD3DSwapChainImpl *container = NULL;
+
+ IWineD3DSurface_GetGlDesc(pRenderTarget, &targetGlDescription);
+ IWineD3DSurface_GetGlDesc(pSurface, &surfaceGlDescription);
+ memset(&surfaceDesc, 0, sizeof(surfaceDesc));
+
+ surfaceDesc.Width = &surfaceWidth;
+ surfaceDesc.Height = &surfaceHeight;
+ IWineD3DSurface_GetDesc(pSurface, &surfaceDesc);
+ /* check to see if it's the backbuffer or the frontbuffer being requested (to make sureteh data is upto date)*/
+
+ /* Ok, I may need to setup some kind of active swapchain reference on the device */
+ IWineD3DSurface_GetContainer(pRenderTarget, &IID_IWineD3DSwapChain, (void **)&container);
+ ENTER_GL();
+ /* TODO: opengl Context switching for swapchains etc... */
+ if (NULL != container || pRenderTarget == This->renderTarget || pRenderTarget == This->depthStencilBuffer) {
+ if (NULL != container && (pRenderTarget == container->backBuffer)) {
+ glReadBuffer(GL_BACK);
+ vcheckGLcall("glReadBuffer(GL_BACK)");
+ } else if ((NULL != container && (pRenderTarget == container->frontBuffer)) || (pRenderTarget == This->renderTarget)) {
+ glReadBuffer(GL_FRONT);
+ vcheckGLcall("glReadBuffer(GL_FRONT)");
+ } else if (pRenderTarget == This->depthStencilBuffer) {
+ FIXME("Reading of depthstencil not yet supported\n");
+ }
+
+ glReadPixels(surfaceGlDescription->target,
+ surfaceGlDescription->level,
+ surfaceWidth,
+ surfaceHeight,
+ surfaceGlDescription->glFormat,
+ surfaceGlDescription->glType,
+ (void *)IWineD3DSurface_GetData(pSurface));
+ vcheckGLcall("glReadPixels(...)");
+ if(NULL != container ){
+ IWineD3DSwapChain_Release((IWineD3DSwapChain*) container);
+ }
+ } else {
+ IWineD3DBaseTexture *container;
+ GLenum textureDimensions = GL_TEXTURE_2D;
+
+ if (D3D_OK == IWineD3DSurface_GetContainer(pSurface, &IID_IWineD3DBaseTexture, (void **)&container)) {
+ textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(container);
+ IWineD3DBaseTexture_Release(container);
+ }
+ /* TODO: 2D -> Cube surface coppies etc.. */
+ if (surfaceGlDescription->target != textureDimensions) {
+ FIXME("(%p) : Texture dimension mismatch\n", This);
+ }
+ glEnable(textureDimensions);
+ vcheckGLcall("glEnable(GL_TEXTURE_...)");
+ /* FIXME: this isn't correct, it need to add a dirty rect if nothing else... */
+ glBindTexture(targetGlDescription->target, targetGlDescription->textureName);
+ vcheckGLcall("glBindTexture");
+ glGetTexImage(surfaceGlDescription->target,
+ surfaceGlDescription->level,
+ surfaceGlDescription->glFormat,
+ surfaceGlDescription->glType,
+ (void *)IWineD3DSurface_GetData(pSurface));
+ glDisable(textureDimensions);
+ vcheckGLcall("glDisable(GL_TEXTURE_...)");
+
+ }
+ LEAVE_GL();
return D3D_OK;
}