DXGL r149 - Code Review

Jump to navigation Jump to search
Repository:DXGL
Revision:r148‎ | r149 | r150 >
Date:17:47, 28 May 2012
Author:admin
Status:new
Tags:
Comment:
Beginning of asynchronous operations. Contains some deadlocks and breaks Direct3D.
Modified paths:
  • /ddraw/glDirect3DDevice.cpp (modified) (history)
  • /ddraw/glDirect3DDevice.h (modified) (history)
  • /ddraw/glDirectDraw.cpp (modified) (history)
  • /ddraw/glRenderer.cpp (modified) (history)
  • /ddraw/glRenderer.h (modified) (history)

Diff [purge]

Index: ddraw/glDirect3DDevice.cpp
@@ -210,16 +210,14 @@
211211 diffuse = specular = NULL;
212212 ZeroMemory(texcoords,8*sizeof(GLfloat*));
213213 memcpy(renderstate,renderstate_default,153*sizeof(DWORD));
214 - __gluMakeIdentityf(matWorld);
215 - __gluMakeIdentityf(matView);
216 - __gluMakeIdentityf(matProjection);
217 - __gluMakeIdentityf(matNormal);
 214+ __gluMakeIdentityf((GLfloat*)&matrices[0]);
 215+ for(int i = 1; i < 24; i++)
 216+ memcpy(&matrices[i],&matrices[0],sizeof(D3DMATRIX));
218217 texstages[0] = texstagedefault0;
219218 texstages[1] = texstages[2] = texstages[3] = texstages[4] =
220219 texstages[5] = texstages[6] = texstages[7] = texstagedefault1;
221220 refcount = 1;
222221 inscene = false;
223 - normal_dirty = false;
224222 this->glD3D7 = glD3D7;
225223 glD3D7->AddRef();
226224 this->glDDS7 = glDDS7;
@@ -235,6 +233,8 @@
236234 d3ddesc.dwMaxTextureWidth = d3ddesc.dwMaxTextureHeight =
237235 d3ddesc.dwMaxTextureRepeat = d3ddesc.dwMaxTextureAspectRatio = glD3D7->glDD7->renderer->gl_caps.TextureMax;
238236 glD3D7->glDD7->renderer->InitD3D(zbuffer);
 237+ glD3D7->glDD7->renderer->SetRenderState(0,153,renderstate);
 238+ glD3D7->glDD7->renderer->SetMatrix(0,24,matrices);
239239 }
240240 glDirect3DDevice7::~glDirect3DDevice7()
241241 {
@@ -513,8 +513,8 @@
514514 if(!inscene) return D3DERR_SCENE_NOT_IN_SCENE;
515515 HRESULT err = fvftoglvertex(dwVertexTypeDesc,(LPDWORD)lpvVertices);
516516 if(err != D3D_OK) return err;
517 - return glD3D7->glDD7->renderer->DrawPrimitives(this,setdrawmode(d3dptPrimitiveType),vertdata,texformats,
518 - dwVertexCount,lpwIndices,dwIndexCount,dwFlags);
 517+ return glD3D7->glDD7->renderer->DrawPrimitives(this,setdrawmode(d3dptPrimitiveType),
 518+ vertdata,true,texformats,dwVertexCount,lpwIndices,dwIndexCount,dwFlags);
519519 }
520520 HRESULT WINAPI glDirect3DDevice7::DrawIndexedPrimitiveStrided(D3DPRIMITIVETYPE d3dptPrimitiveType, DWORD dwVertexTypeDesc,
521521 LPD3DDRAWPRIMITIVESTRIDEDDATA lpvVerticexArray, DWORD dwVertexCount, LPWORD lpwIndices, DWORD dwIndexCount, DWORD dwFlags)
@@ -772,20 +772,9 @@
773773 HRESULT WINAPI glDirect3DDevice7::GetTransform(D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix)
774774 {
775775 if(!this) return DDERR_INVALIDPARAMS;
776 - switch(dtstTransformStateType)
777 - {
778 - case D3DTRANSFORMSTATE_WORLD:
779 - memcpy(lpD3DMatrix,&matWorld,sizeof(D3DMATRIX));
780 - return D3D_OK;
781 - case D3DTRANSFORMSTATE_VIEW:
782 - memcpy(lpD3DMatrix,&matView,sizeof(D3DMATRIX));
783 - return D3D_OK;
784 - case D3DTRANSFORMSTATE_PROJECTION:
785 - memcpy(lpD3DMatrix,&matProjection,sizeof(D3DMATRIX));
786 - return D3D_OK;
787 - default:
788 - ERR(DDERR_INVALIDPARAMS);
789 - }
 776+ if(dtstTransformStateType > D3DTRANSFORMSTATE_TEXTURE7) return DDERR_INVALIDPARAMS;
 777+ memcpy(lpD3DMatrix,&matrices[dtstTransformStateType],sizeof(D3DMATRIX));
 778+ return D3D_OK;
790779 }
791780 HRESULT WINAPI glDirect3DDevice7::GetViewport(LPD3DVIEWPORT7 lpViewport)
792781 {
@@ -1138,22 +1127,10 @@
11391128 HRESULT WINAPI glDirect3DDevice7::SetTransform(D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix)
11401129 {
11411130 if(!this) return DDERR_INVALIDPARAMS;
1142 - switch(dtstTransformStateType)
1143 - {
1144 - case D3DTRANSFORMSTATE_WORLD:
1145 - memcpy(&matWorld,lpD3DMatrix,sizeof(D3DMATRIX));
1146 - normal_dirty = true;
1147 - return D3D_OK;
1148 - case D3DTRANSFORMSTATE_VIEW:
1149 - memcpy(&matView,lpD3DMatrix,sizeof(D3DMATRIX));
1150 - normal_dirty = true;
1151 - return D3D_OK;
1152 - case D3DTRANSFORMSTATE_PROJECTION:
1153 - memcpy(&matProjection,lpD3DMatrix,sizeof(D3DMATRIX));
1154 - return D3D_OK;
1155 - default:
1156 - ERR(DDERR_INVALIDPARAMS);
1157 - }
 1131+ if(dtstTransformStateType > D3DTRANSFORMSTATE_TEXTURE7) return DDERR_INVALIDPARAMS;
 1132+ memcpy(&matrices[dtstTransformStateType],lpD3DMatrix,sizeof(D3DMATRIX));
 1133+ glD3D7->glDD7->renderer->SetMatrix(dtstTransformStateType,1,lpD3DMatrix);
 1134+ return D3D_OK;
11581135 }
11591136 HRESULT WINAPI glDirect3DDevice7::SetViewport(LPD3DVIEWPORT7 lpViewport)
11601137 {
@@ -1187,26 +1164,3 @@
11881165 return D3D_OK;
11891166 }
11901167
1191 -void glDirect3DDevice7::UpdateNormalMatrix()
1192 -{
1193 - GLfloat worldview[16];
1194 - GLfloat tmp[16];
1195 -
1196 - ZeroMemory(&worldview,sizeof(D3DMATRIX));
1197 - ZeroMemory(&tmp,sizeof(D3DMATRIX));
1198 - __gluMultMatricesf(matWorld,matView,worldview); // Get worldview
1199 - if(__gluInvertMatrixf(worldview,tmp)) // Invert
1200 - {
1201 - memcpy(matNormal,tmp,3*sizeof(GLfloat));
1202 - memcpy(matNormal+3,tmp+4,3*sizeof(GLfloat));
1203 - memcpy(matNormal+6,tmp+8,3*sizeof(GLfloat));
1204 - }
1205 - else
1206 - {
1207 - memcpy(matNormal,worldview,3*sizeof(GLfloat));
1208 - memcpy(matNormal+3,worldview+4,3*sizeof(GLfloat));
1209 - memcpy(matNormal+6,worldview+8,3*sizeof(GLfloat));
1210 - }
1211 -
1212 - normal_dirty = false;
1213 -}
\ No newline at end of file
Index: ddraw/glDirect3DDevice.h
@@ -122,12 +122,7 @@
123123 HRESULT WINAPI ValidateDevice(LPDWORD lpdwPasses);
124124 void SetArraySize(DWORD size, DWORD vertex, DWORD texcoord);
125125 __int64 SelectShader(GLVERTEX *VertexType);
126 - void UpdateNormalMatrix();
127 - GLfloat matWorld[16];
128 - GLfloat matView[16];
129 - GLfloat matProjection[16];
130 - GLfloat matNormal[9];
131 - bool normal_dirty;
 126+ D3DMATRIX matrices[24];
132127 D3DMATERIAL7 material;
133128 D3DVIEWPORT7 viewport;
134129 glDirect3DLight **lights;
@@ -153,7 +148,7 @@
154149 GLubyte *ambient;
155150 GLfloat *texcoords[8];
156151 GLVERTEX vertdata[18];
157 - int texformats[8];
 152+ DWORD texformats[8];
158153 };
159154
160155 #endif //__GLDIRECT3DDEVICE_H
\ No newline at end of file
Index: ddraw/glDirectDraw.cpp
@@ -1380,7 +1380,7 @@
13811381
13821382 void glDirectDraw7::DeleteGL()
13831383 {
1384 - delete renderer;
 1384+ if(renderer) delete renderer;
13851385 renderer = NULL;
13861386 }
13871387
Index: ddraw/glRenderer.cpp
@@ -15,6 +15,11 @@
1616 // License along with this library; if not, write to the Free Software
1717 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1818
 19+/**
 20+ * @file glRenderer.cpp
 21+ * @brief Contains the functions that control the DXGL rendering pipeline.
 22+ */
 23+
