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 DWORD shaders[NUM_VERTEX_SHADERS], shader2D;
72 static class D3D8Surface : struct
74 // For compatibility with LFB driver
81 ColorAlpha background;
84 static class D3D8Mesh : struct
86 IDirect3DVertexBuffer8 * vertices;
87 IDirect3DVertexBuffer8 * normals;
88 IDirect3DVertexBuffer8 * texCoords;
89 IDirect3DVertexBuffer8 * texCoords2;
92 static struct D3D8Vertex
99 static class D3D8Indices : struct
102 IDirect3DIndexBuffer8 * buffer;
106 static int primitiveTypes[RenderPrimitiveType] =
108 D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP, D3DPT_TRIANGLEFAN, D3DPT_TRIANGLEFAN, 0, D3DPT_LINESTRIP
111 static void SetTransformMatrix(IDirect3DDevice8 * device, Matrix matrix)
117 (float)matrix.m[0][0], (float)matrix.m[0][1], (float)matrix.m[0][2], (float)matrix.m[0][3],
118 (float)matrix.m[1][0], (float)matrix.m[1][1], (float)matrix.m[1][2], (float)matrix.m[1][3],
119 (float)matrix.m[2][0], (float)matrix.m[2][1], (float)matrix.m[2][2], (float)matrix.m[2][3],
120 (float)matrix.m[3][0], (float)matrix.m[3][1], (float)matrix.m[3][2], (float)matrix.m[3][3]
124 IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &d3dMat);
127 class Direct3D8DisplayDriver : DisplayDriver
129 class_property(name) = "Direct3D8";
131 bool ::LockDisplay(Display display, Surface surface, Bitmap lfbBitmap, Surface * lfbSurface)
134 D3D8Display d3dDisplay = display.driverData;
136 //if(!IDirect3DDevice8_GetBackBuffer(d3dSystem.d3dDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
138 D3DLOCKED_RECT lockedRect;
139 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;
164 lfbBitmap.driver = null;
165 lfbBitmap.displaySystem = null;
166 lfbBitmap.picture = (byte *)lockedRect.pBits;
167 lfbBitmap.transparent = false;
168 lfbBitmap.stride = lockedRect.Pitch >> GetColorDepthShifts(lfbBitmap.pixelFormat);
169 lfbBitmap.width = display.width;
170 lfbBitmap.height = display.height;
172 *lfbSurface = lfbBitmap.GetSurface(surface ? surface.offset.x : 0, surface ? surface.offset.y : 0, surface ? &surface.box : null);
176 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
181 void ::UnlockDisplay(Display display, Surface surface)
183 D3D8Display d3dDisplay = display.driverData;
184 if(d3dDisplay.backBuffer)
186 IDirect3DSurface8_UnlockRect(d3dDisplay.backBuffer);
187 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
192 void ::SetViewportAndMatrices(Display display, int x, int y, Box box)
194 D3D8Display d3dDisplay = display.driverData;
195 DisplaySystem displaySystem = display.displaySystem;
196 D3D8System d3dSystem = displaySystem.driverData;
199 D3DVIEWPORT8 viewport;
202 if(box.right<box.left || box.bottom <box.top)
204 viewport.Width = viewport.Height = 1;
205 viewport.X = viewport.Y = MAXDWORD;
209 viewport.X = x + box.left;
210 viewport.Y = y + box.top;
211 viewport.Width = box.right - box.left + 1;
212 viewport.Height = box.bottom - box.top + 1;
214 if(!IDirect3DDevice8_SetViewport(d3dSystem.d3dDevice, &viewport))
216 D3DMATRIX * matProj = &d3dDisplay.projMatrix;
217 Matrix * matWorld = d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
219 matProj->m[0][0] = 2.0f / viewport.Width;
220 matProj->m[1][1] =-2.0f / viewport.Height;
221 matProj->m[2][2] = matProj->m[3][1] = matProj->m[3][3] = 1;
222 matProj->m[3][0] = -1;
224 IDirect3DDevice8_SetTransform(d3dSystem.d3dDevice, D3DTS_PROJECTION, matProj);
226 matWorld->Identity();
227 matWorld->m[3][0] =-box.left;
228 matWorld->m[3][1] =-box.top;
230 SetTransformMatrix(d3dSystem.d3dDevice, matWorld);
236 bool CreateDisplaySystem(DisplaySystem displaySystem)
239 D3D8System d3dSystem = displaySystem.driverData = D3D8System { };
242 displaySystem.flags.alpha = true;
243 //if(displaySystem.flags.fullScreen)
244 displaySystem.flags.flipping = true;
245 displaySystem.pixelFormat = pixelFormat888;
247 d3dSystem.d3dDll = LoadLibrary("d3d8.dll");
250 d3dSystem.direct3DCreate8 = (void *)GetProcAddress(d3dSystem.d3dDll, "Direct3DCreate8");
251 if(d3dSystem.direct3DCreate8)
253 if((d3dSystem.direct3D = d3dSystem.direct3DCreate8(D3D_SDK_VERSION)))
255 D3DDISPLAYMODE d3ddm;
256 if(!IDirect3D8_GetAdapterDisplayMode(d3dSystem.direct3D, D3DADAPTER_DEFAULT, &d3ddm))
258 d3dSystem.d3dpp.BackBufferCount = 1;
260 if(displaySystem.flags.fullScreen)
262 d3dSystem.d3dpp.BackBufferWidth = d3ddm.Width;
263 d3dSystem.d3dpp.BackBufferHeight = d3ddm.Height;
264 d3dSystem.d3dpp.hDeviceWindow = displaySystem.window;
268 d3dSystem.d3dpp.hDeviceWindow = d3dSystem.hwnd =
269 CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
270 d3dSystem.d3dpp.Windowed = TRUE;
273 d3dSystem.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
274 d3dSystem.format = d3dSystem.d3dpp.BackBufferFormat = d3ddm.Format;
275 d3dSystem.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
277 if(!IDirect3D8_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
278 d3dSystem.d3dpp.hDeviceWindow,
279 D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE|D3DCREATE_FPU_PRESERVE,
280 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
284 d3dSystem.usage = D3DUSAGE_SOFTWAREPROCESSING;
285 if(!IDirect3D8_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
286 d3dSystem.d3dpp.hDeviceWindow,
287 D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,
288 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
294 DWORD vertexShaders[NUM_VERTEX_SHADERS][7] =
298 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
303 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
305 D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3),
310 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
312 D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
317 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
319 D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3),
321 D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
326 DWORD vertexShader2D[] =
329 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
330 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
331 D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
336 for(c = 0; c<NUM_VERTEX_SHADERS; c++)
337 if(IDirect3DDevice8_CreateVertexShader(d3dSystem.d3dDevice, vertexShaders[c], null, &d3dSystem.shaders[c], 0))
340 if(c < NUM_VERTEX_SHADERS ||
341 IDirect3DDevice8_CreateVertexShader(d3dSystem.d3dDevice, vertexShader2D, null, &d3dSystem.shader2D, 0))
345 d3dSystem.ready = false;
351 Log("Couldn't load library d3d8.dll\n");
352 // LogErrorCode(ERR_MISSING_LIBRARY, "d3d8.dll");
357 void DestroyDisplaySystem(DisplaySystem displaySystem)
359 D3D8System d3dSystem = displaySystem.driverData;
362 for(c = 0; c<NUM_VERTEX_SHADERS; c++)
364 if(d3dSystem.shaders[c])
365 IDirect3DDevice8_DeleteVertexShader(d3dSystem.d3dDevice, d3dSystem.shaders[c]);
368 if(d3dSystem.shader2D)
369 IDirect3DDevice8_DeleteVertexShader(d3dSystem.d3dDevice, d3dSystem.shader2D);
371 if(d3dSystem.d3dDevice)
372 IDirect3DDevice8_Release(d3dSystem.d3dDevice);
374 if(d3dSystem.direct3D)
375 IDirect3D8_Release(d3dSystem.direct3D);
377 FreeLibrary(d3dSystem.d3dDll);
380 displaySystem.driverData = null;
384 void DestroyDisplay(Display display)
386 DisplaySystem displaySystem = display.displaySystem;
387 D3D8System d3dSystem = displaySystem.driverData;
388 D3D8Display d3dDisplay = display.driverData;
390 if(d3dSystem.inScene)
392 IDirect3DDevice8_EndScene(d3dSystem.d3dDevice);
393 d3dSystem.inScene = false;
396 if(d3dDisplay.backBuffer)
397 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
399 if(d3dDisplay.depthSurface)
400 IDirect3DSurface8_Release(d3dDisplay.depthSurface);
402 if(d3dDisplay.swapChain)
403 IDirect3DSwapChain8_Release(d3dDisplay.swapChain);
406 display.driverData = null;
409 bool CreateDisplay(Display display)
412 DisplaySystem displaySystem = display.displaySystem;
413 D3D8System d3dSystem = displaySystem.driverData;
414 display.driverData = D3D8Display { };
416 d3dSystem.ready = false;
423 bool DisplaySize(Display display, int width, int height)
426 DisplaySystem displaySystem = display.displaySystem;
427 D3D8System d3dSystem = displaySystem.driverData;
428 D3D8Display d3dDisplay = display.driverData;
429 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
431 d3dSystem.ready = false;
433 if(d3dDisplay.backBuffer)
435 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
436 d3dDisplay.backBuffer = null;
439 if(d3dDisplay.depthSurface)
441 IDirect3DSurface8_Release(d3dDisplay.depthSurface);
442 d3dDisplay.depthSurface = null;
445 if(d3dDisplay.swapChain)
447 IDirect3DSwapChain8_Release(d3dDisplay.swapChain);
448 d3dDisplay.swapChain = null;
454 if(displaySystem.flags.fullScreen)
456 d3dSystem.d3dpp.BackBufferWidth = width;
457 d3dSystem.d3dpp.BackBufferHeight = height;
459 result = !IDirect3DDevice8_Reset(d3dSystem.d3dDevice, &d3dSystem.d3dpp);
463 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;
464 d3dDisplay.d3dpp.BackBufferWidth = width;
465 d3dDisplay.d3dpp.BackBufferHeight = height;
466 d3dDisplay.d3dpp.Windowed = TRUE;
467 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
468 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
469 d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
471 //d3dDisplay.d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
472 d3dDisplay.d3dpp.BackBufferFormat = d3dSystem.format;
473 d3dDisplay.d3dpp.BackBufferCount = 1;
474 d3dDisplay.d3dpp.hDeviceWindow = display.window;
475 d3dDisplay.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
476 // d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_DONOTWAIT;
477 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
478 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
480 result = !IDirect3DDevice8_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
481 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
485 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
486 result = !IDirect3DDevice8_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
487 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
491 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
492 result = !IDirect3DDevice8_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
493 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
499 if(d3dDisplay.swapChain)
500 result = !IDirect3DSwapChain8_GetBackBuffer(d3dDisplay.swapChain,
501 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer);
503 result = !IDirect3DDevice8_GetBackBuffer(d3dSystem.d3dDevice,
504 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer);
507 if(!IDirect3DDevice8_CreateDepthStencilSurface(d3dSystem.d3dDevice, width, height,
508 D3DFMT_D16, d3dDisplay.d3dpp.MultiSampleType,&d3dDisplay.depthSurface))
509 d3dSystem.ready = true;
515 float fogDensity = 0;
517 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shader2D);
519 //IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
520 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
521 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
522 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
523 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
524 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
525 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
526 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGTABLEMODE, D3DFOG_EXP);
527 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGDENSITY, RenderStateFloat { fogDensity }.ui);
528 display.ambient = Color { 50,50,50 };
529 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_NORMALIZENORMALS, TRUE);
530 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
532 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
533 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
534 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
535 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
536 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
537 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
539 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
540 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
541 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
543 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
544 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
546 IDirect3DDevice8_SetTexture(d3dDevice, 0, null);
551 display.width = width;
552 display.height = height;
553 d3dDisplay.updateBox.left = display.width;
554 d3dDisplay.updateBox.top = display.height;
555 d3dDisplay.updateBox.right = 0;
556 d3dDisplay.updateBox.bottom = 0;
561 void DisplayPosition(Display display, int x, int y)
566 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
570 void RestorePalette(Display display)
574 void StartUpdate(Display display)
578 void EndUpdate(Display display)
582 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
586 void Update(Display display, Box updateBox)
588 DisplaySystem displaySystem = display.displaySystem;
589 D3D8System d3dSystem = displaySystem.driverData;
590 D3D8Display d3dDisplay = display.driverData;
593 //eSystem_Sleep(0.05);
594 IDirect3DDevice8_EndScene(d3dSystem.d3dDevice);
596 if(display.displaySystem.flags.flipping)
598 if(d3dDisplay.swapChain)
599 IDirect3DSwapChain8_Present(d3dDisplay.swapChain, null, null, null, null);
601 IDirect3DDevice8_Present(d3dSystem.d3dDevice, null, null, null, null);
607 if(updateBox != null)
609 source.left = dest.left = updateBox.left;
610 source.top = dest.top = updateBox.top;
611 source.right = dest.right = updateBox.right+1;
612 source.bottom = dest.bottom = updateBox.bottom+1;
616 source.left = dest.left = d3dDisplay.updateBox.left;
617 source.top = dest.top = d3dDisplay.updateBox.top;
618 source.right = dest.right = d3dDisplay.updateBox.right+1;
619 source.bottom = dest.bottom = d3dDisplay.updateBox.bottom+1;
621 if(dest.bottom > dest.top && dest.right > dest.left)
622 IDirect3DDevice8_Present(d3dSystem.d3dDevice, &source, &dest, null, null);
623 if(updateBox == null)
625 d3dDisplay.updateBox.left = display.width;
626 d3dDisplay.updateBox.top = display.height;
627 d3dDisplay.updateBox.right = 0;
628 d3dDisplay.updateBox.bottom = 0;
631 d3dSystem.inScene = false;
635 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
639 Bitmap lfbBitmap { };
641 if(LockDisplay(display, null, lfbBitmap, &lfbSurface))
644 if(bitmap.pixelFormat != lfbBitmap.pixelFormat || bitmap.width < w || bitmap.height < h)
647 bitmap.Allocate(null, w,h,w, lfbBitmap.pixelFormat, false);
649 surface = bitmap.GetSurface(0,0,null);
652 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, surface, lfbBitmap, 0, 0, x, y, w, h);
656 UnlockDisplay(display, lfbSurface);
658 lfbBitmap.picture = null;
665 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
667 if(bitmap.driverData)
668 IDirect3DTexture8_Release((IDirect3DTexture8 *)bitmap.driverData);
671 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
676 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps, int cubeMapFace)
679 D3D8System d3dSystem = displaySystem.driverData;
680 if(cubeMapFace && bitmap.Convert(null, pixelFormat888, null))
682 IDirect3DTexture8 * texture;
683 uint w = pow2i(Min(bitmap.width, 512)), h = pow2i(Min(bitmap.height, 512));
685 if(!IDirect3DDevice8_CreateTexture(d3dSystem.d3dDevice, w, h, mipMaps ? log2i(Max(w+1, h+1)) : 1, 0,
686 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture))
692 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
694 D3DSURFACE_DESC desc;
695 D3DLOCKED_RECT lockedRect;
697 if(!IDirect3DTexture8_GetLevelDesc(texture, level, &desc) &&
698 !IDirect3DTexture8_LockRect(texture, level, &lockedRect, null, 0))
703 mipMap.width = desc.Width;
704 mipMap.height = desc.Height;
705 mipMap.picture = lockedRect.pBits;
708 case D3DFMT_R5G6B5: mipMap.pixelFormat = pixelFormat565; break;
709 case D3DFMT_A8R8G8B8: mipMap.pixelFormat = pixelFormat888; break;
710 case D3DFMT_A1R5G5B5: mipMap.pixelFormat = pixelFormat555; break;
716 mipMap.stride = lockedRect.Pitch >> GetColorDepthShifts(mipMap.pixelFormat);
718 mipSurface = mipMap.GetSurface(0,0,null);
721 if(mipMap.width != bitmap.width || mipMap.height != bitmap.height)
722 mipSurface.Filter(bitmap, 0,0, 0,0, mipMap.width, mipMap.height, bitmap.width, bitmap.height);
725 //FillBytesBy4(mipMap.picture, bitmap.picture, mipMap.width * mipMap.height);
726 mipSurface.Blit(bitmap, 0,0, 0,0, bitmap.width, bitmap.height);
733 mipMap.picture = null;
736 IDirect3DTexture8_UnlockRect(texture, level);
741 bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
742 bitmap.driver = displaySystem.driver;
743 bitmap.driverData = (void *)texture;
746 FreeBitmap(displaySystem, bitmap);
752 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
755 D3D8Display d3dDisplay = display.driverData;
756 DisplaySystem displaySystem = display.displaySystem;
757 D3D8System d3dSystem = displaySystem.driverData;
758 D3D8Surface d3dSurface = surface.driverData = D3D8Surface { };
760 if(d3dSurface && d3dSystem.ready)
762 surface.unclippedBox = surface.box = clip;
763 surface.offset.x = x;
764 surface.offset.y = y;
766 d3dDisplay.updateBox.left = Min(x + clip.left, d3dDisplay.updateBox.left);
767 d3dDisplay.updateBox.top = Min(y + clip.top, d3dDisplay.updateBox.top);
768 d3dDisplay.updateBox.right = Max(x + clip.right, d3dDisplay.updateBox.right);
769 d3dDisplay.updateBox.bottom = Max(y + clip.bottom, d3dDisplay.updateBox.bottom);
771 SetViewportAndMatrices(display, x,y, &surface.box);
778 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
783 void ReleaseSurface(Display display, Surface surface)
785 delete surface.driverData;
788 void Clip(Display display, Surface surface, Box clip)
795 box.Clip(surface.unclippedBox);
799 box = surface.box = surface.unclippedBox;
801 SetViewportAndMatrices(display, surface.offset.x, surface.offset.y, box);
804 void SetForeground(Display display, Surface surface, ColorAlpha color)
809 void SetBackground(Display display, Surface surface, ColorAlpha color)
811 D3D8Surface d3dSurface = surface.driverData;
812 d3dSurface.background = color;
815 ColorAlpha GetPixel(Display display, Surface surface, int x, int y)
820 void PutPixel(Display display, Surface surface,int x,int y)
822 DisplaySystem displaySystem = display.displaySystem;
823 D3D8System d3dSystem = displaySystem.driverData;
824 D3D8Vertex vertex = { (float)x, (float)y, 1.0f, surface.foreground, 0, 0 };
826 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_POINTLIST, 1,
827 &vertex, sizeof(D3D8Vertex));
830 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
832 DisplaySystem displaySystem = display.displaySystem;
833 D3D8System d3dSystem = displaySystem.driverData;
834 D3D8Vertex vertex[2] =
836 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
837 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 }
840 if(x1 == x2) vertex[1].y++;
841 else if(y1 == y2) vertex[1].x++;
843 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 1,
844 vertex, sizeof(D3D8Vertex));
847 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
849 DisplaySystem displaySystem = display.displaySystem;
850 D3D8System d3dSystem = displaySystem.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 D3D8Vertex vertex[4] =
872 { (float)x1, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
873 { (float)x2 + 1.0f, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
874 { (float)x1, (float)y2 + 1.0f, 1.0f, d3dSurface.background, 0, 0 },
875 { (float)x2 + 1.0f, (float)y2 + 1.0f, 1.0f, d3dSurface.background, 0, 0 }
878 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
879 vertex, sizeof(D3D8Vertex));
883 void Clear(Display display, Surface surface, ClearType type)
885 DisplaySystem displaySystem = display.displaySystem;
886 D3D8System d3dSystem = displaySystem.driverData;
887 D3D8Surface d3dSurface = surface.driverData;
888 IDirect3DDevice8_Clear(d3dSystem.d3dDevice, 0, null,
889 ((type == depthBuffer) ? 0 : D3DCLEAR_TARGET) |
890 ((type == colorBuffer) ? 0 : D3DCLEAR_ZBUFFER),
891 d3dSurface.background, 1,0);
894 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
899 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
901 DisplaySystem displaySystem = display.displaySystem;
902 D3D8System d3dSystem = displaySystem.driverData;
903 D3D8Surface d3dSurface = surface.driverData;
904 Color foreground = d3dSurface.writingText ? surface.foreground : white;
905 D3D8Vertex vertex[4] =
907 { (float)dx, (float)dy, 1.0f, foreground,
908 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
909 { (float)(dx+w), (float)dy, 1.0f, foreground,
910 (float)(sx+w)/ (src.width-1), (float)sy/ (src.height-1) },
911 { (float)dx, (float)(dy+h), 1.0f, foreground,
912 (float)sx/ (src.width-1), (float)(sy+h)/ (src.height-1) },
913 { (float)(dx+w), (float)(dy+h), 1.0f, foreground,
914 (float)(sx+w) / (src.width-1), (float)(sy+h)/ (src.height-1) }
917 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture8 *)src.driverData);
918 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
919 vertex, sizeof(D3D8Vertex));
920 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, null);
923 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
925 DisplaySystem displaySystem = display.displaySystem;
926 D3D8System d3dSystem = displaySystem.driverData;
927 D3D8Vertex vertex[4] =
929 { (float)dx, (float)dy, 1.0f, surface.foreground,
930 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
931 { (float)(dx+w), (float)dy, 1.0f, surface.foreground,
932 (float)(sx+sw)/ (src.width-1), (float)sy/ (src.height-1) },
933 { (float)dx, (float)(dy+h), 1.0f, surface.foreground,
934 (float)sx/ (src.width-1), (float)(sy+sh)/ (src.height-1) },
935 { (float)(dx+w), (float)(dy+h), 1.0f, surface.foreground,
936 (float)(sx+sw) / (src.width-1), (float)(sy+sh)/ (src.height-1) }
939 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture8 *)src.driverData);
940 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
941 vertex, sizeof(D3D8Vertex));
942 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, null);
945 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
947 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
950 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
953 Bitmap lfbBitmap { };
954 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
956 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Stretch(null, lfbSurface, src, dx, dy, sx, sy, w, h, sw, sh);
957 UnlockDisplay(display, lfbSurface);
959 lfbBitmap.picture = null;
963 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
966 Bitmap lfbBitmap { };
967 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
969 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, lfbSurface, src, dx, dy, sx, sy, w, h);
970 UnlockDisplay(display, lfbSurface);
972 lfbBitmap.picture = null;
976 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
978 StretchDI(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
981 void UnloadFont(DisplaySystem displaySystem, Font font)
983 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
986 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
988 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
991 void TextFont(Display display, Surface surface, Font font)
993 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
996 void TextOpacity(Display display, Surface surface, bool opaque)
998 D3D8Surface d3dSurface = surface.driverData;
999 d3dSurface.opaqueText = opaque;
1002 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
1004 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
1007 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
1009 DisplaySystem displaySystem = display.displaySystem;
1010 D3D8System d3dSystem = displaySystem.driverData;
1011 D3D8Surface d3dSurface = surface.driverData;
1013 if(surface.textOpacity)
1016 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, prevGlyph, rPrevGlyph, &adv);
1020 int x1 = x, y1 = y, x2 = x+w-1, y2 = y+h-1;
1021 D3D8Vertex vertex[4] =
1023 { (float)x1, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1024 { (float)x2 + 1.0f, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1025 { (float)x1, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 },
1026 { (float)x2 + 1.0f, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 }
1029 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
1030 vertex, sizeof(D3D8Vertex));
1032 //display.displaySystem.driver.Area(display, surface, x, y, x+w-1, y+h-1);
1034 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
1035 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
1036 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MIPFILTER, D3DTEXF_NONE);
1037 d3dSurface.writingText = true;
1039 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
1041 d3dSurface.writingText = false;
1042 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
1043 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
1044 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); //NONE);
1047 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
1049 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, width, height, prevGlyph, rPrevGlyph, adv);
1052 void DrawingChar(Display display, Surface surface, byte character)
1057 void LineStipple(Display display, Surface surface, uint stipple)
1060 D3D8Display d3dDisplay = display.driverData;
1061 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_LINEPATTERN,
1062 stipple?MDWORD(1,stipple):0);
1066 void SetRenderState(Display display, RenderState state, uint value)
1068 DisplaySystem displaySystem = display.displaySystem;
1069 D3D8System d3dSystem = displaySystem.driverData;
1073 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, value ? TRUE : FALSE);
1076 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_FILLMODE,
1077 ((FillModeValue)value == solid) ? D3DFILL_SOLID : D3DFILL_WIREFRAME);
1080 // IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_USEW : D3DZB_FALSE);
1081 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_TRUE : D3DZB_FALSE);
1084 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZWRITEENABLE, value);
1087 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGCOLOR, value);
1091 float fogDensity = RenderStateFloat { ui = value }.f;
1092 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGDENSITY, RenderStateFloat { fogDensity }.ui);
1096 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ALPHABLENDENABLE, value);
1099 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_AMBIENT, value);
1104 void SetLight(Display display, int id, Light light)
1106 DisplaySystem displaySystem = display.displaySystem;
1107 D3D8System d3dSystem = displaySystem.driverData;
1108 D3D8Display d3dDisplay = display.driverData;
1111 D3DLIGHT8 d3dLight =
1113 D3DLIGHT_DIRECTIONAL,
1114 // Opacity on the light?
1115 { light.diffuse.r, light.diffuse.g, light.diffuse.b, 1.0f },
1116 { light.specular.r, light.specular.g, light.specular.b, 1.0f },
1117 { light.ambient.r, light.ambient.g, light.ambient.b, 1.0f }
1119 Vector3Df * lightDirection;
1120 Vector3Df vector {0,0,1};
1121 Vector3Df vectorPI {0,0,-1};
1122 Vector3Df direction;
1124 lightDirection = (Vector3Df *)&d3dLight.Direction;
1126 mat.RotationQuaternion(light.orientation);
1128 direction.MultMatrix(vector, mat);
1129 if(!display.display3D || !display.display3D.camera)
1131 d3dLight.Direction.x = direction.x;
1132 d3dLight.Direction.y = direction.y;
1133 d3dLight.Direction.z =-direction.z;
1136 lightDirection->MultMatrix(direction, d3dDisplay.worldMatrix);
1138 d3dDisplay.lights[id] = d3dLight;
1140 IDirect3DDevice8_LightEnable(d3dSystem.d3dDevice, id, TRUE);
1141 IDirect3DDevice8_SetLight(d3dSystem.d3dDevice, id, &d3dDisplay.lights[id]);
1143 direction.MultMatrix(vectorPI, mat);
1144 lightDirection->MultMatrix(direction, d3dDisplay.worldMatrix);
1146 d3dDisplay.lightsPI[id] = d3dLight;
1150 IDirect3DDevice8_LightEnable(d3dSystem.d3dDevice, id, FALSE);
1151 d3dDisplay.lights[id].Type = 0;
1155 void SetCamera(Display display, Surface surface, Camera camera)
1157 DisplaySystem displaySystem = display.displaySystem;
1158 D3D8System d3dSystem = displaySystem.driverData;
1159 D3D8Display d3dDisplay = display.driverData;
1160 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1163 Point topLeft {surface.box.left + surface.offset.x, surface.box.top + surface.offset.y};
1164 Point downRight {surface.box.right + surface.offset.x, surface.box.bottom + surface.offset.y};
1167 surface.offset.x + camera.origin.x,
1168 surface.offset.y + camera.origin.y
1172 float l = (topLeft.x - origin.x) * camera.zMin / camera.focalX;
1173 float r = (downRight.x - origin.x) * camera.zMin / camera.focalX;
1174 float b = (downRight.y - origin.y) * camera.zMin / camera.focalY;
1175 float t = (topLeft.y - origin.y) * camera.zMin / camera.focalY;
1176 float n = camera.zMin;
1177 float f = camera.zMax;
1179 matProj.m[0][0] = 2 * n / (r - l);
1180 matProj.m[0][1] = 0;
1181 matProj.m[0][2] = 0;
1182 matProj.m[0][3] = 0;
1184 matProj.m[1][0] = 0;
1185 matProj.m[1][1] = 2 * n / (t - b);
1186 matProj.m[1][2] = 0;
1187 matProj.m[1][3] = 0;
1189 matProj.m[2][0] = (l + r) / (r - l);
1190 matProj.m[2][1] = (t + b) / (t - b);
1191 matProj.m[2][2] = f / (n - f);
1192 matProj.m[2][3] = -1;
1194 matProj.m[3][0] = 0;
1195 matProj.m[3][1] = 0;
1196 matProj.m[3][2] = n * f / (n - f);
1197 matProj.m[3][3] = 0;
1199 IDirect3DDevice8_SetTransform(d3dDevice, D3DTS_PROJECTION, &matProj);
1201 // *** View Matrix ***
1202 if(!display.display3D.camera)
1203 d3dDisplay.worldMatrix++;
1206 matrix.Scale(1.0f, 1.0f, -1.0f);
1207 d3dDisplay.worldMatrix->Multiply(camera.viewMatrix, matrix);
1209 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1211 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shaders[0]);
1213 // IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_USEW);
1214 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_TRUE);
1215 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZWRITEENABLE, TRUE);
1216 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, FALSE);
1217 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_LIGHTING, TRUE);
1218 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, TRUE);
1220 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1222 else if(display.display3D.camera)
1224 d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
1225 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1226 IDirect3DDevice8_SetTransform(d3dDevice, D3DTS_PROJECTION, &d3dDisplay.projMatrix);
1228 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
1229 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
1230 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
1231 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
1232 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGENABLE, FALSE);
1233 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, FALSE);
1235 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
1236 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
1238 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shader2D);
1240 IDirect3DDevice8_SetTexture(d3dDevice, 0, null);
1244 void ApplyMaterial(Display display, Material material, Mesh mesh)
1246 DisplaySystem displaySystem = display.displaySystem;
1247 D3D8System d3dSystem = displaySystem.driverData;
1248 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1249 D3D8Mesh d3dMesh = mesh.data;
1252 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGENABLE, material.flags.noFog ? FALSE : TRUE);
1255 if(material.baseMap && d3dMesh.texCoords && material.baseMap.driver.displaySystem == displaySystem)
1257 Bitmap map = material.baseMap;
1259 IDirect3DDevice8_SetTexture(d3dDevice, 0, (IDirect3DBaseTexture8 *)map.driverData);
1261 if(material.flags.tile)
1263 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
1264 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
1268 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
1269 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
1273 IDirect3DDevice8_SetTexture(d3dDevice, 0, null);
1276 // IDirect3DDevice8_SetMaterial(d3dDevice, (D3DMATERIAL8 *)&material.diffuse);
1279 D3DMATERIAL8 d3dMaterial;
1281 d3dMaterial.Diffuse.r = material.diffuse.r;
1282 d3dMaterial.Diffuse.g = material.diffuse.g;
1283 d3dMaterial.Diffuse.b = material.diffuse.b;
1284 d3dMaterial.Diffuse.a = material.opacity;
1286 d3dMaterial.Ambient.r = material.ambient.r;
1287 d3dMaterial.Ambient.g = material.ambient.g;
1288 d3dMaterial.Ambient.b = material.ambient.b;
1289 d3dMaterial.Ambient.a = 1;
1291 d3dMaterial.Specular.r = material.specular.r;
1292 d3dMaterial.Specular.g = material.specular.g;
1293 d3dMaterial.Specular.b = material.specular.b;
1294 d3dMaterial.Specular.a = 1;
1296 d3dMaterial.Emissive.r = material.emissive.r;
1297 d3dMaterial.Emissive.g = material.emissive.g;
1298 d3dMaterial.Emissive.b = material.emissive.b;
1299 d3dMaterial.Emissive.a = 1;
1301 d3dMaterial.Power = material.power;
1303 IDirect3DDevice8_SetMaterial(d3dDevice, &d3dMaterial); //(D3DMATERIAL8 *)&material.diffuse
1307 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
1309 D3D8Mesh d3dMesh = mesh.data;
1312 if(!(mesh.flags.vertices))
1314 if(d3dMesh.vertices)
1316 IDirect3DVertexBuffer8_Release(d3dMesh.vertices);
1317 d3dMesh.vertices = null;
1319 delete mesh.vertices;
1321 if(!(mesh.flags.normals))
1325 IDirect3DVertexBuffer8_Release(d3dMesh.normals);
1326 d3dMesh.normals = null;
1328 delete mesh.normals;
1330 if(!(mesh.flags.texCoords1))
1332 if(d3dMesh.texCoords)
1334 IDirect3DVertexBuffer8_Release(d3dMesh.texCoords);
1335 d3dMesh.texCoords = null;
1337 delete mesh.texCoords;
1339 if(!(mesh.flags.texCoords2))
1341 if(d3dMesh.texCoords2)
1343 IDirect3DVertexBuffer8_Release(d3dMesh.texCoords2);
1344 d3dMesh.texCoords2 = null;
1346 // delete mesh.texCoords2;
1356 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
1358 D3D8System d3dSystem = displaySystem.driverData;
1359 bool result = false;
1360 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1363 mesh.data = D3D8Mesh { };
1366 D3D8Mesh d3dMesh = mesh.data;
1368 if(mesh.nVertices == nVertices)
1370 if(mesh.flags != flags)
1372 // Same number of vertices, adding features (Leaves the other features pointers alone)
1373 if(flags.vertices && !d3dMesh.vertices)
1375 mesh.vertices = new Vector3Df[nVertices];
1376 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1377 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices))
1380 if(flags.normals && !d3dMesh.normals)
1382 mesh.normals = new Vector3Df[nVertices];
1383 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1384 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals))
1387 if(flags.texCoords1 && !d3dMesh.texCoords)
1389 mesh.texCoords = new Pointf[nVertices];
1390 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * nVertices,
1391 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords))
1398 // New number of vertices, reallocate all current and new features
1399 flags |= mesh.flags;
1401 // Same number of vertices, adding features (Leaves the other features pointers alone)
1404 if(d3dMesh.vertices)
1406 IDirect3DVertexBuffer8_Release(d3dMesh.vertices);
1407 d3dMesh.vertices = null;
1409 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
1410 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1411 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices))
1418 IDirect3DVertexBuffer8_Release(d3dMesh.normals);
1419 d3dMesh.normals = null;
1421 mesh.normals = renew mesh.normals Vector3Df[nVertices];
1422 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1423 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals))
1426 if(flags.texCoords1)
1428 if(d3dMesh.texCoords)
1430 IDirect3DVertexBuffer8_Release(d3dMesh.texCoords);
1431 d3dMesh.texCoords = null;
1433 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
1434 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * nVertices,
1435 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords))
1443 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1445 D3D8Mesh d3dMesh = mesh.data;
1446 if(!flags) flags = mesh.flags;
1448 if(flags.vertices && mesh.vertices)
1450 Vector3Df * vertices;
1451 if(!IDirect3DVertexBuffer8_Lock(d3dMesh.vertices, 0, 0, (byte **) &vertices, 0))
1453 memcpy(vertices, mesh.vertices, mesh.nVertices * sizeof(Vector3Df));
1454 IDirect3DVertexBuffer8_Unlock(d3dMesh.vertices);
1457 if(flags.normals && mesh.normals)
1459 Vector3Df * normals;
1460 if(!IDirect3DVertexBuffer8_Lock(d3dMesh.normals, 0, 0, (byte **) &normals, 0))
1462 memcpy(normals, mesh.normals, mesh.nVertices * sizeof(Vector3Df));
1463 IDirect3DVertexBuffer8_Unlock(d3dMesh.normals);
1466 if(flags.texCoords1 && mesh.texCoords)
1469 if(!IDirect3DVertexBuffer8_Lock(d3dMesh.texCoords, 0, 0, (byte **) &texCoords, 0))
1471 memcpy(texCoords, mesh.texCoords, mesh.nVertices * sizeof(Pointf));
1472 IDirect3DVertexBuffer8_Unlock(d3dMesh.texCoords);
1477 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1483 void FreeIndices(DisplaySystem displaySystem, D3D8Indices d3dIndices)
1487 if(d3dIndices.buffer)
1488 IDirect3DIndexBuffer8_Release(d3dIndices.buffer);
1489 delete d3dIndices.indices;
1494 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
1496 D3D8System d3dSystem = displaySystem.driverData;
1497 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1498 D3D8Indices d3dIndices { };
1499 if(d3dIndices && nIndices)
1501 d3dIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
1502 IDirect3DDevice8_CreateIndexBuffer(d3dDevice, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * nIndices, 0, indices32bit ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
1503 D3DPOOL_MANAGED, &d3dIndices.buffer);
1504 d3dIndices.nIndices = nIndices;
1509 void UnlockIndices(DisplaySystem displaySystem, D3D8Indices d3dIndices, bool indices32bit, int nIndices)
1511 uint16 * indexBuffer = null;
1512 if(!IDirect3DIndexBuffer8_Lock(d3dIndices.buffer, 0, 0, (byte **)&indexBuffer, 0))
1514 memcpy(indexBuffer, d3dIndices.indices, indices32bit ? sizeof(uint32) : sizeof(uint16) * d3dIndices.nIndices);
1515 IDirect3DIndexBuffer8_Unlock(d3dIndices.buffer);
1519 uint16 * LockIndices(DisplaySystem displaySystem, D3D8Indices d3dIndices)
1521 return d3dIndices.indices;
1524 void SelectMesh(Display display, Mesh mesh)
1526 DisplaySystem displaySystem = display.displaySystem;
1527 D3D8System d3dSystem = displaySystem.driverData;
1528 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1530 if(mesh && mesh.data)
1533 D3D8Mesh d3dMesh = mesh.data;
1535 IDirect3DDevice8_SetStreamSource(d3dDevice, 0, d3dMesh.vertices, sizeof(Vector3Df));
1538 IDirect3DDevice8_SetStreamSource(d3dDevice, 1, d3dMesh.normals, sizeof(Vector3Df));
1542 IDirect3DDevice8_SetStreamSource(d3dDevice, 1, null, sizeof(Vector3Df));
1543 if(d3dMesh.texCoords)
1545 IDirect3DDevice8_SetStreamSource(d3dDevice, 2, d3dMesh.texCoords, sizeof(Pointf));
1549 IDirect3DDevice8_SetStreamSource(d3dDevice, 2, null, sizeof(Pointf));
1551 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shaders[shader]);
1555 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
1557 DisplaySystem displaySystem = display.displaySystem;
1558 D3D8System d3dSystem = displaySystem.driverData;
1559 D3D8Display d3dDisplay = display.driverData;
1560 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1561 if(primitiveTypes[primitive->type.primitiveType])
1563 int numPrimitives = (primitive->type.vertexRange) ? primitive->nVertices : primitive->nIndices;
1566 switch(primitive->type.primitiveType)
1568 case lines: numPrimitives /= 2; break;
1569 case triangles: numPrimitives /= 3; break;
1581 if(primitive->type.vertexRange)
1583 if(primitive->type.primitiveType == quads)
1585 for(c = 0; c<numPrimitives; c++)
1586 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1589 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1593 D3D8Indices indices = primitive->data;
1594 IDirect3DDevice8_SetIndices(d3dDevice, indices.buffer, 0);
1595 if(primitive->type.primitiveType == quads)
1597 for(c = 0; c<numPrimitives; c++)
1598 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, c*4, 2);
1601 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, 0, numPrimitives);
1604 if(display.display3D.material.flags.doubleSided)
1606 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CCW);
1607 if(!display.display3D.material.flags.singleSideLight)
1609 for(c = 0; c<NumberOfLights; c++)
1610 if(d3dDisplay.lights[c].Type)
1611 IDirect3DDevice8_SetLight(d3dDevice, c, &d3dDisplay.lightsPI[c]);
1613 if(primitive->type.vertexRange)
1615 if(primitive->type.primitiveType == quads)
1617 for(c = 0; c<numPrimitives; c++)
1618 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1621 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1625 D3D8Indices indices = primitive->data;
1626 IDirect3DDevice8_SetIndices(d3dDevice, indices.buffer, 0);
1627 if(primitive->type.primitiveType == quads)
1629 for(c = 0; c<numPrimitives; c++)
1630 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, c*4, 2);
1633 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, 0, numPrimitives);
1636 if(!display.display3D.material.flags.singleSideLight)
1638 for(c = 0; c<NumberOfLights; c++)
1639 if(d3dDisplay.lights[c].Type)
1640 IDirect3DDevice8_SetLight(d3dDevice, c, &d3dDisplay.lights[c]);
1642 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1647 void PushMatrix(Display display)
1649 D3D8Display d3dDisplay = display.driverData;
1650 *(d3dDisplay.worldMatrix+1) = *(d3dDisplay.worldMatrix);
1651 d3dDisplay.worldMatrix++;
1654 void PopMatrix(Display display, bool setMatrix)
1656 D3D8Display d3dDisplay = display.driverData;
1657 DisplaySystem displaySystem = display.displaySystem;
1658 D3D8System d3dSystem = displaySystem.driverData;
1660 d3dDisplay.worldMatrix--;
1662 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1665 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
1667 DisplaySystem displaySystem = display.displaySystem;
1668 D3D8System d3dSystem = displaySystem.driverData;
1669 Camera camera = useCamera ? display.display3D.camera : null;
1670 D3D8Display d3dDisplay = display.driverData;
1672 Matrix matrix = transMatrix, temp;
1676 matrix.Scale(1.0f, 1.0f, -1.0f);
1677 *(d3dDisplay.worldMatrix) = matrix;
1683 - camera.cPosition.x,
1684 - camera.cPosition.y,
1685 - camera.cPosition.z);
1686 temp.Multiply(matrix, d3dDisplay.worldMatrix);
1687 *(d3dDisplay.worldMatrix) = temp;
1690 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1693 bool Lock(Display display)
1695 DisplaySystem displaySystem = display.displaySystem;
1696 D3D8System d3dSystem = displaySystem.driverData;
1697 D3D8Display d3dDisplay = display.driverData;
1699 if(d3dDisplay.backBuffer)
1701 IDirect3DDevice8_SetRenderTarget(d3dSystem.d3dDevice, d3dDisplay.backBuffer, d3dDisplay.depthSurface);
1702 IDirect3DDevice8_BeginScene(d3dSystem.d3dDevice);
1704 d3dSystem.inScene = true;
1709 void Unlock(Display display)
1711 DisplaySystem displaySystem = display.displaySystem;
1712 D3D8System d3dSystem = displaySystem.driverData;
1714 if(d3dSystem.inScene)
1716 IDirect3DDevice8_EndScene(d3dSystem.d3dDevice);
1717 d3dSystem.inScene = false;