Authors: Christian Costa <titan.costa@wanadoo.fr>, Jason Edmeades <us@the-edmeades.demon.co.uk>

Fixes for rendering targets.
This commit is contained in:
Alexandre Julliard 2004-05-02 04:22:31 +00:00
parent 73d8c97f12
commit ac7b9451f7
4 changed files with 29 additions and 21 deletions

View File

@ -1,7 +1,8 @@
/* /*
* IDirect3DDevice8 implementation * IDirect3DDevice8 implementation
* *
* Copyright 2002 Jason Edmeades * Copyright 2002-2004 Jason Edmeades
* Copyright 2004 Christian Costa
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -1169,7 +1170,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, ID
ICOM_THIS(IDirect3DDevice8Impl,iface); ICOM_THIS(IDirect3DDevice8Impl,iface);
FIXME("(%p) : see if behavior correct\n", This); FIXME("(%p) : Should return whole screen, only returns GL context window in top left corner\n", This);
if (D3DFMT_A8R8G8B8 != ((IDirect3DSurface8Impl*) pDestSurface)->myDesc.Format) { if (D3DFMT_A8R8G8B8 != ((IDirect3DSurface8Impl*) pDestSurface)->myDesc.Format) {
ERR("(%p) : surface(%p) have a invalid format\n", This, pDestSurface); ERR("(%p) : surface(%p) have a invalid format\n", This, pDestSurface);
@ -1204,7 +1205,6 @@ HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, ID
{ {
long j; long j;
for (j = 0; j < This->PresentParms.BackBufferHeight; ++j) { for (j = 0; j < This->PresentParms.BackBufferHeight; ++j) {
/*memcpy(lockedRect.pBits + (j * lockedRect.Pitch), This->frontBuffer->allocatedMemory + (j * i), i);*/
glReadPixels(0, This->PresentParms.BackBufferHeight - j - 1, This->PresentParms.BackBufferWidth, 1, glReadPixels(0, This->PresentParms.BackBufferHeight - j - 1, This->PresentParms.BackBufferWidth, 1,
GL_BGRA, GL_UNSIGNED_BYTE, ((char*) lockedRect.pBits) + (j * lockedRect.Pitch)); GL_BGRA, GL_UNSIGNED_BYTE, ((char*) lockedRect.pBits) + (j * lockedRect.Pitch));
vcheckGLcall("glReadPixels"); vcheckGLcall("glReadPixels");
@ -1261,7 +1261,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, I
HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) { HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
ICOM_THIS(IDirect3DDevice8Impl,iface); ICOM_THIS(IDirect3DDevice8Impl,iface);
TRACE("(%p)->(%p) default(%p)\n", This, This->renderTarget, This->frontBuffer); TRACE("(%p)->returning (%p) default is backbuffer=(%p)\n", This, This->renderTarget, This->backBuffer);
*ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget; *ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget); IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
@ -1303,12 +1303,12 @@ HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
getchar(); getchar();
#endif #endif
if (This->frontBuffer != This->renderTarget) { if ((This->frontBuffer != This->renderTarget) && (This->backBuffer != This->renderTarget)) {
#if 0 #if 0
GLenum prev_read; GLenum prev_read;
glGetIntegerv(GL_READ_BUFFER, &prev_read); glGetIntegerv(GL_READ_BUFFER, &prev_read);
vcheckGLcall("glIntegerv"); vcheckGLcall("glIntegerv");
glReadBuffer(GL_BACK); glReadBuffer(GL_FRONT);
vcheckGLcall("glReadBuffer"); vcheckGLcall("glReadBuffer");
{ {
long j; long j;
@ -1413,14 +1413,14 @@ HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count
/* Note gl uses lower left, width/height */ /* Note gl uses lower left, width/height */
TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect, TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
curRect->x1, curRect->y1, curRect->x2, curRect->y2, curRect->x1, curRect->y1, curRect->x2, curRect->y2,
curRect->x1, (This->PresentParms.BackBufferHeight - curRect->y2), curRect->x1, (This->renderTarget->myDesc.Height - curRect->y2),
curRect->x2 - curRect->x1, curRect->y2 - curRect->y1); curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
glScissor(curRect->x1, (This->PresentParms.BackBufferHeight - curRect->y2), glScissor(curRect->x1, (This->renderTarget->myDesc.Height - curRect->y2),
curRect->x2 - curRect->x1, curRect->y2 - curRect->y1); curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
checkGLcall("glScissor"); checkGLcall("glScissor");
} else { } else {
glScissor(This->StateBlock->viewport.X, glScissor(This->StateBlock->viewport.X,
(This->PresentParms.BackBufferHeight - (This->StateBlock->viewport.Y + This->StateBlock->viewport.Height)), (This->renderTarget->myDesc.Height - (This->StateBlock->viewport.Y + This->StateBlock->viewport.Height)),
This->StateBlock->viewport.Width, This->StateBlock->viewport.Width,
This->StateBlock->viewport.Height); This->StateBlock->viewport.Height);
checkGLcall("glScissor"); checkGLcall("glScissor");
@ -4614,7 +4614,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_ActiveRender(LPDIRECT3DDEVICE8 iface,
{ {
DWORD value; DWORD value;
/* The surface must be rendered upside down to cancel the flip produce by glCopyTexImage */ /* The surface must be rendered upside down to cancel the flip produce by glCopyTexImage */
This->renderUpsideDown = This->renderTarget != This->frontBuffer; This->renderUpsideDown = (This->renderTarget != This->frontBuffer) && (This->renderTarget != This->backBuffer);
/* Force updating the cull mode */ /* Force updating the cull mode */
IDirect3DDevice8_GetRenderState(iface, D3DRS_CULLMODE, &value); IDirect3DDevice8_GetRenderState(iface, D3DRS_CULLMODE, &value);
IDirect3DDevice8_SetRenderState(iface, D3DRS_CULLMODE, value); IDirect3DDevice8_SetRenderState(iface, D3DRS_CULLMODE, value);

View File

@ -441,6 +441,8 @@ HRESULT WINAPI IDirect3D8Impl_CheckDeviceFormat (LPDIRECT3D8 iface,
case D3DFMT_L6V5U5: case D3DFMT_L6V5U5:
/*case D3DFMT_V8U8:*/ /*case D3DFMT_V8U8:*/
case D3DFMT_L8: case D3DFMT_L8:
case D3DFMT_P8:
case D3DFMT_A8P8:
/* Since we do not support these formats right now, don't pretend to. */ /* Since we do not support these formats right now, don't pretend to. */
return D3DERR_NOTAVAILABLE; return D3DERR_NOTAVAILABLE;
default: default:
@ -1269,7 +1271,7 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
/* init the default renderTarget management */ /* init the default renderTarget management */
object->drawable = object->win; object->drawable = object->win;
object->render_ctx = object->glCtx; object->render_ctx = object->glCtx;
object->renderTarget = object->frontBuffer; object->renderTarget = object->backBuffer;
IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->renderTarget); IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->renderTarget);
object->stencilBufferTarget = object->depthStencilBuffer; object->stencilBufferTarget = object->depthStencilBuffer;
if (NULL != object->stencilBufferTarget) { if (NULL != object->stencilBufferTarget) {
@ -1330,6 +1332,10 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
object->last_was_rhw = 0; object->last_was_rhw = 0;
glGetIntegerv(GL_MAX_LIGHTS, &object->maxConcurrentLights); glGetIntegerv(GL_MAX_LIGHTS, &object->maxConcurrentLights);
TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This, Adapter, object); TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This, Adapter, object);
/* Clear the screen */
IDirect3DDevice8Impl_Clear((LPDIRECT3DDEVICE8) object, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);
return D3D_OK; return D3D_OK;
} }

View File

@ -1605,11 +1605,11 @@ void drawPrimitive(LPDIRECT3DDEVICE8 iface,
if (isDumpingFrames == TRUE) { if (isDumpingFrames == TRUE) {
D3DLOCKED_RECT r; D3DLOCKED_RECT r;
char buffer[80]; char buffer[80];
IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) This->backBuffer, &r, NULL, D3DLOCK_READONLY); IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) This->renderTarget, &r, NULL, D3DLOCK_READONLY);
sprintf(buffer, "/tmp/backbuffer_%ld.ppm", primCounter); sprintf(buffer, "/tmp/backbuffer_%ld.ppm", primCounter);
TRACE("Saving screenshot %s\n", buffer); TRACE("Saving screenshot %s\n", buffer);
IDirect3DSurface8Impl_SaveSnapshot((LPDIRECT3DSURFACE8) This->backBuffer, buffer); IDirect3DSurface8Impl_SaveSnapshot((LPDIRECT3DSURFACE8) This->renderTarget, buffer);
IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) This->backBuffer); IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) This->renderTarget);
#if defined(SHOW_TEXTURE_MAKEUP) #if defined(SHOW_TEXTURE_MAKEUP)
{ {

View File

@ -1,8 +1,9 @@
/* /*
* IDirect3DSurface8 implementation * IDirect3DSurface8 implementation
* *
* Copyright 2002-2003 Jason Edmeades * Copyright 2002-2004 Jason Edmeades
* Raphael Junqueira * Copyright 2002-2003 Raphael Junqueira
* Copyright 2004 Christian Costa
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -193,7 +194,7 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
/* Nothing to do ;) */ /* Nothing to do ;) */
} else if (D3DUSAGE_RENDERTARGET & This->myDesc.Usage) { /* render surfaces */ } else if (D3DUSAGE_RENDERTARGET & This->myDesc.Usage && !(Flags&D3DLOCK_DISCARD)) { /* render surfaces */
if (This == This->Device->backBuffer || This == This->Device->renderTarget || This == This->Device->frontBuffer) { if (This == This->Device->backBuffer || This == This->Device->renderTarget || This == This->Device->frontBuffer) {
GLint prev_store; GLint prev_store;
@ -293,18 +294,19 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
if (This == This->Device->backBuffer || This == This->Device->frontBuffer || This->Device->depthStencilBuffer) { if (This == This->Device->backBuffer || This == This->Device->frontBuffer || This->Device->depthStencilBuffer || This == This->Device->renderTarget) {
if (This == This->Device->backBuffer) { if (This == This->Device->backBuffer) {
TRACE("(%p, backBuffer) : dirtyfied(%d)\n", This, This->Dirty); TRACE("(%p, backBuffer) : dirtyfied(%d)\n", This, This->Dirty);
} else if (This == This->Device->frontBuffer) { } else if (This == This->Device->frontBuffer) {
TRACE("(%p, frontBuffer) : dirtyfied(%d)\n", This, This->Dirty); TRACE("(%p, frontBuffer) : dirtyfied(%d)\n", This, This->Dirty);
} else if (This == This->Device->depthStencilBuffer) { } else if (This == This->Device->depthStencilBuffer) {
TRACE("(%p, stencilBuffer) : dirtyfied(%d)\n", This, This->Dirty); TRACE("(%p, stencilBuffer) : dirtyfied(%d)\n", This, This->Dirty);
} else if (This == This->Device->renderTarget) {
TRACE("(%p, renderTarget) : dirtyfied(%d)\n", This, This->Dirty);
} }
} else { } else {
TRACE("(%p) : dirtyfied(%d)\n", This, This->Dirty); TRACE("(%p) : dirtyfied(%d)\n", This, This->Dirty);
} }
/*TRACE("(%p) see if behavior is correct\n", This);*/
if (FALSE == This->Dirty) { if (FALSE == This->Dirty) {
TRACE("(%p) : Not Dirtified so nothing to do, return now\n", This); TRACE("(%p) : Not Dirtified so nothing to do, return now\n", This);
@ -318,7 +320,7 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
*/ */
} else if (D3DUSAGE_RENDERTARGET & This->myDesc.Usage) { /* render surfaces */ } else if (D3DUSAGE_RENDERTARGET & This->myDesc.Usage) { /* render surfaces */
if (This == This->Device->backBuffer || This == This->Device->frontBuffer) { if (This == This->Device->backBuffer || This == This->Device->frontBuffer || This == This->Device->renderTarget) {
GLint prev_store; GLint prev_store;
GLenum prev_draw; GLenum prev_draw;
GLint prev_rasterpos[4]; GLint prev_rasterpos[4];
@ -376,7 +378,7 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
if (This == This->Device->backBuffer) { if (This == This->Device->backBuffer) {
glDrawBuffer(GL_BACK); glDrawBuffer(GL_BACK);
} else if (This == This->Device->frontBuffer) { } else if (This == This->Device->frontBuffer || This == This->Device->renderTarget) {
glDrawBuffer(GL_FRONT); glDrawBuffer(GL_FRONT);
} }
vcheckGLcall("glDrawBuffer"); vcheckGLcall("glDrawBuffer");