1924 #include "common.h"
2025 #include "glDirectDraw.h"
2126 #include "glDirectDrawSurface.h"
@@ -26,6 +31,7 @@
2732 #include "ddraw.h"
2833 #include "scalers.h"
2934 #include <string>
 35+#include <cstdarg>
3036 using namespace std;
3137 #include "shadergen.h"
3238 #include "matrix.h"
@@ -37,12 +43,55 @@
3844 int backy = 0;
3945 BltVertex bltvertices[4];
4046 const GLushort bltindices[4] = {0,1,2,3};
 47+const RECT nullrect = {0,0,0,0};
4148
 49+/**
 50+ * Waits for an object to be signaled, while processing window messages received
 51+ * by the calling thread.
 52+ * @param object
 53+ * Win32 handle to the object to wait for
 54+ */
 55+void WaitForMessageAndObject(HANDLE object)
 56+{
 57+ bool loop = true;
 58+ DWORD wake;
 59+ MSG msg;
 60+ DWORD error;
 61+ while(loop)
 62+ {
 63+ wake = MsgWaitForMultipleObjects(1,&object,FALSE,INFINITE,QS_ALLEVENTS);
 64+ if(wake == (WAIT_OBJECT_0+1))
 65+ {
 66+ while(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
 67+ {
 68+ TranslateMessage(&msg);
 69+ DispatchMessage(&msg);
 70+ }
 71+ }
 72+ else loop = false;
 73+ error = GetLastError();
 74+ }
 75+}
4276
 77+/**
 78+ * Expands a 5-bit value to 8 bits.
 79+ * @param number
 80+ * 5-bit value to convert to 8 bits.
 81+ * @return
 82+ * Converted 8-bit value
 83+ */
4384 inline int _5to8bit(int number)
4485 {
4586 return (number << 3)+(number>>2);
4687 }
 88+
 89+/**
 90+ * Expands a 6-bit value to 8 bits.
 91+ * @param number
 92+ * 6-bit value to convert to 8 bits.
 93+ * @return
 94+ * Converted 8-bit value
 95+ */
4796 inline int _6to8bit(int number)
4897 {
4998 return (number<<2)+(number>>4);
@@ -50,6 +99,12 @@
51100
52101 int oldswap = 0;
53102 int swapinterval = 0;
 103+
 104+/**
 105+ * Sets the Windows OpenGL swap interval
 106+ * @param swap
 107+ * Number of vertical retraces to wait per frame, 0 disable vsync
 108+ */
54109 inline void SetSwap(int swap)
55110 {
56111 if(swap != oldswap)
@@ -60,8 +115,151 @@
61116 }
62117 }
63118
64 -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)
 119+/**
 120+ * Adds a command to the renderer queue.\n
 121+ * If the command requires more space than the queue buffer, the buffer will be
 122+ * expanded. If there is no free space for the command, execution will pause
 123+ * until the queue has been sufficiently emptied.
 124+ * @param opcode
 125+ * Code that describes the command to be added to the queue.
 126+ * @param mode
 127+ * Method to use for synchronization:
 128+ * - 0: Do not fail the call
 129+ * - 1: Fail if queue is full
 130+ * - 2: Fail if queue is not empty
 131+ * @param size
 132+ * Size of the command in DWORDs
 133+ * @param paramcount
 134+ * Number of parameters to add to the queue command.
 135+ * @param ...
 136+ * Parameters for the command, when required. This is given in pairs of two
 137+ * arguments:
 138+ * - size: The size of the parameter, in bytes. Note that parameters are DWORD
 139+ * aligned. The size cannot exceed the size of the command, minus data already
 140+ * written to the queue.
 141+ * - pointer: A pointer to the data to be added to the command.\n
 142+ * If no parameters are used for the opcode, then supply 0 and NULL for the ...
 143+ * parameter.
 144+ * @return
 145+ * Zero if the call succeeds, nonzero otherwise.
 146+ */
 147+int glRenderer::AddQueue(DWORD opcode, int mode, DWORD size, int paramcount, ...)
65148 {
 149+ EnterCriticalSection(&queuecs);
 150+ if((mode == 2) && queuelength)
 151+ {
 152+ LeaveCriticalSection(&queuecs);
 153+ return 1;
 154+ }
 155+ va_list params;
 156+ // Check queue size
 157+ va_start(params,paramcount);
 158+ int argsize;
 159+ void *argptr;
 160+ if(size > queuesize)
 161+ {
 162+ queue = (LPDWORD)realloc(queue,(queuesize+size)*sizeof(DWORD));
 163+ queuesize += size;
 164+ }
 165+ if(queuesize - queue_write < size)
 166+ {
 167+ if(queue_read < size)
 168+ {
 169+ if(mode == 1)
 170+ {
 171+ LeaveCriticalSection(&queuecs);
 172+ return 1;
 173+ }
 174+ if(queue_write < queuesize)
 175+ {
 176+ queue[queue_write] = OP_RESETQUEUE;
 177+ queuelength++;
 178+ }
 179+ LeaveCriticalSection(&queuecs);
 180+ Sync(size);
 181+ EnterCriticalSection(&queuecs);
 182+ }
 183+ }
 184+ if(queue_write < queue_read)
 185+ {
 186+ if(queue_read - queue_write < size)
 187+ {
 188+ LeaveCriticalSection(&queuecs);
 189+ Sync(size);
 190+ EnterCriticalSection(&queuecs);
 191+ }
 192+ }
 193+ queue[queue_write++] = opcode;
 194+ queue[queue_write++] = size;
 195+ size -= 2;
 196+ for(int i = 0; i < paramcount; i++)
 197+ {
 198+ argsize = va_arg(params,int);
 199+ argptr = va_arg(params,void*);
 200+ if(!argsize) continue;
 201+ if((NextMultipleOf4(argsize)/4) > size) break;
 202+ queue[queue_write++] = argsize;
 203+ if(argptr) memcpy(queue+queue_write,argptr,argsize);
 204+ queue_write += (NextMultipleOf4(argsize)/4);
 205+ size -= (NextMultipleOf4(argsize)/4);
 206+ }
 207+ va_end(params);
 208+ queuelength++;
 209+ if(!running) SetEvent(start);
 210+ LeaveCriticalSection(&queuecs);
 211+ return 0;
 212+}
 213+
 214+/**
 215+ * Waits until the specified amount of queue space is free
 216+ * @param size
 217+ * If nonzero, the number of DWORDs that must be available within the queue.
 218+ * If zero, waits until the queue is empty.
 219+ */
 220+void glRenderer::Sync(int size)
 221+{
 222+ EnterCriticalSection(&queuecs);
 223+ if(!queuelength && !running)
 224+ {
 225+ LeaveCriticalSection(&queuecs);
 226+ return;
 227+ }
 228+ ResetEvent(sync);
 229+ syncsize = size;
 230+ if(!running) SetEvent(start);
 231+ LeaveCriticalSection(&queuecs);
 232+ WaitForMessageAndObject(sync);
 233+}
 234+
 235+/**
 236+ * Internal function for uploading surface content to an OpenGL texture
 237+ * @param buffer
 238+ * Contains the contents of the surface
 239+ * @param bigbuffer
 240+ * Optional buffer to receive the rescaled surface contents, for when primary
 241+ * scaling is enabled.
 242+ * @param texture
 243+ * OpenGL texture name to upload to
 244+ * @param x,y
 245+ * Width and height of the surface
 246+ * @param bigx,bigy
 247+ * Width and height of the scaled surface buffer
 248+ * @param pitch
 249+ * Bytes from one line of graphics to the next in the surface
 250+ * @param bigpitch
 251+ * Pitch of the scaled surface buffer
 252+ * @param bpp
 253+ * Number of bits per surface pixel
 254+ * @param texformat
 255+ * OpenGL format parameter for glTexImage2D
 256+ * @param texformat2
 257+ * OpenGL type parameter for glTexImage2D
 258+ * @param texformat3
 259+ * OpenGL internalformat parameter for glTexImage2D
 260+ */
 261+void glRenderer::_UploadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y,
 262+ int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2, int texformat3)
 263+{
66264 if(bpp == 15) bpp = 16;
67265 glBindTexture(GL_TEXTURE_2D,texture); // Select surface's texture
68266 if((x == bigx && y == bigy) || !bigbuffer)
@@ -88,9 +286,35 @@
89287 }
90288 glTexImage2D(GL_TEXTURE_2D,0,texformat3,bigx,bigy,0,texformat,texformat2,bigbuffer);
91289 }
92 - return 0;
93290 }
94 -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)
 291+
 292+
 293+/**
 294+ * Internal function for downloading surface content from an OpenGL texture
 295+ * @param buffer
 296+ * Buffer to receive the surface contents
 297+ * @param bigbuffer
 298+ * Optional buffer to receive the rescaled surface contents, for when primary
 299+ * scaling is enabled.
 300+ * @param texture
 301+ * OpenGL texture name to download from
 302+ * @param x,y
 303+ * Width and height of the surface
 304+ * @param bigx,bigy
 305+ * Width and height of the scaled surface buffer
 306+ * @param pitch
 307+ * Bytes from one line of graphics to the next in the surface
 308+ * @param bigpitch
 309+ * Pitch of the scaled surface buffer
 310+ * @param bpp
 311+ * Number of bits per surface pixel
 312+ * @param texformat
 313+ * OpenGL format parameter for glGetTexImage
 314+ * @param texformat2
 315+ * OpenGL type parameter for glGetTexImage
 316+ */
 317+void glRenderer::_DownloadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y,
 318+ int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2)
