1 namespace gfx::drivers;
5 #define D3D_DEBUG_INFO 1
16 #if defined(__MINGW32__)
17 #undef DECLARE_INTERFACE
18 #define DECLARE_INTERFACE(i) \
19 interface i { CONST_VTABLE struct i##Vtbl *lpVtbl; }; \
20 typedef CONST_VTABLE struct i##Vtbl i##Vtbl; \
21 CONST_VTABLE struct i##Vtbl
33 #define MATRIX_STACK_SIZE 32
35 #define NUM_VERTEX_SHADERS 4
37 static class D3D8Display : struct
40 IDirect3DSwapChain8 * swapChain;
41 Matrix worldMatrixStack[MATRIX_STACK_SIZE];
44 D3DLIGHT8 lights[NumberOfLights], lightsPI[NumberOfLights];
45 D3DPRESENT_PARAMETERS d3dpp;
46 IDirect3DSurface8 * backBuffer, * depthSurface;
49 static class D3D8System : struct
52 IDirect3D8 * direct3D;
53 IDirect3DDevice8 * d3dDevice;
54 IDirect3D8 * (WINAPI * direct3DCreate8)(UINT);
56 D3DPRESENT_PARAMETERS d3dpp;
57 uint shaders[NUM_VERTEX_SHADERS], shader2D;
64 static class D3D8Surface : struct
66 // For compatibility with LFB driver
72 ColorAlpha background;
75 static class D3D8Mesh : struct
77 IDirect3DVertexBuffer8 * vertices;
78 IDirect3DVertexBuffer8 * normals;
79 IDirect3DVertexBuffer8 * texCoords;
80 IDirect3DVertexBuffer8 * texCoords2;
83 static struct D3D8Vertex
90 static class D3D8Indices : struct
93 IDirect3DIndexBuffer8 * buffer;
97 static int primitiveTypes[RenderPrimitiveType] =
99 D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP, D3DPT_TRIANGLEFAN, D3DPT_TRIANGLEFAN, 0, D3DPT_LINESTRIP
102 static void SetTransformMatrix(IDirect3DDevice8 * device, Matrix matrix)
108 (float)matrix.m[0][0], (float)matrix.m[0][1], (float)matrix.m[0][2], (float)matrix.m[0][3],
109 (float)matrix.m[1][0], (float)matrix.m[1][1], (float)matrix.m[1][2], (float)matrix.m[1][3],
110 (float)matrix.m[2][0], (float)matrix.m[2][1], (float)matrix.m[2][2], (float)matrix.m[2][3],
111 (float)matrix.m[3][0], (float)matrix.m[3][1], (float)matrix.m[3][2], (float)matrix.m[3][3]
115 IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &d3dMat);
118 class Direct3D8DisplayDriver : DisplayDriver
120 class_property(name) = "Direct3D8";
122 bool ::LockDisplay(Display display, Surface surface, Bitmap lfbBitmap, Surface * lfbSurface)
125 DisplaySystem displaySystem = display.displaySystem;
126 D3D8System d3dSystem = displaySystem.driverData;
127 D3D8Display d3dDisplay = display.driverData;
129 //if(!IDirect3DDevice8_GetBackBuffer(d3dSystem.d3dDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
131 D3DLOCKED_RECT lockedRect;
132 if(!IDirect3DSurface8_LockRect(d3dDisplay.backBuffer, &lockedRect, null, 0))
134 switch(d3dDisplay.d3dpp.BackBufferFormat)
136 case D3DFMT_A8R8G8B8:
137 case D3DFMT_X8R8G8B8:
138 lfbBitmap.pixelFormat = pixelFormat888;
141 lfbBitmap.pixelFormat = pixelFormat565;
143 case D3DFMT_X1R5G5B5:
144 case D3DFMT_A1R5G5B5:
145 lfbBitmap.pixelFormat = pixelFormat555;
147 case D3DFMT_A4R4G4B4:
148 case D3DFMT_X4R4G4B4:
149 lfbBitmap.pixelFormat = pixelFormat444;
152 lfbBitmap.driver = null;
153 lfbBitmap.displaySystem = null;
154 lfbBitmap.picture = (byte *)lockedRect.pBits;
155 lfbBitmap.transparent = false;
156 lfbBitmap.stride = lockedRect.Pitch >> GetColorDepthShifts(lfbBitmap.pixelFormat);
157 lfbBitmap.width = display.width;
158 lfbBitmap.height = display.height;
160 *lfbSurface = lfbBitmap.GetSurface(surface ? surface.offset.x : 0, surface ? surface.offset.y : 0, surface ? &surface.box : null);
164 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
169 void ::UnlockDisplay(Display display, Surface surface)
171 DisplaySystem displaySystem = display.displaySystem;
172 D3D8System d3dSystem = displaySystem.driverData;
173 D3D8Display d3dDisplay = display.driverData;
174 if(d3dDisplay.backBuffer)
176 IDirect3DSurface8_UnlockRect(d3dDisplay.backBuffer);
177 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
182 void ::SetViewportAndMatrices(Display display, int x, int y, Box box)
184 D3D8Display d3dDisplay = display.driverData;
185 DisplaySystem displaySystem = display.displaySystem;
186 D3D8System d3dSystem = displaySystem.driverData;
189 D3DVIEWPORT8 viewport;
192 if(box.right<box.left || box.bottom <box.top)
194 viewport.Width = viewport.Height = 1;
195 viewport.X = viewport.Y = MAXDWORD;
199 viewport.X = x + box.left;
200 viewport.Y = y + box.top;
201 viewport.Width = box.right - box.left + 1;
202 viewport.Height = box.bottom - box.top + 1;
204 if(!IDirect3DDevice8_SetViewport(d3dSystem.d3dDevice, &viewport))
206 D3DMATRIX * matProj = &d3dDisplay.projMatrix;
207 Matrix * matWorld = d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
209 matProj->m[0][0] = 2.0f / viewport.Width;
210 matProj->m[1][1] =-2.0f / viewport.Height;
211 matProj->m[2][2] = matProj->m[3][1] = matProj->m[3][3] = 1;
212 matProj->m[3][0] = -1;
214 IDirect3DDevice8_SetTransform(d3dSystem.d3dDevice, D3DTS_PROJECTION, matProj);
216 matWorld->Identity();
217 matWorld->m[3][0] =-box.left;
218 matWorld->m[3][1] =-box.top;
220 SetTransformMatrix(d3dSystem.d3dDevice, matWorld);
226 bool CreateDisplaySystem(DisplaySystem displaySystem)
229 D3D8System d3dSystem = displaySystem.driverData = D3D8System { };
232 displaySystem.flags.alpha = true;
233 //if(displaySystem.flags.fullScreen)
234 displaySystem.flags.flipping = true;
235 displaySystem.pixelFormat = pixelFormat888;
237 d3dSystem.d3dDll = LoadLibrary("d3d8.dll");
240 d3dSystem.direct3DCreate8 = (void *)GetProcAddress(d3dSystem.d3dDll, "Direct3DCreate8");
241 if(d3dSystem.direct3DCreate8)
243 if(d3dSystem.direct3D = d3dSystem.direct3DCreate8(D3D_SDK_VERSION))
245 D3DDISPLAYMODE d3ddm;
246 if(!IDirect3D8_GetAdapterDisplayMode(d3dSystem.direct3D, D3DADAPTER_DEFAULT, &d3ddm))
248 d3dSystem.d3dpp.BackBufferCount = 1;
250 if(displaySystem.flags.fullScreen)
252 d3dSystem.d3dpp.BackBufferWidth = d3ddm.Width;
253 d3dSystem.d3dpp.BackBufferHeight = d3ddm.Height;
254 d3dSystem.d3dpp.hDeviceWindow = displaySystem.window;
258 d3dSystem.d3dpp.hDeviceWindow = d3dSystem.hwnd =
259 CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
260 d3dSystem.d3dpp.Windowed = TRUE;
263 d3dSystem.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
264 d3dSystem.format = d3dSystem.d3dpp.BackBufferFormat = d3ddm.Format;
265 d3dSystem.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
267 if(!IDirect3D8_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
268 d3dSystem.d3dpp.hDeviceWindow,
269 D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE|D3DCREATE_FPU_PRESERVE,
270 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
274 d3dSystem.usage = D3DUSAGE_SOFTWAREPROCESSING;
275 if(!IDirect3D8_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
276 d3dSystem.d3dpp.hDeviceWindow,
277 D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,
278 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
284 DWORD vertexShaders[NUM_VERTEX_SHADERS][7] =
288 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
293 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
295 D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3),
300 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
302 D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
307 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
309 D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3),
311 D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
316 DWORD vertexShader2D[] =
319 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
320 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
321 D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
326 for(c = 0; c<NUM_VERTEX_SHADERS; c++)
327 if(IDirect3DDevice8_CreateVertexShader(d3dSystem.d3dDevice, vertexShaders[c], null, &d3dSystem.shaders[c], 0))
330 if(c < NUM_VERTEX_SHADERS ||
331 IDirect3DDevice8_CreateVertexShader(d3dSystem.d3dDevice, vertexShader2D, null, &d3dSystem.shader2D, 0))
335 d3dSystem.ready = false;
341 Log("Couldn't load library d3d8.dll\n");
342 // LogErrorCode(ERR_MISSING_LIBRARY, "d3d8.dll");
347 void DestroyDisplaySystem(DisplaySystem displaySystem)
349 D3D8System d3dSystem = displaySystem.driverData;
352 for(c = 0; c<NUM_VERTEX_SHADERS; c++)
354 if(d3dSystem.shaders[c])
355 IDirect3DDevice8_DeleteVertexShader(d3dSystem.d3dDevice, d3dSystem.shaders[c]);
358 if(d3dSystem.shader2D)
359 IDirect3DDevice8_DeleteVertexShader(d3dSystem.d3dDevice, d3dSystem.shader2D);
361 if(d3dSystem.d3dDevice)
362 IDirect3DDevice8_Release(d3dSystem.d3dDevice);
364 if(d3dSystem.direct3D)
365 IDirect3D8_Release(d3dSystem.direct3D);
367 FreeLibrary(d3dSystem.d3dDll);
370 displaySystem.driverData = null;
374 void DestroyDisplay(Display display)
376 DisplaySystem displaySystem = display.displaySystem;
377 D3D8System d3dSystem = displaySystem.driverData;
378 D3D8Display d3dDisplay = display.driverData;
380 if(d3dSystem.inScene)
382 IDirect3DDevice8_EndScene(d3dSystem.d3dDevice);
383 d3dSystem.inScene = false;
386 if(d3dDisplay.backBuffer)
387 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
389 if(d3dDisplay.depthSurface)
390 IDirect3DSurface8_Release(d3dDisplay.depthSurface);
392 if(d3dDisplay.swapChain)
393 IDirect3DSwapChain8_Release(d3dDisplay.swapChain);
396 display.driverData = null;
399 bool CreateDisplay(Display display)
402 DisplaySystem displaySystem = display.displaySystem;
403 D3D8System d3dSystem = displaySystem.driverData;
404 D3D8Display d3dDisplay = display.driverData = D3D8Display { };
406 d3dSystem.ready = false;
413 bool DisplaySize(Display display, int width, int height)
416 DisplaySystem displaySystem = display.displaySystem;
417 D3D8System d3dSystem = displaySystem.driverData;
418 D3D8Display d3dDisplay = display.driverData;
419 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
421 d3dSystem.ready = false;
423 if(d3dDisplay.backBuffer)
425 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
426 d3dDisplay.backBuffer = null;
429 if(d3dDisplay.depthSurface)
431 IDirect3DSurface8_Release(d3dDisplay.depthSurface);
432 d3dDisplay.depthSurface = null;
435 if(d3dDisplay.swapChain)
437 IDirect3DSwapChain8_Release(d3dDisplay.swapChain);
438 d3dDisplay.swapChain = null;
444 if(displaySystem.flags.fullScreen)
446 d3dSystem.d3dpp.BackBufferWidth = width;
447 d3dSystem.d3dpp.BackBufferHeight = height;
449 result = !IDirect3DDevice8_Reset(d3dSystem.d3dDevice, &d3dSystem.d3dpp);
453 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;
454 d3dDisplay.d3dpp.BackBufferWidth = width;
455 d3dDisplay.d3dpp.BackBufferHeight = height;
456 d3dDisplay.d3dpp.Windowed = TRUE;
457 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
458 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
459 d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
461 //d3dDisplay.d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
462 d3dDisplay.d3dpp.BackBufferFormat = d3dSystem.format;
463 d3dDisplay.d3dpp.BackBufferCount = 1;
464 d3dDisplay.d3dpp.hDeviceWindow = display.window;
465 d3dDisplay.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
466 // d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_DONOTWAIT;
467 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
468 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
470 result = !IDirect3DDevice8_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
471 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
475 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
476 result = !IDirect3DDevice8_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
477 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
481 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
482 result = !IDirect3DDevice8_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
483 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
489 if(d3dDisplay.swapChain)
490 result = !IDirect3DSwapChain8_GetBackBuffer(d3dDisplay.swapChain,
491 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer);
493 result = !IDirect3DDevice8_GetBackBuffer(d3dSystem.d3dDevice,
494 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer);
497 if(!IDirect3DDevice8_CreateDepthStencilSurface(d3dSystem.d3dDevice, width, height,
498 D3DFMT_D16, d3dDisplay.d3dpp.MultiSampleType,&d3dDisplay.depthSurface))
499 d3dSystem.ready = true;
505 float fogDensity = 0;
507 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shader2D);
509 //IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
510 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
511 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
512 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
513 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
514 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
515 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
516 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGTABLEMODE, D3DFOG_EXP);
517 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGDENSITY, *(uint *)(void *)&fogDensity);
518 display.ambient = Color { 50,50,50 };
519 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_NORMALIZENORMALS, TRUE);
520 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
522 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
523 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
524 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
525 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
526 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
527 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
529 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
530 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
531 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
533 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
534 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
536 IDirect3DDevice8_SetTexture(d3dDevice, 0, null);
541 display.width = width;
542 display.height = height;
543 d3dDisplay.updateBox.left = display.width;
544 d3dDisplay.updateBox.top = display.height;
545 d3dDisplay.updateBox.right = 0;
546 d3dDisplay.updateBox.bottom = 0;
551 void DisplayPosition(Display display, int x, int y)
556 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
560 void RestorePalette(Display display)
564 void StartUpdate(Display display)
568 void EndUpdate(Display display)
572 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
576 void Update(Display display, Box updateBox)
578 DisplaySystem displaySystem = display.displaySystem;
579 D3D8System d3dSystem = displaySystem.driverData;
580 D3D8Display d3dDisplay = display.driverData;
583 //eSystem_Sleep(0.05);
584 IDirect3DDevice8_EndScene(d3dSystem.d3dDevice);
586 if(display.displaySystem.flags.flipping)
588 if(d3dDisplay.swapChain)
589 IDirect3DSwapChain8_Present(d3dDisplay.swapChain, null, null, null, null);
591 IDirect3DDevice8_Present(d3dSystem.d3dDevice, null, null, null, null);
597 if(updateBox != null)
599 source.left = dest.left = updateBox.left;
600 source.top = dest.top = updateBox.top;
601 source.right = dest.right = updateBox.right+1;
602 source.bottom = dest.bottom = updateBox.bottom+1;
606 source.left = dest.left = d3dDisplay.updateBox.left;
607 source.top = dest.top = d3dDisplay.updateBox.top;
608 source.right = dest.right = d3dDisplay.updateBox.right+1;
609 source.bottom = dest.bottom = d3dDisplay.updateBox.bottom+1;
611 if(dest.bottom > dest.top && dest.right > dest.left)
612 IDirect3DDevice8_Present(d3dSystem.d3dDevice, &source, &dest, null, null);
613 if(updateBox == null)
615 d3dDisplay.updateBox.left = display.width;
616 d3dDisplay.updateBox.top = display.height;
617 d3dDisplay.updateBox.right = 0;
618 d3dDisplay.updateBox.bottom = 0;
621 d3dSystem.inScene = false;
625 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
629 Bitmap lfbBitmap { };
631 if(LockDisplay(display, null, lfbBitmap, &lfbSurface))
634 if(bitmap.pixelFormat != lfbBitmap.pixelFormat || bitmap.width < w || bitmap.height < h)
637 bitmap.Allocate(null, w,h,w, lfbBitmap.pixelFormat, false);
639 surface = bitmap.GetSurface(0,0,null);
642 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, surface, lfbBitmap, 0, 0, x, y, w, h);
646 UnlockDisplay(display, lfbSurface);
648 lfbBitmap.picture = null;
655 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
658 IDirect3DTexture8_Release((IDirect3DTexture8 *)bitmap.picture);
661 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
666 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
669 D3D8System d3dSystem = displaySystem.driverData;
670 if(bitmap.Convert(null, pixelFormat888, null))
672 IDirect3DTexture8 * texture;
673 uint w = pow2i(Min(bitmap.width, 512)), h = pow2i(Min(bitmap.height, 512));
675 if(!IDirect3DDevice8_CreateTexture(d3dSystem.d3dDevice, w, h, mipMaps ? log2i(Max(w+1, h+1)) : 1, 0,
676 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture))
682 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
684 D3DSURFACE_DESC desc;
685 D3DLOCKED_RECT lockedRect;
687 if(!IDirect3DTexture8_GetLevelDesc(texture, level, &desc) &&
688 !IDirect3DTexture8_LockRect(texture, level, &lockedRect, null, 0))
693 mipMap.width = desc.Width;
694 mipMap.height = desc.Height;
695 mipMap.picture = lockedRect.pBits;
698 case D3DFMT_R5G6B5: mipMap.pixelFormat = pixelFormat565; break;
699 case D3DFMT_A8R8G8B8: mipMap.pixelFormat = pixelFormat888; break;
700 case D3DFMT_A1R5G5B5: mipMap.pixelFormat = pixelFormat555; break;
702 mipMap.stride = lockedRect.Pitch >> GetColorDepthShifts(mipMap.pixelFormat);
704 mipSurface = mipMap.GetSurface(0,0,null);
707 if(mipMap.width != bitmap.width || mipMap.height != bitmap.height)
708 mipSurface.Filter(bitmap, 0,0, 0,0, mipMap.width, mipMap.height, bitmap.width, bitmap.height);
711 //FillBytesBy4(mipMap.picture, bitmap.picture, mipMap.width * mipMap.height);
712 mipSurface.Blit(bitmap, 0,0, 0,0, bitmap.width, bitmap.height);
718 mipMap.picture = null;
721 IDirect3DTexture8_UnlockRect(texture, level);
726 bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
727 bitmap.driver = displaySystem.driver;
728 bitmap.picture = (void *)texture;
731 FreeBitmap(displaySystem, bitmap);
737 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
740 D3D8Display d3dDisplay = display.driverData;
741 DisplaySystem displaySystem = display.displaySystem;
742 D3D8System d3dSystem = displaySystem.driverData;
743 D3D8Surface d3dSurface = surface.driverData = D3D8Surface { };
745 if(d3dSurface && d3dSystem.ready)
747 surface.unclippedBox = surface.box = clip;
748 surface.offset.x = x;
749 surface.offset.y = y;
751 d3dDisplay.updateBox.left = Min(x + clip.left, d3dDisplay.updateBox.left);
752 d3dDisplay.updateBox.top = Min(y + clip.top, d3dDisplay.updateBox.top);
753 d3dDisplay.updateBox.right = Max(x + clip.right, d3dDisplay.updateBox.right);
754 d3dDisplay.updateBox.bottom = Max(y + clip.bottom, d3dDisplay.updateBox.bottom);
756 SetViewportAndMatrices(display, x,y, &surface.box);
763 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
768 void ReleaseSurface(Display display, Surface surface)
770 delete surface.driverData;
773 void Clip(Display display, Surface surface, Box clip)
776 D3D8Display d3dDisplay = display.driverData;
781 box.Clip(surface.unclippedBox);
785 box = surface.box = surface.unclippedBox;
787 SetViewportAndMatrices(display, surface.offset.x, surface.offset.y, box);
790 void SetForeground(Display display, Surface surface, ColorAlpha color)
795 void SetBackground(Display display, Surface surface, ColorAlpha color)
797 D3D8Surface d3dSurface = surface.driverData;
798 d3dSurface.background = color;
801 ColorAlpha GetPixel(Display display, Surface surface, int x, int y)
806 void PutPixel(Display display, Surface surface,int x,int y)
808 D3D8Display d3dDisplay = display.driverData;
809 D3D8Surface d3dSurface = surface.driverData;
810 DisplaySystem displaySystem = display.displaySystem;
811 D3D8System d3dSystem = displaySystem.driverData;
812 D3D8Vertex vertex = { (float)x, (float)y, 1.0f, surface.foreground, 0, 0 };
814 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_POINTLIST, 1,
815 &vertex, sizeof(D3D8Vertex));
818 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
820 D3D8Surface d3dSurface = surface.driverData;
821 D3D8Display d3dDisplay = display.driverData;
822 DisplaySystem displaySystem = display.displaySystem;
823 D3D8System d3dSystem = displaySystem.driverData;
824 D3D8Vertex vertex[2] =
826 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
827 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 }
830 if(x1 == x2) vertex[1].y++;
831 else if(y1 == y2) vertex[1].x++;
833 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 1,
834 vertex, sizeof(D3D8Vertex));
837 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
839 DisplaySystem displaySystem = display.displaySystem;
840 D3D8System d3dSystem = displaySystem.driverData;
841 D3D8Surface d3dSurface = surface.driverData;
842 D3D8Display d3dDisplay = display.driverData;
843 D3D8Vertex vertex[5] =
845 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
846 { (float)x2, (float)y1, 1.0f, surface.foreground, 0, 0 },
847 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 },
848 { (float)x1, (float)y2, 1.0f, surface.foreground, 0, 0 },
849 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 }
852 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 4,
853 vertex, sizeof(D3D8Vertex));
857 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
859 DisplaySystem displaySystem = display.displaySystem;
860 D3D8System d3dSystem = displaySystem.driverData;
861 D3D8Surface d3dSurface = surface.driverData;
862 D3D8Display d3dDisplay = display.driverData;
863 D3D8Vertex vertex[4] =
865 { (float)x1, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
866 { (float)x2 + 1.0f, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
867 { (float)x1, (float)y2 + 1.0f, 1.0f, d3dSurface.background, 0, 0 },
868 { (float)x2 + 1.0f, (float)y2 + 1.0f, 1.0f, d3dSurface.background, 0, 0 }
871 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
872 vertex, sizeof(D3D8Vertex));
876 void Clear(Display display, Surface surface, ClearType type)
878 DisplaySystem displaySystem = display.displaySystem;
879 D3D8System d3dSystem = displaySystem.driverData;
880 D3D8Surface d3dSurface = surface.driverData;
881 D3D8Display d3dDisplay = display.driverData;
882 IDirect3DDevice8_Clear(d3dSystem.d3dDevice, 0, null,
883 ((type == depthBuffer) ? 0 : D3DCLEAR_TARGET) |
884 ((type == colorBuffer) ? 0 : D3DCLEAR_ZBUFFER),
885 d3dSurface.background, 1,0);
888 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
893 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
895 DisplaySystem displaySystem = display.displaySystem;
896 D3D8System d3dSystem = displaySystem.driverData;
897 D3D8Surface d3dSurface = surface.driverData;
898 D3D8Display d3dDisplay = display.driverData;
899 Color foreground = d3dSurface.writingText ? surface.foreground : white;
900 D3D8Vertex vertex[4] =
902 { (float)dx, (float)dy, 1.0f, foreground,
903 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
904 { (float)(dx+w), (float)dy, 1.0f, foreground,
905 (float)(sx+w)/ (src.width-1), (float)sy/ (src.height-1) },
906 { (float)dx, (float)(dy+h), 1.0f, foreground,
907 (float)sx/ (src.width-1), (float)(sy+h)/ (src.height-1) },
908 { (float)(dx+w), (float)(dy+h), 1.0f, foreground,
909 (float)(sx+w) / (src.width-1), (float)(sy+h)/ (src.height-1) }
912 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture8 *)src.picture);
913 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
914 vertex, sizeof(D3D8Vertex));
915 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, null);
918 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
920 DisplaySystem displaySystem = display.displaySystem;
921 D3D8System d3dSystem = displaySystem.driverData;
922 D3D8Surface d3dSurface = surface.driverData;
923 D3D8Display d3dDisplay = display.driverData;
924 D3D8Vertex vertex[4] =
926 { (float)dx, (float)dy, 1.0f, surface.foreground,
927 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
928 { (float)(dx+w), (float)dy, 1.0f, surface.foreground,
929 (float)(sx+sw)/ (src.width-1), (float)sy/ (src.height-1) },
930 { (float)dx, (float)(dy+h), 1.0f, surface.foreground,
931 (float)sx/ (src.width-1), (float)(sy+sh)/ (src.height-1) },
932 { (float)(dx+w), (float)(dy+h), 1.0f, surface.foreground,
933 (float)(sx+sw) / (src.width-1), (float)(sy+sh)/ (src.height-1) }
936 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture8 *)src.picture);
937 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
938 vertex, sizeof(D3D8Vertex));
939 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, null);
942 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
944 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
947 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
949 DisplaySystem displaySystem = display.displaySystem;
950 D3D8System d3dSystem = displaySystem.driverData;
952 Bitmap lfbBitmap { };
953 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
955 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Stretch(null, lfbSurface, src, dx, dy, sx, sy, w, h, sw, sh);
956 UnlockDisplay(display, lfbSurface);
958 lfbBitmap.picture = null;
962 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
964 DisplaySystem displaySystem = display.displaySystem;
965 D3D8System d3dSystem = displaySystem.driverData;
967 Bitmap lfbBitmap { };
968 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
970 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, lfbSurface, src, dx, dy, sx, sy, w, h);
971 UnlockDisplay(display, lfbSurface);
973 lfbBitmap.picture = null;
977 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
979 StretchDI(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
982 void UnloadFont(DisplaySystem displaySystem, Font font)
984 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
987 Font LoadFont(DisplaySystem displaySystem, char * faceName, float size, FontFlags flags)
989 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
992 void TextFont(Display display, Surface surface, Font font)
994 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
997 void TextOpacity(Display display, Surface surface, bool opaque)
999 D3D8Surface d3dSurface = surface.driverData;
1000 d3dSurface.opaqueText = opaque;
1003 void FontExtent(DisplaySystem displaySystem, Font font, byte * text, int len, int * width, int * height)
1005 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
1008 void WriteText(Display display, Surface surface, int x, int y, byte * text, int len)
1010 DisplaySystem displaySystem = display.displaySystem;
1011 D3D8System d3dSystem = displaySystem.driverData;
1012 D3D8Display d3dDisplay = display.driverData;
1013 D3D8Surface d3dSurface = surface.driverData;
1015 if(surface.textOpacity)
1018 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
1021 int x1 = x, y1 = y, x2 = x+w-1, y2 = y+h-1;
1022 D3D8Vertex vertex[4] =
1024 { (float)x1, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1025 { (float)x2 + 1.0f, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1026 { (float)x1, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 },
1027 { (float)x2 + 1.0f, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 }
1030 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
1031 vertex, sizeof(D3D8Vertex));
1033 //display.displaySystem.driver.Area(display, surface, x, y, x+w-1, y+h-1);
1035 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
1036 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
1037 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MIPFILTER, D3DTEXF_NONE);
1038 d3dSurface.writingText = true;
1040 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
1042 d3dSurface.writingText = false;
1043 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
1044 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
1045 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); //NONE);
1048 void TextExtent(Display display, Surface surface, byte * text, int len, int * width, int * height)
1050 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, width, height);
1053 void DrawingChar(Display display, Surface surface, byte character)
1058 void LineStipple(Display display, Surface surface, uint stipple)
1060 D3D8Display d3dDisplay = display.driverData;
1062 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_LINEPATTERN,
1063 stipple?MDWORD(1,stipple):0);
1067 void SetRenderState(Display display, RenderState state, uint value)
1069 DisplaySystem displaySystem = display.displaySystem;
1070 D3D8System d3dSystem = displaySystem.driverData;
1071 D3D8Display d3dDisplay = display.driverData;
1075 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, value ? TRUE : FALSE);
1078 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_FILLMODE,
1079 ((FillModeValue)value == solid) ? D3DFILL_SOLID : D3DFILL_WIREFRAME);
1082 // IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_USEW : D3DZB_FALSE);
1083 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_TRUE : D3DZB_FALSE);
1086 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZWRITEENABLE, value);
1089 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGCOLOR, value);
1093 float fogDensity = *(float *)(void *)&value;
1094 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGDENSITY, *(uint *)(void *)&fogDensity);
1098 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ALPHABLENDENABLE, value);
1101 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_AMBIENT, value);
1106 void SetLight(Display display, int id, Light light)
1108 DisplaySystem displaySystem = display.displaySystem;
1109 D3D8System d3dSystem = displaySystem.driverData;
1110 D3D8Display d3dDisplay = display.driverData;
1113 D3DLIGHT8 d3dLight =
1115 D3DLIGHT_DIRECTIONAL,
1116 // Opacity on the light?
1117 { light.diffuse.r, light.diffuse.g, light.diffuse.b, 1.0f },
1118 { light.specular.r, light.specular.g, light.specular.b, 1.0f },
1119 { light.ambient.r, light.ambient.g, light.ambient.b, 1.0f },
1121 Vector3Df vector {0,0,1};
1122 Vector3Df vectorPI {0,0,-1};
1123 Vector3Df 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;
1137 ((Vector3Df *)&d3dLight.Direction)->MultMatrix(direction, d3dDisplay.worldMatrix);
1140 d3dDisplay.lights[id] = d3dLight;
1142 IDirect3DDevice8_LightEnable(d3dSystem.d3dDevice, id, TRUE);
1143 IDirect3DDevice8_SetLight(d3dSystem.d3dDevice, id, &d3dDisplay.lights[id]);
1145 direction.MultMatrix(vectorPI, mat);
1146 ((Vector3Df *)&d3dLight.Direction)->MultMatrix(direction, d3dDisplay.worldMatrix);
1148 d3dDisplay.lightsPI[id] = d3dLight;
1152 IDirect3DDevice8_LightEnable(d3dSystem.d3dDevice, id, FALSE);
1153 d3dDisplay.lights[id].Type = 0;
1157 void SetCamera(Display display, Surface surface, Camera camera)
1159 DisplaySystem displaySystem = display.displaySystem;
1160 D3D8System d3dSystem = displaySystem.driverData;
1161 D3D8Display d3dDisplay = display.driverData;
1162 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1165 Point topLeft {surface.box.left + surface.offset.x, surface.box.top + surface.offset.y};
1166 Point downRight {surface.box.right + surface.offset.x, surface.box.bottom + surface.offset.y};
1169 surface.offset.x + camera.origin.x,
1170 surface.offset.y + camera.origin.y
1174 float l = (topLeft.x - origin.x) * camera.zMin / camera.focalX;
1175 float r = (downRight.x - origin.x) * camera.zMin / camera.focalX;
1176 float b = (downRight.y - origin.y) * camera.zMin / camera.focalY;
1177 float t = (topLeft.y - origin.y) * camera.zMin / camera.focalY;
1178 float n = camera.zMin;
1179 float f = camera.zMax;
1181 matProj.m[0][0] = 2 * n / (r - l);
1182 matProj.m[0][1] = 0;
1183 matProj.m[0][2] = 0;
1184 matProj.m[0][3] = 0;
1186 matProj.m[1][0] = 0;
1187 matProj.m[1][1] = 2 * n / (t - b);
1188 matProj.m[1][2] = 0;
1189 matProj.m[1][3] = 0;
1191 matProj.m[2][0] = (l + r) / (r - l);
1192 matProj.m[2][1] = (t + b) / (t - b);
1193 matProj.m[2][2] = f / (n - f);
1194 matProj.m[2][3] = -1;
1196 matProj.m[3][0] = 0;
1197 matProj.m[3][1] = 0;
1198 matProj.m[3][2] = n * f / (n - f);
1199 matProj.m[3][3] = 0;
1201 IDirect3DDevice8_SetTransform(d3dDevice, D3DTS_PROJECTION, &matProj);
1203 // *** View Matrix ***
1204 if(!display.display3D.camera)
1205 d3dDisplay.worldMatrix++;
1208 matrix.Scale(1.0f, 1.0f, -1.0f);
1209 d3dDisplay.worldMatrix->Multiply(camera.viewMatrix, matrix);
1211 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1213 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shaders[0]);
1215 // IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_USEW);
1216 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_TRUE);
1217 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZWRITEENABLE, TRUE);
1218 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, FALSE);
1219 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_LIGHTING, TRUE);
1220 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, TRUE);
1222 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1224 else if(display.display3D.camera)
1226 d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
1227 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1228 IDirect3DDevice8_SetTransform(d3dDevice, D3DTS_PROJECTION, &d3dDisplay.projMatrix);
1230 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
1231 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
1232 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
1233 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
1234 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGENABLE, FALSE);
1235 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, FALSE);
1237 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
1238 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
1240 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shader2D);
1242 IDirect3DDevice8_SetTexture(d3dDevice, 0, null);
1246 void ApplyMaterial(Display display, Material material, Mesh mesh)
1248 DisplaySystem displaySystem = display.displaySystem;
1249 D3D8System d3dSystem = displaySystem.driverData;
1250 D3D8Display d3dDisplay = display.driverData;
1251 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1252 D3D8Mesh d3dMesh = mesh.data;
1255 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGENABLE, material.flags.noFog ? FALSE : TRUE);
1258 if(material.baseMap && d3dMesh.texCoords && material.baseMap.driver.displaySystem == displaySystem)
1260 Bitmap map = material.baseMap;
1262 IDirect3DDevice8_SetTexture(d3dDevice, 0, (IDirect3DBaseTexture8 *)map.picture);
1264 if(material.flags.tile)
1266 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
1267 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
1271 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
1272 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
1276 IDirect3DDevice8_SetTexture(d3dDevice, 0, null);
1279 // IDirect3DDevice8_SetMaterial(d3dDevice, (D3DMATERIAL8 *)&material.diffuse);
1282 D3DMATERIAL8 d3dMaterial;
1284 d3dMaterial.Diffuse.r = material.diffuse.r;
1285 d3dMaterial.Diffuse.g = material.diffuse.g;
1286 d3dMaterial.Diffuse.b = material.diffuse.b;
1287 d3dMaterial.Diffuse.a = material.opacity;
1289 d3dMaterial.Ambient.r = material.ambient.r;
1290 d3dMaterial.Ambient.g = material.ambient.g;
1291 d3dMaterial.Ambient.b = material.ambient.b;
1292 d3dMaterial.Ambient.a = 1;
1294 d3dMaterial.Specular.r = material.specular.r;
1295 d3dMaterial.Specular.g = material.specular.g;
1296 d3dMaterial.Specular.b = material.specular.b;
1297 d3dMaterial.Specular.a = 1;
1299 d3dMaterial.Emissive.r = material.emissive.r;
1300 d3dMaterial.Emissive.g = material.emissive.g;
1301 d3dMaterial.Emissive.b = material.emissive.b;
1302 d3dMaterial.Emissive.a = 1;
1304 d3dMaterial.Power = material.power;
1306 IDirect3DDevice8_SetMaterial(d3dDevice, &d3dMaterial); //(D3DMATERIAL8 *)&material.diffuse
1310 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
1312 D3D8System d3dSystem = displaySystem.driverData;
1313 D3D8Mesh d3dMesh = mesh.data;
1316 if(!(mesh.flags.vertices))
1318 if(d3dMesh.vertices)
1320 IDirect3DVertexBuffer8_Release(d3dMesh.vertices);
1321 d3dMesh.vertices = null;
1323 delete mesh.vertices;
1325 if(!(mesh.flags.normals))
1329 IDirect3DVertexBuffer8_Release(d3dMesh.normals);
1330 d3dMesh.normals = null;
1332 delete mesh.normals;
1334 if(!(mesh.flags.texCoords1))
1336 if(d3dMesh.texCoords)
1338 IDirect3DVertexBuffer8_Release(d3dMesh.texCoords);
1339 d3dMesh.texCoords = null;
1341 delete mesh.texCoords;
1343 if(!(mesh.flags.texCoords2))
1345 if(d3dMesh.texCoords2)
1347 IDirect3DVertexBuffer8_Release(d3dMesh.texCoords2);
1348 d3dMesh.texCoords2 = null;
1350 // delete mesh.texCoords2;
1360 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh)
1362 D3D8System d3dSystem = displaySystem.driverData;
1363 bool result = false;
1364 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1367 mesh.data = D3D8Mesh { };
1370 D3D8Mesh d3dMesh = mesh.data;
1372 if((mesh.flags .vertices) && !d3dMesh.vertices)
1374 mesh.vertices = new Vector3Df[mesh.nVertices];
1375 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * mesh.nVertices,
1376 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices))
1379 if((mesh.flags.normals) && !d3dMesh.normals)
1381 mesh.normals = new Vector3Df[mesh.nVertices];
1382 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * mesh.nVertices,
1383 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals))
1386 if((mesh.flags.texCoords1) && !d3dMesh.texCoords)
1388 mesh.texCoords = new Pointf[mesh.nVertices];
1389 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * mesh.nVertices,
1390 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords))
1397 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1399 D3D8System d3dSystem = displaySystem.driverData;
1400 D3D8Mesh d3dMesh = mesh.data;
1401 if(!flags) flags = mesh.flags;
1403 if(flags.vertices && mesh.vertices)
1405 Vector3Df * vertices;
1406 if(!IDirect3DVertexBuffer8_Lock(d3dMesh.vertices, 0, 0, (byte **) &vertices, 0))
1408 memcpy(vertices, mesh.vertices, mesh.nVertices * sizeof(Vector3Df));
1409 IDirect3DVertexBuffer8_Unlock(d3dMesh.vertices);
1412 if(flags.normals && mesh.normals)
1414 Vector3Df * normals;
1415 if(!IDirect3DVertexBuffer8_Lock(d3dMesh.normals, 0, 0, (byte **) &normals, 0))
1417 memcpy(normals, mesh.normals, mesh.nVertices * sizeof(Vector3Df));
1418 IDirect3DVertexBuffer8_Unlock(d3dMesh.normals);
1421 if(flags.texCoords1 && mesh.texCoords)
1424 if(!IDirect3DVertexBuffer8_Lock(d3dMesh.texCoords, 0, 0, (byte **) &texCoords, 0))
1426 memcpy(texCoords, mesh.texCoords, mesh.nVertices * sizeof(Pointf));
1427 IDirect3DVertexBuffer8_Unlock(d3dMesh.texCoords);
1432 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1438 void FreeIndices(DisplaySystem displaySystem, D3D8Indices d3dIndices)
1442 if(d3dIndices.buffer)
1443 IDirect3DIndexBuffer8_Release(d3dIndices.buffer);
1444 delete d3dIndices.indices;
1449 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
1451 D3D8System d3dSystem = displaySystem.driverData;
1452 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1453 D3D8Indices d3dIndices { };
1454 if(d3dIndices && nIndices)
1456 d3dIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
1457 IDirect3DDevice8_CreateIndexBuffer(d3dDevice, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * nIndices, 0, indices32bit ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
1458 D3DPOOL_MANAGED, &d3dIndices.buffer);
1459 d3dIndices.nIndices = nIndices;
1464 void UnlockIndices(DisplaySystem displaySystem, D3D8Indices d3dIndices, bool indices32bit, int nIndices)
1466 uint16 * indexBuffer = null;
1467 if(!IDirect3DIndexBuffer8_Lock(d3dIndices.buffer, 0, 0, (byte **)&indexBuffer, 0))
1469 memcpy(indexBuffer, d3dIndices.indices, indices32bit ? sizeof(uint32) : sizeof(uint16) * d3dIndices.nIndices);
1470 IDirect3DIndexBuffer8_Unlock(d3dIndices.buffer);
1474 uint16 * LockIndices(DisplaySystem displaySystem, D3D8Indices d3dIndices)
1476 return d3dIndices.indices;
1479 void SelectMesh(Display display, Mesh mesh)
1481 DisplaySystem displaySystem = display.displaySystem;
1482 D3D8System d3dSystem = displaySystem.driverData;
1483 D3D8Display d3dDisplay = display.driverData;
1484 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1486 if(mesh && mesh.data)
1489 D3D8Mesh d3dMesh = mesh.data;
1491 IDirect3DDevice8_SetStreamSource(d3dSystem.d3dDevice, 0, d3dMesh.vertices, sizeof(Vector3Df));
1494 IDirect3DDevice8_SetStreamSource(d3dSystem.d3dDevice, 1, d3dMesh.normals, sizeof(Vector3Df));
1498 IDirect3DDevice8_SetStreamSource(d3dSystem.d3dDevice, 1, null, sizeof(Vector3Df));
1499 if(d3dMesh.texCoords)
1501 IDirect3DDevice8_SetStreamSource(d3dSystem.d3dDevice, 2, d3dMesh.texCoords, sizeof(Pointf));
1505 IDirect3DDevice8_SetStreamSource(d3dSystem.d3dDevice, 2, null, sizeof(Pointf));
1507 IDirect3DDevice8_SetVertexShader(d3dSystem.d3dDevice, d3dSystem.shaders[shader]);
1511 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
1513 DisplaySystem displaySystem = display.displaySystem;
1514 D3D8System d3dSystem = displaySystem.driverData;
1515 D3D8Display d3dDisplay = display.driverData;
1516 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1517 if(primitiveTypes[primitive->type.primitiveType])
1519 int numPrimitives = (primitive->type.vertexRange) ? primitive->nVertices : primitive->nIndices;
1522 switch(primitive->type.primitiveType)
1524 case lines: numPrimitives /= 2; break;
1525 case triangles: numPrimitives /= 3; break;
1537 if(primitive->type.vertexRange)
1539 if(primitive->type.primitiveType == quads)
1541 for(c = 0; c<numPrimitives; c++)
1542 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1545 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1549 D3D8Indices indices = primitive->data;
1550 IDirect3DDevice8_SetIndices(d3dDevice, indices.buffer, 0);
1551 if(primitive->type.primitiveType == quads)
1553 for(c = 0; c<numPrimitives; c++)
1554 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, c*4, 2);
1557 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, 0, numPrimitives);
1560 if(display.display3D.material.flags.doubleSided)
1562 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CCW);
1563 if(!display.display3D.material.flags.singleSideLight)
1565 for(c = 0; c<NumberOfLights; c++)
1566 if(d3dDisplay.lights[c].Type)
1567 IDirect3DDevice8_SetLight(d3dDevice, c, &d3dDisplay.lightsPI[c]);
1569 if(primitive->type.vertexRange)
1571 if(primitive->type.primitiveType == quads)
1573 for(c = 0; c<numPrimitives; c++)
1574 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1577 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1581 D3D8Indices indices = primitive->data;
1582 IDirect3DDevice8_SetIndices(d3dDevice, indices.buffer, 0);
1583 if(primitive->type.primitiveType == quads)
1585 for(c = 0; c<numPrimitives; c++)
1586 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, c*4, 2);
1589 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, 0, numPrimitives);
1592 if(!display.display3D.material.flags.singleSideLight)
1594 for(c = 0; c<NumberOfLights; c++)
1595 if(d3dDisplay.lights[c].Type)
1596 IDirect3DDevice8_SetLight(d3dDevice, c, &d3dDisplay.lights[c]);
1598 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1603 void PushMatrix(Display display)
1605 D3D8Display d3dDisplay = display.driverData;
1606 *(d3dDisplay.worldMatrix+1) = *(d3dDisplay.worldMatrix);
1607 d3dDisplay.worldMatrix++;
1610 void PopMatrix(Display display, bool setMatrix)
1612 D3D8Display d3dDisplay = display.driverData;
1613 DisplaySystem displaySystem = display.displaySystem;
1614 D3D8System d3dSystem = displaySystem.driverData;
1616 d3dDisplay.worldMatrix--;
1618 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1621 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
1623 DisplaySystem displaySystem = display.displaySystem;
1624 D3D8System d3dSystem = displaySystem.driverData;
1625 Camera camera = useCamera ? display.display3D.camera : null;
1626 D3D8Display d3dDisplay = display.driverData;
1627 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1629 Matrix matrix = transMatrix, temp;
1633 matrix.Scale(1.0f, 1.0f, -1.0f);
1634 *(d3dDisplay.worldMatrix) = matrix;
1640 - camera.cPosition.x,
1641 - camera.cPosition.y,
1642 - camera.cPosition.z);
1643 temp.Multiply(matrix, d3dDisplay.worldMatrix);
1644 *(d3dDisplay.worldMatrix) = temp;
1647 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1650 bool Lock(Display display)
1652 DisplaySystem displaySystem = display.displaySystem;
1653 D3D8System d3dSystem = displaySystem.driverData;
1654 D3D8Display d3dDisplay = display.driverData;
1656 if(d3dDisplay.backBuffer)
1658 IDirect3DDevice8_SetRenderTarget(d3dSystem.d3dDevice, d3dDisplay.backBuffer, d3dDisplay.depthSurface);
1659 IDirect3DDevice8_BeginScene(d3dSystem.d3dDevice);
1661 d3dSystem.inScene = true;
1666 void Unlock(Display display)
1668 DisplaySystem displaySystem = display.displaySystem;
1669 D3D8System d3dSystem = displaySystem.driverData;
1670 D3D8Display d3dDisplay = display.driverData;
1672 if(d3dSystem.inScene)
1674 IDirect3DDevice8_EndScene(d3dSystem.d3dDevice);
1675 d3dSystem.inScene = false;