DXGL r88 - Code Review

Jump to navigation Jump to search
Repository:DXGL
Revision:r87‎ | r88 | r89 >
Date:19:00, 27 January 2012
Author:admin
Status:new
Tags:
Comment:
Move OpenGL rendering to dedicated thread
Modified paths:
  • /ddraw/ddraw.vcxproj (modified) (history)
  • /ddraw/ddraw.vcxproj.filters (modified) (history)
  • /ddraw/glDirectDraw.cpp (modified) (history)
  • /ddraw/glDirectDraw.h (modified) (history)
  • /ddraw/glDirectDrawSurface.cpp (modified) (history)
  • /ddraw/glDirectDrawSurface.h (modified) (history)
  • /ddraw/glRenderer.cpp (added) (history)
  • /ddraw/glRenderer.h (added) (history)
  • /ddraw/glThread.cpp (deleted) (history)
  • /ddraw/glThread.h (deleted) (history)

Diff [purge]

Index: ddraw/glThread.h
@@ -1,31 +0,0 @@
2 -// DXGL
3 -// Copyright (C) 2012 William Feely
4 -
5 -// This library is free software; you can redistribute it and/or
6 -// modify it under the terms of the GNU Lesser General Public
7 -// License as published by the Free Software Foundation; either
8 -// version 2.1 of the License, or (at your option) any later version.
9 -
10 -// This library is distributed in the hope that it will be useful,
11 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 -// Lesser General Public License for more details.
14 -
15 -// You should have received a copy of the GNU Lesser General Public
16 -// License along with this library; if not, write to the Free Software
17 -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 -
19 -#ifndef _GLTHREAD_H
20 -#define _GLTHREAD_H
21 -
22 -class glThread
23 -{
24 -public:
25 - glThread(int width, int height, int bpp, bool fullscreen, HWND hWnd, glDirectDraw7 *glDD7);
26 - ~glThread();
27 - void ThreadEntry(void *entry);
28 -private:
29 - glDirectDraw7 *ddInterface;
30 -};
31 -
32 -#endif //_GLTHREAD_H
\ No newline at end of file
Index: ddraw/glThread.cpp
@@ -1,19 +0,0 @@
2 -// DXGL
3 -// Copyright (C) 2012 William Feely
4 -
5 -// This library is free software; you can redistribute it and/or
6 -// modify it under the terms of the GNU Lesser General Public
7 -// License as published by the Free Software Foundation; either
8 -// version 2.1 of the License, or (at your option) any later version.
9 -
10 -// This library is distributed in the hope that it will be useful,
11 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 -// Lesser General Public License for more details.
14 -
15 -// You should have received a copy of the GNU Lesser General Public
16 -// License along with this library; if not, write to the Free Software
17 -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 -
19 -#include "common.h"
20 -#include "glThread.h"
\ No newline at end of file
Index: ddraw/ddraw.vcxproj
@@ -171,7 +171,7 @@
172172 <ClInclude Include="glDirectDrawPalette.h" />
173173 <ClInclude Include="glDirectDrawSurface.h" />
174174 <ClInclude Include="glExtensions.h" />
175 - <ClInclude Include="glThread.h" />
 175+ <ClInclude Include="glRenderer.h" />
176176 <ClInclude Include="glutil.h" />
177177 <ClInclude Include="include\d3d.h" />
178178 <ClInclude Include="include\d3dcaps.h" />
@@ -214,7 +214,7 @@
215215 <ClCompile Include="glDirectDrawPalette.cpp" />
216216 <ClCompile Include="glDirectDrawSurface.cpp" />
217217 <ClCompile Include="glExtensions.cpp" />
218 - <ClCompile Include="glThread.cpp" />
 218+ <ClCompile Include="glRenderer.cpp" />
219219 <ClCompile Include="glutil.cpp" />
220220 <ClCompile Include="precomp.cpp">
221221 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug no DXGL|Win32'">Create</PrecompiledHeader>
Index: ddraw/ddraw.vcxproj.filters
@@ -92,7 +92,7 @@
9393 <ClInclude Include="shadergen.h">
9494 <Filter>Header Files</Filter>
9595 </ClInclude>
96 - <ClInclude Include="glThread.h">
 96+ <ClInclude Include="glRenderer.h">
9797 <Filter>Header Files</Filter>
9898 </ClInclude>
9999 </ItemGroup>
@@ -148,7 +148,7 @@
149149 <ClCompile Include="shadergen.cpp">
150150 <Filter>Source Files</Filter>
151151 </ClCompile>
152 - <ClCompile Include="glThread.cpp">
 152+ <ClCompile Include="glRenderer.cpp">
153153 <Filter>Source Files</Filter>
154154 </ClCompile>
155155 </ItemGroup>
Index: ddraw/glDirectDraw.cpp
@@ -23,11 +23,11 @@
2424 #include "glDirectDrawClipper.h"
2525 #include "glDirectDrawSurface.h"
2626 #include "glDirectDrawPalette.h"
 27+#include "glRenderer.h"