95319 {
96320 glBindTexture(GL_TEXTURE_2D,texture); // Select surface's texture
97321 if((bigx == x && bigy == y) || !bigbuffer)
@@ -118,21 +342,34 @@
119343 break;
120344 }
121345 }
122 - return 0;
123346 }
124347
 348+/**
 349+ * Constructor for the glRenderer object
 350+ * @param width,height,bpp
 351+ * Width, height, and BPP of the rendering window
 352+ * @param fullscreen
 353+ * True if fullscreen mode is required, false for windowed
 354+ * @param hwnd
 355+ * Handle of the window to render into. If this value is NULL, then a transparent
 356+ * layered window will be created for the renderer.
 357+ * @param glDD7
 358+ * Pointer to the glDirectDraw7 object that is managing the glRenderer object
 359+ */
125360 glRenderer::glRenderer(int width, int height, int bpp, bool fullscreen, HWND hwnd, glDirectDraw7 *glDD7)
126361 {
127 - MSG Msg;
128 - wndbusy = false;
129362 hDC = NULL;
130363 hRC = NULL;
131364 PBO = 0;
132365 hasHWnd = false;
133366 dib.enabled = false;
 367+ normal_dirty = false;
 368+ running = false;
134369 hWnd = hwnd;
135370 hRenderWnd = NULL;
136 - InitializeCriticalSection(&cs);
 371+ busy = CreateEvent(NULL,FALSE,FALSE,NULL);
 372+ InitializeCriticalSection(&commandcs);
 373+ InitializeCriticalSection(&queuecs);
137374 if(fullscreen)
138375 {
139376 SetWindowLongPtrA(hWnd,GWL_EXSTYLE,WS_EX_APPWINDOW);
@@ -143,6 +380,7 @@
144381 {
145382 // TODO: Adjust window rect
146383 }
 384+ EnterCriticalSection(&commandcs);
147385 SetWindowPos(hWnd,HWND_TOP,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
148386 inputs[0] = (void*)width;
149387 inputs[1] = (void*)height;
@@ -151,39 +389,31 @@
152390 inputs[4] = (void*)hWnd;
153391 inputs[5] = glDD7;
154392 inputs[6] = this;
155 - wndbusy = true;
156393 hThread = CreateThread(NULL,0,ThreadEntry,inputs,0,NULL);
157 - while(wndbusy)
158 - {
159 - while(PeekMessage(&Msg,hRenderWnd,0,0,PM_REMOVE))
160 - {
161 - TranslateMessage(&Msg);
162 - DispatchMessage(&Msg);
163 - }
164 - Sleep(0);
165 - }
 394+ WaitForMessageAndObject(busy);
 395+ LeaveCriticalSection(&commandcs);
166396 }
167397
 398+/**
 399+ * Destructor for the glRenderer object
 400+ */
168401 glRenderer::~glRenderer()
169402 {
170 - MSG Msg;
171 - EnterCriticalSection(&cs);
172 - wndbusy = true;
173 - SendMessage(hRenderWnd,GLEVENT_DELETE,0,0);
174 - while(wndbusy)
175 - {
176 - while(PeekMessage(&Msg,hRenderWnd,0,0,PM_REMOVE))
177 - {
178 - TranslateMessage(&Msg);
179 - DispatchMessage(&Msg);
180 - }
181 - Sleep(0);
182 - }
183 - LeaveCriticalSection(&cs);
184 - DeleteCriticalSection(&cs);
 403+ EnterCriticalSection(&commandcs);
 404+ AddQueue(OP_DELETE,0,2,0,NULL);
 405+ Sync(0);
 406+ LeaveCriticalSection(&commandcs);
 407+ DeleteCriticalSection(&commandcs);
 408+ CloseHandle(busy);
 409+ CloseHandle(sync);
 410+ CloseHandle(start);
185411 }
186412
187 -
 413+/**
 414+ * Entry point for the renderer thread
 415+ * @param entry
 416+ * Pointer to the inputs passed by the CreateThread function
 417+ */
188418 DWORD WINAPI glRenderer::ThreadEntry(void *entry)
189419 {
190420 void **inputsin = (void**)entry;
@@ -191,249 +421,459 @@
192422 return This->_Entry();
193423 }
194424
 425+/**
 426+ * Creates an OpenGL texture.
 427+ * @param min,mag
 428+ * Minification and magnification filters for the OpenGL texture
 429+ * @param wraps,wrapt
 430+ * OpenGL texture wrap parameters
 431+ * @param width,height
 432+ * Width and height of the texture.
 433+ * @param texformat
 434+ * OpenGL format parameter for glTexImage2D
 435+ * @param texformat2
 436+ * OpenGL type parameter for glTexImage2D
 437+ * @param texformat3
 438+ * OpenGL internalformat parameter for glTexImage2D
 439+ * @return
 440+ * Number representing the texture created by OpenGL.
 441+ */
195442 GLuint glRenderer::MakeTexture(GLint min, GLint mag, GLint wraps, GLint wrapt, DWORD width, DWORD height, GLint texformat1, GLint texformat2, GLint texformat3)
196443 {
197 - EnterCriticalSection(&cs);
198 - inputs[0] = (void*)min;
199 - inputs[1] = (void*)mag;
200 - inputs[2] = (void*)wraps;
201 - inputs[3] = (void*)wrapt;
202 - inputs[4] = (void*)width;
203 - inputs[5] = (void*)height;
204 - inputs[6] = (void*)texformat1;
205 - inputs[7] = (void*)texformat2;
206 - inputs[8] = (void*)texformat3;
207 - SendMessage(hRenderWnd,GLEVENT_CREATE,0,0);
208 - LeaveCriticalSection(&cs);
209 - return (GLuint)outputs[0];
 444+ EnterCriticalSection(&commandcs);
 445+ AddQueue(OP_CREATE,0,20,9,4,&min,4,&mag,4,&wraps,4,&wrapt,4,&width,
 446+ 4,&height,4,&texformat1,4,&texformat2,4,&texformat3);
 447+ Sync(0);
 448+ LeaveCriticalSection(&commandcs);
 449+ return (GLuint)output;
210450 }
211451
212 -int glRenderer::UploadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y,
 452+
 453+/**
 454+ * Uploads the content of a surface to an OpenGL texture.
 455+ * @param buffer
 456+ * Contains the contents of the surface
 457+ * @param bigbuffer
 458+ * Optional buffer to receive the rescaled surface contents, for when primary
 459+ * scaling is enabled.
 460+ * @param texture
 461+ * OpenGL texture name to upload to
 462+ * @param x,y
 463+ * Width and height of the surface
 464+ * @param bigx,bigy
 465+ * Width and height of the scaled surface buffer
 466+ * @param pitch
 467+ * Bytes from one line of graphics to the next in the surface
 468+ * @param bigpitch
 469+ * Pitch of the scaled surface buffer
 470+ * @param bpp
 471+ * Number of bits per surface pixel
 472+ * @param texformat
 473+ * OpenGL format parameter for glTexImage2D
 474+ * @param texformat2
 475+ * OpenGL type parameter for glTexImage2D
 476+ * @param texformat3
 477+ * OpenGL internalformat parameter for glTexImage2D
 478+ */
 479+void glRenderer::UploadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y,
213480 int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2, int texformat3)
214481 {
215 - EnterCriticalSection(&cs);
216 - MSG Msg;
217 - inputs[0] = buffer;
218 - inputs[1] = bigbuffer;
219 - inputs[2] = (void*)texture;
220 - inputs[3] = (void*)x;
221 - inputs[4] = (void*)y;
222 - inputs[5] = (void*)bigx;
223 - inputs[6] = (void*)bigy;
224 - inputs[7] = (void*)pitch;
225 - inputs[8] = (void*)bigpitch;
226 - inputs[9] = (void*)bpp;
227 - inputs[10] = (void*)texformat;
228 - inputs[11] = (void*)texformat2;
229 - inputs[12] = (void*)texformat3;
230 - wndbusy = true;
231 - SendMessage(hRenderWnd,GLEVENT_UPLOAD,0,0);
232 - while(wndbusy)
233 - {
234 - while(PeekMessage(&Msg,hRenderWnd,0,0,PM_REMOVE))
235 - {
236 - TranslateMessage(&Msg);
237 - DispatchMessage(&Msg);
238 - }
239 - Sleep(0);
240 - }
241 - LeaveCriticalSection(&cs);
242 - return (int)outputs[0];
 482+ EnterCriticalSection(&commandcs);
 483+ AddQueue(OP_UPLOAD,0,28,13,4,&buffer,4,&bigbuffer,4,&texture,4,&x,4,&y,4,&bigx,
 484+ 4,&bigy,4,&pitch,4,&bigpitch,4,&bpp,4,&texformat,4,&texformat2,4,&texformat3);
 485+ Sync(0);
 486+ LeaveCriticalSection(&commandcs);
243487 }
244488
245 -int glRenderer::DownloadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y,
 489+/**
 490+ * Downloads the contents of an OpenGL texture to a surface buffer.
 491+ * @param buffer
 492+ * Buffer to receive the surface contents
 493+ * @param bigbuffer
 494+ * Optional buffer to receive the rescaled surface contents, for when primary
 495+ * scaling is enabled.
 496+ * @param texture
 497+ * OpenGL texture name to download from
 498+ * @param x,y
 499+ * Width and height of the surface
 500+ * @param bigx,bigy
 501+ * Width and height of the scaled surface buffer
 502+ * @param pitch
 503+ * Bytes from one line of graphics to the next in the surface
 504+ * @param bigpitch
 505+ * Pitch of the scaled surface buffer
 506+ * @param bpp
 507+ * Number of bits per surface pixel
 508+ * @param texformat
 509+ * OpenGL format parameter for glGetTexImage
 510+ * @param texformat2
 511+ * OpenGL type parameter for glGetTexImage
 512+ */
 513+void glRenderer::DownloadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y,
246514 int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2)
247515 {
248 - EnterCriticalSection(&cs);
249 - MSG Msg;
250 - inputs[0] = buffer;
251 - inputs[1] = bigbuffer;
252 - inputs[2] = (void*)texture;
253 - inputs[3] = (void*)x;
254 - inputs[4] = (void*)y;
255 - inputs[5] = (void*)bigx;
256 - inputs[6] = (void*)bigy;
257 - inputs[7] = (void*)pitch;
258 - inputs[8] = (void*)bigpitch;
259 - inputs[9] = (void*)bpp;
260 - inputs[10] = (void*)texformat;
261 - inputs[11] = (void*)texformat2;
262 - wndbusy = true;
263 - SendMessage(hRenderWnd,GLEVENT_DOWNLOAD,0,0);
264 - while(wndbusy)
265 - {
266 - while(PeekMessage(&Msg,hRenderWnd,0,0,PM_REMOVE))
267 - {
268 - TranslateMessage(&Msg);
269 - DispatchMessage(&Msg);
270 - }
271 - Sleep(0);
272 - }
273 - LeaveCriticalSection(&cs);
274 - return (int)outputs[0];
 516+ EnterCriticalSection(&commandcs);
 517+ AddQueue(OP_DOWNLOAD,0,26,12,4,&buffer,4,&bigbuffer,4,&texture,4,&x,4,&y,4,&bigx,
 518+ 4,&bigy,4,&pitch,4,&bigpitch,4,&bpp,4,&texformat,4,&texformat2);
 519+ Sync(0);
 520+ LeaveCriticalSection(&commandcs);
275521 }
276522
 523+/**
 524+ * Deletes an OpenGL texture.
 525+ * @param texture
 526+ * OpenGL texture to be deleted
 527+ */
