Index: ddraw/glDirectDraw.cpp |
— | — | @@ -1138,7 +1138,7 @@ |
1139 | 1139 | else TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
1140 | 1140 | if(ddCaps.dwSize > sizeof(DDCAPS_DX7)) ddCaps.dwSize = sizeof(DDCAPS_DX7);
|
1141 | 1141 | if (ddCaps.dwSize < sizeof(DDCAPS_DX3)) TRACE_RET(HRESULT, 23, DDERR_INVALIDPARAMS);
|
1142 | | - ddCaps.dwCaps = DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTSTRETCH |
|
| 1142 | + ddCaps.dwCaps = DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_BLTSTRETCH |
|
1143 | 1143 | DDCAPS_COLORKEY | DDCAPS_GDI | DDCAPS_PALETTE | DDCAPS_CANBLTSYSMEM |
|
1144 | 1144 | DDCAPS_3D | DDCAPS_CANCLIP | DDCAPS_CANCLIPSTRETCHED | DDCAPS_READSCANLINE;
|
1145 | 1145 | ddCaps.dwCaps2 = DDCAPS2_CANRENDERWINDOWED | DDCAPS2_WIDESURFACES | DDCAPS2_NOPAGELOCKREQUIRED |
|
Index: ddraw/glDirectDrawSurface.cpp |
— | — | @@ -56,6 +56,7 @@ |
57 | 57 | bitmapinfo = (BITMAPINFO *)malloc(sizeof(BITMAPINFO)+(255*sizeof(RGBQUAD)));
|
58 | 58 | ZeroMemory(bitmapinfo,sizeof(BITMAPINFO)+(255*sizeof(RGBQUAD)));
|
59 | 59 | ZeroMemory(&fbo,sizeof(FBO));
|
| 60 | + ZeroMemory(&zfbo,sizeof(FBO));
|
60 | 61 | ZeroMemory(&stencilfbo,sizeof(FBO));
|
61 | 62 | palette = NULL;
|
62 | 63 | stencil = NULL;
|
— | — | @@ -62,6 +63,7 @@ |
63 | 64 | paltex = NULL;
|
64 | 65 | texture = NULL;
|
65 | 66 | clipper = NULL;
|
| 67 | + dummycolor = NULL;
|
66 | 68 | hdc = NULL;
|
67 | 69 | dds1 = new glDirectDrawSurface1(this);
|
68 | 70 | dds2 = new glDirectDrawSurface2(this);
|
— | — | @@ -74,6 +76,8 @@ |
75 | 77 | bigbuffer = NULL;
|
76 | 78 | clientbuffer = NULL;
|
77 | 79 | zbuffer = NULL;
|
| 80 | + attachcount = 0;
|
| 81 | + attachparent = NULL;
|
78 | 82 | this->miplevel = miplevel;
|
79 | 83 | DWORD colormasks[3];
|
80 | 84 | magfilter = minfilter = GL_NEAREST;
|
— | — | @@ -429,7 +433,13 @@ |
430 | 434 | if(clipper) glDirectDrawClipper_Release(clipper);
|
431 | 435 | if(buffer) free(buffer);
|
432 | 436 | if(bigbuffer) free(bigbuffer);
|
433 | | - if(zbuffer) zbuffer_iface->Release();
|
| 437 | + if (zbuffer)
|
| 438 | + {
|
| 439 | + if (zbuffer->attachparent == this) zbuffer->attachparent = NULL;
|
| 440 | + if (zbuffer->attachcount) zbuffer->attachcount--;
|
| 441 | + if (!zbuffer->attachcount) zbuffer->attachparent = NULL;
|
| 442 | + zbuffer_iface->Release();
|
| 443 | + }
|
434 | 444 | if(miptexture) miptexture->Release();
|
435 | 445 | if (device) device->Release();
|
436 | 446 | if (device1) delete device1;
|
— | — | @@ -736,8 +746,23 @@ |
737 | 747 | attached->GetSurfaceDesc(&ddsd);
|
738 | 748 | if((ddsd.ddpfPixelFormat.dwFlags & DDPF_ZBUFFER) || (ddsd.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
|
739 | 749 | {
|
| 750 | + if (zbuffer)
|
| 751 | + {
|
| 752 | + if (zbuffer->zfbo.fbo)
|
| 753 | + {
|
| 754 | + glRenderer_DeleteFBO(ddInterface->renderer, &zbuffer->zfbo);
|
| 755 | + ZeroMemory(&zbuffer->zfbo, sizeof(FBO));
|
| 756 | + }
|
| 757 | + if (zbuffer->dummycolor)
|
| 758 | + {
|
| 759 | + glRenderer_DeleteTexture(ddInterface->renderer, zbuffer->dummycolor);
|
| 760 | + zbuffer->dummycolor = NULL;
|
| 761 | + }
|
| 762 | + }
|
740 | 763 | zbuffer = attached;
|
741 | 764 | zbuffer_iface = iface;
|
| 765 | + if (!zbuffer->attachcount) zbuffer->attachparent = this;
|
| 766 | + zbuffer->attachcount++;
|
742 | 767 | TRACE_EXIT(23,DD_OK);
|
743 | 768 | return DD_OK;
|
744 | 769 | }
|
— | — | @@ -758,6 +783,7 @@ |
759 | 784 | glDirectDrawSurface7 *pattern;
|
760 | 785 | TRACE_ENTER(6,14,this,26,lpDestRect,14,lpDDSrcSurface,26,lpSrcRect,9,dwFlags,14,lpDDBltFx);
|
761 | 786 | if(!this) TRACE_RET(HRESULT,23,DDERR_INVALIDOBJECT);
|
| 787 | + if ((dwFlags & DDBLT_DEPTHFILL) && !lpDDBltFx) TRACE_RET(HRESULT,32,DDERR_INVALIDPARAMS);
|
762 | 788 | if((dwFlags & DDBLT_COLORFILL) && !lpDDBltFx) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
763 | 789 | if((dwFlags & DDBLT_DDFX) && !lpDDBltFx) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
764 | 790 | if (dwFlags & DDBLT_ROP)
|
— | — | @@ -823,6 +849,11 @@ |
824 | 850 | dwFlags |= 0x10000000;
|
825 | 851 | }
|
826 | 852 | }
|
| 853 | + if (dwFlags & DDBLT_DEPTHFILL)
|
| 854 | + {
|
| 855 | + if (!(ddsd.ddpfPixelFormat.dwFlags & DDPF_ZBUFFER)) TRACE_RET(HRESULT, 23, DDERR_UNSUPPORTED);
|
| 856 | + TRACE_RET(HRESULT, 23, glRenderer_DepthFill(ddInterface->renderer, lpDestRect, this, lpDDBltFx));
|
| 857 | + }
|
827 | 858 | if (this == src)
|
828 | 859 | {
|
829 | 860 | tmprect.left = tmprect.top = 0;
|
— | — | @@ -877,6 +908,9 @@ |
878 | 909 | if(!this) TRACE_RET(HRESULT,23,DDERR_INVALIDOBJECT);
|
879 | 910 | if(lpDDSAttachedSurface == (LPDIRECTDRAWSURFACE7)zbuffer)
|
880 | 911 | {
|
| 912 | + if (zbuffer->attachparent == this) zbuffer->attachparent = NULL;
|
| 913 | + if (zbuffer->attachcount) zbuffer->attachcount--;
|
| 914 | + if (!zbuffer->attachcount) zbuffer->attachparent = NULL;
|
881 | 915 | zbuffer_iface->Release();
|
882 | 916 | zbuffer = NULL;
|
883 | 917 | TRACE_EXIT(23,DD_OK);
|
Index: ddraw/glDirectDrawSurface.h |
— | — | @@ -1,5 +1,5 @@ |
2 | 2 | // DXGL
|
3 | | -// Copyright (C) 2011-2014 William Feely
|
| 3 | +// Copyright (C) 2011-2015 William Feely
|
4 | 4 |
|
5 | 5 | // This library is free software; you can redistribute it and/or
|
6 | 6 | // modify it under the terms of the GNU Lesser General Public
|
— | — | @@ -145,6 +145,7 @@ |
146 | 146 | TEXTURE *texture;
|
147 | 147 | TEXTURE *paltex;
|
148 | 148 | TEXTURE *stencil;
|
| 149 | + TEXTURE *dummycolor;
|
149 | 150 | bool hasstencil;
|
150 | 151 | DWORD miplevel;
|
151 | 152 | char *buffer;
|
— | — | @@ -155,6 +156,7 @@ |
156 | 157 | HGLRC hRC;
|
157 | 158 | D3DMATERIALHANDLE handle;
|
158 | 159 | FBO fbo;
|
| 160 | + FBO zfbo;
|
159 | 161 | FBO stencilfbo;
|
160 | 162 | glDirectDrawClipper *clipper;
|
161 | 163 | IUnknown *creator;
|
— | — | @@ -163,6 +165,8 @@ |
164 | 166 | glDirectDrawSurface7 *miptexture;
|
165 | 167 | glDirectDrawSurface7 *backbuffer;
|
166 | 168 | glDirectDrawSurface7 *backbufferwraparound;
|
| 169 | + DWORD attachcount;
|
| 170 | + glDirectDrawSurface7 *attachparent;
|
167 | 171 | private:
|
168 | 172 | int swapinterval;
|
169 | 173 | ULONG refcount7, refcount4, refcount3, refcount2, refcount1;
|
Index: ddraw/glRenderer.cpp |
— | — | @@ -690,6 +690,31 @@ |
691 | 691 | }
|
692 | 692 |
|
693 | 693 | /**
|
| 694 | +* Fills a depth surface with a specified value.
|
| 695 | +* @param This
|
| 696 | +* Pointer to glRenderer object
|
| 697 | +* @param lpDestRect
|
| 698 | +* Pointer to bounding rectangle for depth fill. If NULL, then fill entire surface
|
| 699 | +* @param dest
|
| 700 | +* Destination surface to depth fill
|
| 701 | +* @param lpDDBltFx
|
| 702 | +* Pointer to DDBLTFX structure with dwFillDepth defining the depth value.
|
| 703 | +*/
|
| 704 | +HRESULT glRenderer_DepthFill(glRenderer *This, LPRECT lpDestRect, glDirectDrawSurface7 *dest, LPDDBLTFX lpDDBltFx)
|
| 705 | +{
|
| 706 | + EnterCriticalSection(&This->cs);
|
| 707 | + This->inputs[0] = lpDestRect;
|
| 708 | + This->inputs[1] = dest;
|
| 709 | + This->inputs[2] = lpDDBltFx;
|
| 710 | + This->opcode = OP_DEPTHFILL;
|
| 711 | + SetEvent(This->start);
|
| 712 | + WaitForSingleObject(This->busy, INFINITE);
|
| 713 | + LeaveCriticalSection(&This->cs);
|
| 714 | + return (HRESULT)This->outputs[0];
|
| 715 | +}
|
| 716 | +
|
| 717 | +
|
| 718 | +/**
|
694 | 719 | * Main loop for glRenderer class
|
695 | 720 | * @param This
|
696 | 721 | * Pointer to glRenderer object
|
— | — | @@ -805,6 +830,10 @@ |
806 | 831 | case OP_UPDATECLIPPER:
|
807 | 832 | glRenderer__UpdateClipper(This,(glDirectDrawSurface7*)This->inputs[0]);
|
808 | 833 | break;
|
| 834 | + case OP_DEPTHFILL:
|
| 835 | + glRenderer__DepthFill(This, (LPRECT)This->inputs[0], (glDirectDrawSurface7*)This->inputs[1],
|
| 836 | + (LPDDBLTFX)This->inputs[2]);
|
| 837 | + break;
|
809 | 838 | }
|
810 | 839 | }
|
811 | 840 | return 0;
|
— | — | @@ -1644,6 +1673,7 @@ |
1645 | 1674 | {
|
1646 | 1675 | clearbits |= GL_DEPTH_BUFFER_BIT;
|
1647 | 1676 | This->util->ClearDepth(dvZ);
|
| 1677 | + This->util->DepthWrite(true);
|
1648 | 1678 | }
|
1649 | 1679 | if(dwFlags & D3DCLEAR_STENCIL)
|
1650 | 1680 | {
|
— | — | @@ -2092,6 +2122,67 @@ |
2093 | 2123 | SetEvent(This->busy);
|
2094 | 2124 | }
|
2095 | 2125 |
|
| 2126 | +void glRenderer__DepthFill(glRenderer *This, LPRECT lpDestRect, glDirectDrawSurface7 *dest, LPDDBLTFX lpDDBltFx)
|
| 2127 | +{
|
| 2128 | + RECT destrect;
|
| 2129 | + DDSURFACEDESC2 ddsd;
|
| 2130 | + ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
| 2131 | + dest->GetSurfaceDesc(&ddsd);
|
| 2132 | + if (!lpDestRect)
|
| 2133 | + {
|
| 2134 | + destrect.left = 0;
|
| 2135 | + destrect.top = 0;
|
| 2136 | + destrect.right = ddsd.dwWidth;
|
| 2137 | + destrect.bottom = ddsd.dwHeight;
|
| 2138 | + }
|
| 2139 | + else destrect = *lpDestRect;
|
| 2140 | + if (dest->attachparent)
|
| 2141 | + {
|
| 2142 | + do
|
| 2143 | + {
|
| 2144 | + if (This->util->SetFBO(dest->attachparent) == GL_FRAMEBUFFER_COMPLETE) break;
|
| 2145 | + if (!dest->attachparent->texture->internalformats[1]) break;
|
| 2146 | + TextureManager_FixTexture(This->texman, dest->attachparent->texture,
|
| 2147 | + (dest->attachparent->bigbuffer ? dest->attachparent->bigbuffer : dest->attachparent->buffer),
|
| 2148 | + &dest->attachparent->dirty, dest->attachparent->miplevel);
|
| 2149 | + This->util->SetFBO((FBO*)NULL);
|
| 2150 | + dest->attachparent->fbo.fbcolor = NULL;
|
| 2151 | + dest->attachparent->fbo.fbz = NULL;
|
| 2152 | + } while (1);
|
| 2153 | + }
|
| 2154 | + else
|
| 2155 | + {
|
| 2156 | + if (!dest->dummycolor)
|
| 2157 | + {
|
| 2158 | + dest->dummycolor = (TEXTURE*)malloc(sizeof(TEXTURE));
|
| 2159 | + ZeroMemory(dest->dummycolor, sizeof(TEXTURE));
|
| 2160 | + dest->dummycolor->minfilter = dest->dummycolor->magfilter = GL_NEAREST;
|
| 2161 | + dest->dummycolor->wraps = dest->dummycolor->wrapt = GL_CLAMP_TO_EDGE;
|
| 2162 | + dest->dummycolor->pixelformat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
|
| 2163 | + dest->dummycolor->pixelformat.dwBBitMask = 0xF;
|
| 2164 | + dest->dummycolor->pixelformat.dwGBitMask = 0xF0;
|
| 2165 | + dest->dummycolor->pixelformat.dwRBitMask = 0xF00;
|
| 2166 | + dest->dummycolor->pixelformat.dwZBitMask = 0xF000;
|
| 2167 | + dest->dummycolor->pixelformat.dwRGBBitCount = 16;
|
| 2168 | + TextureManager__CreateTexture(This->texman, dest->dummycolor, dest->ddsd.dwWidth, dest->ddsd.dwHeight);
|
| 2169 | + }
|
| 2170 | + if ((dest->ddsd.dwWidth != dest->dummycolor->width) ||
|
| 2171 | + (dest->ddsd.dwHeight != dest->dummycolor->height))
|
| 2172 | + TextureManager__UploadTexture(This->texman, dest->dummycolor, 0, NULL,
|
| 2173 | + dest->ddsd.dwWidth, dest->ddsd.dwHeight, FALSE, TRUE);
|
| 2174 | + This->util->SetFBO(&dest->zfbo, dest->dummycolor, dest->texture, false);
|
| 2175 | + }
|
| 2176 | + This->util->SetViewport(0, 0, dest->ddsd.dwWidth, dest->ddsd.dwHeight);
|
| 2177 | + if (lpDestRect) This->util->SetScissor(true, lpDestRect->left, lpDestRect->top,
|
| 2178 | + lpDestRect->right, lpDestRect->bottom);
|
| 2179 | + This->util->DepthWrite(true);
|
| 2180 | + This->util->ClearDepth(lpDDBltFx->dwFillDepth / (double)0xFFFF);
|
| 2181 | + glClear(GL_DEPTH_BUFFER_BIT);
|
| 2182 | + if (lpDestRect)This->util->SetScissor(false, 0, 0, 0, 0);
|
| 2183 | + This->outputs[0] = DD_OK;
|
| 2184 | + SetEvent(This->busy);
|
| 2185 | +}
|
| 2186 | +
|
2096 | 2187 | void glRenderer__SetFogColor(glRenderer *This, DWORD color)
|
2097 | 2188 | {
|
2098 | 2189 | if (color == This->fogcolor) return;
|
Index: ddraw/glRenderer.h |
— | — | @@ -1,5 +1,5 @@ |
2 | 2 | // DXGL
|
3 | | -// Copyright (C) 2012-2014 William Feely
|
| 3 | +// Copyright (C) 2012-2015 William Feely
|
4 | 4 |
|
5 | 5 | // This library is free software; you can redistribute it and/or
|
6 | 6 | // modify it under the terms of the GNU Lesser General Public
|
— | — | @@ -65,7 +65,8 @@ |
66 | 66 | #define OP_FLUSH 11
|
67 | 67 | #define OP_DRAWPRIMITIVES 12
|
68 | 68 | #define OP_DELETEFBO 13
|
69 | | -#define OP_UPDATECLIPPER 14
|
| 69 | +#define OP_UPDATECLIPPER 14
|
| 70 | +#define OP_DEPTHFILL 15
|
70 | 71 |
|
71 | 72 | #ifdef __cplusplus
|
72 | 73 | class glDirectDraw7;
|
— | — | @@ -137,6 +138,7 @@ |
138 | 139 | void glRenderer_DeleteFBO(glRenderer *This, FBO *fbo);
|
139 | 140 | void glRenderer_UpdateClipper(glRenderer *This, glDirectDrawSurface7 *surface);
|
140 | 141 | unsigned int glRenderer_GetScanLine(glRenderer *This);
|
| 142 | +HRESULT glRenderer_DepthFill(glRenderer *This, LPRECT lpDestRect, glDirectDrawSurface7 *dest, LPDDBLTFX lpDDBltFx);
|
141 | 143 | // In-thread APIs
|
142 | 144 | DWORD glRenderer__Entry(glRenderer *This);
|
143 | 145 | BOOL glRenderer__InitGL(glRenderer *This, int width, int height, int bpp, int fullscreen, unsigned int frequency, HWND hWnd, glDirectDraw7 *glDD7);
|
— | — | @@ -157,6 +159,7 @@ |
158 | 160 | void glRenderer__SetWnd(glRenderer *This, int width, int height, int fullscreen, int bpp, unsigned int frequency, HWND newwnd, BOOL devwnd);
|
159 | 161 | void glRenderer__DeleteFBO(glRenderer *This, FBO *fbo);
|
160 | 162 | void glRenderer__UpdateClipper(glRenderer *This, glDirectDrawSurface7 *surface);
|
| 163 | +void glRenderer__DepthFill(glRenderer *This, LPRECT lpDestRect, glDirectDrawSurface7 *dest, LPDDBLTFX lpDDBltFx);
|
161 | 164 | void glRenderer__SetFogColor(glRenderer *This, DWORD color);
|
162 | 165 | void glRenderer__SetFogStart(glRenderer *This, GLfloat start);
|
163 | 166 | void glRenderer__SetFogEnd(glRenderer *This, GLfloat end);
|