2728 #include "glutil.h"
2829 #include "../common/version.h"
2930
3031 bool directdraw_created = false; // emulate only one ddraw device
31 -bool wndclasscreated = false;
3232
3333 DDDEVICEIDENTIFIER2 devid = {
3434 "ddraw.dll",
@@ -700,7 +700,7 @@
701701 }
702702 HRESULT WINAPI glDirectDraw7::CreateSurface(LPDDSURFACEDESC2 lpDDSurfaceDesc2, LPDIRECTDRAWSURFACE7 FAR *lplpDDSurface, IUnknown FAR *pUnkOuter)
703703 {
704 - if(primary && (lpDDSurfaceDesc2->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && (hRC == primary->hrc) )
 704+ if(primary && (lpDDSurfaceDesc2->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && (renderer == primary->renderer) )
705705 ERR(DDERR_PRIMARYSURFACEALREADYEXISTS);
706706 surfacecount++;
707707 if(surfacecount > surfacecountmax)
@@ -892,13 +892,8 @@
893893 HRESULT WINAPI glDirectDraw7::Initialize(GUID FAR *lpGUID)
894894 {
895895 if(initialized) return DDERR_ALREADYINITIALIZED;
896 - hDC = NULL;
897 - hRC = NULL;
898 - PBO = 0;
899 - hasHWnd = false;
900 - dib.enabled = false;
901896 glD3D7 = NULL;
902 - hRenderWnd = NULL;
 897+ renderer = NULL;
903898 primary = NULL;
904899 fullscreen = false;
905900 fpupreserve = false;
@@ -947,7 +942,7 @@
948943 HRESULT WINAPI glDirectDraw7::SetCooperativeLevel(HWND hWnd, DWORD dwFlags)
949944 {
950945 this->hWnd = hWnd;
951 - if(hRC) DeleteGL();
 946+ if(renderer) DeleteGL();
952947 winstyle = GetWindowLongPtrA(hWnd,GWL_STYLE);
953948 winstyleex = GetWindowLongPtrA(hWnd,GWL_EXSTYLE);
954949 bool exclusive = false;
@@ -1309,180 +1304,13 @@
13101305
13111306 void glDirectDraw7::DeleteGL()
13121307 {
1313 - if(hRC)
1314 - {
1315 - if(dib.enabled)
1316 - {
1317 - if(dib.hbitmap) DeleteObject(dib.hbitmap);
1318 - if(dib.hdc) DeleteDC(dib.hdc);
1319 - ZeroMemory(&dib,sizeof(DIB));
1320 - }
1321 - DeleteShaders();
1322 - DeleteFBO();
1323 - if(PBO)
1324 - {
1325 - glBindBuffer(GL_PIXEL_PACK_BUFFER,0);
1326 - glDeleteBuffers(1,&PBO);
1327 - PBO = 0;
1328 - }
1329 - wglMakeCurrent(NULL,NULL);
1330 - wglDeleteContext(hRC);
1331 - };
1332 - if(hDC) ReleaseDC(hRenderWnd,hDC);
1333 - if(hRenderWnd) DestroyWindow(hRenderWnd);
1334 - hRC = NULL;
1335 - hDC = NULL;
1336 - hRenderWnd = NULL;
 1308+ delete renderer;
 1309+ renderer = NULL;
13371310 }
13381311
13391312 BOOL glDirectDraw7::InitGL(int width, int height, int bpp, bool fullscreen, HWND hWnd)
13401313 {
1341 - if(hRC)
1342 - {
1343 - wglMakeCurrent(NULL,NULL);
1344 - wglDeleteContext(hRC);
1345 - };
1346 - if(hDC) ReleaseDC(hRenderWnd,hDC);
1347 - if(hRenderWnd) DestroyWindow(hRenderWnd);
1348 - WNDCLASSEXA wndclass;
1349 - if(!wndclasscreated)
1350 - {
1351 - wndclass.cbSize = sizeof(WNDCLASSEXA);
1352 - wndclass.style = 0;
1353 - wndclass.lpfnWndProc = RenderWndProc;
1354 - wndclass.cbClsExtra = 0;
1355 - wndclass.cbWndExtra = 0;
1356 - wndclass.hInstance = (HINSTANCE)GetWindowLongPtr(hWnd,GWLP_HINSTANCE);
1357 - wndclass.hIcon = NULL;
1358 - wndclass.hCursor = NULL;
1359 - wndclass.hbrBackground = NULL;
1360 - wndclass.lpszMenuName = NULL;
1361 - wndclass.lpszClassName = "DXGLRenderWindow";
1362 - wndclass.hIconSm = NULL;
1363 - if(!RegisterClassExA(&wndclass)) ERR(DDERR_GENERIC);
1364 - wndclasscreated = true;
1365 - }
1366 - GLuint pf;
1367 - RECT rect;
1368 - rect.left = 0;
1369 - rect.right = width;
1370 - rect.top = 0;
1371 - rect.bottom = height;
1372 - if(fullscreen)
1373 - {
1374 - SetWindowLongPtrA(hWnd,GWL_EXSTYLE,WS_EX_APPWINDOW);
1375 - SetWindowLongPtrA(hWnd,GWL_STYLE,WS_POPUP);
1376 - ShowWindow(hWnd,SW_MAXIMIZE);
1377 - }
1378 - if(width)
1379 - {
1380 - // TODO: Adjust window rect
1381 - }
1382 - SetWindowPos(hWnd,NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
1383 - RECT rectRender;
1384 - GetClientRect(hWnd,&rectRender);
1385 - if(hWnd)
1386 - {
1387 - hRenderWnd = CreateWindowA("DXGLRenderWindow","Renderer",WS_CHILD|WS_VISIBLE,0,0,rectRender.right - rectRender.left,
1388 - rectRender.bottom - rectRender.top,hWnd,NULL,NULL,this);
1389 - hasHWnd = true;
1390 - }
1391 - else
1392 - {
1393 - width = GetSystemMetrics(SM_CXSCREEN);
1394 - height = GetSystemMetrics(SM_CYSCREEN);
1395 - hRenderWnd = CreateWindowExA(WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_TOPMOST,"DXGLRenderWindow","Renderer",
1396 - WS_POPUP,0,0,width,height,0,0,NULL,this);
1397 - hasHWnd = false;
1398 - }
1399 - SetWindowPos(hRenderWnd,HWND_TOP,0,0,rectRender.right,rectRender.bottom,SWP_SHOWWINDOW);
1400 - PIXELFORMATDESCRIPTOR pfd;
1401 - ZeroMemory(&pfd,sizeof(PIXELFORMATDESCRIPTOR));
1402 - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
1403 - pfd.nVersion = 1;
1404 - if(hasHWnd) pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
1405 - else pfd.dwFlags = pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
1406 - pfd.iPixelType = PFD_TYPE_RGBA;
1407 - if(hasHWnd) pfd.cColorBits = bpp;
1408 - else
1409 - {
1410 - pfd.cColorBits = 24;
1411 - pfd.cAlphaBits = 8;
1412 - }
1413 - pfd.iLayerType = PFD_MAIN_PLANE;
1414 - hDC = GetDC(hRenderWnd);
1415 - if(!hDC)
1416 - {
1417 - DEBUG("glDirectDraw7::InitGL: Can not create hDC\n");
1418 - return FALSE;
1419 - }
1420 - pf = ChoosePixelFormat(hDC,&pfd);
1421 - if(!pf)
1422 - {
1423 - DEBUG("glDirectDraw7::InitGL: Can not get pixelformat\n");
1424 - return FALSE;
1425 - }
1426 - if(!SetPixelFormat(hDC,pf,&pfd))
1427 - DEBUG("glDirectDraw7::InitGL: Can not set pixelformat\n");
1428 - gllock = true;
1429 - hRC = wglCreateContext(hDC);
1430 - if(!hRC)
1431 - {
1432 - DEBUG("glDirectDraw7::InitGL: Can not create GL context\n");
1433 - gllock = false;
1434 - return FALSE;
1435 - }
1436 - if(!wglMakeCurrent(hDC,hRC))
1437 - {
1438 - DEBUG("glDirectDraw7::InitGL: Can not activate GL context\n");
1439 - wglDeleteContext(hRC);
1440 - hRC = NULL;
1441 - ReleaseDC(hRenderWnd,hDC);
1442 - hDC = NULL;
1443 - gllock = false;
1444 - return FALSE;
1445 - }
1446 - gllock = false;
1447 - InitGLExt();
1448 - SetSwap(1);
1449 - SetSwap(0);
1450 - glViewport(0,0,width,height);
1451 - glDisable(GL_DEPTH_TEST);
1452 - const GLubyte *glver = glGetString(GL_VERSION);
1453 - gl_caps.Version = (GLfloat)atof((char*)glver);
1454 - if(gl_caps.Version >= 2)
1455 - {
1456 - glver = glGetString(GL_SHADING_LANGUAGE_VERSION);
1457 - gl_caps.ShaderVer = (GLfloat)atof((char*)glver);
1458 - }
1459 - else gl_caps.ShaderVer = 0;
1460 - CompileShaders();
1461 - InitFBO();
1462 - glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1463 - glClear(GL_COLOR_BUFFER_BIT);
1464 - glFlush();
1465 - SwapBuffers(hDC);
1466 - if(!hasHWnd)
1467 - {
1468 - dib.enabled = true;
1469 - dib.width = width;
1470 - dib.height = height;
1471 - dib.pitch = (((width<<3)+31)&~31) >>3;
1472 - dib.pixels = NULL;
1473 - dib.hdc = CreateCompatibleDC(NULL);
1474 - ZeroMemory(&dib.info,sizeof(BITMAPINFO));
1475 - dib.info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1476 - dib.info.bmiHeader.biBitCount = 32;
1477 - dib.info.bmiHeader.biWidth = width;
1478 - dib.info.bmiHeader.biHeight = height;
1479 - dib.info.bmiHeader.biCompression = BI_RGB;
1480 - dib.info.bmiHeader.biPlanes = 1;
1481 - dib.hbitmap = CreateDIBSection(dib.hdc,&dib.info,DIB_RGB_COLORS,(void**)&dib.pixels,NULL,0);
1482 - glGenBuffers(1,&PBO);
1483 - glBindBuffer(GL_PIXEL_PACK_BUFFER,PBO);
1484 - glBufferData(GL_PIXEL_PACK_BUFFER,width*height*4,NULL,GL_STREAM_READ);
1485 - glBindBuffer(GL_PIXEL_PACK_BUFFER,0);
1486 - }
 1314+ renderer = new glRenderer(width,height,bpp,fullscreen,hWnd,this);
14871315 return TRUE;
14881316 }
14891317 void glDirectDraw7::GetSizes(LONG *sizes) // allocate 6 dwords
@@ -1542,11 +1370,6 @@
15431371 }
15441372 return DefWindowProc(hwnd,msg,wParam,lParam);
15451373 }
1546 -void glDirectDraw7::GetHandles(HWND *hwnd, HWND *hrender)
1547 -{
1548 - if(hwnd) *hwnd = hWnd;
1549 - if(hrender) *hrender = hRenderWnd;
1550 -}
15511374
15521375 void glDirectDraw7::DeleteSurface(glDirectDrawSurface7 *surface)
15531376 {
Index: ddraw/glDirectDraw.h
@@ -22,32 +22,10 @@
2323 class glDirectDrawSurface7;
2424 class glDirectDrawClipper;
2525 class glDirect3D7;
 26+class glRenderer;
2627
2728 LRESULT CALLBACK RenderWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
2829
29 -typedef struct
30 -{
31 - float Version;
32 - float ShaderVer;
33 - int TextureMaxX;
34 - int TextureMaxY;
35 - bool NonPowerOfTwo;
36 - int RenderToTexture; // 0 - no support, 1 -
37 - int MultiTextureExt;
38 - int PalettedTextures;
39 -} GLCAPS;
40 -typedef struct
41 -{
42 - bool enabled;
43 - int width;
44 - int height;
45 - int pitch;
46 - HDC hdc;
47 - HBITMAP hbitmap;
48 - BITMAPINFO info;
49 - BYTE *pixels;
50 -} DIB;
51 -
5230 class glDirectDraw7 : public IDirectDraw7
5331 {
5432 public:
@@ -98,19 +76,13 @@
9977 LRESULT WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
10078 DWORD GetBPP(){return primarybpp;}
10179 DWORD GetBPPMultipleOf8(){if(primarybpp == 15) return 16; else return primarybpp;}
102 - HGLRC hRC;
103 - HDC hDC;
10480 DWORD screenx,screeny,screenrefresh,screenbpp;
10581 DWORD internalx,internaly,internalrefresh,internalbpp;
10682 DWORD primaryx,primaryy,primaryrefresh,primarybpp;
10783 bool GetFullscreen(){return fullscreen;};
108 - void GetHandles(HWND *hwnd, HWND *hrender);
10984 void DeleteSurface(glDirectDrawSurface7 *surface);
11085 glDirectDrawSurface7 *primary;
111 - bool hasHWnd;
112 - DIB dib;
113 - GLuint PBO;
114 - HWND hRenderWnd;
 86+ glRenderer *renderer;
11587 private:
11688 void DeleteGL();
11789 BOOL InitGL(int width, int height, int bpp, bool fullscreen, HWND hWnd);
@@ -127,7 +99,6 @@
128100 int surfacecount, surfacecountmax;
129101 glDirectDrawClipper **clippers;
130102 int clippercount, clippercountmax;
131 - GLCAPS gl_caps;
132103 DEVMODE oldmode;
133104 bool initialized;
134105 glDirect3D7 *glD3D7;
Index: ddraw/glDirectDrawSurface.cpp
@@ -24,25 +24,13 @@
2525 #include "glDirectDrawSurface.h"
2626 #include "glDirectDrawPalette.h"
2727 #include "glDirectDrawClipper.h"
 28+#include "glRenderer.h"
2829 #include "glutil.h"
2930
30 -BltVertex bltvertices[4];
31 -const GLushort bltindices[4] = {0,1,2,3};
3231
33 -int swapinterval = 0;
34 -inline void SetSwap(int swap)
35 -{
36 - if(swap != swapinterval)
37 - {
38 - wglSwapIntervalEXT(swap);
39 - swapinterval = wglGetSwapIntervalEXT();
40 - swapinterval = swap;
41 - }
42 -}
43 -
44 -inline int NextMultipleOf8(int number){return ((number+7) & (~7));}
45 -inline int NextMultipleOf4(int number){return ((number+3) & (~3));}
46 -inline int NextMultipleOf2(int number){return ((number+1) & (~1));}
 32+static inline int NextMultipleOf8(int number){return ((number+7) & (~7));}
 33+static inline int NextMultipleOf4(int number){return ((number+3) & (~3));}
 34+static inline int NextMultipleOf2(int number){return ((number+1) & (~1));}
4735 #ifdef _M_X64
4836 #define NextMultipleOfWord NextMultipleOf8
4937 #else
@@ -49,77 +37,8 @@
5038 #define NextMultipleOfWord NextMultipleOf4
5139 #endif
5240
53 -inline int _5to8bit(int number)
54 -{
55 - return (number << 3)+(number>>2);
56 -}
57 -inline int _6to8bit(int number)
58 -{
59 - return (number<<2)+(number>>4);
60 -}
6141
6242
63 -int UploadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y, int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2, int texformat3)
64 -{
65 - if(bpp == 15) bpp = 16;
66 - glBindTexture(GL_TEXTURE_2D,texture); // Select surface's texture
67 - if((x == bigx && y == bigy) || !bigbuffer)
68 - {
69 - glTexImage2D(GL_TEXTURE_2D,0,texformat3,x,y,0,texformat,texformat2,buffer);
70 - }
71 - else
72 - {
73 - switch(bpp)
74 - {
75 - case 8:
76 - ScaleNearest8(bigbuffer,buffer,bigx,bigy,x,y,pitch,bigpitch);
77 - break;
78 - case 16:
79 - ScaleNearest16(bigbuffer,buffer,bigx,bigy,x,y,pitch/2,bigpitch/2);
80 - break;
81 - case 24:
82 - ScaleNearest24(bigbuffer,buffer,bigx,bigy,x,y,pitch,bigpitch);
83 - break;
84 - case 32:
85 - ScaleNearest32(bigbuffer,buffer,bigx,bigy,x,y,pitch/4,bigpitch/4);
86 - break;
87 - break;
88 - }
89 - glTexImage2D(GL_TEXTURE_2D,0,texformat3,bigx,bigy,0,texformat,texformat2,bigbuffer);
90 - }
91 - return 0;
92 -}
93 -int DownloadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y, int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2)
94 -{
95 - glBindTexture(GL_TEXTURE_2D,texture); // Select surface's texture
96 - if((bigx == x && bigy == y) || !bigbuffer)
97 - {
98 - glGetTexImage(GL_TEXTURE_2D,0,texformat,texformat2,buffer); // Shortcut for no scaling
99 - }
100 - else
101 - {
102 - glGetTexImage(GL_TEXTURE_2D,0,texformat,texformat2,bigbuffer);
103 - switch(bpp)
104 - {
105 - case 8:
106 - ScaleNearest8(buffer,bigbuffer,x,y,bigx,bigy,bigpitch,pitch);
107 - break;
108 - case 15:
109 - case 16:
110 - ScaleNearest16(buffer,bigbuffer,x,y,bigx,bigy,bigpitch/2,pitch/2);
111 - break;
112 - case 24:
113 - ScaleNearest24(buffer,bigbuffer,x,y,bigx,bigy,bigpitch,pitch);
114 - break;
115 - case 32:
116 - ScaleNearest32(buffer,bigbuffer,x,y,bigx,bigy,bigpitch/4,pitch/4);
117 - break;
118 - break;
119 - }
120 - }
121 - return 0;
122 -}
123 -
12443 // DDRAW7 routines
12544 glDirectDrawSurface7::glDirectDrawSurface7(LPDIRECTDRAW7 lpDD7, LPDDSURFACEDESC2 lpDDSurfaceDesc2, LPDIRECTDRAWSURFACE7 *lplpDDSurface7, HRESULT *error, bool copysurface, glDirectDrawPalette *palettein)
12645 {
@@ -144,6 +63,7 @@
14564 bigbuffer = NULL;
14665 zbuffer = NULL;
14766 DWORD colormasks[3];
 67+ GLint filter = GL_NEAREST;
14868 if(copysurface)
14969 {
15070 FIXME("glDirectDrawSurface7::glDirectDrawSurface7: copy surface stub\n");
@@ -153,7 +73,7 @@
15474 else
15575 {
15676 ddInterface = (glDirectDraw7 *)lpDD7;
157 - hrc = ddInterface->hRC;
 77+ renderer = ddInterface->renderer;
15878 ddsd = *lpDDSurfaceDesc2;
15979 }
16080 LONG sizes[6];
@@ -201,13 +121,7 @@
202122 palette = palettein;
203123 palette->AddRef();
204124 }
205 - glGenTextures(1,&paltex);
206 - glBindTexture(GL_TEXTURE_2D,paltex);
207 - glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
208 - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
209 - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
210 - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
211 - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
 125+ paltex = renderer->MakeTexture(GL_NEAREST,GL_NEAREST,GL_CLAMP,GL_CLAMP,256,1,GL_RGBA,GL_UNSIGNED_BYTE,GL_RGB);
212126 }
213127 else paltex = 0;
214128 }
@@ -289,21 +203,8 @@
290204 case 2:
291205 maketex:
292206 buffer = NULL;
293 - glGenTextures(1,&texture);
294 - glBindTexture(GL_TEXTURE_2D,texture);
295 - glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
296 - if((dxglcfg.scalingfilter == 0) || (ddInterface->GetBPP() == 8))
297 - {
298 - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
299 - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
300 - }
301 - else
302 - {
303 - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
304 - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
305 - }
306 - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
307 - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
 207+ if((dxglcfg.scalingfilter == 0) || (ddInterface->GetBPP() == 8)) filter = GL_NEAREST;
 208+ else filter = GL_LINEAR;
308209 if(ddsd.dwFlags & DDSD_PIXELFORMAT)
309210 {
310211 if(ddsd.ddpfPixelFormat.dwFlags & DDPF_RGB)
@@ -455,7 +356,7 @@
456357 memcpy(bitmapinfo->bmiColors,colormasks,3*sizeof(DWORD));
457358 }
458359 }
459 - glTexImage2D(GL_TEXTURE_2D,0,texformat3,fakex,fakey,0,texformat,texformat2,NULL);
 360+ texture = renderer->MakeTexture(filter,filter,GL_CLAMP,GL_CLAMP,fakex,fakey,texformat,texformat2,texformat3);
460361 }
461362
462363 refcount = 1;
@@ -487,8 +388,8 @@
488389 if(dds2) dds2->Release();
489390 if(dds3) dds3->Release();
490391 if(dds4) dds4->Release();
491 - if(paltex)glDeleteTextures(1,&paltex);
492 - if(texture)glDeleteTextures(1,&texture);
 392+ if(paltex) renderer->DeleteTexture(paltex);
 393+ if(texture) renderer->DeleteTexture(texture);
493394 if(bitmapinfo) free(bitmapinfo);
494395 if(palette) palette->Release();
495396 if(backbuffer) backbuffer->Release();
@@ -610,7 +511,7 @@
611512 glDirectDrawSurface7 *src = (glDirectDrawSurface7 *)lpDDSrcSurface;
612513 if(dirty & 1)
613514 {
614 - UploadTexture(buffer,bigbuffer,texture,ddsd.dwWidth,ddsd.dwHeight,
 515+ renderer->UploadTexture(buffer,bigbuffer,texture,ddsd.dwWidth,ddsd.dwHeight,
615516 fakex,fakey,ddsd.lPitch,(NextMultipleOf4((ddInterface->GetBPPMultipleOf8()/8)*fakex)),
616517 ddsd.ddpfPixelFormat.dwRGBBitCount,texformat,texformat2,texformat3);
617518 dirty &= ~1;
@@ -617,157 +518,13 @@
618519 }
619520 if(src && (src->dirty & 1))
620521 {
621 - UploadTexture(src->buffer,src->bigbuffer,src->texture,src->ddsd.dwWidth,src->ddsd.dwHeight,
 522+ renderer->UploadTexture(src->buffer,src->bigbuffer,src->texture,src->ddsd.dwWidth,src->ddsd.dwHeight,
622523 src->fakex,src->fakey,src->ddsd.lPitch,
623524 (NextMultipleOf4((ddInterface->GetBPPMultipleOf8()/8)*src->fakex)),
624525 src->ddsd.ddpfPixelFormat.dwRGBBitCount,src->texformat,src->texformat2,src->texformat3);
625526 src->dirty &= ~1;
626527 }
627 - LONG sizes[6];
628 - ddInterface->GetSizes(sizes);
629 - int error;
630 - error = SetFBO(texture,0,false);
631 - glViewport(0,0,fakex,fakey);
632 - RECT destrect;
633 - if(!lpDestRect)
634 - {
635 - destrect.left = 0;
636 - destrect.top = 0;
637 - destrect.right = ddsd.dwWidth;
638 - destrect.bottom = ddsd.dwHeight;
639 - }
640 - else destrect = *lpDestRect;
641 - RECT srcrect;
642 - DDSURFACEDESC2 ddsdSrc;
643 - ddsdSrc.dwSize = sizeof(DDSURFACEDESC2);
644 - if(lpDDSrcSurface) lpDDSrcSurface->GetSurfaceDesc(&ddsdSrc);
645 - if(!lpSrcRect)
646 - {
647 - srcrect.left = 0;
648 - srcrect.top = 0;
649 - srcrect.right = ddsdSrc.dwWidth;
650 - srcrect.bottom = ddsdSrc.dwHeight;
651 - }
652 - else srcrect = *lpSrcRect;
653 - bltvertices[1].x = bltvertices[3].x = (GLfloat)destrect.left * ((GLfloat)fakex/(GLfloat)ddsd.dwWidth);
654 - bltvertices[0].x = bltvertices[2].x = (GLfloat)destrect.right * ((GLfloat)fakex/(GLfloat)ddsd.dwWidth);
655 - bltvertices[0].y = bltvertices[1].y = (GLfloat)fakey-((GLfloat)destrect.top * ((GLfloat)fakey/(GLfloat)ddsd.dwHeight));
656 - bltvertices[2].y = bltvertices[3].y = (GLfloat)fakey-((GLfloat)destrect.bottom * ((GLfloat)fakey/(GLfloat)ddsd.dwHeight));
657 - bltvertices[1].s = bltvertices[3].s = (GLfloat)srcrect.left / (GLfloat)ddsdSrc.dwWidth;
658 - bltvertices[0].s = bltvertices[2].s = (GLfloat)srcrect.right / (GLfloat)ddsdSrc.dwWidth;
659 - bltvertices[0].t = bltvertices[1].t = (GLfloat)srcrect.top / (GLfloat)ddsdSrc.dwHeight;
660 - bltvertices[2].t = bltvertices[3].t = (GLfloat)srcrect.bottom / (GLfloat)ddsdSrc.dwHeight;
661 - glClear(GL_DEPTH_BUFFER_BIT);
662 - if(dwFlags & DDBLT_COLORFILL)
663 - {
664 - SetShader(PROG_FILL,1);
665 - glDisable(GL_TEXTURE_2D);
666 - glDisable(GL_ALPHA_TEST);
667 - switch(ddInterface->GetBPP())
668 - {
669 - case 8:
670 - bltvertices[0].r = bltvertices[0].g = bltvertices[0].b =
671 - bltvertices[1].r = bltvertices[1].g = bltvertices[1].b =
672 - bltvertices[2].r = bltvertices[2].g = bltvertices[2].b =
673 - bltvertices[3].r = bltvertices[3].g = bltvertices[3].b = (GLubyte)lpDDBltFx->dwFillColor;
674 - break;
675 - case 15:
676 - bltvertices[0].r = bltvertices[1].r = bltvertices[2].r = bltvertices[3].r =
677 - _5to8bit((lpDDBltFx->dwFillColor>>10) & 31);
678 - bltvertices[0].g = bltvertices[1].g = bltvertices[2].g = bltvertices[3].g =
679 - _5to8bit((lpDDBltFx->dwFillColor>>5) & 31);
680 - bltvertices[0].b = bltvertices[1].b = bltvertices[2].b = bltvertices[3].b =
681 - _5to8bit(lpDDBltFx->dwFillColor & 31);
682 - break;
683 - case 16:
684 - bltvertices[0].r = bltvertices[1].r = bltvertices[2].r = bltvertices[3].r =
685 - _5to8bit((lpDDBltFx->dwFillColor>>11) & 31);
686 - bltvertices[0].g = bltvertices[1].g = bltvertices[2].g = bltvertices[3].g =
687 - _6to8bit((lpDDBltFx->dwFillColor>>5) & 63);
688 - bltvertices[0].b = bltvertices[1].b = bltvertices[2].b = bltvertices[3].b =
689 - _5to8bit(lpDDBltFx->dwFillColor & 31);
690 - break;
691 - case 24:
692 - case 32:
693 - bltvertices[0].r = bltvertices[1].r = bltvertices[2].r = bltvertices[3].r =
694 - ((lpDDBltFx->dwFillColor>>16) & 255);
695 - bltvertices[0].g = bltvertices[1].g = bltvertices[2].g = bltvertices[3].g =
696 - ((lpDDBltFx->dwFillColor>>8) & 255);
697 - bltvertices[0].b = bltvertices[1].b = bltvertices[2].b = bltvertices[3].b =
698 - (lpDDBltFx->dwFillColor & 255);
699 - default:
700 - break;
701 - }
702 - }
703 - else
704 - {
705 - glEnable(GL_TEXTURE_2D);
706 - }
707 - if(lpDDSrcSurface) glBindTexture(GL_TEXTURE_2D,((glDirectDrawSurface7*)lpDDSrcSurface)->GetTexture());
708 - if((dwFlags & DDBLT_KEYSRC) && (src && src->colorkey[0].enabled) && !(dwFlags & DDBLT_COLORFILL))
709 - {
710 - SetShader(PROG_CKEY,1);
711 - GLint keyloc = glGetUniformLocation(shaders[PROG_CKEY].prog,"keyIn");
712 - switch(ddInterface->GetBPP())
713 - {
714 - case 8:
715 - glUniform3i(keyloc,src->colorkey[0].key.dwColorSpaceHighValue,src->colorkey[0].key.dwColorSpaceHighValue,
716 - src->colorkey[0].key.dwColorSpaceHighValue);
717 - break;
718 - case 15:
719 - glUniform3i(keyloc,_5to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>10 & 31),
720 - _5to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>5 & 31),
721 - _5to8bit(src->colorkey[0].key.dwColorSpaceHighValue & 31));
722 - break;
723 - case 16:
724 - glUniform3i(keyloc,_5to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>11 & 31),
725 - _6to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>5 & 63),
726 - _5to8bit(src->colorkey[0].key.dwColorSpaceHighValue & 31));
727 - break;
728 - case 24:
729 - case 32:
730 - default:
731 - glUniform3i(keyloc,(src->colorkey[0].key.dwColorSpaceHighValue>>16 & 255),
732 - (src->colorkey[0].key.dwColorSpaceHighValue>>8 & 255),
733 - (src->colorkey[0].key.dwColorSpaceHighValue & 255));
734 - break;
735 - }
736 - GLint texloc = glGetUniformLocation(shaders[PROG_CKEY].prog,"myTexture");
737 - glUniform1i(texloc,0);
738 - }
739 - else if(!(dwFlags & DDBLT_COLORFILL))
740 - {
741 - SetShader(PROG_TEXTURE,1);
742 - GLint texloc = glGetUniformLocation(shaders[PROG_TEXTURE].prog,"Texture");
743 - glUniform1i(texloc,0);
744 - }
745 - GLuint prog = GetProgram()&0xffffffff;
746 - GLint viewloc = glGetUniformLocation(prog,"view");
747 - glUniform4f(viewloc,0,(GLfloat)fakex,0,(GLfloat)fakey);
748 - this->dirty |= 2;
749 - GLint xyloc = glGetAttribLocation(prog,"xy");
750 - glEnableVertexAttribArray(xyloc);
751 - glVertexAttribPointer(xyloc,2,GL_FLOAT,false,sizeof(BltVertex),&bltvertices[0].x);
752 - if(dwFlags & DDBLT_COLORFILL)
753 - {
754 - GLint rgbloc = glGetAttribLocation(prog,"rgb");
755 - glEnableVertexAttribArray(rgbloc);
756 - glVertexAttribPointer(rgbloc,3,GL_UNSIGNED_BYTE,true,sizeof(BltVertex),&bltvertices[0].r);
757 - }
758 - else
759 - {
760 - GLint stloc = glGetAttribLocation(prog,"st");
761 - glEnableVertexAttribArray(stloc);
762 - glVertexAttribPointer(stloc,2,GL_FLOAT,false,sizeof(BltVertex),&bltvertices[0].s);
763 - }
764 - glDrawRangeElements(GL_TRIANGLE_STRIP,0,3,4,GL_UNSIGNED_SHORT,bltindices);
765 - glDisable(GL_TEXTURE_2D);
766 - SetFBO(0,0,false);
767 - if(((ddsd.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER)) &&
768 - (ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) ||
769 - ((ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) &&
770 - !(ddsd.ddsCaps.dwCaps & DDSCAPS_FLIP))) RenderScreen(texture,this);
771 - return DD_OK;
 528+ return renderer->Blt(lpDestRect,src,this,lpSrcRect,dwFlags,lpDDBltFx);