277528 void glRenderer::DeleteTexture(GLuint texture)
278529 {
279 - EnterCriticalSection(&cs);
280 - inputs[0] = (void*)texture;
281 - SendMessage(hRenderWnd,GLEVENT_DELETETEX,0,0);
282 - LeaveCriticalSection(&cs);
 530+ EnterCriticalSection(&commandcs);
 531+ AddQueue(OP_DELETETEX,0,4,1,4,&texture);
 532+ LeaveCriticalSection(&commandcs);
283533 }
284534
 535+/**
 536+ * Copies the contents of one surface to another.
 537+ * @param lpDestRect
 538+ * Pointer to the coordinates to blit to. If NULL, blits to the entire surface.
 539+ * @param src
 540+ * Surface to be used as the source.
 541+ * @param dest
 542+ * Surface to blit to.
 543+ * @param lpSrcRect
 544+ * Pointer of the coordinates to blit from on the source surface. If NULL, the
 545+ * entire surface will be used.
 546+ * @param dwFlags
 547+ * Flags to determine the behavior of the blitter. Certain flags control the
 548+ * synchronization of the operation:
 549+ * - DDBLT_ASYNC: Adds the command to the queue. If the queue is full, returns
 550+ * DDERR_WASSTILLDRAWING.
 551+ * - DDBLT_DONOTWAIT: Fails and returns DDERR_WASSTILLDRAWING if the queue is full.
 552+ * - DDBLT_WAIT: Waits until the Blt command is processed before returning.
 553+ * @param lpDDBltFx
 554+ * Effect parameters for the Blt operation.
 555+ * @return
 556+ * DD_OK if the call succeeds, or DDERR_WASSTILLDRAWING if busy.
 557+ */
