1 namespace gfx::drivers;
5 #define D3D_DEBUG_INFO 1
13 #define String _String
16 #define Platform _Platform
20 #if defined(__MINGW32__) && !defined(_W64)
21 #undef DECLARE_INTERFACE
22 #define DECLARE_INTERFACE(i) \
23 interface i { CONST_VTABLE struct i##Vtbl *lpVtbl; }; \
24 typedef CONST_VTABLE struct i##Vtbl i##Vtbl; \
25 CONST_VTABLE struct i##Vtbl
41 #define MATRIX_STACK_SIZE 32
43 #define NUM_VERTEX_SHADERS 4
45 static class D3D8Display : struct
48 IDirect3DSwapChain8 * swapChain;
49 Matrix worldMatrixStack[MATRIX_STACK_SIZE];
52 D3DLIGHT8 lights[NumberOfLights], lightsPI[NumberOfLights];
53 D3DPRESENT_PARAMETERS d3dpp;
54 IDirect3DSurface8 * backBuffer, * depthSurface;
57 static class D3D8System : struct
60 IDirect3D8 * direct3D;
61 IDirect3DDevice8 * d3dDevice;
62 IDirect3D8 * (WINAPI * direct3DCreate8)(UINT);
64 D3DPRESENT_PARAMETERS d3dpp;
65 uint shaders[NUM_VERTEX_SHADERS], shader2D;
72 static class D3D8Surface : struct
74 // For compatibility with LFB driver
80 ColorAlpha background;
83 static class D3D8Mesh : struct
85 IDirect3DVertexBuffer8 * vertices;
86 IDirect3DVertexBuffer8 * normals;
87 IDirect3DVertexBuffer8 * texCoords;
88 IDirect3DVertexBuffer8 * texCoords2;
91 static struct D3D8Vertex
98 static class D3D8Indices : struct
101 IDirect3DIndexBuffer8 * buffer;
105 static int primitiveTypes[RenderPrimitiveType] =
107 D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP, D3DPT_TRIANGLEFAN, D3DPT_TRIANGLEFAN, 0, D3DPT_LINESTRIP
110 static void SetTransformMatrix(IDirect3DDevice8 * device, Matrix matrix)
116 (float)matrix.m[0][0], (float)matrix.m[0][1], (float)matrix.m[0][2], (float)matrix.m[0][3],
117 (float)matrix.m[1][0], (float)matrix.m[1][1], (float)matrix.m[1][2], (float)matrix.m[1][3],
118 (float)matrix.m[2][0], (float)matrix.m[2][1], (float)matrix.m[2][2], (float)matrix.m[2][3],
119 (float)matrix.m[3][0], (float)matrix.m[3][1], (float)matrix.m[3][2], (float)matrix.m[3][3]
123 IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &d3dMat);
126 class Direct3D8DisplayDriver : DisplayDriver
128 class_property(name) = "Direct3D8";
130 bool ::LockDisplay(Display display, Surface surface, Bitmap lfbBitmap, Surface * lfbSurface)
133 DisplaySystem displaySystem = display.displaySystem;
134 D3D8System d3dSystem = displaySystem.driverData;
135 D3D8Display d3dDisplay = display.driverData;
137 //if(!IDirect3DDevice8_GetBackBuffer(d3dSystem.d3dDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
139 D3DLOCKED_RECT lockedRect;
140 if(!IDirect3DSurface8_LockRect(d3dDisplay.backBuffer, &lockedRect, null, 0))
142 switch(d3dDisplay.d3dpp.BackBufferFormat)
144 case D3DFMT_A8R8G8B8:
145 case D3DFMT_X8R8G8B8:
146 lfbBitmap.pixelFormat = pixelFormat888;
149 lfbBitmap.pixelFormat = pixelFormat565;
151 case D3DFMT_X1R5G5B5:
152 case D3DFMT_A1R5G5B5:
153 lfbBitmap.pixelFormat = pixelFormat555;
155 case D3DFMT_A4R4G4B4:
156 case D3DFMT_X4R4G4B4:
157 lfbBitmap.pixelFormat = pixelFormat444;
160 lfbBitmap.driver = null;
161 lfbBitmap.displaySystem = null;
162 lfbBitmap.picture = (byte *)lockedRect.pBits;
163 lfbBitmap.transparent = false;
164 lfbBitmap.stride = lockedRect.Pitch >> GetColorDepthShifts(lfbBitmap.pixelFormat);
165 lfbBitmap.width = display.width;
166 lfbBitmap.height = display.height;
168 *lfbSurface = lfbBitmap.GetSurface(surface ? surface.offset.x : 0, surface ? surface.offset.y : 0, surface ? &surface.box : null);
172 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
177 void ::UnlockDisplay(Display display, Surface surface)
179 DisplaySystem displaySystem = display.displaySystem;
180 D3D8System d3dSystem = displaySystem.driverData;
181 D3D8Display d3dDisplay = display.driverData;
182 if(d3dDisplay.backBuffer)
184 IDirect3DSurface8_UnlockRect(d3dDisplay.backBuffer);
185 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
190 void ::SetViewportAndMatrices(Display display, int x, int y, Box box)
192 D3D8Display d3dDisplay = display.driverData;
193 DisplaySystem displaySystem = display.displaySystem;
194 D3D8System d3dSystem = displaySystem.driverData;
197 D3DVIEWPORT8 viewport;
200 if(box.right<box.left || box.bottom <box.top)
202 viewport.Width = viewport.Height = 1;
203 viewport.X = viewport.Y = MAXDWORD;
207 viewport.X = x + box.left;
208 viewport.Y = y + box.top;
209 viewport.Width = box.right - box.left + 1;
210 viewport.Height = box.bottom - box.top + 1;
212 if(!IDirect3DDevice8_SetViewport(d3dSystem.d3dDevice, &viewport))
214 D3DMATRIX * matProj = &d3dDisplay.projMatrix;
215 Matrix * matWorld = d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
217 matProj->m[0][0] = 2.0f / viewport.Width;
218 matProj->m[1][1] =-2.0f / viewport.Height;
219 matProj->m[2][2] = matProj->m[3][1] = matProj->m[3][3] = 1;
220 matProj->m[3][0] = -1;
222 IDirect3DDevice8_SetTransform(d3dSystem.d3dDevice, D3DTS_PROJECTION, matProj);
224 matWorld->Identity();
225 matWorld->m[3][0] =-box.left;
226 matWorld->m[3][1] =-box.top;
228 SetTransformMatrix(d3dSystem.d3dDevice, matWorld);
234 bool CreateDisplaySystem(DisplaySystem displaySystem)
237 D3D8System d3dSystem = displaySystem.driverData = D3D8System { };
240 displaySystem.flags.alpha = true;
241 //if(displaySystem.flags.fullScreen)
242 displaySystem.flags.flipping = true;
243 displaySystem.pixelFormat = pixelFormat888;
245 d3dSystem.d3dDll = LoadLibrary("d3d8.dll");
248 d3dSystem.direct3DCreate8 = (void *)GetProcAddress(d3dSystem.d3dDll, "Direct3DCreate8");
249 if(d3dSystem.direct3DCreate8)
251 if(d3dSystem.direct3D = d3dSystem.direct3DCreate8(D3D_SDK_VERSION))
253 D3DDISPLAYMODE d3ddm;
254 if(!IDirect3D8_GetAdapterDisplayMode(d3dSystem.direct3D, D3DADAPTER_DEFAULT, &d3ddm))
256 d3dSystem.d3dpp.BackBufferCount = 1;
258 if(displaySystem.flags.fullScreen)
260 d3dSystem.d3dpp.BackBufferWidth = d3ddm.Width;
261 d3dSystem.d3dpp.BackBufferHeight = d3ddm.Height;
262 d3dSystem.d3dpp.hDeviceWindow = displaySystem.window;
266 d3dSystem.d3dpp.hDeviceWindow = d3dSystem.hwnd =
267 CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
268 d3dSystem.d3dpp.Windowed = TRUE;
271 d3dSystem.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
272 d3dSystem.format = d3dSystem.d3dpp.BackBufferFormat = d3ddm.Format;
273 d3dSystem.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
275 if(!IDirect3D8_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
276 d3dSystem.d3dpp.hDeviceWindow,
277 D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE|D3DCREATE_FPU_PRESERVE,
278 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
282 d3dSystem.usage = D3DUSAGE_SOFTWAREPROCESSING;
283 if(!IDirect3D8_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
284 d3dSystem.d3dpp.hDeviceWindow,
285 D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,
286 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
292 DWORD vertexShaders[NUM_VERTEX_SHADERS][7] =
296 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
301 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
303 D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3),
308 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
310 D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
315 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
317 D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3),
319 D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
324 DWORD vertexShader2D[] =
327 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
328 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
329 D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
334 for(c = 0; c<NUM_VERTEX_SHADERS; c++)
335 if(IDirect3DDevice8_CreateVertexShader(d3dSystem.d3dDevice, vertexShaders[c], null, &d3dSystem.shaders[c], 0))
338 if(c < NUM_VERTEX_SHADERS ||
339 IDirect3DDevice8_CreateVertexShader(d3dSystem.d3dDevice, vertexShader2D, null, &d3dSystem.shader2D, 0))
343 d3dSystem.ready = false;
349 Log("Couldn't load library d3d8.dll\n");
350 // LogErrorCode(ERR_MISSING_LIBRARY, "d3d8.dll");
355 void DestroyDisplaySystem(DisplaySystem displaySystem)
357 D3D8System d3dSystem = displaySystem.driverData;
360 for(c = 0; c<NUM_VERTEX_SHADERS; c++)
362 if(d3dSystem.shaders[c])
363 IDirect3DDevice8_DeleteVertexShader(d3dSystem.d3dDevice, d3dSystem.shaders[c]);
366 if(d3dSystem.shader2D)
367 IDirect3DDevice8_DeleteVertexShader(d3dSystem.d3dDevice, d3dSystem.shader2D);
369 if(d3dSystem.d3dDevice)
370 IDirect3DDevice8_Release(d3dSystem.d3dDevice);
372 if(d3dSystem.direct3D)
373 IDirect3D8_Release(d3dSystem.direct3D);
375 FreeLibrary(d3dSystem.d3dDll);
378 displaySystem.driverData = null;
382 void DestroyDisplay(Display display)
384 DisplaySystem displaySystem = display.displaySystem;
385 D3D8System d3dSystem = displaySystem.driverData;
386 D3D8Display d3dDisplay = display.driverData;
388 if(d3dSystem.inScene)
390 IDirect3DDevice8_EndScene(d3dSystem.d3dDevice);
391 d3dSystem.inScene = false;
394 if(d3dDisplay.backBuffer)
395 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
397 if(d3dDisplay.depthSurface)
398 IDirect3DSurface8_Release(d3dDisplay.depthSurface);
400 if(d3dDisplay.swapChain)
401 IDirect3DSwapChain8_Release(d3dDisplay.swapChain);
404 display.driverData = null;
407 bool CreateDisplay(Display display)
410 DisplaySystem displaySystem = display.displaySystem;
411 D3D8System d3dSystem = displaySystem.driverData;
412 D3D8Display d3dDisplay = display.driverData = D3D8Display { };
414 d3dSystem.ready = false;
421 bool DisplaySize(Display display, int width, int height)
424 DisplaySystem displaySystem = display.displaySystem;
425 D3D8System d3dSystem = displaySystem.driverData;
426 D3D8Display d3dDisplay = display.driverData;
427 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
429 d3dSystem.ready = false;
431 if(d3dDisplay.backBuffer)
433 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
434 d3dDisplay.backBuffer = null;
437 if(d3dDisplay.depthSurface)
439 IDirect3DSurface8_Release(d3dDisplay.depthSurface);
440 d3dDisplay.depthSurface = null;
443 if(d3dDisplay.swapChain)
445 IDirect3DSwapChain8_Release(d3dDisplay.swapChain);
446 d3dDisplay.swapChain = null;
452 if(displaySystem.flags.fullScreen)
454 d3dSystem.d3dpp.BackBufferWidth = width;
455 d3dSystem.d3dpp.BackBufferHeight = height;
457 result = !IDirect3DDevice8_Reset(d3dSystem.d3dDevice, &d3dSystem.d3dpp);
461 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;
462 d3dDisplay.d3dpp.BackBufferWidth = width;
463 d3dDisplay.d3dpp.BackBufferHeight = height;
464 d3dDisplay.d3dpp.Windowed = TRUE;
465 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
466 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
467 d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
469 //d3dDisplay.d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
470 d3dDisplay.d3dpp.BackBufferFormat = d3dSystem.format;
471 d3dDisplay.d3dpp.BackBufferCount = 1;
472 d3dDisplay.d3dpp.hDeviceWindow = display.window;
473 d3dDisplay.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
474 // d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_DONOTWAIT;
475 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
476 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
478 result = !IDirect3DDevice8_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
479 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
483 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
484 result = !IDirect3DDevice8_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
485 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
489 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
490 result = !IDirect3DDevice8_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
491 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
497 if(d3dDisplay.swapChain)
498 result = !IDirect3DSwapChain8_GetBackBuffer(d3dDisplay.swapChain,
499 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer);
501 result = !IDirect3DDevice8_GetBackBuffer(d3dSystem.d3dDevice,
502 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer);
505 if(!IDirect3DDevice8_CreateDepthStencilSurface(d3dSystem.d3dDevice, width, height,
506 D3DFMT_D16, d3dDisplay.d3dpp.MultiSampleType,&d3dDisplay.depthSurface))
507 d3dSystem.ready = true;
513 float fogDensity = 0;
515 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shader2D);
517 //IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
518 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
519 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
520 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
521 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
522 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
523 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
524 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGTABLEMODE, D3DFOG_EXP);
525 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGDENSITY, *(uint *)(void *)&fogDensity);
526 display.ambient = Color { 50,50,50 };
527 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_NORMALIZENORMALS, TRUE);
528 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
530 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
531 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
532 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
533 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
534 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
535 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
537 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
538 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
539 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
541 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
542 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
544 IDirect3DDevice8_SetTexture(d3dDevice, 0, null);
549 display.width = width;
550 display.height = height;
551 d3dDisplay.updateBox.left = display.width;
552 d3dDisplay.updateBox.top = display.height;
553 d3dDisplay.updateBox.right = 0;
554 d3dDisplay.updateBox.bottom = 0;
559 void DisplayPosition(Display display, int x, int y)
564 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
568 void RestorePalette(Display display)
572 void StartUpdate(Display display)
576 void EndUpdate(Display display)
580 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
584 void Update(Display display, Box updateBox)
586 DisplaySystem displaySystem = display.displaySystem;
587 D3D8System d3dSystem = displaySystem.driverData;
588 D3D8Display d3dDisplay = display.driverData;
591 //eSystem_Sleep(0.05);
592 IDirect3DDevice8_EndScene(d3dSystem.d3dDevice);
594 if(display.displaySystem.flags.flipping)
596 if(d3dDisplay.swapChain)
597 IDirect3DSwapChain8_Present(d3dDisplay.swapChain, null, null, null, null);
599 IDirect3DDevice8_Present(d3dSystem.d3dDevice, null, null, null, null);
605 if(updateBox != null)
607 source.left = dest.left = updateBox.left;
608 source.top = dest.top = updateBox.top;
609 source.right = dest.right = updateBox.right+1;
610 source.bottom = dest.bottom = updateBox.bottom+1;
614 source.left = dest.left = d3dDisplay.updateBox.left;
615 source.top = dest.top = d3dDisplay.updateBox.top;
616 source.right = dest.right = d3dDisplay.updateBox.right+1;
617 source.bottom = dest.bottom = d3dDisplay.updateBox.bottom+1;
619 if(dest.bottom > dest.top && dest.right > dest.left)
620 IDirect3DDevice8_Present(d3dSystem.d3dDevice, &source, &dest, null, null);
621 if(updateBox == null)
623 d3dDisplay.updateBox.left = display.width;
624 d3dDisplay.updateBox.top = display.height;
625 d3dDisplay.updateBox.right = 0;
626 d3dDisplay.updateBox.bottom = 0;
629 d3dSystem.inScene = false;
633 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
637 Bitmap lfbBitmap { };
639 if(LockDisplay(display, null, lfbBitmap, &lfbSurface))
642 if(bitmap.pixelFormat != lfbBitmap.pixelFormat || bitmap.width < w || bitmap.height < h)
645 bitmap.Allocate(null, w,h,w, lfbBitmap.pixelFormat, false);
647 surface = bitmap.GetSurface(0,0,null);
650 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, surface, lfbBitmap, 0, 0, x, y, w, h);
654 UnlockDisplay(display, lfbSurface);
656 lfbBitmap.picture = null;
663 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
666 IDirect3DTexture8_Release((IDirect3DTexture8 *)bitmap.picture);
669 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
674 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
677 D3D8System d3dSystem = displaySystem.driverData;
678 if(bitmap.Convert(null, pixelFormat888, null))
680 IDirect3DTexture8 * texture;
681 uint w = pow2i(Min(bitmap.width, 512)), h = pow2i(Min(bitmap.height, 512));
683 if(!IDirect3DDevice8_CreateTexture(d3dSystem.d3dDevice, w, h, mipMaps ? log2i(Max(w+1, h+1)) : 1, 0,
684 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture))
690 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
692 D3DSURFACE_DESC desc;
693 D3DLOCKED_RECT lockedRect;
695 if(!IDirect3DTexture8_GetLevelDesc(texture, level, &desc) &&
696 !IDirect3DTexture8_LockRect(texture, level, &lockedRect, null, 0))
701 mipMap.width = desc.Width;
702 mipMap.height = desc.Height;
703 mipMap.picture = lockedRect.pBits;
706 case D3DFMT_R5G6B5: mipMap.pixelFormat = pixelFormat565; break;
707 case D3DFMT_A8R8G8B8: mipMap.pixelFormat = pixelFormat888; break;
708 case D3DFMT_A1R5G5B5: mipMap.pixelFormat = pixelFormat555; break;
710 mipMap.stride = lockedRect.Pitch >> GetColorDepthShifts(mipMap.pixelFormat);
712 mipSurface = mipMap.GetSurface(0,0,null);
715 if(mipMap.width != bitmap.width || mipMap.height != bitmap.height)
716 mipSurface.Filter(bitmap, 0,0, 0,0, mipMap.width, mipMap.height, bitmap.width, bitmap.height);
719 //FillBytesBy4(mipMap.picture, bitmap.picture, mipMap.width * mipMap.height);
720 mipSurface.Blit(bitmap, 0,0, 0,0, bitmap.width, bitmap.height);
726 mipMap.picture = null;
729 IDirect3DTexture8_UnlockRect(texture, level);
734 bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
735 bitmap.driver = displaySystem.driver;
736 bitmap.picture = (void *)texture;
739 FreeBitmap(displaySystem, bitmap);
745 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
748 D3D8Display d3dDisplay = display.driverData;
749 DisplaySystem displaySystem = display.displaySystem;
750 D3D8System d3dSystem = displaySystem.driverData;
751 D3D8Surface d3dSurface = surface.driverData = D3D8Surface { };
753 if(d3dSurface && d3dSystem.ready)
755 surface.unclippedBox = surface.box = clip;
756 surface.offset.x = x;
757 surface.offset.y = y;
759 d3dDisplay.updateBox.left = Min(x + clip.left, d3dDisplay.updateBox.left);
760 d3dDisplay.updateBox.top = Min(y + clip.top, d3dDisplay.updateBox.top);
761 d3dDisplay.updateBox.right = Max(x + clip.right, d3dDisplay.updateBox.right);
762 d3dDisplay.updateBox.bottom = Max(y + clip.bottom, d3dDisplay.updateBox.bottom);
764 SetViewportAndMatrices(display, x,y, &surface.box);
771 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
776 void ReleaseSurface(Display display, Surface surface)
778 delete surface.driverData;
781 void Clip(Display display, Surface surface, Box clip)
784 D3D8Display d3dDisplay = display.driverData;
789 box.Clip(surface.unclippedBox);
793 box = surface.box = surface.unclippedBox;
795 SetViewportAndMatrices(display, surface.offset.x, surface.offset.y, box);
798 void SetForeground(Display display, Surface surface, ColorAlpha color)
803 void SetBackground(Display display, Surface surface, ColorAlpha color)
805 D3D8Surface d3dSurface = surface.driverData;
806 d3dSurface.background = color;
809 ColorAlpha GetPixel(Display display, Surface surface, int x, int y)
814 void PutPixel(Display display, Surface surface,int x,int y)
816 D3D8Display d3dDisplay = display.driverData;
817 D3D8Surface d3dSurface = surface.driverData;
818 DisplaySystem displaySystem = display.displaySystem;
819 D3D8System d3dSystem = displaySystem.driverData;
820 D3D8Vertex vertex = { (float)x, (float)y, 1.0f, surface.foreground, 0, 0 };
822 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_POINTLIST, 1,
823 &vertex, sizeof(D3D8Vertex));
826 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
828 D3D8Surface d3dSurface = surface.driverData;
829 D3D8Display d3dDisplay = display.driverData;
830 DisplaySystem displaySystem = display.displaySystem;
831 D3D8System d3dSystem = displaySystem.driverData;
832 D3D8Vertex vertex[2] =
834 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
835 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 }
838 if(x1 == x2) vertex[1].y++;
839 else if(y1 == y2) vertex[1].x++;
841 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 1,
842 vertex, sizeof(D3D8Vertex));
845 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
847 DisplaySystem displaySystem = display.displaySystem;
848 D3D8System d3dSystem = displaySystem.driverData;
849 D3D8Surface d3dSurface = surface.driverData;
850 D3D8Display d3dDisplay = display.driverData;
851 D3D8Vertex vertex[5] =
853 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
854 { (float)x2, (float)y1, 1.0f, surface.foreground, 0, 0 },
855 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 },
856 { (float)x1, (float)y2, 1.0f, surface.foreground, 0, 0 },
857 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 }
860 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 4,
861 vertex, sizeof(D3D8Vertex));
865 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
867 DisplaySystem displaySystem = display.displaySystem;
868 D3D8System d3dSystem = displaySystem.driverData;
869 D3D8Surface d3dSurface = surface.driverData;
870 D3D8Display d3dDisplay = display.driverData;
871 D3D8Vertex vertex[4] =
873 { (float)x1, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
874 { (float)x2 + 1.0f, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
875 { (float)x1, (float)y2 + 1.0f, 1.0f, d3dSurface.background, 0, 0 },
876 { (float)x2 + 1.0f, (float)y2 + 1.0f, 1.0f, d3dSurface.background, 0, 0 }
879 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
880 vertex, sizeof(D3D8Vertex));
884 void Clear(Display display, Surface surface, ClearType type)
886 DisplaySystem displaySystem = display.displaySystem;
887 D3D8System d3dSystem = displaySystem.driverData;
888 D3D8Surface d3dSurface = surface.driverData;
889 D3D8Display d3dDisplay = display.driverData;
890 IDirect3DDevice8_Clear(d3dSystem.d3dDevice, 0, null,
891 ((type == depthBuffer) ? 0 : D3DCLEAR_TARGET) |
892 ((type == colorBuffer) ? 0 : D3DCLEAR_ZBUFFER),
893 d3dSurface.background, 1,0);
896 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
901 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
903 DisplaySystem displaySystem = display.displaySystem;
904 D3D8System d3dSystem = displaySystem.driverData;
905 D3D8Surface d3dSurface = surface.driverData;
906 D3D8Display d3dDisplay = display.driverData;
907 Color foreground = d3dSurface.writingText ? surface.foreground : white;
908 D3D8Vertex vertex[4] =
910 { (float)dx, (float)dy, 1.0f, foreground,
911 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
912 { (float)(dx+w), (float)dy, 1.0f, foreground,
913 (float)(sx+w)/ (src.width-1), (float)sy/ (src.height-1) },
914 { (float)dx, (float)(dy+h), 1.0f, foreground,
915 (float)sx/ (src.width-1), (float)(sy+h)/ (src.height-1) },
916 { (float)(dx+w), (float)(dy+h), 1.0f, foreground,
917 (float)(sx+w) / (src.width-1), (float)(sy+h)/ (src.height-1) }
920 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture8 *)src.picture);
921 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
922 vertex, sizeof(D3D8Vertex));
923 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, null);
926 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
928 DisplaySystem displaySystem = display.displaySystem;
929 D3D8System d3dSystem = displaySystem.driverData;
930 D3D8Surface d3dSurface = surface.driverData;
931 D3D8Display d3dDisplay = display.driverData;
932 D3D8Vertex vertex[4] =
934 { (float)dx, (float)dy, 1.0f, surface.foreground,
935 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
936 { (float)(dx+w), (float)dy, 1.0f, surface.foreground,
937 (float)(sx+sw)/ (src.width-1), (float)sy/ (src.height-1) },
938 { (float)dx, (float)(dy+h), 1.0f, surface.foreground,
939 (float)sx/ (src.width-1), (float)(sy+sh)/ (src.height-1) },
940 { (float)(dx+w), (float)(dy+h), 1.0f, surface.foreground,
941 (float)(sx+sw) / (src.width-1), (float)(sy+sh)/ (src.height-1) }
944 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture8 *)src.picture);
945 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
946 vertex, sizeof(D3D8Vertex));
947 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, null);
950 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
952 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
955 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
957 DisplaySystem displaySystem = display.displaySystem;
958 D3D8System d3dSystem = displaySystem.driverData;
960 Bitmap lfbBitmap { };
961 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
963 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Stretch(null, lfbSurface, src, dx, dy, sx, sy, w, h, sw, sh);
964 UnlockDisplay(display, lfbSurface);
966 lfbBitmap.picture = null;
970 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
972 DisplaySystem displaySystem = display.displaySystem;
973 D3D8System d3dSystem = displaySystem.driverData;
975 Bitmap lfbBitmap { };
976 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
978 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, lfbSurface, src, dx, dy, sx, sy, w, h);
979 UnlockDisplay(display, lfbSurface);
981 lfbBitmap.picture = null;
985 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
987 StretchDI(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
990 void UnloadFont(DisplaySystem displaySystem, Font font)
992 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
995 Font LoadFont(DisplaySystem displaySystem, char * faceName, float size, FontFlags flags)
997 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
1000 void TextFont(Display display, Surface surface, Font font)
1002 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
1005 void TextOpacity(Display display, Surface surface, bool opaque)
1007 D3D8Surface d3dSurface = surface.driverData;
1008 d3dSurface.opaqueText = opaque;
1011 void FontExtent(DisplaySystem displaySystem, Font font, byte * text, int len, int * width, int * height)
1013 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
1016 void WriteText(Display display, Surface surface, int x, int y, byte * text, int len)
1018 DisplaySystem displaySystem = display.displaySystem;
1019 D3D8System d3dSystem = displaySystem.driverData;
1020 D3D8Display d3dDisplay = display.driverData;
1021 D3D8Surface d3dSurface = surface.driverData;
1023 if(surface.textOpacity)
1026 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
1029 int x1 = x, y1 = y, x2 = x+w-1, y2 = y+h-1;
1030 D3D8Vertex vertex[4] =
1032 { (float)x1, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1033 { (float)x2 + 1.0f, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1034 { (float)x1, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 },
1035 { (float)x2 + 1.0f, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 }
1038 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
1039 vertex, sizeof(D3D8Vertex));
1041 //display.displaySystem.driver.Area(display, surface, x, y, x+w-1, y+h-1);
1043 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
1044 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
1045 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MIPFILTER, D3DTEXF_NONE);
1046 d3dSurface.writingText = true;
1048 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
1050 d3dSurface.writingText = false;
1051 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
1052 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
1053 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); //NONE);
1056 void TextExtent(Display display, Surface surface, byte * text, int len, int * width, int * height)
1058 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, width, height);
1061 void DrawingChar(Display display, Surface surface, byte character)
1066 void LineStipple(Display display, Surface surface, uint stipple)
1068 D3D8Display d3dDisplay = display.driverData;
1070 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_LINEPATTERN,
1071 stipple?MDWORD(1,stipple):0);
1075 void SetRenderState(Display display, RenderState state, uint value)
1077 DisplaySystem displaySystem = display.displaySystem;
1078 D3D8System d3dSystem = displaySystem.driverData;
1079 D3D8Display d3dDisplay = display.driverData;
1083 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, value ? TRUE : FALSE);
1086 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_FILLMODE,
1087 ((FillModeValue)value == solid) ? D3DFILL_SOLID : D3DFILL_WIREFRAME);
1090 // IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_USEW : D3DZB_FALSE);
1091 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_TRUE : D3DZB_FALSE);
1094 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZWRITEENABLE, value);
1097 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGCOLOR, value);
1101 float fogDensity = *(float *)(void *)&value;
1102 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGDENSITY, *(uint *)(void *)&fogDensity);
1106 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ALPHABLENDENABLE, value);
1109 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_AMBIENT, value);
1114 void SetLight(Display display, int id, Light light)
1116 DisplaySystem displaySystem = display.displaySystem;
1117 D3D8System d3dSystem = displaySystem.driverData;
1118 D3D8Display d3dDisplay = display.driverData;
1121 D3DLIGHT8 d3dLight =
1123 D3DLIGHT_DIRECTIONAL,
1124 // Opacity on the light?
1125 { light.diffuse.r, light.diffuse.g, light.diffuse.b, 1.0f },
1126 { light.specular.r, light.specular.g, light.specular.b, 1.0f },
1127 { light.ambient.r, light.ambient.g, light.ambient.b, 1.0f }
1129 Vector3Df vector {0,0,1};
1130 Vector3Df vectorPI {0,0,-1};
1131 Vector3Df direction;
1134 mat.RotationQuaternion(light.orientation);
1136 direction.MultMatrix(vector, mat);
1137 if(!display.display3D || !display.display3D.camera)
1139 d3dLight.Direction.x = direction.x;
1140 d3dLight.Direction.y = direction.y;
1141 d3dLight.Direction.z =-direction.z;
1145 ((Vector3Df *)&d3dLight.Direction)->MultMatrix(direction, d3dDisplay.worldMatrix);
1148 d3dDisplay.lights[id] = d3dLight;
1150 IDirect3DDevice8_LightEnable(d3dSystem.d3dDevice, id, TRUE);
1151 IDirect3DDevice8_SetLight(d3dSystem.d3dDevice, id, &d3dDisplay.lights[id]);
1153 direction.MultMatrix(vectorPI, mat);
1154 ((Vector3Df *)&d3dLight.Direction)->MultMatrix(direction, d3dDisplay.worldMatrix);
1156 d3dDisplay.lightsPI[id] = d3dLight;
1160 IDirect3DDevice8_LightEnable(d3dSystem.d3dDevice, id, FALSE);
1161 d3dDisplay.lights[id].Type = 0;
1165 void SetCamera(Display display, Surface surface, Camera camera)
1167 DisplaySystem displaySystem = display.displaySystem;
1168 D3D8System d3dSystem = displaySystem.driverData;
1169 D3D8Display d3dDisplay = display.driverData;
1170 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1173 Point topLeft {surface.box.left + surface.offset.x, surface.box.top + surface.offset.y};
1174 Point downRight {surface.box.right + surface.offset.x, surface.box.bottom + surface.offset.y};
1177 surface.offset.x + camera.origin.x,
1178 surface.offset.y + camera.origin.y
1182 float l = (topLeft.x - origin.x) * camera.zMin / camera.focalX;
1183 float r = (downRight.x - origin.x) * camera.zMin / camera.focalX;
1184 float b = (downRight.y - origin.y) * camera.zMin / camera.focalY;
1185 float t = (topLeft.y - origin.y) * camera.zMin / camera.focalY;
1186 float n = camera.zMin;
1187 float f = camera.zMax;
1189 matProj.m[0][0] = 2 * n / (r - l);
1190 matProj.m[0][1] = 0;
1191 matProj.m[0][2] = 0;
1192 matProj.m[0][3] = 0;
1194 matProj.m[1][0] = 0;
1195 matProj.m[1][1] = 2 * n / (t - b);
1196 matProj.m[1][2] = 0;
1197 matProj.m[1][3] = 0;
1199 matProj.m[2][0] = (l + r) / (r - l);
1200 matProj.m[2][1] = (t + b) / (t - b);
1201 matProj.m[2][2] = f / (n - f);
1202 matProj.m[2][3] = -1;
1204 matProj.m[3][0] = 0;
1205 matProj.m[3][1] = 0;
1206 matProj.m[3][2] = n * f / (n - f);
1207 matProj.m[3][3] = 0;
1209 IDirect3DDevice8_SetTransform(d3dDevice, D3DTS_PROJECTION, &matProj);
1211 // *** View Matrix ***
1212 if(!display.display3D.camera)
1213 d3dDisplay.worldMatrix++;
1216 matrix.Scale(1.0f, 1.0f, -1.0f);
1217 d3dDisplay.worldMatrix->Multiply(camera.viewMatrix, matrix);
1219 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1221 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shaders[0]);
1223 // IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_USEW);
1224 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_TRUE);
1225 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZWRITEENABLE, TRUE);
1226 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, FALSE);
1227 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_LIGHTING, TRUE);
1228 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, TRUE);
1230 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1232 else if(display.display3D.camera)
1234 d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
1235 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1236 IDirect3DDevice8_SetTransform(d3dDevice, D3DTS_PROJECTION, &d3dDisplay.projMatrix);
1238 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
1239 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
1240 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
1241 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
1242 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGENABLE, FALSE);
1243 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, FALSE);
1245 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
1246 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
1248 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shader2D);
1250 IDirect3DDevice8_SetTexture(d3dDevice, 0, null);
1254 void ApplyMaterial(Display display, Material material, Mesh mesh)
1256 DisplaySystem displaySystem = display.displaySystem;
1257 D3D8System d3dSystem = displaySystem.driverData;
1258 D3D8Display d3dDisplay = display.driverData;
1259 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1260 D3D8Mesh d3dMesh = mesh.data;
1263 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGENABLE, material.flags.noFog ? FALSE : TRUE);
1266 if(material.baseMap && d3dMesh.texCoords && material.baseMap.driver.displaySystem == displaySystem)
1268 Bitmap map = material.baseMap;
1270 IDirect3DDevice8_SetTexture(d3dDevice, 0, (IDirect3DBaseTexture8 *)map.picture);
1272 if(material.flags.tile)
1274 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
1275 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
1279 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
1280 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
1284 IDirect3DDevice8_SetTexture(d3dDevice, 0, null);
1287 // IDirect3DDevice8_SetMaterial(d3dDevice, (D3DMATERIAL8 *)&material.diffuse);
1290 D3DMATERIAL8 d3dMaterial;
1292 d3dMaterial.Diffuse.r = material.diffuse.r;
1293 d3dMaterial.Diffuse.g = material.diffuse.g;
1294 d3dMaterial.Diffuse.b = material.diffuse.b;
1295 d3dMaterial.Diffuse.a = material.opacity;
1297 d3dMaterial.Ambient.r = material.ambient.r;
1298 d3dMaterial.Ambient.g = material.ambient.g;
1299 d3dMaterial.Ambient.b = material.ambient.b;
1300 d3dMaterial.Ambient.a = 1;
1302 d3dMaterial.Specular.r = material.specular.r;
1303 d3dMaterial.Specular.g = material.specular.g;
1304 d3dMaterial.Specular.b = material.specular.b;
1305 d3dMaterial.Specular.a = 1;
1307 d3dMaterial.Emissive.r = material.emissive.r;
1308 d3dMaterial.Emissive.g = material.emissive.g;
1309 d3dMaterial.Emissive.b = material.emissive.b;
1310 d3dMaterial.Emissive.a = 1;
1312 d3dMaterial.Power = material.power;
1314 IDirect3DDevice8_SetMaterial(d3dDevice, &d3dMaterial); //(D3DMATERIAL8 *)&material.diffuse
1318 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
1320 D3D8System d3dSystem = displaySystem.driverData;
1321 D3D8Mesh d3dMesh = mesh.data;
1324 if(!(mesh.flags.vertices))
1326 if(d3dMesh.vertices)
1328 IDirect3DVertexBuffer8_Release(d3dMesh.vertices);
1329 d3dMesh.vertices = null;
1331 delete mesh.vertices;
1333 if(!(mesh.flags.normals))
1337 IDirect3DVertexBuffer8_Release(d3dMesh.normals);
1338 d3dMesh.normals = null;
1340 delete mesh.normals;
1342 if(!(mesh.flags.texCoords1))
1344 if(d3dMesh.texCoords)
1346 IDirect3DVertexBuffer8_Release(d3dMesh.texCoords);
1347 d3dMesh.texCoords = null;
1349 delete mesh.texCoords;
1351 if(!(mesh.flags.texCoords2))
1353 if(d3dMesh.texCoords2)
1355 IDirect3DVertexBuffer8_Release(d3dMesh.texCoords2);
1356 d3dMesh.texCoords2 = null;
1358 // delete mesh.texCoords2;
1368 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh)
1370 D3D8System d3dSystem = displaySystem.driverData;
1371 bool result = false;
1372 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1375 mesh.data = D3D8Mesh { };
1378 D3D8Mesh d3dMesh = mesh.data;
1380 if((mesh.flags .vertices) && !d3dMesh.vertices)
1382 mesh.vertices = new Vector3Df[mesh.nVertices];
1383 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * mesh.nVertices,
1384 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices))
1387 if((mesh.flags.normals) && !d3dMesh.normals)
1389 mesh.normals = new Vector3Df[mesh.nVertices];
1390 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * mesh.nVertices,
1391 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals))
1394 if((mesh.flags.texCoords1) && !d3dMesh.texCoords)
1396 mesh.texCoords = new Pointf[mesh.nVertices];
1397 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * mesh.nVertices,
1398 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords))
1405 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1407 D3D8System d3dSystem = displaySystem.driverData;
1408 D3D8Mesh d3dMesh = mesh.data;
1409 if(!flags) flags = mesh.flags;
1411 if(flags.vertices && mesh.vertices)
1413 Vector3Df * vertices;
1414 if(!IDirect3DVertexBuffer8_Lock(d3dMesh.vertices, 0, 0, (byte **) &vertices, 0))
1416 memcpy(vertices, mesh.vertices, mesh.nVertices * sizeof(Vector3Df));
1417 IDirect3DVertexBuffer8_Unlock(d3dMesh.vertices);
1420 if(flags.normals && mesh.normals)
1422 Vector3Df * normals;
1423 if(!IDirect3DVertexBuffer8_Lock(d3dMesh.normals, 0, 0, (byte **) &normals, 0))
1425 memcpy(normals, mesh.normals, mesh.nVertices * sizeof(Vector3Df));
1426 IDirect3DVertexBuffer8_Unlock(d3dMesh.normals);
1429 if(flags.texCoords1 && mesh.texCoords)
1432 if(!IDirect3DVertexBuffer8_Lock(d3dMesh.texCoords, 0, 0, (byte **) &texCoords, 0))
1434 memcpy(texCoords, mesh.texCoords, mesh.nVertices * sizeof(Pointf));
1435 IDirect3DVertexBuffer8_Unlock(d3dMesh.texCoords);
1440 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1446 void FreeIndices(DisplaySystem displaySystem, D3D8Indices d3dIndices)
1450 if(d3dIndices.buffer)
1451 IDirect3DIndexBuffer8_Release(d3dIndices.buffer);
1452 delete d3dIndices.indices;
1457 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
1459 D3D8System d3dSystem = displaySystem.driverData;
1460 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1461 D3D8Indices d3dIndices { };
1462 if(d3dIndices && nIndices)
1464 d3dIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
1465 IDirect3DDevice8_CreateIndexBuffer(d3dDevice, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * nIndices, 0, indices32bit ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
1466 D3DPOOL_MANAGED, &d3dIndices.buffer);
1467 d3dIndices.nIndices = nIndices;
1472 void UnlockIndices(DisplaySystem displaySystem, D3D8Indices d3dIndices, bool indices32bit, int nIndices)
1474 uint16 * indexBuffer = null;
1475 if(!IDirect3DIndexBuffer8_Lock(d3dIndices.buffer, 0, 0, (byte **)&indexBuffer, 0))
1477 memcpy(indexBuffer, d3dIndices.indices, indices32bit ? sizeof(uint32) : sizeof(uint16) * d3dIndices.nIndices);
1478 IDirect3DIndexBuffer8_Unlock(d3dIndices.buffer);
1482 uint16 * LockIndices(DisplaySystem displaySystem, D3D8Indices d3dIndices)
1484 return d3dIndices.indices;
1487 void SelectMesh(Display display, Mesh mesh)
1489 DisplaySystem displaySystem = display.displaySystem;
1490 D3D8System d3dSystem = displaySystem.driverData;
1491 D3D8Display d3dDisplay = display.driverData;
1492 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1494 if(mesh && mesh.data)
1497 D3D8Mesh d3dMesh = mesh.data;
1499 IDirect3DDevice8_SetStreamSource(d3dSystem.d3dDevice, 0, d3dMesh.vertices, sizeof(Vector3Df));
1502 IDirect3DDevice8_SetStreamSource(d3dSystem.d3dDevice, 1, d3dMesh.normals, sizeof(Vector3Df));
1506 IDirect3DDevice8_SetStreamSource(d3dSystem.d3dDevice, 1, null, sizeof(Vector3Df));
1507 if(d3dMesh.texCoords)
1509 IDirect3DDevice8_SetStreamSource(d3dSystem.d3dDevice, 2, d3dMesh.texCoords, sizeof(Pointf));
1513 IDirect3DDevice8_SetStreamSource(d3dSystem.d3dDevice, 2, null, sizeof(Pointf));
1515 IDirect3DDevice8_SetVertexShader(d3dSystem.d3dDevice, d3dSystem.shaders[shader]);
1519 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
1521 DisplaySystem displaySystem = display.displaySystem;
1522 D3D8System d3dSystem = displaySystem.driverData;
1523 D3D8Display d3dDisplay = display.driverData;
1524 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1525 if(primitiveTypes[primitive->type.primitiveType])
1527 int numPrimitives = (primitive->type.vertexRange) ? primitive->nVertices : primitive->nIndices;
1530 switch(primitive->type.primitiveType)
1532 case lines: numPrimitives /= 2; break;
1533 case triangles: numPrimitives /= 3; break;
1545 if(primitive->type.vertexRange)
1547 if(primitive->type.primitiveType == quads)
1549 for(c = 0; c<numPrimitives; c++)
1550 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1553 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1557 D3D8Indices indices = primitive->data;
1558 IDirect3DDevice8_SetIndices(d3dDevice, indices.buffer, 0);
1559 if(primitive->type.primitiveType == quads)
1561 for(c = 0; c<numPrimitives; c++)
1562 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, c*4, 2);
1565 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, 0, numPrimitives);
1568 if(display.display3D.material.flags.doubleSided)
1570 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CCW);
1571 if(!display.display3D.material.flags.singleSideLight)
1573 for(c = 0; c<NumberOfLights; c++)
1574 if(d3dDisplay.lights[c].Type)
1575 IDirect3DDevice8_SetLight(d3dDevice, c, &d3dDisplay.lightsPI[c]);
1577 if(primitive->type.vertexRange)
1579 if(primitive->type.primitiveType == quads)
1581 for(c = 0; c<numPrimitives; c++)
1582 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1585 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1589 D3D8Indices indices = primitive->data;
1590 IDirect3DDevice8_SetIndices(d3dDevice, indices.buffer, 0);
1591 if(primitive->type.primitiveType == quads)
1593 for(c = 0; c<numPrimitives; c++)
1594 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, c*4, 2);
1597 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, 0, numPrimitives);
1600 if(!display.display3D.material.flags.singleSideLight)
1602 for(c = 0; c<NumberOfLights; c++)
1603 if(d3dDisplay.lights[c].Type)
1604 IDirect3DDevice8_SetLight(d3dDevice, c, &d3dDisplay.lights[c]);
1606 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1611 void PushMatrix(Display display)
1613 D3D8Display d3dDisplay = display.driverData;
1614 *(d3dDisplay.worldMatrix+1) = *(d3dDisplay.worldMatrix);
1615 d3dDisplay.worldMatrix++;
1618 void PopMatrix(Display display, bool setMatrix)
1620 D3D8Display d3dDisplay = display.driverData;
1621 DisplaySystem displaySystem = display.displaySystem;
1622 D3D8System d3dSystem = displaySystem.driverData;
1624 d3dDisplay.worldMatrix--;
1626 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1629 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
1631 DisplaySystem displaySystem = display.displaySystem;
1632 D3D8System d3dSystem = displaySystem.driverData;
1633 Camera camera = useCamera ? display.display3D.camera : null;
1634 D3D8Display d3dDisplay = display.driverData;
1635 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1637 Matrix matrix = transMatrix, temp;
1641 matrix.Scale(1.0f, 1.0f, -1.0f);
1642 *(d3dDisplay.worldMatrix) = matrix;
1648 - camera.cPosition.x,
1649 - camera.cPosition.y,
1650 - camera.cPosition.z);
1651 temp.Multiply(matrix, d3dDisplay.worldMatrix);
1652 *(d3dDisplay.worldMatrix) = temp;
1655 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1658 bool Lock(Display display)
1660 DisplaySystem displaySystem = display.displaySystem;
1661 D3D8System d3dSystem = displaySystem.driverData;
1662 D3D8Display d3dDisplay = display.driverData;
1664 if(d3dDisplay.backBuffer)
1666 IDirect3DDevice8_SetRenderTarget(d3dSystem.d3dDevice, d3dDisplay.backBuffer, d3dDisplay.depthSurface);
1667 IDirect3DDevice8_BeginScene(d3dSystem.d3dDevice);
1669 d3dSystem.inScene = true;
1674 void Unlock(Display display)
1676 DisplaySystem displaySystem = display.displaySystem;
1677 D3D8System d3dSystem = displaySystem.driverData;
1678 D3D8Display d3dDisplay = display.driverData;
1680 if(d3dSystem.inScene)
1682 IDirect3DDevice8_EndScene(d3dSystem.d3dDevice);
1683 d3dSystem.inScene = false;