772529 }
773530 HRESULT WINAPI glDirectDrawSurface7::BltBatch(LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags)
774531 {
@@ -838,7 +595,7 @@
839596 glDirectDrawSurface7 *tmp = this;
840597 if(dirty & 1)
841598 {
842 - UploadTexture(buffer,bigbuffer,texture,ddsd.dwWidth,ddsd.dwHeight,
 599+ renderer->UploadTexture(buffer,bigbuffer,texture,ddsd.dwWidth,ddsd.dwHeight,
843600 fakex,fakey,ddsd.lPitch,(NextMultipleOf4((ddInterface->GetBPPMultipleOf8()/8)*fakex)),
844601 ddsd.ddpfPixelFormat.dwRGBBitCount,texformat,texformat2,texformat3);
845602 dirty &= ~1;
@@ -849,7 +606,7 @@
850607 tmp = tmp->GetBackbuffer();
851608 if(tmp->dirty & 1)
852609 {
853 - UploadTexture(tmp->buffer,tmp->bigbuffer,tmp->texture,tmp->ddsd.dwWidth,tmp->ddsd.dwHeight,
 610+ renderer->UploadTexture(tmp->buffer,tmp->bigbuffer,tmp->texture,tmp->ddsd.dwWidth,tmp->ddsd.dwHeight,
854611 tmp->fakex,tmp->fakey,tmp->ddsd.lPitch,(NextMultipleOf4((ddInterface->GetBPPMultipleOf8()/8)*tmp->fakex)),
855612 tmp->ddsd.ddpfPixelFormat.dwRGBBitCount,tmp->texformat,tmp->texformat2,tmp->texformat3);
856613 tmp->dirty &= ~1;
@@ -1025,7 +782,7 @@
1026783 }
1027784 HRESULT WINAPI glDirectDrawSurface7::IsLost()
1028785 {
1029 - if(hrc == ddInterface->hRC) return DD_OK;
 786+ if(renderer == ddInterface->renderer) return DD_OK;
1030787 else return DDERR_SURFACELOST;
1031788 }
1032789
@@ -1041,7 +798,7 @@
1042799 break;
1043800 case 0:
1044801 if(dirty & 2)
1045 - DownloadTexture(buffer,bigbuffer,texture,ddsd.dwWidth,ddsd.dwHeight,fakex,fakey,ddsd.lPitch,
 802+ renderer->DownloadTexture(buffer,bigbuffer,texture,ddsd.dwWidth,ddsd.dwHeight,fakex,fakey,ddsd.lPitch,
1046803 (ddInterface->GetBPPMultipleOf8()/8)*fakex,ddsd.ddpfPixelFormat.dwRGBBitCount,texformat,texformat2);
1047804 ddsd.lpSurface = buffer;
1048805 break;
@@ -1054,7 +811,7 @@
1055812 if((ddsd.dwWidth != fakex) || (ddsd.dwHeight != fakey))
1056813 bigbuffer = (char *)malloc((ddsd.ddpfPixelFormat.dwRGBBitCount * NextMultipleOfWord(fakex) * fakey)/8);
1057814 else bigbuffer = NULL;
1058 - DownloadTexture(buffer,bigbuffer,texture,ddsd.dwWidth,ddsd.dwHeight,fakex,fakey,ddsd.lPitch,
 815+ renderer->DownloadTexture(buffer,bigbuffer,texture,ddsd.dwWidth,ddsd.dwHeight,fakex,fakey,ddsd.lPitch,
1059816 (ddInterface->GetBPPMultipleOf8()/8)*fakex,ddsd.ddpfPixelFormat.dwRGBBitCount,texformat,texformat2);
1060817 dirty &= ~2;
1061818 surfacetype = 0;
@@ -1066,8 +823,8 @@
1067824 }
1068825 HRESULT WINAPI glDirectDrawSurface7::ReleaseDC(HDC hDC)
1069826 {
1070 - if(!hdc) ERR(DDERR_INVALIDOBJECT);
1071 - if(hDC != hdc) ERR(DDERR_INVALIDOBJECT);
 827+ if(!hdc) return DDERR_INVALIDOBJECT;
 828+ if(hDC != hdc) return DDERR_INVALIDOBJECT;
1072829 GetDIBits(hDC,hbitmap,0,ddsd.dwHeight,ddsd.lpSurface,bitmapinfo,DIB_RGB_COLORS);
1073830 Unlock(NULL);
1074831 DeleteObject(hbitmap);
@@ -1078,7 +835,7 @@
1079836 }
1080837 HRESULT WINAPI glDirectDrawSurface7::Restore()
1081838 {
1082 - if(hrc != ddInterface->hRC)
 839+ if(renderer != ddInterface->renderer)
1083840 {
1084841 FIXME("glDirectDrawSurface7::Restore: stub\n");
1085842 ERR(DDERR_GENERIC);
@@ -1154,134 +911,7 @@
1155912
1156913 void glDirectDrawSurface7::RenderScreen(GLuint texture, glDirectDrawSurface7 *surface)
1157914 {
1158 - LONG sizes[6];
1159 - GLfloat view[4];
1160 - RECT r,r2;
1161 - if(surface->dirty & 1)
1162 - {
1163 - UploadTexture(buffer,surface->bigbuffer,texture,surface->ddsd.dwWidth,surface->ddsd.dwHeight,
1164 - surface->fakex,surface->fakey,surface->ddsd.lPitch,
1165 - (NextMultipleOf4((ddInterface->GetBPPMultipleOf8()/8)*surface->fakex)),
1166 - surface->ddsd.ddpfPixelFormat.dwRGBBitCount,surface->texformat,surface->texformat2,surface->texformat3);
1167 - surface->dirty &= ~1;
1168 - }
1169 - if(ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1170 - {
1171 - if(ddInterface->GetFullscreen())
1172 - {
1173 - ddInterface->GetSizes(sizes);
1174 - glViewport(0,0,sizes[4],sizes[5]);
1175 - view[0] = (GLfloat)-(sizes[4]-sizes[0])/2;
1176 - view[1] = (GLfloat)(sizes[4]-sizes[0])/2+sizes[0];
1177 - view[2] = (GLfloat)(sizes[5]-sizes[1])/2+sizes[1];
1178 - view[3] = (GLfloat)-(sizes[5]-sizes[1])/2;
1179 - }
1180 - else
1181 - {
1182 - HWND hwnd,hrender;
1183 - ddInterface->GetHandles(&hwnd,&hrender);
1184 - GetClientRect(hwnd,&r);
1185 - GetClientRect(hrender,&r2);
1186 - if(memcmp(&r2,&r,sizeof(RECT)))
1187 - SetWindowPos(hrender,NULL,0,0,r.right,r.bottom,SWP_SHOWWINDOW);
1188 - r2 = r;
1189 - ClientToScreen(hwnd,(LPPOINT)&r2.left);
1190 - ClientToScreen(hwnd,(LPPOINT)&r2.right);
1191 - glViewport(0,0,r.right,r.bottom);
1192 - view[0] = (GLfloat)r2.left;
1193 - view[1] = (GLfloat)r2.right;
1194 - view[2] = (GLfloat)fakey-(GLfloat)r2.top;
1195 - view[3] = (GLfloat)fakey-(GLfloat)r2.bottom;
1196 - }
1197 - }
1198 - else
1199 - {
1200 - view[0] = 0;
1201 - view[1] = (GLfloat)fakex;
1202 - view[2] = 0;
1203 - view[3] = (GLfloat)fakey;
1204 - }
1205 - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1206 - if(ddInterface->GetBPP() == 8)
1207 - {
1208 - SetShader(PROG_PAL256,true);
1209 - glBindTexture(GL_TEXTURE_2D,paltex);
1210 - glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,256,1,0,GL_RGBA,GL_UNSIGNED_BYTE,palette->GetPalette(NULL));
1211 - GLint palloc = glGetUniformLocation(shaders[PROG_PAL256].prog,"ColorTable");
1212 - GLint texloc = glGetUniformLocation(shaders[PROG_PAL256].prog,"IndexTexture");
1213 - glUniform1i(texloc,0);
1214 - glUniform1i(palloc,1);
1215 - glActiveTexture(GL_TEXTURE0);
1216 - glBindTexture(GL_TEXTURE_2D,texture);
1217 - glActiveTexture(GL_TEXTURE1);
1218 - glBindTexture(GL_TEXTURE_2D,paltex);
1219 - glActiveTexture(GL_TEXTURE0);
1220 - }
1221 - else
1222 - {
1223 - SetShader(PROG_TEXTURE,true);
1224 - glEnable(GL_TEXTURE_2D);
1225 - glBindTexture(GL_TEXTURE_2D,texture);
1226 - GLuint prog = GetProgram() & 0xFFFFFFFF;
1227 - GLint texloc = glGetUniformLocation(prog,"Texture");
1228 - }
1229 - GLuint prog = GetProgram();
1230 - GLint viewloc = glGetUniformLocation(prog,"view");
1231 - glUniform4f(viewloc,view[0],view[1],view[2],view[3]);
1232 - if(ddInterface->GetFullscreen())
1233 - {
1234 - bltvertices[0].x = bltvertices[2].x = (float)sizes[0];
1235 - bltvertices[0].y = bltvertices[1].y = bltvertices[1].x = bltvertices[3].x = 0.;
1236 - bltvertices[2].y = bltvertices[3].y = (float)sizes[1];
1237 - }
1238 - else
1239 - {
1240 - bltvertices[0].x = bltvertices[2].x = (float)fakex;
1241 - bltvertices[0].y = bltvertices[1].y = bltvertices[1].x = bltvertices[3].x = 0.;
1242 - bltvertices[2].y = bltvertices[3].y = (float)fakey;
1243 - }
1244 - bltvertices[0].s = bltvertices[0].t = bltvertices[1].t = bltvertices[2].s = 1.;
1245 - bltvertices[1].s = bltvertices[2].t = bltvertices[3].s = bltvertices[3].t = 0.;
1246 - GLint xyloc = glGetAttribLocation(prog,"xy");
1247 - glEnableVertexAttribArray(xyloc);
1248 - glVertexAttribPointer(xyloc,2,GL_FLOAT,false,sizeof(BltVertex),&bltvertices[0].x);
1249 - GLint stloc = glGetAttribLocation(prog,"st");
1250 - glEnableVertexAttribArray(stloc);
1251 - glVertexAttribPointer(stloc,2,GL_FLOAT,false,sizeof(BltVertex),&bltvertices[0].s);
1252 - glDrawRangeElements(GL_TRIANGLE_STRIP,0,3,4,GL_UNSIGNED_SHORT,bltindices);
1253 - glDisable(GL_TEXTURE_2D);
1254 - glFlush();
1255 - if(ddInterface->hasHWnd) SwapBuffers(ddInterface->hDC);
1256 - else
1257 - {
1258 - glReadBuffer(GL_FRONT);
1259 - glBindBuffer(GL_PIXEL_PACK_BUFFER,ddInterface->PBO);
1260 - GLint packalign;
1261 - glGetIntegerv(GL_PACK_ALIGNMENT,&packalign);
1262 - glPixelStorei(GL_PACK_ALIGNMENT,1);
1263 - glReadPixels(0,0,sizes[4],sizes[5],GL_BGRA,GL_UNSIGNED_BYTE,0);
1264 - GLubyte *pixels = (GLubyte*)glMapBuffer(GL_PIXEL_PACK_BUFFER,GL_READ_ONLY);
1265 - for(int i = 0; i < sizes[5];i++)
1266 - {
1267 - memcpy(&ddInterface->dib.pixels[ddInterface->dib.pitch*i],
1268 - &pixels[((sizes[5]-1)-i)*(sizes[4]*4)],sizes[4]*4);
1269 - }
1270 - glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
1271 - glBindBuffer(GL_PIXEL_PACK_BUFFER,0);
1272 - glPixelStorei(GL_PACK_ALIGNMENT,packalign);
1273 - HDC hRenderDC = (HDC)::GetDC(ddInterface->hRenderWnd);
1274 - HGDIOBJ hPrevObj = 0;
1275 - POINT dest = {0,0};
1276 - POINT src = {0,0};
1277 - SIZE wnd = {ddInterface->dib.width,ddInterface->dib.height};
1278 - BLENDFUNCTION func = {AC_SRC_OVER,0,255,AC_SRC_ALPHA};
1279 - hPrevObj = SelectObject(ddInterface->dib.hdc,ddInterface->dib.hbitmap);
1280 - ClientToScreen(ddInterface->hRenderWnd,&dest);
1281 - UpdateLayeredWindow(ddInterface->hRenderWnd,hRenderDC,&dest,&wnd,
1282 - ddInterface->dib.hdc,&src,0,&func,ULW_ALPHA);
1283 - SelectObject(ddInterface->dib.hdc,hPrevObj);
1284 - ::ReleaseDC(ddInterface->hRenderWnd,hRenderDC);
1285 - }
 915+ renderer->DrawScreen(texture,paltex,this,surface);
1286916 }
1287917 // ddraw 2+ api
1288918 HRESULT WINAPI glDirectDrawSurface7::GetDDInterface(LPVOID FAR *lplpDD)
Index: ddraw/glDirectDrawSurface.h
@@ -19,8 +19,6 @@
2020 #ifndef _GLDIRECTDRAWSURFACE_H
2121 #define _GLDIRECTDRAWSURFACE_H
2222
23 -extern inline void SetSwap(int swap);
24 -
2523 typedef struct
2624 {
2725 bool enabled;
@@ -28,16 +26,7 @@
2927 DDCOLORKEY key;
3028 } CKEY;
3129
32 -struct BltVertex
33 -{
34 - GLfloat x,y;
35 - GLubyte r,g,b,a;
36 - GLfloat s,t;
37 - GLfloat padding[3];
38 -};
39 -
40 -extern BltVertex bltvertices[4];
41 -
 30+class glRenderer;
4231 class glDirectDrawClipper;
4332 class glDirectDrawPalette;
4433 class glDirectDrawSurface1;
@@ -123,13 +112,19 @@
124113 GLint texformat3;
125114 DWORD fakex,fakey;
126115 DWORD dirty;
127 - HGLRC hrc;
 116+ glRenderer *renderer;
128117 // dirty bits:
129118 // 1 - Surface was locked
130119 // 2 - Texture was written to by ddraw
131120 CKEY colorkey[4];
132121 GLuint texture;
 122+ GLuint paltex;
133123 bool hasstencil;
 124+ char *buffer;
 125+ char *bigbuffer;
 126+ char *gdibuffer;
 127+ DDSURFACEDESC2 ddsd;
 128+ glDirectDrawPalette *palette;
134129 private:
135130 ULONG refcount;
136131 int locked;
@@ -137,15 +132,9 @@
138133 HBITMAP hbitmap;
139134 BITMAPINFO *bitmapinfo;
140135 glDirectDraw7 *ddInterface;
141 - DDSURFACEDESC2 ddsd;
142 - GLuint paltex;
143136 int surfacetype; // 0-generic memory, 1-GDI surface, 2-OpenGL Texture
144 - char *buffer;
145 - char *bigbuffer;
146 - char *gdibuffer;
147137 glDirectDrawSurface7 *backbuffer;
148138 glDirectDrawSurface7 *zbuffer;
149 - glDirectDrawPalette *palette;
150139 glDirectDrawClipper *clipper;
151140 int pagelocked;
152141 };
Index: ddraw/glRenderer.cpp
@@ -0,0 +1,791 @@
 2+// DXGL
 3+// Copyright (C) 2012 William Feely
 4+
 5+// This library is free software; you can redistribute it and/or
 6+// modify it under the terms of the GNU Lesser General Public
 7+// License as published by the Free Software Foundation; either
 8+// version 2.1 of the License, or (at your option) any later version.
 9+
 10+// This library is distributed in the hope that it will be useful,
 11+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 12+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 13+// Lesser General Public License for more details.
 14+
 15+// You should have received a copy of the GNU Lesser General Public
 16+// License along with this library; if not, write to the Free Software
 17+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 18+
 19+#include "common.h"
 20+#include "glDirectDraw.h"
 21+#include "glDirectDrawSurface.h"
 22+#include "glDirectDrawPalette.h"
 23+#include "glRenderer.h"
 24+#include "glutil.h"
 25+#include "ddraw.h"
 26+#include "scalers.h"
 27+#include "shadergen.h"
 28+
 29+static inline int NextMultipleOf8(int number){return ((number+7) & (~7));}
 30+static inline int NextMultipleOf4(int number){return ((number+3) & (~3));}
 31+static inline int NextMultipleOf2(int number){return ((number+1) & (~1));}
 32+#ifdef _M_X64
 33+#define NextMultipleOfWord NextMultipleOf8
 34+#else
 35+#define NextMultipleOfWord NextMultipleOf4
 36+#endif
 37+
 38+bool wndclasscreated = false;
 39+
 40+BltVertex bltvertices[4];
 41+const GLushort bltindices[4] = {0,1,2,3};
 42+
 43+inline int _5to8bit(int number)
 44+{
 45+ return (number << 3)+(number>>2);
 46+}
 47+inline int _6to8bit(int number)
 48+{
 49+ return (number<<2)+(number>>4);
 50+}
 51+
 52+int swapinterval = 0;
 53+inline void SetSwap(int swap)
 54+{
 55+ if(swap != swapinterval)
 56+ {
 57+ wglSwapIntervalEXT(swap);
 58+ swapinterval = wglGetSwapIntervalEXT();
 59+ swapinterval = swap;
 60+ }
 61+}
 62+
 63+int glRenderer::_UploadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y, int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2, int texformat3)
 64+{
 65+ if(bpp == 15) bpp = 16;
 66+ glBindTexture(GL_TEXTURE_2D,texture); // Select surface's texture
 67+ if((x == bigx && y == bigy) || !bigbuffer)
 68+ {
 69+ glTexImage2D(GL_TEXTURE_2D,0,texformat3,x,y,0,texformat,texformat2,buffer);
 70+ }
 71+ else
 72+ {
 73+ switch(bpp)
 74+ {
 75+ case 8:
 76+ ScaleNearest8(bigbuffer,buffer,bigx,bigy,x,y,pitch,bigpitch);
 77+ break;
 78+ case 16:
 79+ ScaleNearest16(bigbuffer,buffer,bigx,bigy,x,y,pitch/2,bigpitch/2);
 80+ break;
 81+ case 24:
 82+ ScaleNearest24(bigbuffer,buffer,bigx,bigy,x,y,pitch,bigpitch);
 83+ break;
 84+ case 32:
 85+ ScaleNearest32(bigbuffer,buffer,bigx,bigy,x,y,pitch/4,bigpitch/4);
 86+ break;
 87+ break;
 88+ }
 89+ glTexImage2D(GL_TEXTURE_2D,0,texformat3,bigx,bigy,0,texformat,texformat2,bigbuffer);
 90+ }
 91+ return 0;
 92+}
 93+int glRenderer::_DownloadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y, int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2)
 94+{
 95+ glBindTexture(GL_TEXTURE_2D,texture); // Select surface's texture
 96+ if((bigx == x && bigy == y) || !bigbuffer)
 97+ {
 98+ glGetTexImage(GL_TEXTURE_2D,0,texformat,texformat2,buffer); // Shortcut for no scaling
 99+ }
 100+ else
 101+ {
 102+ glGetTexImage(GL_TEXTURE_2D,0,texformat,texformat2,bigbuffer);
 103+ switch(bpp)
 104+ {
 105+ case 8:
 106+ ScaleNearest8(buffer,bigbuffer,x,y,bigx,bigy,bigpitch,pitch);
 107+ break;
 108+ case 15:
 109+ case 16:
 110+ ScaleNearest16(buffer,bigbuffer,x,y,bigx,bigy,bigpitch/2,pitch/2);
 111+ break;
 112+ case 24:
 113+ ScaleNearest24(buffer,bigbuffer,x,y,bigx,bigy,bigpitch,pitch);
 114+ break;
 115+ case 32:
 116+ ScaleNearest32(buffer,bigbuffer,x,y,bigx,bigy,bigpitch/4,pitch/4);
 117+ break;
 118+ break;
 119+ }
 120+ }
 121+ return 0;
 122+}
 123+
 124+glRenderer::glRenderer(int width, int height, int bpp, bool fullscreen, HWND hwnd, glDirectDraw7 *glDD7)
 125+{
 126+ hDC = NULL;
 127+ hRC = NULL;
 128+ PBO = 0;
 129+ hasHWnd = false;
 130+ dib.enabled = false;
 131+ hWnd = hwnd;
 132+ hRenderWnd = NULL;
 133+ if(fullscreen)
 134+ {
 135+ SetWindowLongPtrA(hWnd,GWL_EXSTYLE,WS_EX_APPWINDOW);
 136+ SetWindowLongPtrA(hWnd,GWL_STYLE,WS_POPUP);
 137+ ShowWindow(hWnd,SW_MAXIMIZE);
 138+ }
 139+ if(width)
 140+ {
 141+ // TODO: Adjust window rect
 142+ }
 143+ SetWindowPos(hWnd,NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
 144+ if(hDC) ReleaseDC(hRenderWnd,hDC);
 145+ if(hRenderWnd) DestroyWindow(hRenderWnd);
 146+ WNDCLASSEXA wndclass;
 147+ if(!wndclasscreated)
 148+ {
 149+ wndclass.cbSize = sizeof(WNDCLASSEXA);
 150+ wndclass.style = 0;
 151+ wndclass.lpfnWndProc = RenderWndProc;
 152+ wndclass.cbClsExtra = 0;
 153+ wndclass.cbWndExtra = 0;
 154+ wndclass.hInstance = (HINSTANCE)GetWindowLongPtr(hWnd,GWLP_HINSTANCE);
 155+ wndclass.hIcon = NULL;
 156+ wndclass.hCursor = NULL;
 157+ wndclass.hbrBackground = NULL;
 158+ wndclass.lpszMenuName = NULL;
 159+ wndclass.lpszClassName = "DXGLRenderWindow";
 160+ wndclass.hIconSm = NULL;
 161+ RegisterClassExA(&wndclass);
 162+ wndclasscreated = true;
 163+ }
 164+ RECT rectRender;
 165+ GetClientRect(hWnd,&rectRender);
 166+ if(hWnd)
 167+ {
 168+ hRenderWnd = CreateWindowA("DXGLRenderWindow","Renderer",WS_CHILD|WS_VISIBLE,0,0,rectRender.right - rectRender.left,
 169+ rectRender.bottom - rectRender.top,hWnd,NULL,NULL,this);
 170+ hasHWnd = true;
 171+ }
 172+ else
 173+ {
 174+ width = GetSystemMetrics(SM_CXSCREEN);
 175+ height = GetSystemMetrics(SM_CYSCREEN);
 176+ hRenderWnd = CreateWindowExA(WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_TOPMOST,"DXGLRenderWindow","Renderer",
 177+ WS_POPUP,0,0,width,height,0,0,NULL,this);
 178+ hasHWnd = false;
 179+ }
 180+ SetWindowPos(hRenderWnd,HWND_TOP,0,0,rectRender.right,rectRender.bottom,SWP_SHOWWINDOW);
 181+ eventnum = GLEVENT_NULL;
 182+ EventSend = CreateEventA(NULL,FALSE,FALSE,NULL);
 183+ EventWait = CreateEventA(NULL,FALSE,FALSE,NULL);
 184+ inputs[0] = (void*)width;
 185+ inputs[1] = (void*)height;
 186+ inputs[2] = (void*)bpp;
 187+ inputs[3] = (void*)fullscreen;
 188+ inputs[4] = (void*)hWnd;
 189+ inputs[5] = glDD7;
 190+ inputs[6] = this;
 191+ hThread = CreateThread(NULL,0,ThreadEntry,inputs,0,NULL);
 192+ WaitForSingleObject(EventWait,INFINITE);
 193+}
 194+
 195+glRenderer::~glRenderer()
 196+{
 197+ eventnum = GLEVENT_DELETE;
 198+ SetEvent(EventSend);
 199+ WaitForSingleObject(EventWait,INFINITE);
 200+ if(hDC) ReleaseDC(hRenderWnd,hDC);
 201+ if(hRenderWnd) DestroyWindow(hRenderWnd);
 202+ hDC = NULL;
 203+ hRenderWnd = NULL;
 204+}
 205+
 206+
 207+DWORD WINAPI glRenderer::ThreadEntry(void *entry)
 208+{
 209+ void **inputsin = (void**)entry;
 210+ glRenderer *This = (glRenderer*)inputsin[6];
 211+ return This->_Entry();
 212+}
 213+
 214+GLuint glRenderer::MakeTexture(GLint min, GLint mag, GLint wraps, GLint wrapt, DWORD width, DWORD height, GLint texformat1, GLint texformat2, GLint texformat3)
 215+{
 216+ inputs[0] = (void*)min;
 217+ inputs[1] = (void*)mag;
 218+ inputs[2] = (void*)wraps;
 219+ inputs[3] = (void*)wrapt;
 220+ inputs[4] = (void*)width;
 221+ inputs[5] = (void*)height;
 222+ inputs[6] = (void*)texformat1;
 223+ inputs[7] = (void*)texformat2;
 224+ inputs[8] = (void*)texformat3;
 225+ eventnum = GLEVENT_CREATE;
 226+ SetEvent(EventSend);
 227+ WaitForSingleObject(EventWait,INFINITE);
 228+ return (GLuint)outputs[0];
 229+}
 230+
 231+int glRenderer::UploadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y,
 232+ int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2, int texformat3)
 233+{
 234+ inputs[0] = buffer;
 235+ inputs[1] = bigbuffer;
 236+ inputs[2] = (void*)texture;
 237+ inputs[3] = (void*)x;
 238+ inputs[4] = (void*)y;
 239+ inputs[5] = (void*)bigx;
 240+ inputs[6] = (void*)bigy;
 241+ inputs[7] = (void*)pitch;
 242+ inputs[8] = (void*)bigpitch;
 243+ inputs[9] = (void*)bpp;
 244+ inputs[10] = (void*)texformat;
 245+ inputs[11] = (void*)texformat2;
 246+ inputs[12] = (void*)texformat3;
 247+ eventnum = GLEVENT_UPLOAD;
 248+ SetEvent(EventSend);
 249+ WaitForSingleObject(EventWait,INFINITE);
 250+ return (int)outputs[0];
 251+}
 252+
 253+int glRenderer::DownloadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y,
 254+ int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2)
 255+{
 256+ inputs[0] = buffer;
 257+ inputs[1] = bigbuffer;
 258+ inputs[2] = (void*)texture;
 259+ inputs[3] = (void*)x;
 260+ inputs[4] = (void*)y;
 261+ inputs[5] = (void*)bigx;
 262+ inputs[6] = (void*)bigy;
 263+ inputs[7] = (void*)pitch;
 264+ inputs[8] = (void*)bigpitch;
 265+ inputs[9] = (void*)bpp;
 266+ inputs[10] = (void*)texformat;
 267+ inputs[11] = (void*)texformat2;
 268+ eventnum = GLEVENT_DOWNLOAD;
 269+ SetEvent(EventSend);
 270+ WaitForSingleObject(EventWait,INFINITE);
 271+ return (int)outputs[0];
 272+}
 273+
 274+void glRenderer::DeleteTexture(GLuint texture)
 275+{
 276+ inputs[0] = (void*)texture;
 277+ eventnum = GLEVENT_DELETETEX;
 278+ SetEvent(EventSend);
 279+ WaitForSingleObject(EventWait,INFINITE);
 280+}
 281+
 282+HRESULT glRenderer::Blt(LPRECT lpDestRect, glDirectDrawSurface7 *src,
 283+ glDirectDrawSurface7 *dest, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
 284+{
 285+ RECT r,r2;
 286+ if(((dest->ddsd.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER)) &&
 287+ (dest->ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) ||
 288+ ((dest->ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) &&
 289+ !(dest->ddsd.ddsCaps.dwCaps & DDSCAPS_FLIP)))
 290+ {
 291+ GetClientRect(hWnd,&r);
 292+ GetClientRect(hRenderWnd,&r2);
 293+ if(memcmp(&r2,&r,sizeof(RECT)))
 294+ SetWindowPos(hRenderWnd,NULL,0,0,r.right,r.bottom,SWP_SHOWWINDOW);
 295+ }
 296+ inputs[0] = lpDestRect;
 297+ inputs[1] = src;
 298+ inputs[2] = dest;
 299+ inputs[3] = lpSrcRect;
 300+ inputs[4] = (void*)dwFlags;
 301+ inputs[5] = lpDDBltFx;
 302+ inputs[6] = &r2;
 303+ eventnum = GLEVENT_BLT;
 304+ SetEvent(EventSend);
 305+ WaitForSingleObject(EventWait,INFINITE);
 306+ return (HRESULT)outputs[0];
 307+}
 308+
 309+void glRenderer::DrawScreen(GLuint texture, GLuint paltex, glDirectDrawSurface7 *dest, glDirectDrawSurface7 *src)
 310+{
 311+ RECT r,r2;
 312+ if(!(dest->ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
 313+ {
 314+ GetClientRect(hWnd,&r);
 315+ GetClientRect(hRenderWnd,&r2);
 316+ if(memcmp(&r2,&r,sizeof(RECT)))
 317+ SetWindowPos(hRenderWnd,NULL,0,0,r.right,r.bottom,SWP_SHOWWINDOW);
 318+ }
 319+ inputs[0] = (void*)texture;
 320+ inputs[1] = (void*)paltex;
 321+ inputs[2] = dest;
 322+ inputs[3] = src;
 323+ inputs[4] = &r2;
 324+ eventnum = GLEVENT_DRAWSCREEN;
 325+ SetEvent(EventSend);
 326+ WaitForSingleObject(EventWait,INFINITE);
 327+}
 328+
 329+DWORD glRenderer::_Entry()
 330+{
 331+ _InitGL((int)inputs[0],(int)inputs[1],(int)inputs[2],(int)inputs[3],(HWND)inputs[4],(glDirectDraw7*)inputs[5]);
 332+ SetEvent(EventWait);
 333+ do
 334+ {
 335+ WaitForSingleObject(EventSend,INFINITE);
 336+ switch(eventnum)
 337+ {
 338+ case GLEVENT_DELETE:
 339+ break;
 340+ case GLEVENT_CREATE:
 341+ outputs[0] = (void*)_MakeTexture((GLint)inputs[0],(GLint)inputs[1],(GLint)inputs[2],(GLint)inputs[3],
 342+ (DWORD)inputs[4],(DWORD)inputs[5],(GLint)inputs[6],(GLint)inputs[7],(GLint)inputs[8]);
 343+ SetEvent(EventWait);
 344+ break;
 345+ case GLEVENT_UPLOAD:
 346+ outputs[0] = (void*)_UploadTexture((char*)inputs[0],(char*)inputs[1],(GLuint)inputs[2],(int)inputs[3],
 347+ (int)inputs[4],(int)inputs[5],(int)inputs[6],(int)inputs[7],(int)inputs[8],(int)inputs[9],
 348+ (int)inputs[10],(int)inputs[11],(int)inputs[12]);
 349+ SetEvent(EventWait);
 350+ break;
 351+ case GLEVENT_DOWNLOAD:
 352+ outputs[0] = (void*)_DownloadTexture((char*)inputs[0],(char*)inputs[1],(GLuint)inputs[2],(int)inputs[3],
 353+ (int)inputs[4],(int)inputs[5],(int)inputs[6],(int)inputs[7],(int)inputs[8],(int)inputs[9],
 354+ (int)inputs[10],(int)inputs[11]);
 355+ SetEvent(EventWait);
 356+ break;
 357+ case GLEVENT_DELETETEX:
 358+ _DeleteTexture((GLuint)inputs[0]);
 359+ SetEvent(EventWait);
 360+ break;
 361+ case GLEVENT_BLT:
 362+ outputs[0] = (void*)_Blt((LPRECT)inputs[0],(glDirectDrawSurface7*)inputs[1],(glDirectDrawSurface7*)inputs[2],
 363+ (LPRECT)inputs[3],(DWORD)inputs[4],(LPDDBLTFX)inputs[5],(RECT*)inputs[6]);
 364+ SetEvent(EventWait);
 365+ break;
 366+ case GLEVENT_DRAWSCREEN:
 367+ _DrawScreen((GLuint)inputs[0],(GLuint)inputs[1],(glDirectDrawSurface7*)inputs[2],(glDirectDrawSurface7*)inputs[3],(RECT*)inputs[4]);
 368+ SetEvent(EventWait);
 369+ break;
 370+ default:
 371+ break;
 372+ }
 373+ } while(eventnum != GLEVENT_DELETE);
 374+ if(hRC)
 375+ {
 376+ if(dib.enabled)
 377+ {
 378+ if(dib.hbitmap) DeleteObject(dib.hbitmap);
 379+ if(dib.hdc) DeleteDC(dib.hdc);
 380+ ZeroMemory(&dib,sizeof(DIB));
 381+ }
 382+ DeleteShaders();
 383+ DeleteFBO();
 384+ if(PBO)
 385+ {
 386+ glBindBuffer(GL_PIXEL_PACK_BUFFER,0);
 387+ glDeleteBuffers(1,&PBO);
 388+ PBO = 0;
 389+ }
 390+ wglMakeCurrent(NULL,NULL);
 391+ wglDeleteContext(hRC);
 392+ };
 393+ hRC = NULL;
 394+ SetEvent(EventWait);
 395+ return 0;
 396+}
 397+
 398+BOOL glRenderer::_InitGL(int width, int height, int bpp, int fullscreen, HWND hWnd, glDirectDraw7 *glDD7)
 399+{
 400+ ddInterface = glDD7;
 401+ if(hRC)
 402+ {
 403+ wglMakeCurrent(NULL,NULL);
 404+ wglDeleteContext(hRC);
 405+ };
 406+ PIXELFORMATDESCRIPTOR pfd;
 407+ GLuint pf;
 408+ ZeroMemory(&pfd,sizeof(PIXELFORMATDESCRIPTOR));
 409+ pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
 410+ pfd.nVersion = 1;
 411+ if(hasHWnd) pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
 412+ else pfd.dwFlags = pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
 413+ pfd.iPixelType = PFD_TYPE_RGBA;
 414+ if(hasHWnd) pfd.cColorBits = bpp;
 415+ else
 416+ {
 417+ pfd.cColorBits = 24;
 418+ pfd.cAlphaBits = 8;
 419+ }
 420+ pfd.iLayerType = PFD_MAIN_PLANE;
 421+ hDC = GetDC(hRenderWnd);
 422+ if(!hDC)
 423+ {
 424+ DEBUG("glDirectDraw7::InitGL: Can not create hDC\n");
 425+ return FALSE;
 426+ }
 427+ pf = ChoosePixelFormat(hDC,&pfd);
 428+ if(!pf)
 429+ {
 430+ DEBUG("glDirectDraw7::InitGL: Can not get pixelformat\n");
 431+ return FALSE;
 432+ }
 433+ if(!SetPixelFormat(hDC,pf,&pfd))
 434+ DEBUG("glDirectDraw7::InitGL: Can not set pixelformat\n");
 435+ gllock = true;
 436+ hRC = wglCreateContext(hDC);
 437+ if(!hRC)
 438+ {
 439+ DEBUG("glDirectDraw7::InitGL: Can not create GL context\n");
 440+ gllock = false;
 441+ return FALSE;
 442+ }
 443+ if(!wglMakeCurrent(hDC,hRC))
 444+ {
 445+ DEBUG("glDirectDraw7::InitGL: Can not activate GL context\n");
 446+ wglDeleteContext(hRC);
 447+ hRC = NULL;
 448+ ReleaseDC(hRenderWnd,hDC);
 449+ hDC = NULL;
 450+ gllock = false;
 451+ return FALSE;
 452+ }
 453+ gllock = false;
 454+ InitGLExt();
 455+ SetSwap(1);
 456+ SetSwap(0);
 457+ glViewport(0,0,width,height);
 458+ glDisable(GL_DEPTH_TEST);
 459+ const GLubyte *glver = glGetString(GL_VERSION);
 460+ gl_caps.Version = (GLfloat)atof((char*)glver);
 461+ if(gl_caps.Version >= 2)
 462+ {
 463+ glver = glGetString(GL_SHADING_LANGUAGE_VERSION);
 464+ gl_caps.ShaderVer = (GLfloat)atof((char*)glver);
 465+ }
 466+ else gl_caps.ShaderVer = 0;
 467+ CompileShaders();
 468+ InitFBO();
 469+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 470+ glClear(GL_COLOR_BUFFER_BIT);
 471+ glFlush();
 472+ SwapBuffers(hDC);
 473+ if(!hasHWnd)
 474+ {
 475+ dib.enabled = true;
 476+ dib.width = width;
 477+ dib.height = height;
 478+ dib.pitch = (((width<<3)+31)&~31) >>3;
 479+ dib.pixels = NULL;
 480+ dib.hdc = CreateCompatibleDC(NULL);
 481+ ZeroMemory(&dib.info,sizeof(BITMAPINFO));
 482+ dib.info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 483+ dib.info.bmiHeader.biBitCount = 32;
 484+ dib.info.bmiHeader.biWidth = width;
 485+ dib.info.bmiHeader.biHeight = height;
 486+ dib.info.bmiHeader.biCompression = BI_RGB;
 487+ dib.info.bmiHeader.biPlanes = 1;
 488+ dib.hbitmap = CreateDIBSection(dib.hdc,&dib.info,DIB_RGB_COLORS,(void**)&dib.pixels,NULL,0);
 489+ glGenBuffers(1,&PBO);
 490+ glBindBuffer(GL_PIXEL_PACK_BUFFER,PBO);
 491+ glBufferData(GL_PIXEL_PACK_BUFFER,width*height*4,NULL,GL_STREAM_READ);
 492+ glBindBuffer(GL_PIXEL_PACK_BUFFER,0);
 493+ }
 494+ return TRUE;
 495+}
 496+
 497+HRESULT glRenderer::_Blt(LPRECT lpDestRect, glDirectDrawSurface7 *src,
 498+ glDirectDrawSurface7 *dest, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx, RECT *viewrect)
 499+{
 500+ LONG sizes[6];
 501+ ddInterface->GetSizes(sizes);
 502+ int error;
 503+ error = SetFBO(dest->texture,0,false);
 504+ glViewport(0,0,dest->fakex,dest->fakey);
 505+ RECT destrect;
 506+ DDSURFACEDESC2 ddsd;
 507+ ddsd.dwSize = sizeof(DDSURFACEDESC2);
 508+ dest->GetSurfaceDesc(&ddsd);
 509+ if(!lpDestRect)
 510+ {
 511+ destrect.left = 0;
 512+ destrect.top = 0;
 513+ destrect.right = ddsd.dwWidth;
 514+ destrect.bottom = ddsd.dwHeight;
 515+ }
 516+ else destrect = *lpDestRect;
 517+ RECT srcrect;
 518+ DDSURFACEDESC2 ddsdSrc;
 519+ ddsdSrc.dwSize = sizeof(DDSURFACEDESC2);
 520+ if(src) src->GetSurfaceDesc(&ddsdSrc);
 521+ if(!lpSrcRect)
 522+ {
 523+ srcrect.left = 0;
 524+ srcrect.top = 0;
 525+ srcrect.right = ddsdSrc.dwWidth;
 526+ srcrect.bottom = ddsdSrc.dwHeight;
 527+ }
 528+ else srcrect = *lpSrcRect;
 529+ bltvertices[1].x = bltvertices[3].x = (GLfloat)destrect.left * ((GLfloat)dest->fakex/(GLfloat)ddsd.dwWidth);
 530+ bltvertices[0].x = bltvertices[2].x = (GLfloat)destrect.right * ((GLfloat)dest->fakex/(GLfloat)ddsd.dwWidth);
 531+ bltvertices[0].y = bltvertices[1].y = (GLfloat)dest->fakey-((GLfloat)destrect.top * ((GLfloat)dest->fakey/(GLfloat)ddsd.dwHeight));
 532+ bltvertices[2].y = bltvertices[3].y = (GLfloat)dest->fakey-((GLfloat)destrect.bottom * ((GLfloat)dest->fakey/(GLfloat)ddsd.dwHeight));
 533+ bltvertices[1].s = bltvertices[3].s = (GLfloat)srcrect.left / (GLfloat)ddsdSrc.dwWidth;
 534+ bltvertices[0].s = bltvertices[2].s = (GLfloat)srcrect.right / (GLfloat)ddsdSrc.dwWidth;
 535+ bltvertices[0].t = bltvertices[1].t = (GLfloat)srcrect.top / (GLfloat)ddsdSrc.dwHeight;
 536+ bltvertices[2].t = bltvertices[3].t = (GLfloat)srcrect.bottom / (GLfloat)ddsdSrc.dwHeight;
 537+ glClear(GL_DEPTH_BUFFER_BIT);
 538+ if(dwFlags & DDBLT_COLORFILL)
 539+ {
 540+ SetShader(PROG_FILL,1);
 541+ glDisable(GL_TEXTURE_2D);
 542+ glDisable(GL_ALPHA_TEST);
 543+ switch(ddInterface->GetBPP())
 544+ {
 545+ case 8:
 546+ bltvertices[0].r = bltvertices[0].g = bltvertices[0].b =
 547+ bltvertices[1].r = bltvertices[1].g = bltvertices[1].b =
 548+ bltvertices[2].r = bltvertices[2].g = bltvertices[2].b =
 549+ bltvertices[3].r = bltvertices[3].g = bltvertices[3].b = (GLubyte)lpDDBltFx->dwFillColor;
 550+ break;
 551+ case 15:
 552+ bltvertices[0].r = bltvertices[1].r = bltvertices[2].r = bltvertices[3].r =
 553+ _5to8bit((lpDDBltFx->dwFillColor>>10) & 31);
 554+ bltvertices[0].g = bltvertices[1].g = bltvertices[2].g = bltvertices[3].g =
 555+ _5to8bit((lpDDBltFx->dwFillColor>>5) & 31);
 556+ bltvertices[0].b = bltvertices[1].b = bltvertices[2].b = bltvertices[3].b =
 557+ _5to8bit(lpDDBltFx->dwFillColor & 31);
 558+ break;
 559+ case 16:
 560+ bltvertices[0].r = bltvertices[1].r = bltvertices[2].r = bltvertices[3].r =
 561+ _5to8bit((lpDDBltFx->dwFillColor>>11) & 31);
 562+ bltvertices[0].g = bltvertices[1].g = bltvertices[2].g = bltvertices[3].g =
 563+ _6to8bit((lpDDBltFx->dwFillColor>>5) & 63);
 564+ bltvertices[0].b = bltvertices[1].b = bltvertices[2].b = bltvertices[3].b =
 565+ _5to8bit(lpDDBltFx->dwFillColor & 31);
 566+ break;
 567+ case 24:
 568+ case 32:
 569+ bltvertices[0].r = bltvertices[1].r = bltvertices[2].r = bltvertices[3].r =
 570+ ((lpDDBltFx->dwFillColor>>16) & 255);
 571+ bltvertices[0].g = bltvertices[1].g = bltvertices[2].g = bltvertices[3].g =
 572+ ((lpDDBltFx->dwFillColor>>8) & 255);
 573+ bltvertices[0].b = bltvertices[1].b = bltvertices[2].b = bltvertices[3].b =
 574+ (lpDDBltFx->dwFillColor & 255);
 575+ default:
 576+ break;
 577+ }
 578+ }
 579+ else
 580+ {
 581+ glEnable(GL_TEXTURE_2D);
 582+ }
 583+ if(src) glBindTexture(GL_TEXTURE_2D,src->GetTexture());
 584+ if((dwFlags & DDBLT_KEYSRC) && (src && src->colorkey[0].enabled) && !(dwFlags & DDBLT_COLORFILL))
 585+ {
 586+ SetShader(PROG_CKEY,1);
 587+ GLint keyloc = glGetUniformLocation(shaders[PROG_CKEY].prog,"keyIn");
 588+ switch(ddInterface->GetBPP())
 589+ {
 590+ case 8:
 591+ glUniform3i(keyloc,src->colorkey[0].key.dwColorSpaceHighValue,src->colorkey[0].key.dwColorSpaceHighValue,
 592+ src->colorkey[0].key.dwColorSpaceHighValue);
 593+ break;
 594+ case 15:
 595+ glUniform3i(keyloc,_5to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>10 & 31),
 596+ _5to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>5 & 31),
 597+ _5to8bit(src->colorkey[0].key.dwColorSpaceHighValue & 31));
 598+ break;
 599+ case 16:
 600+ glUniform3i(keyloc,_5to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>11 & 31),
 601+ _6to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>5 & 63),
 602+ _5to8bit(src->colorkey[0].key.dwColorSpaceHighValue & 31));
 603+ break;
 604+ case 24:
 605+ case 32:
 606+ default:
 607+ glUniform3i(keyloc,(src->colorkey[0].key.dwColorSpaceHighValue>>16 & 255),
 608+ (src->colorkey[0].key.dwColorSpaceHighValue>>8 & 255),
 609+ (src->colorkey[0].key.dwColorSpaceHighValue & 255));
 610+ break;
 611+ }
 612+ GLint texloc = glGetUniformLocation(shaders[PROG_CKEY].prog,"myTexture");
 613+ glUniform1i(texloc,0);
 614+ }
 615+ else if(!(dwFlags & DDBLT_COLORFILL))
 616+ {
 617+ SetShader(PROG_TEXTURE,1);
 618+ GLint texloc = glGetUniformLocation(shaders[PROG_TEXTURE].prog,"Texture");
 619+ glUniform1i(texloc,0);
 620+ }
 621+ GLuint prog = GetProgram()&0xffffffff;
 622+ GLint viewloc = glGetUniformLocation(prog,"view");
 623+ glUniform4f(viewloc,0,(GLfloat)dest->fakex,0,(GLfloat)dest->fakey);
 624+ dest->dirty |= 2;
 625+ GLint xyloc = glGetAttribLocation(prog,"xy");
 626+ glEnableVertexAttribArray(xyloc);
 627+ glVertexAttribPointer(xyloc,2,GL_FLOAT,false,sizeof(BltVertex),&bltvertices[0].x);
 628+ if(dwFlags & DDBLT_COLORFILL)
 629+ {
 630+ GLint rgbloc = glGetAttribLocation(prog,"rgb");
 631+ glEnableVertexAttribArray(rgbloc);
 632+ glVertexAttribPointer(rgbloc,3,GL_UNSIGNED_BYTE,true,sizeof(BltVertex),&bltvertices[0].r);
 633+ }
 634+ else
 635+ {
 636+ GLint stloc = glGetAttribLocation(prog,"st");
 637+ glEnableVertexAttribArray(stloc);
 638+ glVertexAttribPointer(stloc,2,GL_FLOAT,false,sizeof(BltVertex),&bltvertices[0].s);
 639+ }
 640+ glDrawRangeElements(GL_TRIANGLE_STRIP,0,3,4,GL_UNSIGNED_SHORT,bltindices);
 641+ glDisable(GL_TEXTURE_2D);
 642+ SetFBO(0,0,false);
 643+ if(((ddsd.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER)) &&
 644+ (ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) ||
 645+ ((ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) &&
 646+ !(ddsd.ddsCaps.dwCaps & DDSCAPS_FLIP)))_DrawScreen(dest->texture,dest->paltex,dest,dest,viewrect);
 647+ return DD_OK;
 648+}
 649+
 650+GLuint glRenderer::_MakeTexture(GLint min, GLint mag, GLint wraps, GLint wrapt, DWORD width, DWORD height, GLint texformat1, GLint texformat2, GLint texformat3)
 651+{
 652+ GLuint texture;
 653+ glGenTextures(1,&texture);
 654+ glBindTexture(GL_TEXTURE_2D,texture);
 655+ glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
 656+ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,(GLfloat)min);
 657+ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,(GLfloat)mag);
 658+ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,(GLfloat)wraps);
 659+ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,(GLfloat)wrapt);
 660+ glTexImage2D(GL_TEXTURE_2D,0,texformat3,width,height,0,texformat1,texformat2,NULL);
 661+ return texture;
 662+}
 663+
 664+void glRenderer::_DrawScreen(GLuint texture, GLuint paltex, glDirectDrawSurface7 *dest, glDirectDrawSurface7 *src, RECT *viewrect)
 665+{
 666+ LONG sizes[6];
 667+ GLfloat view[4];
 668+ if(src->dirty & 1)
 669+ {
 670+ _UploadTexture(src->buffer,src->bigbuffer,texture,src->ddsd.dwWidth,src->ddsd.dwHeight,
 671+ src->fakex,src->fakey,src->ddsd.lPitch,
 672+ (NextMultipleOf4((ddInterface->GetBPPMultipleOf8()/8)*src->fakex)),
 673+ src->ddsd.ddpfPixelFormat.dwRGBBitCount,src->texformat,src->texformat2,src->texformat3);
 674+ src->dirty &= ~1;
 675+ }
 676+ if(dest->ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
 677+ {
 678+ if(ddInterface->GetFullscreen())
 679+ {
 680+ ddInterface->GetSizes(sizes);
 681+ glViewport(0,0,sizes[4],sizes[5]);
 682+ view[0] = (GLfloat)-(sizes[4]-sizes[0])/2;
 683+ view[1] = (GLfloat)(sizes[4]-sizes[0])/2+sizes[0];
 684+ view[2] = (GLfloat)(sizes[5]-sizes[1])/2+sizes[1];
 685+ view[3] = (GLfloat)-(sizes[5]-sizes[1])/2;
 686+ }
 687+ else
 688+ {
 689+ glViewport(0,0,viewrect->right,viewrect->bottom);
 690+ ClientToScreen(hRenderWnd,(LPPOINT)&viewrect->left);
 691+ ClientToScreen(hRenderWnd,(LPPOINT)&viewrect->right);
 692+ view[0] = (GLfloat)viewrect->left;
 693+ view[1] = (GLfloat)viewrect->right;
 694+ view[2] = (GLfloat)dest->fakey-(GLfloat)viewrect->top;
 695+ view[3] = (GLfloat)dest->fakey-(GLfloat)viewrect->bottom;
 696+ }
 697+ }
 698+ else
 699+ {
 700+ view[0] = 0;
 701+ view[1] = (GLfloat)dest->fakex;
 702+ view[2] = 0;
 703+ view[3] = (GLfloat)dest->fakey;
 704+ }
 705+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 706+ if(ddInterface->GetBPP() == 8)
 707+ {
 708+ SetShader(PROG_PAL256,true);
 709+ glBindTexture(GL_TEXTURE_2D,paltex);
 710+ glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,256,1,0,GL_RGBA,GL_UNSIGNED_BYTE,dest->palette->GetPalette(NULL));
 711+ GLint palloc = glGetUniformLocation(shaders[PROG_PAL256].prog,"ColorTable");
 712+ GLint texloc = glGetUniformLocation(shaders[PROG_PAL256].prog,"IndexTexture");
 713+ glUniform1i(texloc,0);
 714+ glUniform1i(palloc,1);
 715+ glActiveTexture(GL_TEXTURE0);
 716+ glBindTexture(GL_TEXTURE_2D,texture);
 717+ glActiveTexture(GL_TEXTURE1);
 718+ glBindTexture(GL_TEXTURE_2D,paltex);
 719+ glActiveTexture(GL_TEXTURE0);
 720+ }
 721+ else
 722+ {
 723+ SetShader(PROG_TEXTURE,true);
 724+ glEnable(GL_TEXTURE_2D);
 725+ glBindTexture(GL_TEXTURE_2D,texture);
 726+ GLuint prog = GetProgram() & 0xFFFFFFFF;
 727+ GLint texloc = glGetUniformLocation(prog,"Texture");
 728+ }
 729+ GLuint prog = GetProgram();
 730+ GLint viewloc = glGetUniformLocation(prog,"view");
 731+ glUniform4f(viewloc,view[0],view[1],view[2],view[3]);
 732+ if(ddInterface->GetFullscreen())
 733+ {
 734+ bltvertices[0].x = bltvertices[2].x = (float)sizes[0];
 735+ bltvertices[0].y = bltvertices[1].y = bltvertices[1].x = bltvertices[3].x = 0.;
 736+ bltvertices[2].y = bltvertices[3].y = (float)sizes[1];
 737+ }
 738+ else
 739+ {
 740+ bltvertices[0].x = bltvertices[2].x = (float)dest->fakex;
 741+ bltvertices[0].y = bltvertices[1].y = bltvertices[1].x = bltvertices[3].x = 0.;
 742+ bltvertices[2].y = bltvertices[3].y = (float)dest->fakey;
 743+ }
 744+ bltvertices[0].s = bltvertices[0].t = bltvertices[1].t = bltvertices[2].s = 1.;
 745+ bltvertices[1].s = bltvertices[2].t = bltvertices[3].s = bltvertices[3].t = 0.;
 746+ GLint xyloc = glGetAttribLocation(prog,"xy");
 747+ glEnableVertexAttribArray(xyloc);
 748+ glVertexAttribPointer(xyloc,2,GL_FLOAT,false,sizeof(BltVertex),&bltvertices[0].x);
 749+ GLint stloc = glGetAttribLocation(prog,"st");
 750+ glEnableVertexAttribArray(stloc);
 751+ glVertexAttribPointer(stloc,2,GL_FLOAT,false,sizeof(BltVertex),&bltvertices[0].s);
 752+ glDrawRangeElements(GL_TRIANGLE_STRIP,0,3,4,GL_UNSIGNED_SHORT,bltindices);
 753+ glDisable(GL_TEXTURE_2D);
 754+ glFlush();
 755+ if(hasHWnd) SwapBuffers(hDC);
 756+ else
 757+ {
 758+ glReadBuffer(GL_FRONT);
 759+ glBindBuffer(GL_PIXEL_PACK_BUFFER,PBO);
 760+ GLint packalign;
 761+ glGetIntegerv(GL_PACK_ALIGNMENT,&packalign);
 762+ glPixelStorei(GL_PACK_ALIGNMENT,1);
 763+ glReadPixels(0,0,sizes[4],sizes[5],GL_BGRA,GL_UNSIGNED_BYTE,0);
 764+ GLubyte *pixels = (GLubyte*)glMapBuffer(GL_PIXEL_PACK_BUFFER,GL_READ_ONLY);
 765+ for(int i = 0; i < sizes[5];i++)
 766+ {
 767+ memcpy(&dib.pixels[dib.pitch*i],
 768+ &pixels[((sizes[5]-1)-i)*(sizes[4]*4)],sizes[4]*4);
 769+ }
 770+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
 771+ glBindBuffer(GL_PIXEL_PACK_BUFFER,0);
 772+ glPixelStorei(GL_PACK_ALIGNMENT,packalign);
 773+ HDC hRenderDC = (HDC)::GetDC(hRenderWnd);
 774+ HGDIOBJ hPrevObj = 0;
 775+ POINT dest = {0,0};
 776+ POINT src = {0,0};
 777+ SIZE wnd = {dib.width,dib.height};
 778+ BLENDFUNCTION func = {AC_SRC_OVER,0,255,AC_SRC_ALPHA};
 779+ hPrevObj = SelectObject(dib.hdc,dib.hbitmap);
 780+ ClientToScreen(hRenderWnd,&dest);
 781+ UpdateLayeredWindow(hRenderWnd,hRenderDC,&dest,&wnd,
 782+ dib.hdc,&src,0,&func,ULW_ALPHA);
 783+ SelectObject(dib.hdc,hPrevObj);
 784+ ::ReleaseDC(hRenderWnd,hRenderDC);
 785+ }
 786+
 787+}
 788+
 789+void glRenderer::_DeleteTexture(GLuint texture)
 790+{
 791+ glDeleteTextures(1,&texture);
 792+}