285558 HRESULT glRenderer::Blt(LPRECT lpDestRect, glDirectDrawSurface7 *src,
286559 glDirectDrawSurface7 *dest, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
287560 {
288 - MSG Msg;
289 - EnterCriticalSection(&cs);
290 - inputs[0] = lpDestRect;
291 - inputs[1] = src;
292 - inputs[2] = dest;
293 - inputs[3] = lpSrcRect;
294 - inputs[4] = (void*)dwFlags;
295 - inputs[5] = lpDDBltFx;
296 - wndbusy = true;
297 - SendMessage(hRenderWnd,GLEVENT_BLT,0,0);
298 - while(wndbusy)
 561+ DWORD nullfx = 0xFFFFFFFF;
 562+ RECT emptyrect = nullrect;
 563+ EnterCriticalSection(&commandcs);
 564+ int syncmode = 0;
 565+ if(dwFlags & DDBLT_ASYNC) syncmode = 1;
 566+ if(dwFlags & DDBLT_DONOTWAIT) syncmode = 2;
 567+ if(!lpSrcRect) lpSrcRect = &emptyrect;
 568+ if(!lpDestRect) lpDestRect = &emptyrect;
 569+ int fxsize = 4;
 570+ if(lpDDBltFx) fxsize = sizeof(DDBLTFX);
 571+ else lpDDBltFx = (LPDDBLTFX)&nullfx;
 572+ if(AddQueue(OP_BLT,syncmode,5+(sizeof(RECT)/2)+(fxsize/4),6,sizeof(RECT),lpDestRect,4,&src,
 573+ 4,&dest,sizeof(RECT),lpSrcRect,4,&dwFlags,fxsize,lpDDBltFx))
299574 {
300 - while(PeekMessage(&Msg,hRenderWnd,0,0,PM_REMOVE))
301 - {
302 - TranslateMessage(&Msg);
303 - DispatchMessage(&Msg);
304 - }
305 - Sleep(0);
 575+ LeaveCriticalSection(&commandcs);
 576+ return DDERR_WASSTILLDRAWING;
306577 }
307 - LeaveCriticalSection(&cs);
308 - return (HRESULT)outputs[0];
 578+ if(dwFlags & DDBLT_WAIT) Sync(0);
 579+ LeaveCriticalSection(&commandcs);
 580+ return DD_OK;
309581 }
310582
 583+/**
 584+ * Updates the display with the current primary texture.
 585+ * @param texture
 586+ * Texture to use as the primary
 587+ * @param paltex
 588+ * Texture that contains the color palette for 8-bit modes
 589+ * @param dest
 590+ * Destination surface to be updated
 591+ * @param src
 592+ * Source surface to be updated
 593+ */
311594 void glRenderer::DrawScreen(GLuint texture, GLuint paltex, glDirectDrawSurface7 *dest, glDirectDrawSurface7 *src)
312595 {
313 - MSG Msg;
314 - EnterCriticalSection(&cs);
315 - inputs[0] = (void*)texture;
316 - inputs[1] = (void*)paltex;
317 - inputs[2] = dest;
318 - inputs[3] = src;
319 - wndbusy = true;
320 - SendMessage(hRenderWnd,GLEVENT_DRAWSCREEN,0,0);
321 - while(wndbusy)
322 - {
323 - while(PeekMessage(&Msg,hRenderWnd,0,0,PM_REMOVE))
324 - {
325 - TranslateMessage(&Msg);
326 - DispatchMessage(&Msg);
327 - }
328 - Sleep(0);
329 - }
330 - LeaveCriticalSection(&cs);
 596+ EnterCriticalSection(&commandcs);
 597+ AddQueue(OP_DRAWSCREEN,0,10,4,4,&texture,4,&paltex,4,&dest,4,&src);
 598+ Sync(0);
 599+ LeaveCriticalSection(&commandcs);
331600 }
332601
 602+/**
 603+ * Ensures the renderer is set up for handling Direct3D commands.
 604+ * @param zbuffer
 605+ * Nonzero if a Z buffer is present.
 606+ */
333607 void glRenderer::InitD3D(int zbuffer)
334608 {
335 - MSG Msg;
336 - EnterCriticalSection(&cs);
337 - wndbusy = true;
338 - inputs[0] = (void*)zbuffer;
339 - SendMessage(hRenderWnd,GLEVENT_INITD3D,0,0);
340 - while(wndbusy)
341 - {
342 - while(PeekMessage(&Msg,hRenderWnd,0,0,PM_REMOVE))
343 - {
344 - TranslateMessage(&Msg);
345 - DispatchMessage(&Msg);
346 - }
347 - Sleep(0);
348 - }
349 - LeaveCriticalSection(&cs);
 609+ EnterCriticalSection(&commandcs);
 610+ AddQueue(OP_INITD3D,0,4,1,4,zbuffer);
 611+ LeaveCriticalSection(&commandcs);
350612 }
351613
 614+/**
 615+ * Clears the viewport.
 616+ * @param target
 617+ * Surface to be cleared
 618+ * @param dwCount
 619+ * Number of rects to use to clear the buffer, or 0 to clear the entire buffer.
 620+ * @param lpRects
 621+ * Pointer to rects to clear.
 622+ * @param dwFlags
 623+ * Flags to determine which surfaces to clear.
 624+ * @param dwColor
 625+ * Color value to fill the surface with.
 626+ * @param dvZ
 627+ * Value to fill the Z buffer with.
 628+ * @param dwStencil
 629+ * Value to fill the stencil buffer with.
 630+ * @return
 631+ * Returns D3D_OK
 632+ */
352633 HRESULT glRenderer::Clear(glDirectDrawSurface7 *target, DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags, DWORD dwColor, D3DVALUE dvZ, DWORD dwStencil)
353634 {
354 - MSG Msg;
355 - EnterCriticalSection(&cs);
356 - wndbusy = true;
357 - inputs[0] = target;
358 - inputs[1] = (void*)dwCount;
359 - inputs[2] = lpRects;
360 - inputs[3] = (void*)dwFlags;
361 - inputs[4] = (void*)dwColor;
362 - memcpy(&inputs[5],&dvZ,4);
363 - inputs[6] = (void*)dwStencil;
364 - SendMessage(hRenderWnd,GLEVENT_CLEAR,0,0);
365 - while(wndbusy)
366 - {
367 - while(PeekMessage(&Msg,hRenderWnd,0,0,PM_REMOVE))
368 - {
369 - TranslateMessage(&Msg);
370 - DispatchMessage(&Msg);
371 - }
372 - Sleep(0);
373 - }
374 - LeaveCriticalSection(&cs);
375 - return (HRESULT)outputs[0];
 635+ EnterCriticalSection(&commandcs);
 636+ int rectsize = dwCount * sizeof(D3DRECT);
 637+ AddQueue(OP_CLEAR,0,15+(rectsize/4),7,4,&target,4,&dwCount,rectsize,lpRects,
 638+ 4,dwFlags,4,dwColor,4,dvZ,4,dwStencil);
 639+ LeaveCriticalSection(&commandcs);
 640+ return D3D_OK;
376641 }
377642
 643+/**
 644+ * Issues a glFlush command and empties the queue.
 645+ */
378646 void glRenderer::Flush()
379647 {
380 - MSG Msg;
381 - EnterCriticalSection(&cs);
382 - wndbusy = true;
383 - SendMessage(hRenderWnd,GLEVENT_FLUSH,0,0);
384 - while(wndbusy)
385 - {
386 - while(PeekMessage(&Msg,hRenderWnd,0,0,PM_REMOVE))
387 - {
388 - TranslateMessage(&Msg);
389 - DispatchMessage(&Msg);
390 - }
391 - Sleep(0);
392 - }
393 - LeaveCriticalSection(&cs);
 648+ EnterCriticalSection(&commandcs);
 649+ AddQueue(OP_CLEAR,0,2,0,0,NULL);
 650+ Sync(0);
 651+ LeaveCriticalSection(&commandcs);
394652 }
395653
396 -HRESULT glRenderer::DrawPrimitives(glDirect3DDevice7 *device, GLenum mode, GLVERTEX *vertices, int *texformats, DWORD count, LPWORD indices,
397 - DWORD indexcount, DWORD flags)
 654+/**
 655+ * Draws one or more primitives to the currently selected render target.
 656+ * @param device
 657+ * glDirect3DDevice7 interface to use for drawing
 658+ * @param mode
 659+ * OpenGL primitive drawing mode to use
 660+ * @param vertices
 661+ * Pointer to vertex data
 662+ * @param packed
 663+ * True if vertex data is packed (e.g. xyz,normal,texcoord,xyz,normal,etc.)
 664+ * @param texformats
 665+ * Pointer to texture coordinate formats used in the call
 666+ * @param count
 667+ * Number of vertices to copy to the draw command
 668+ * @param indices
 669+ * List of vertex indices to use in the drawing command, may be NULL for
 670+ * non-indexed mode.
 671+ * @param indexcount
 672+ * Number of vertex indices. May be 0 for non-indexed mode.
 673+ * @param flags
 674+ * Set to D3DDP_WAIT to wait until the queue has processed the call.
 675+ * @return
 676+ * D3D_OK if the call succeeds, or D3DERR_INVALIDVERTEXTYPE if the vertex format
 677+ * has no position coordinates.
 678+ */
 679+HRESULT glRenderer::DrawPrimitives(glDirect3DDevice7 *device, GLenum mode, GLVERTEX *vertices, bool packed,
 680+ DWORD *texformats, DWORD count, LPWORD indices, DWORD indexcount, DWORD flags)
398681 {
399 - MSG Msg;
400 - EnterCriticalSection(&cs);
401 - wndbusy = true;
402 - inputs[0] = device;
403 - inputs[1] = (void*)mode;
404 - inputs[2] = vertices;
405 - inputs[3] = texformats;
406 - inputs[4] = (void*)count;
407 - inputs[5] = indices;
408 - inputs[6] = (void*)indexcount;
409 - inputs[7] = (void*)flags;
410 - SendMessage(hRenderWnd,GLEVENT_DRAWPRIMITIVES,0,0);
411 - while(wndbusy)
 682+ if(!vertices[0].data) return D3DERR_INVALIDVERTEXTYPE;
 683+ GLVERTEX vertdata[18];
 684+ EnterCriticalSection(&commandcs);
 685+ __int64 shader = device->SelectShader(vertices);
 686+ int vertsize = 0;
 687+ if(packed)
412688 {
413 - while(PeekMessage(&Msg,hRenderWnd,0,0,PM_REMOVE))
 689+ vertsize = vertices[0].stride * count;
 690+ AddQueue(OP_DRAWPRIMITIVES,0,NextMultipleOf4(40+(18*sizeof(GLVERTEX))+(8*sizeof(DWORD))+(indexcount*sizeof(WORD))+vertsize)/4,
 691+ 10,4,&device,4,&mode,18*sizeof(GLVERTEX),vertices,1,&packed,8*sizeof(DWORD),texformats,4,&count,indexcount*sizeof(WORD),
 692+ &indices,4,&indexcount,4,&flags,8,&shader,vertsize,vertices[0].data);
 693+ }
 694+ else
 695+ {
 696+ for(int i = 0; i < 18; i++)
414697 {
415 - TranslateMessage(&Msg);
416 - DispatchMessage(&Msg);
 698+ vertdata[i].stride = vertices[i].stride;
 699+ if(vertices[i].data)
 700+ {
 701+ vertdata[i].data = (void*)vertsize;
 702+ vertsize += (vertices[i].stride * count);
 703+ }
 704+ else vertdata[i].data = (void*)-1;
417705 }
418 - Sleep(0);
 706+ FIXME("glRenderer::DrawPrimitives: Add Strided Vertex format");
 707+ AddQueue(OP_DRAWPRIMITIVES,0,NextMultipleOf4(32+(18*sizeof(GLVERTEX))+(8*sizeof(DWORD))+(indexcount*sizeof(WORD))+vertsize)/4,
 708+ 10,4,&device,4,&mode,18*sizeof(GLVERTEX),vertdata,1,packed,8*sizeof(DWORD),texformats,4,count,indexcount*sizeof(WORD),
 709+ indices,4,indexcount,4,flags,vertsize,vertdata[0].data);
419710 }
420 - return (HRESULT)outputs[0];
 711+ if(flags & D3DDP_WAIT) Sync(0);
 712+ LeaveCriticalSection(&commandcs);
 713+ return D3D_OK;
421714 }
422715
 716+/**
 717+ * Sets one or more render states in the glRenderer class
 718+ * @param index
 719+ * Index of the render state(s) to set
 720+ * @param count
 721+ * Number of states to set at once
 722+ * @param data
 723+ * Pointer to state data to copy
 724+ * @remark
 725+ * If the render thread is not currently running, this function will immediately
 726+ * copy the data to the renderer. Otherwise, it will add a command to the queue.
 727+ */
 728+void glRenderer::SetRenderState(DWORD index, DWORD count, DWORD *data)
 729+{
 730+ EnterCriticalSection(&commandcs);
 731+ if(!running) memcpy(&renderstate[index],data,count*sizeof(DWORD));
 732+ else AddQueue(OP_SETRENDERSTATE,0,4+count,2,4,&index,count*4,data);
 733+ LeaveCriticalSection(&commandcs);
 734+}
423735
 736+/**
 737+ * Sets one or more Direct3D matrices in the glRenderer class
 738+ * @param index
 739+ * Index of the matrix or matrices to set
 740+ * @param count
 741+ * Number of matrices to set at once
 742+ * @param data
 743+ * Pointer to matrices to copy
 744+ * @remark
 745+ * If the render thread is not currently running, this function will immediately
 746+ * copy the data to the renderer. Otherwise, it will add a command to the queue.
 747+ */
 748+void glRenderer::SetMatrix(DWORD index, DWORD count, D3DMATRIX *data)
 749+{
 750+ EnterCriticalSection(&commandcs);
 751+ if(!running) memcpy(&renderstate[index],data,count*sizeof(D3DMATRIX));
 752+ else AddQueue(OP_SETMATRIX,0,4+((count*sizeof(D3DMATRIX))/4),2,4,&index,count*4,data);
 753+ LeaveCriticalSection(&commandcs);
 754+}
 755+
 756+/**
 757+ * Main loop for glRenderer class
 758+ * @return
 759+ * Returns 0 to signal successful thread termination
 760+ */
424761 DWORD glRenderer::_Entry()
425762 {
 763+ DWORD size;
426764 MSG Msg;
427 - EnterCriticalSection(&cs);
428765 _InitGL((int)inputs[0],(int)inputs[1],(int)inputs[2],(int)inputs[3],(HWND)inputs[4],(glDirectDraw7*)inputs[5]);
429 - LeaveCriticalSection(&cs);
430 - while(GetMessage(&Msg, NULL, 0, 0) > 0)
 766+ dead = false;
 767+ queue = (LPDWORD)malloc(1048576);
 768+ queuesize = 1048576/sizeof(DWORD);
 769+ queuelength = queue_read = queue_write = syncsize = 0;
 770+ SetEvent(busy);
 771+ start = CreateEvent(NULL,TRUE,FALSE,NULL);
 772+ ResetEvent(start);
 773+ sync = CreateEvent(NULL,TRUE,FALSE,NULL);
 774+ queueloop:
 775+ MsgWaitForMultipleObjects(1,&start,FALSE,INFINITE,QS_ALLEVENTS);
 776+ if(PeekMessage(&Msg,NULL,0,0,PM_REMOVE))
431777 {
432778 TranslateMessage(&Msg);
433779 DispatchMessage(&Msg);
434780 }
 781+ if(queuelength)
 782+ {
 783+ running = true;
 784+ switch(queue[queue_read])
 785+ {
 786+ case OP_NULL:
 787+ default:
 788+ break;
 789+ case OP_DELETE:
 790+ DestroyWindow(hRenderWnd);
 791+ break;
 792+ case OP_CREATE:
 793+ if(queue[queue_read+1] != 20) break;
 794+ output = (void*)_MakeTexture(queue[queue_read+3],queue[queue_read+5],queue[queue_read+7],queue[queue_read+9],
 795+ queue[queue_read+11],queue[queue_read+13],queue[queue_read+15],queue[queue_read+17],queue[queue_read+19]);
 796+ break;
 797+ case OP_UPLOAD:
 798+ if(queue[queue_read+1] != 28) break;
 799+ _UploadTexture((char*)queue[queue_read+3],(char*)queue[queue_read+5],queue[queue_read+7],queue[queue_read+9],
 800+ queue[queue_read+11],queue[queue_read+13],queue[queue_read+15],queue[queue_read+17],queue[queue_read+19],
 801+ queue[queue_read+21],queue[queue_read+23],queue[queue_read+25],queue[queue_read+27]);
 802+ break;
 803+ case OP_DOWNLOAD:
 804+ if(queue[queue_read+1] != 26) break;
 805+ _DownloadTexture((char*)queue[queue_read+3],(char*)queue[queue_read+5],queue[queue_read+7],queue[queue_read+9],
 806+ queue[queue_read+11],queue[queue_read+13],queue[queue_read+15],queue[queue_read+17],queue[queue_read+19],
 807+ queue[queue_read+21],queue[queue_read+23],queue[queue_read+25]);
 808+ break;
 809+ case OP_DELETETEX:
 810+ if(queue[queue_read+1] != 4) break;
 811+ _DeleteTexture(queue[queue_read+3]);
 812+ break;
 813+ case OP_BLT:
 814+ if(queue[queue_read+1] < 5) break;
 815+ _Blt((LPRECT)&queue[queue_read+3],(glDirectDrawSurface7*)queue[queue_read+4+(sizeof(RECT)/4)],
 816+ (glDirectDrawSurface7*)queue[queue_read+6+(sizeof(RECT)/4)],(LPRECT)&queue[queue_read+8+(sizeof(RECT)/4)],
 817+ queue[queue_read+9+(sizeof(RECT)/2)],(LPDDBLTFX)&queue[queue_read+11+(sizeof(RECT)/2)]);
 818+ break;
 819+ case OP_DRAWSCREEN:
 820+ if(queue[queue_read+1] != 10) break;
 821+ _DrawScreen(queue[queue_read+3],queue[queue_read+5],(glDirectDrawSurface7*)queue[queue_read+7],
 822+ (glDirectDrawSurface7*)queue[queue_read+9]);
 823+ break;
 824+ case OP_INITD3D:
 825+ if(queue[queue_read+1] != 4) break;
 826+ _InitD3D(queue[queue_read+3]);
 827+ break;
 828+ case OP_CLEAR:
 829+ if(queue[queue_read+1] < 15) break;
 830+ size = queue[queue_read+1] - 15;
 831+ if(!size) _Clear((glDirectDrawSurface7*)queue[queue_read+3],queue[queue_read+5],NULL,
 832+ queue[queue_read+8],queue[queue_read+10],queue[queue_read+12],queue[queue_read+14]);
 833+ else _Clear((glDirectDrawSurface7*)queue[queue_read+3],queue[queue_read+5],(LPD3DRECT)&queue[queue_read+7],
 834+ queue[queue_read+8+size],queue[queue_read+10+size],queue[queue_read+12+size],
 835+ queue[queue_read+14+size]);
 836+ break;
 837+ case OP_FLUSH:
 838+ _Flush();
 839+ break;
 840+ }
 841+ EnterCriticalSection(&queuecs);
 842+ queuelength--;
 843+ queue_read+=queue[queue_read+1];
 844+ if((queue_read >= syncsize) && syncsize != 0) SetEvent(sync);
 845+ }
 846+ else EnterCriticalSection(&queuecs);
 847+ if(!queuelength)
 848+ {
 849+ ResetEvent(start);
 850+ queue_read = 0;
 851+ queue_write = 0;
 852+ running = false;
 853+ SetEvent(sync);
 854+ }
 855+ LeaveCriticalSection(&queuecs);
 856+ if(!dead) goto queueloop;
 857+ free(queue);
 858+ queue = NULL;
435859 return 0;
436860 }
437861
 862+/**
 863+ * Creates a render window and initializes OpenGL.
 864+ * @param width,height
 865+ * Width and height of the render window.
 866+ * @param bpp
 867+ * Color depth of the screen.
 868+ * @param fullscreen
 869+ * True if full screen mode is requested.
 870+ * @param hWnd
 871+ * Handle to the window to use as the renderer. If NULL, then creates a
 872+ * transparent overlay window.
 873+ * @param glDD7
 874+ * Pointer to the glDirectDraw7 interface that creates the renderer.
 875+ * @return
 876+ * TRUE if OpenGL has been initialized, FALSE otherwise.
 877+ */
438878 BOOL glRenderer::_InitGL(int width, int height, int bpp, int fullscreen, HWND hWnd, glDirectDraw7 *glDD7)
439879 {
440880 ddInterface = glDD7;
@@ -469,8 +909,13 @@
470910 {
471911 width = GetSystemMetrics(SM_CXSCREEN);
472912 height = GetSystemMetrics(SM_CYSCREEN);
 913+#ifdef _DEBUG
 914+ hRenderWnd = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_LAYERED|WS_EX_TRANSPARENT,
 915+ "DXGLRenderWindow","Renderer",WS_POPUP,0,0,width,height,0,0,NULL,this);
 916+#else
473917 hRenderWnd = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_TOPMOST,
474918 "DXGLRenderWindow","Renderer",WS_POPUP,0,0,width,height,0,0,NULL,this);
 919+#endif
475920 hasHWnd = false;
476921 SetWindowPos(hRenderWnd,HWND_TOP,0,0,rectRender.right,rectRender.bottom,SWP_SHOWWINDOW|SWP_NOACTIVATE);
477922 }
@@ -526,7 +971,6 @@
527972 gllock = false;
528973 return FALSE;
529974 }
530 - wndbusy = false;
531975 gllock = false;
532976 InitGLExt();
533977 SetSwap(1);
@@ -573,7 +1017,7 @@
5741018 return TRUE;
5751019 }
5761020
577 -HRESULT glRenderer::_Blt(LPRECT lpDestRect, glDirectDrawSurface7 *src,
 1021+void glRenderer::_Blt(LPRECT lpDestRect, glDirectDrawSurface7 *src,
5781022 glDirectDrawSurface7 *dest, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
5791023 {
5801024 LONG sizes[6];
@@ -588,7 +1032,6 @@
5891033 if(memcmp(&r2,&r,sizeof(RECT)))
5901034 SetWindowPos(hRenderWnd,NULL,0,0,r.right,r.bottom,SWP_SHOWWINDOW);
5911035 }
592 - wndbusy = false;
5931036 ddInterface->GetSizes(sizes);
5941037 int error;
5951038 error = SetFBO(dest->texture,0,false);
@@ -729,7 +1172,7 @@
7301173 (ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) ||
7311174 ((ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) &&
7321175 !(ddsd.ddsCaps.dwCaps & DDSCAPS_FLIP)))_DrawScreen(dest->texture,dest->paltex,dest,dest);
733 - return DD_OK;
 1176+ SetEvent(busy);
7341177 }
7351178
7361179 GLuint glRenderer::_MakeTexture(GLint min, GLint mag, GLint wraps, GLint wrapt, DWORD width, DWORD height, GLint texformat1, GLint texformat2, GLint texformat3)
@@ -799,7 +1242,6 @@
8001243 if(memcmp(&r2,&r,sizeof(RECT)))
8011244 SetWindowPos(hRenderWnd,NULL,0,0,r.right,r.bottom,SWP_SHOWWINDOW);
8021245 }
803 - wndbusy = false;
8041246 RECT *viewrect = &r2;
8051247 SetSwap(swapinterval);
8061248 LONG sizes[6];
@@ -949,14 +1391,15 @@
9501392 void glRenderer::_DeleteTexture(GLuint texture)
9511393 {
9521394 glDeleteTextures(1,&texture);
 1395+ SetEvent(busy);
9531396 }
9541397
9551398 void glRenderer::_InitD3D(int zbuffer)
9561399 {
957 - wndbusy = false;
 1400+ if(zbuffer) glEnable(GL_DEPTH_TEST);
 1401+ SetEvent(busy);
9581402 glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
9591403 GLfloat ambient[] = {0.0,0.0,0.0,0.0};
960 - if(zbuffer) glEnable(GL_DEPTH_TEST);
9611404 glDepthFunc(GL_LEQUAL);
9621405 glDisable(GL_DITHER);
9631406 }
@@ -965,13 +1408,9 @@
9661409 {
9671410 if(dwCount)
9681411 {
969 - outputs[0] = (void*)DDERR_INVALIDPARAMS;
9701412 FIXME("glDirect3DDevice7::Clear: Cannot clear rects yet.");
971 - wndbusy = false;
9721413 return;
9731414 }
974 - outputs[0] = (void*)D3D_OK;
975 - wndbusy = false;
9761415 GLfloat color[4];
9771416 dwordto4float(dwColor,color);
9781417 if(target->zbuffer) SetFBO(target->texture,target->GetZBuffer()->texture,target->GetZBuffer()->hasstencil);
@@ -995,12 +1434,13 @@
9961435 glClear(clearbits);
9971436 if(target->zbuffer) target->zbuffer->dirty |= 2;
9981437 target->dirty |= 2;
 1438+ SetEvent(busy);
9991439 }
10001440
10011441 void glRenderer::_Flush()
10021442 {
1003 - wndbusy = false;
10041443 glFlush();
 1444+ SetEvent(busy);
10051445 }
10061446
10071447 void glRenderer::_DrawPrimitives(glDirect3DDevice7 *device, GLenum mode, GLVERTEX *vertices, int *texformats, DWORD count, LPWORD indices,
@@ -1014,12 +1454,6 @@
10151455 int i;
10161456 if(vertices[1].data) transformed = true;
10171457 else transformed = false;
1018 - if(!vertices[0].data)
1019 - {
1020 - outputs[0] = (void*)DDERR_INVALIDPARAMS;
1021 - wndbusy = false;
1022 - return;
1023 - }
10241458 __int64 shader = device->SelectShader(vertices);
10251459 SetShader(shader,device->texstages,texformats,0);
10261460 _GENSHADER prog = genshaders[current_genshader].shader;
@@ -1102,11 +1536,11 @@
11031537
11041538 }
11051539 }
1106 - if(device->normal_dirty) device->UpdateNormalMatrix();
1107 - if(prog.uniforms[0] != -1) glUniformMatrix4fv(prog.uniforms[0],1,false,device->matWorld);
1108 - if(prog.uniforms[1] != -1) glUniformMatrix4fv(prog.uniforms[1],1,false,device->matView);
1109 - if(prog.uniforms[2] != -1) glUniformMatrix4fv(prog.uniforms[2],1,false,device->matProjection);
1110 - if(prog.uniforms[3] != -1) glUniformMatrix3fv(prog.uniforms[3],1,true,device->matNormal);
 1540+ if(normal_dirty) _UpdateNormalMatrix();
 1541+ if(prog.uniforms[0] != -1) glUniformMatrix4fv(prog.uniforms[0],1,false,(GLfloat*)&matrices[1]);
 1542+ if(prog.uniforms[1] != -1) glUniformMatrix4fv(prog.uniforms[1],1,false,(GLfloat*)&matrices[2]);
 1543+ if(prog.uniforms[2] != -1) glUniformMatrix4fv(prog.uniforms[2],1,false,(GLfloat*)&matrices[3]);
 1544+ if(prog.uniforms[3] != -1) glUniformMatrix3fv(prog.uniforms[3],1,true,(GLfloat*)&matrices[7]);
11111545
11121546 if(prog.uniforms[15] != -1) glUniform4fv(prog.uniforms[15],1,(GLfloat*)&device->material.ambient);
11131547 if(prog.uniforms[16] != -1) glUniform4fv(prog.uniforms[16],1,(GLfloat*)&device->material.diffuse);
@@ -1150,7 +1584,7 @@
11511585 lightindex++;
11521586 }
11531587
1154 - DWORD ambient = device->renderstate[D3DRENDERSTATE_AMBIENT];
 1588+ DWORD ambient = renderstate[D3DRENDERSTATE_AMBIENT];
11551589 if(prog.uniforms[136] != -1)
11561590 glUniform4f(prog.uniforms[136],RGBA_GETRED(ambient),RGBA_GETGREEN(ambient),
11571591 RGBA_GETBLUE(ambient),RGBA_GETALPHA(ambient));
@@ -1187,11 +1621,32 @@
11881622 if(device->glDDS7->zbuffer) device->glDDS7->zbuffer->dirty |= 2;
11891623 device->glDDS7->dirty |= 2;
11901624 if(flags & D3DDP_WAIT) glFlush();
1191 - outputs[0] = (void*)D3D_OK;
1192 - wndbusy = false;
 1625+ SetEvent(busy);
11931626 return;
11941627 }
 1628+void glRenderer::_UpdateNormalMatrix()
 1629+{
 1630+ GLfloat worldview[16];
 1631+ GLfloat tmp[16];
11951632
 1633+ ZeroMemory(&worldview,sizeof(D3DMATRIX));
 1634+ ZeroMemory(&tmp,sizeof(D3DMATRIX));
 1635+ __gluMultMatricesf((GLfloat*)&matrices[1],(GLfloat*)&matrices[2],worldview); // Get worldview
 1636+ if(__gluInvertMatrixf(worldview,tmp)) // Invert
 1637+ {
 1638+ memcpy((GLfloat*)&matrices[7],tmp,3*sizeof(GLfloat));
 1639+ memcpy((GLfloat*)&matrices[7]+3,tmp+4,3*sizeof(GLfloat));
 1640+ memcpy((GLfloat*)&matrices[7]+6,tmp+8,3*sizeof(GLfloat));
 1641+ }
 1642+ else
 1643+ {
 1644+ memcpy((GLfloat*)&matrices[7],worldview,3*sizeof(GLfloat));
 1645+ memcpy((GLfloat*)&matrices[7]+3,worldview+4,3*sizeof(GLfloat));
 1646+ memcpy((GLfloat*)&matrices[7]+6,worldview+8,3*sizeof(GLfloat));
 1647+ }
 1648+
 1649+ normal_dirty = false;
 1650+}