Index: ddraw/glRenderer.h
@@ -0,0 +1,106 @@
 2+// DXGL
 3+// Copyright (C) 2012 William Feely
 4+
 5+// This library is free software; you can redistribute it and/or
 6+// modify it under the terms of the GNU Lesser General Public
 7+// License as published by the Free Software Foundation; either
 8+// version 2.1 of the License, or (at your option) any later version.
 9+
 10+// This library is distributed in the hope that it will be useful,
 11+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 12+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 13+// Lesser General Public License for more details.
 14+
 15+// You should have received a copy of the GNU Lesser General Public
 16+// License along with this library; if not, write to the Free Software
 17+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 18+
 19+#ifndef _GLRENDERER_H
 20+#define _GLRENDERER_H
 21+
 22+typedef struct
 23+{
 24+ float Version;
 25+ float ShaderVer;
 26+ int TextureMaxX;
 27+ int TextureMaxY;
 28+ bool NonPowerOfTwo;
 29+ int RenderToTexture; // 0 - no support, 1 -
 30+ int MultiTextureExt;
 31+ int PalettedTextures;
 32+} GLCAPS;
 33+typedef struct
 34+{
 35+ bool enabled;
 36+ int width;
 37+ int height;
 38+ int pitch;
 39+ HDC hdc;
 40+ HBITMAP hbitmap;
 41+ BITMAPINFO info;
 42+ BYTE *pixels;
 43+} DIB;
 44+
 45+struct BltVertex
 46+{
 47+ GLfloat x,y;
 48+ GLubyte r,g,b,a;
 49+ GLfloat s,t;
 50+ GLfloat padding[3];
 51+};
 52+
 53+extern BltVertex bltvertices[4];
 54+
 55+#define GLEVENT_NULL 0
 56+#define GLEVENT_DELETE 1
 57+#define GLEVENT_CREATE 2
 58+#define GLEVENT_UPLOAD 3
 59+#define GLEVENT_DOWNLOAD 4
 60+#define GLEVENT_DELETETEX 5
 61+#define GLEVENT_BLT 6
 62+#define GLEVENT_DRAWSCREEN 7
 63+
 64+extern inline void SetSwap(int swap);
 65+
 66+class glRenderer
 67+{
 68+public:
 69+ glRenderer(int width, int height, int bpp, bool fullscreen, HWND hwnd, glDirectDraw7 *glDD7);
 70+ ~glRenderer();
 71+ static DWORD WINAPI ThreadEntry(void *entry);
 72+ int UploadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y, int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2, int texformat3);
 73+ int DownloadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y, int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2);
 74+ HRESULT Blt(LPRECT lpDestRect, glDirectDrawSurface7 *src,
 75+ glDirectDrawSurface7 *dest, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx);
 76+ GLuint MakeTexture(GLint min, GLint mag, GLint wraps, GLint wrapt, DWORD width, DWORD height, GLint texformat1, GLint texformat2, GLint texformat3);
 77+ void DrawScreen(GLuint texture, GLuint paltex, glDirectDrawSurface7 *dest, glDirectDrawSurface7 *src);
 78+ void DeleteTexture(GLuint texture);
 79+private:
 80+ // In-thread APIs
 81+ DWORD _Entry();
 82+ BOOL _InitGL(int width, int height, int bpp, int fullscreen, HWND hWnd, glDirectDraw7 *glDD7);
 83+ int _UploadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y, int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2, int texformat3);
 84+ int _DownloadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y, int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2);
 85+ HRESULT _Blt(LPRECT lpDestRect, glDirectDrawSurface7 *src,
 86+ glDirectDrawSurface7 *dest, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx, RECT *viewrect);
 87+ GLuint _MakeTexture(GLint min, GLint mag, GLint wraps, GLint wrapt, DWORD width, DWORD height, GLint texformat1, GLint texformat2, GLint texformat3);
 88+ void _DrawScreen(GLuint texture, GLuint paltex, glDirectDrawSurface7 *dest, glDirectDrawSurface7 *src, RECT *viewrect);
 89+ void _DeleteTexture(GLuint texture);
 90+ glDirectDraw7 *ddInterface;
 91+ int eventnum;
 92+ void* inputs[32];
 93+ void* outputs[32];
 94+ HANDLE hThread;
 95+ HANDLE EventSend;
 96+ HANDLE EventWait;
 97+ HGLRC hRC;
 98+ HDC hDC;
 99+ HWND hWnd;
 100+ HWND hRenderWnd;
 101+ bool hasHWnd;
 102+ GLCAPS gl_caps;
 103+ DIB dib;
 104+ GLuint PBO;
 105+};
 106+
 107+#endif //_GLRENDERER_H
\ No newline at end of file