11961651 LRESULT glRenderer::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
11971652 {
11981653 int oldx,oldy;
@@ -1236,14 +1691,15 @@
12371692 };
12381693 if(hDC) ReleaseDC(hRenderWnd,hDC);
12391694 hDC = NULL;
1240 - wndbusy = false;
12411695 PostQuitMessage(0);
 1696+ dead = true;
12421697 return 0;
12431698 case WM_SETCURSOR:
12441699 hParent = GetParent(hwnd);
12451700 cursor = (HCURSOR)GetClassLong(hParent,GCL_HCURSOR);
12461701 SetCursor(cursor);
1247 - return SendMessage(hParent,msg,wParam,lParam);
 1702+ PostMessage(hParent,msg,wParam,lParam);
 1703+ return 0;
12481704 case WM_MOUSEMOVE:
12491705 case WM_LBUTTONDOWN:
12501706 case WM_LBUTTONUP:
@@ -1278,53 +1734,10 @@
12791735 if(oldx >= sizes[2]) oldx = sizes[2]-1;
12801736 if(oldy >= sizes[3]) oldy = sizes[3]-1;
12811737 newpos = oldx + (oldy << 16);
1282 - return SendMessage(hParent,msg,wParam,newpos);
 1738+ PostMessage(hParent,msg,wParam,newpos);
12831739 }
1284 - else return SendMessage(hParent,msg,wParam,lParam);
1285 - case GLEVENT_DELETE:
1286 - DestroyWindow(hRenderWnd);
 1740+ else PostMessage(hParent,msg,wParam,lParam);
12871741 return 0;
1288 - case GLEVENT_CREATE:
1289 - outputs[0] = (void*)_MakeTexture((GLint)inputs[0],(GLint)inputs[1],(GLint)inputs[2],(GLint)inputs[3],
1290 - (DWORD)inputs[4],(DWORD)inputs[5],(GLint)inputs[6],(GLint)inputs[7],(GLint)inputs[8]);
1291 - return 0;
1292 - case GLEVENT_UPLOAD:
1293 - outputs[0] = (void*)_UploadTexture((char*)inputs[0],(char*)inputs[1],(GLuint)inputs[2],(int)inputs[3],
1294 - (int)inputs[4],(int)inputs[5],(int)inputs[6],(int)inputs[7],(int)inputs[8],(int)inputs[9],
1295 - (int)inputs[10],(int)inputs[11],(int)inputs[12]);
1296 - wndbusy = false;
1297 - return 0;
1298 - case GLEVENT_DOWNLOAD:
1299 - outputs[0] = (void*)_DownloadTexture((char*)inputs[0],(char*)inputs[1],(GLuint)inputs[2],(int)inputs[3],
1300 - (int)inputs[4],(int)inputs[5],(int)inputs[6],(int)inputs[7],(int)inputs[8],(int)inputs[9],
1301 - (int)inputs[10],(int)inputs[11]);
1302 - wndbusy = false;
1303 - return 0;
1304 - case GLEVENT_DELETETEX:
1305 - _DeleteTexture((GLuint)inputs[0]);
1306 - return 0;
1307 - case GLEVENT_BLT:
1308 - outputs[0] = (void*)_Blt((LPRECT)inputs[0],(glDirectDrawSurface7*)inputs[1],(glDirectDrawSurface7*)inputs[2],
1309 - (LPRECT)inputs[3],(DWORD)inputs[4],(LPDDBLTFX)inputs[5]);
1310 - return 0;
1311 - case GLEVENT_DRAWSCREEN:
1312 - _DrawScreen((GLuint)inputs[0],(GLuint)inputs[1],(glDirectDrawSurface7*)inputs[2],(glDirectDrawSurface7*)inputs[3]);
1313 - return 0;
1314 - case GLEVENT_INITD3D:
1315 - _InitD3D((int)inputs[0]);
1316 - return 0;
1317 - case GLEVENT_CLEAR:
1318 - memcpy(&tmpfloats[0],&inputs[5],4);
1319 - _Clear((glDirectDrawSurface7*)inputs[0],(DWORD)inputs[1],(LPD3DRECT)inputs[2],(DWORD)inputs[3],(DWORD)inputs[4],
1320 - tmpfloats[0],(DWORD)inputs[6]);
1321 - return 0;
1322 - case GLEVENT_FLUSH:
1323 - _Flush();
1324 - return 0;
1325 - case GLEVENT_DRAWPRIMITIVES:
1326 - _DrawPrimitives((glDirect3DDevice7*)inputs[0],(GLenum)inputs[1],(GLVERTEX*)inputs[2],(int*)inputs[3],(DWORD)inputs[4],
1327 - (LPWORD)inputs[5],(DWORD)inputs[6],(DWORD)inputs[7]);
1328 - return 0;
13291742 default:
13301743 return DefWindowProc(hwnd,msg,wParam,lParam);
13311744 }
Index: ddraw/glRenderer.h
@@ -52,20 +52,24 @@
5353
5454 extern BltVertex bltvertices[4];
5555
56 -#define GLEVENT_NULL WM_USER
57 -#define GLEVENT_DELETE WM_USER+1
58 -#define GLEVENT_CREATE WM_USER+2
59 -#define GLEVENT_UPLOAD WM_USER+3
60 -#define GLEVENT_DOWNLOAD WM_USER+4
61 -#define GLEVENT_DELETETEX WM_USER+5
62 -#define GLEVENT_BLT WM_USER+6
63 -#define GLEVENT_DRAWSCREEN WM_USER+7
64 -#define GLEVENT_INITD3D WM_USER+8
65 -#define GLEVENT_CLEAR WM_USER+9
66 -#define GLEVENT_FLUSH WM_USER+10
67 -#define GLEVENT_DRAWPRIMITIVES WM_USER+11
 56+#define OP_NULL 0
 57+#define OP_DELETE 1
 58+#define OP_CREATE 2
 59+#define OP_UPLOAD 3
 60+#define OP_DOWNLOAD 4
 61+#define OP_DELETETEX 5
 62+#define OP_BLT 6
 63+#define OP_DRAWSCREEN 7
 64+#define OP_INITD3D 8
 65+#define OP_CLEAR 9
 66+#define OP_FLUSH 10
 67+#define OP_DRAWPRIMITIVES 11
 68+#define OP_SETRENDERSTATE 12
 69+#define OP_SETMATRIX 13
6870
 71+#define OP_RESETQUEUE 0xFFFFFFFF
6972
 73+
7074 extern int swapinterval;
7175 extern inline void SetSwap(int swap);
7276
@@ -79,8 +83,8 @@
8084 glRenderer(int width, int height, int bpp, bool fullscreen, HWND hwnd, glDirectDraw7 *glDD7);
8185 ~glRenderer();
8286 static DWORD WINAPI ThreadEntry(void *entry);
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);
 87+ void 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);
 88+ void 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);
8589 HRESULT Blt(LPRECT lpDestRect, glDirectDrawSurface7 *src,
8690 glDirectDrawSurface7 *dest, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx);
8791 GLuint MakeTexture(GLint min, GLint mag, GLint wraps, GLint wrapt, DWORD width, DWORD height, GLint texformat1, GLint texformat2, GLint texformat3);
@@ -88,8 +92,12 @@
8993 void DeleteTexture(GLuint texture);
9094 void InitD3D(int zbuffer);
9195 void Flush();
 96+ void SetRenderState(DWORD index, DWORD count, DWORD *data);
 97+ void SetMatrix(DWORD index, DWORD count, D3DMATRIX *data);
 98+ void Sync(int size);
 99+ int AddQueue(DWORD opcode, int mode, DWORD size, int paramcount, ...);
92100 HRESULT Clear(glDirectDrawSurface7 *target, DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags, DWORD dwColor, D3DVALUE dvZ, DWORD dwStencil);
93 - HRESULT DrawPrimitives(glDirect3DDevice7 *device, GLenum mode, GLVERTEX *vertices, int *texformats, DWORD count, LPWORD indices,
 101+ HRESULT DrawPrimitives(glDirect3DDevice7 *device, GLenum mode, GLVERTEX *vertices, bool packed, DWORD *texformats, DWORD count, LPWORD indices,
94102 DWORD indexcount, DWORD flags);
95103 HGLRC hRC;
96104 LRESULT WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
@@ -98,9 +106,9 @@
99107 // In-thread APIs
100108 DWORD _Entry();
101109 BOOL _InitGL(int width, int height, int bpp, int fullscreen, HWND hWnd, glDirectDraw7 *glDD7);
102 - 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);
103 - 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);
104 - HRESULT _Blt(LPRECT lpDestRect, glDirectDrawSurface7 *src,
 110+ void _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);
 111+ void _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);
 112+ void _Blt(LPRECT lpDestRect, glDirectDrawSurface7 *src,
105113 glDirectDrawSurface7 *dest, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx);
106114 GLuint _MakeTexture(GLint min, GLint mag, GLint wraps, GLint wrapt, DWORD width, DWORD height, GLint texformat1, GLint texformat2, GLint texformat3);
107115 void _DrawScreen(GLuint texture, GLuint paltex, glDirectDrawSurface7 *dest, glDirectDrawSurface7 *src);
@@ -108,14 +116,16 @@
109117 void _DrawBackbuffer(GLuint *texture, int x, int y);
110118 void _InitD3D(int zbuffer);
111119 void _Clear(glDirectDrawSurface7 *target, DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags, DWORD dwColor, D3DVALUE dvZ, DWORD dwStencil);
112 - void glRenderer::_DrawPrimitives(glDirect3DDevice7 *device, GLenum mode, GLVERTEX *vertices, int *texcormats, DWORD count, LPWORD indices,
 120+ void _DrawPrimitives(glDirect3DDevice7 *device, GLenum mode, GLVERTEX *vertices, int *texcormats, DWORD count, LPWORD indices,
113121 DWORD indexcount, DWORD flags);
 122+ void _SetRenderState(DWORD index, DWORD count, DWORD *data);
 123+ void _SetMatrix(DWORD index, DWORD count, D3DMATRIX *data);
 124+ void _UpdateNormalMatrix();
114125 glDirectDraw7 *ddInterface;
115126 void _Flush();
116 - void* inputs[32];
117 - void* outputs[32];
 127+ void* inputs[7];
 128+ void* output;
118129 HANDLE hThread;
119 - bool wndbusy;
120130 HDC hDC;
121131 HWND hWnd;
122132 HWND hRenderWnd;
@@ -122,7 +132,22 @@
123133 bool hasHWnd;
124134 DIB dib;
125135 GLuint PBO;
126 - CRITICAL_SECTION cs;
 136+ HANDLE busy;
 137+ HANDLE start;
 138+ HANDLE sync;
 139+ bool running;
 140+ CRITICAL_SECTION commandcs;
 141+ CRITICAL_SECTION queuecs;
 142+ LPDWORD queue;
 143+ int queuesize;
 144+ int queuelength;
 145+ int queue_read;
 146+ int queue_write;
 147+ int syncsize;
 148+ bool dead;
 149+ DWORD renderstate[153];
 150+ D3DMATRIX matrices[24];
 151+ bool normal_dirty;
127152 };
128153
129154 #endif //_GLRENDERER_H
\ No newline at end of file

Follow-up revisions

RevisionCommit summaryAuthorDate
r595Implement the asynchronous queue from r149. Currently D3D doesn't work.admin14:54, 22 February 2015