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
80 ColorAlpha background;
83 static class D3D8Mesh : struct
85 IDirect3DVertexBuffer8 * vertices;
86 IDirect3DVertexBuffer8 * normals;
87 IDirect3DVertexBuffer8 * texCoords;
88 IDirect3DVertexBuffer8 * texCoords2;
91 static struct D3D8Vertex
98 static class D3D8Indices : struct
101 IDirect3DIndexBuffer8 * buffer;
105 static int primitiveTypes[RenderPrimitiveType] =
107 D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP, D3DPT_TRIANGLEFAN, D3DPT_TRIANGLEFAN, 0, D3DPT_LINESTRIP
110 static void SetTransformMatrix(IDirect3DDevice8 * device, Matrix matrix)
116 (float)matrix.m[0][0], (float)matrix.m[0][1], (float)matrix.m[0][2], (float)matrix.m[0][3],
117 (float)matrix.m[1][0], (float)matrix.m[1][1], (float)matrix.m[1][2], (float)matrix.m[1][3],
118 (float)matrix.m[2][0], (float)matrix.m[2][1], (float)matrix.m[2][2], (float)matrix.m[2][3],
119 (float)matrix.m[3][0], (float)matrix.m[3][1], (float)matrix.m[3][2], (float)matrix.m[3][3]
123 IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &d3dMat);
126 class Direct3D8DisplayDriver : DisplayDriver
128 class_property(name) = "Direct3D8";
130 bool ::LockDisplay(Display display, Surface surface, Bitmap lfbBitmap, Surface * lfbSurface)
133 D3D8Display d3dDisplay = display.driverData;
135 //if(!IDirect3DDevice8_GetBackBuffer(d3dSystem.d3dDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
137 D3DLOCKED_RECT lockedRect;
138 if(!IDirect3DSurface8_LockRect(d3dDisplay.backBuffer, &lockedRect, null, 0))
141 switch(d3dDisplay.d3dpp.BackBufferFormat)
143 case D3DFMT_A8R8G8B8:
144 case D3DFMT_X8R8G8B8:
145 lfbBitmap.pixelFormat = pixelFormat888;
148 lfbBitmap.pixelFormat = pixelFormat565;
150 case D3DFMT_X1R5G5B5:
151 case D3DFMT_A1R5G5B5:
152 lfbBitmap.pixelFormat = pixelFormat555;
154 case D3DFMT_A4R4G4B4:
155 case D3DFMT_X4R4G4B4:
156 lfbBitmap.pixelFormat = pixelFormat444;
163 lfbBitmap.driver = null;
164 lfbBitmap.displaySystem = null;
165 lfbBitmap.picture = (byte *)lockedRect.pBits;
166 lfbBitmap.transparent = false;
167 lfbBitmap.stride = lockedRect.Pitch >> GetColorDepthShifts(lfbBitmap.pixelFormat);
168 lfbBitmap.width = display.width;
169 lfbBitmap.height = display.height;
171 *lfbSurface = lfbBitmap.GetSurface(surface ? surface.offset.x : 0, surface ? surface.offset.y : 0, surface ? &surface.box : null);
175 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
180 void ::UnlockDisplay(Display display, Surface surface)
182 D3D8Display d3dDisplay = display.driverData;
183 if(d3dDisplay.backBuffer)
185 IDirect3DSurface8_UnlockRect(d3dDisplay.backBuffer);
186 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
191 void ::SetViewportAndMatrices(Display display, int x, int y, Box box)
193 D3D8Display d3dDisplay = display.driverData;
194 DisplaySystem displaySystem = display.displaySystem;
195 D3D8System d3dSystem = displaySystem.driverData;
198 D3DVIEWPORT8 viewport;
201 if(box.right<box.left || box.bottom <box.top)
203 viewport.Width = viewport.Height = 1;
204 viewport.X = viewport.Y = MAXDWORD;
208 viewport.X = x + box.left;
209 viewport.Y = y + box.top;
210 viewport.Width = box.right - box.left + 1;
211 viewport.Height = box.bottom - box.top + 1;
213 if(!IDirect3DDevice8_SetViewport(d3dSystem.d3dDevice, &viewport))
215 D3DMATRIX * matProj = &d3dDisplay.projMatrix;
216 Matrix * matWorld = d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
218 matProj->m[0][0] = 2.0f / viewport.Width;
219 matProj->m[1][1] =-2.0f / viewport.Height;
220 matProj->m[2][2] = matProj->m[3][1] = matProj->m[3][3] = 1;
221 matProj->m[3][0] = -1;
223 IDirect3DDevice8_SetTransform(d3dSystem.d3dDevice, D3DTS_PROJECTION, matProj);
225 matWorld->Identity();
226 matWorld->m[3][0] =-box.left;
227 matWorld->m[3][1] =-box.top;
229 SetTransformMatrix(d3dSystem.d3dDevice, matWorld);
235 bool CreateDisplaySystem(DisplaySystem displaySystem)
238 D3D8System d3dSystem = displaySystem.driverData = D3D8System { };
241 displaySystem.flags.alpha = true;
242 //if(displaySystem.flags.fullScreen)
243 displaySystem.flags.flipping = true;
244 displaySystem.pixelFormat = pixelFormat888;
246 d3dSystem.d3dDll = LoadLibrary("d3d8.dll");
249 d3dSystem.direct3DCreate8 = (void *)GetProcAddress(d3dSystem.d3dDll, "Direct3DCreate8");
250 if(d3dSystem.direct3DCreate8)
252 if((d3dSystem.direct3D = d3dSystem.direct3DCreate8(D3D_SDK_VERSION)))
254 D3DDISPLAYMODE d3ddm;
255 if(!IDirect3D8_GetAdapterDisplayMode(d3dSystem.direct3D, D3DADAPTER_DEFAULT, &d3ddm))
257 d3dSystem.d3dpp.BackBufferCount = 1;
259 if(displaySystem.flags.fullScreen)
261 d3dSystem.d3dpp.BackBufferWidth = d3ddm.Width;
262 d3dSystem.d3dpp.BackBufferHeight = d3ddm.Height;
263 d3dSystem.d3dpp.hDeviceWindow = displaySystem.window;
267 d3dSystem.d3dpp.hDeviceWindow = d3dSystem.hwnd =
268 CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
269 d3dSystem.d3dpp.Windowed = TRUE;
272 d3dSystem.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
273 d3dSystem.format = d3dSystem.d3dpp.BackBufferFormat = d3ddm.Format;
274 d3dSystem.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
276 if(!IDirect3D8_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
277 d3dSystem.d3dpp.hDeviceWindow,
278 D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE|D3DCREATE_FPU_PRESERVE,
279 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
283 d3dSystem.usage = D3DUSAGE_SOFTWAREPROCESSING;
284 if(!IDirect3D8_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
285 d3dSystem.d3dpp.hDeviceWindow,
286 D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,
287 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
293 DWORD vertexShaders[NUM_VERTEX_SHADERS][7] =
297 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
302 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
304 D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3),
309 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
311 D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
316 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
318 D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3),
320 D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
325 DWORD vertexShader2D[] =
328 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
329 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
330 D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
335 for(c = 0; c<NUM_VERTEX_SHADERS; c++)
336 if(IDirect3DDevice8_CreateVertexShader(d3dSystem.d3dDevice, vertexShaders[c], null, &d3dSystem.shaders[c], 0))
339 if(c < NUM_VERTEX_SHADERS ||
340 IDirect3DDevice8_CreateVertexShader(d3dSystem.d3dDevice, vertexShader2D, null, &d3dSystem.shader2D, 0))
344 d3dSystem.ready = false;
350 Log("Couldn't load library d3d8.dll\n");
351 // LogErrorCode(ERR_MISSING_LIBRARY, "d3d8.dll");
356 void DestroyDisplaySystem(DisplaySystem displaySystem)
358 D3D8System d3dSystem = displaySystem.driverData;
361 for(c = 0; c<NUM_VERTEX_SHADERS; c++)
363 if(d3dSystem.shaders[c])
364 IDirect3DDevice8_DeleteVertexShader(d3dSystem.d3dDevice, d3dSystem.shaders[c]);
367 if(d3dSystem.shader2D)
368 IDirect3DDevice8_DeleteVertexShader(d3dSystem.d3dDevice, d3dSystem.shader2D);
370 if(d3dSystem.d3dDevice)
371 IDirect3DDevice8_Release(d3dSystem.d3dDevice);
373 if(d3dSystem.direct3D)
374 IDirect3D8_Release(d3dSystem.direct3D);
376 FreeLibrary(d3dSystem.d3dDll);
379 displaySystem.driverData = null;
383 void DestroyDisplay(Display display)
385 DisplaySystem displaySystem = display.displaySystem;
386 D3D8System d3dSystem = displaySystem.driverData;
387 D3D8Display d3dDisplay = display.driverData;
389 if(d3dSystem.inScene)
391 IDirect3DDevice8_EndScene(d3dSystem.d3dDevice);
392 d3dSystem.inScene = false;
395 if(d3dDisplay.backBuffer)
396 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
398 if(d3dDisplay.depthSurface)
399 IDirect3DSurface8_Release(d3dDisplay.depthSurface);
401 if(d3dDisplay.swapChain)
402 IDirect3DSwapChain8_Release(d3dDisplay.swapChain);
405 display.driverData = null;
408 bool CreateDisplay(Display display)
411 DisplaySystem displaySystem = display.displaySystem;
412 D3D8System d3dSystem = displaySystem.driverData;
413 display.driverData = D3D8Display { };
415 d3dSystem.ready = false;
422 bool DisplaySize(Display display, int width, int height)
425 DisplaySystem displaySystem = display.displaySystem;
426 D3D8System d3dSystem = displaySystem.driverData;
427 D3D8Display d3dDisplay = display.driverData;
428 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
430 d3dSystem.ready = false;
432 if(d3dDisplay.backBuffer)
434 IDirect3DSurface8_Release(d3dDisplay.backBuffer);
435 d3dDisplay.backBuffer = null;
438 if(d3dDisplay.depthSurface)
440 IDirect3DSurface8_Release(d3dDisplay.depthSurface);
441 d3dDisplay.depthSurface = null;
444 if(d3dDisplay.swapChain)
446 IDirect3DSwapChain8_Release(d3dDisplay.swapChain);
447 d3dDisplay.swapChain = null;
453 if(displaySystem.flags.fullScreen)
455 d3dSystem.d3dpp.BackBufferWidth = width;
456 d3dSystem.d3dpp.BackBufferHeight = height;
458 result = !IDirect3DDevice8_Reset(d3dSystem.d3dDevice, &d3dSystem.d3dpp);
462 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;
463 d3dDisplay.d3dpp.BackBufferWidth = width;
464 d3dDisplay.d3dpp.BackBufferHeight = height;
465 d3dDisplay.d3dpp.Windowed = TRUE;
466 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
467 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
468 d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
470 //d3dDisplay.d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
471 d3dDisplay.d3dpp.BackBufferFormat = d3dSystem.format;
472 d3dDisplay.d3dpp.BackBufferCount = 1;
473 d3dDisplay.d3dpp.hDeviceWindow = display.window;
474 d3dDisplay.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
475 // d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_DONOTWAIT;
476 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
477 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
479 result = !IDirect3DDevice8_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
480 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
484 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
485 result = !IDirect3DDevice8_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
486 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
490 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
491 result = !IDirect3DDevice8_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
492 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
498 if(d3dDisplay.swapChain)
499 result = !IDirect3DSwapChain8_GetBackBuffer(d3dDisplay.swapChain,
500 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer);
502 result = !IDirect3DDevice8_GetBackBuffer(d3dSystem.d3dDevice,
503 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer);
506 if(!IDirect3DDevice8_CreateDepthStencilSurface(d3dSystem.d3dDevice, width, height,
507 D3DFMT_D16, d3dDisplay.d3dpp.MultiSampleType,&d3dDisplay.depthSurface))
508 d3dSystem.ready = true;
514 float fogDensity = 0;
516 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shader2D);
518 //IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
519 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
520 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
521 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
522 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
523 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
524 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
525 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGTABLEMODE, D3DFOG_EXP);
526 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGDENSITY, RenderStateFloat { fogDensity }.ui);
527 display.ambient = Color { 50,50,50 };
528 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_NORMALIZENORMALS, TRUE);
529 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
531 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
532 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
533 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
534 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
535 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
536 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
538 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
539 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
540 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
542 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
543 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
545 IDirect3DDevice8_SetTexture(d3dDevice, 0, null);
550 display.width = width;
551 display.height = height;
552 d3dDisplay.updateBox.left = display.width;
553 d3dDisplay.updateBox.top = display.height;
554 d3dDisplay.updateBox.right = 0;
555 d3dDisplay.updateBox.bottom = 0;
560 void DisplayPosition(Display display, int x, int y)
565 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
569 void RestorePalette(Display display)
573 void StartUpdate(Display display)
577 void EndUpdate(Display display)
581 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
585 void Update(Display display, Box updateBox)
587 DisplaySystem displaySystem = display.displaySystem;
588 D3D8System d3dSystem = displaySystem.driverData;
589 D3D8Display d3dDisplay = display.driverData;
592 //eSystem_Sleep(0.05);
593 IDirect3DDevice8_EndScene(d3dSystem.d3dDevice);
595 if(display.displaySystem.flags.flipping)
597 if(d3dDisplay.swapChain)
598 IDirect3DSwapChain8_Present(d3dDisplay.swapChain, null, null, null, null);
600 IDirect3DDevice8_Present(d3dSystem.d3dDevice, null, null, null, null);
606 if(updateBox != null)
608 source.left = dest.left = updateBox.left;
609 source.top = dest.top = updateBox.top;
610 source.right = dest.right = updateBox.right+1;
611 source.bottom = dest.bottom = updateBox.bottom+1;
615 source.left = dest.left = d3dDisplay.updateBox.left;
616 source.top = dest.top = d3dDisplay.updateBox.top;
617 source.right = dest.right = d3dDisplay.updateBox.right+1;
618 source.bottom = dest.bottom = d3dDisplay.updateBox.bottom+1;
620 if(dest.bottom > dest.top && dest.right > dest.left)
621 IDirect3DDevice8_Present(d3dSystem.d3dDevice, &source, &dest, null, null);
622 if(updateBox == null)
624 d3dDisplay.updateBox.left = display.width;
625 d3dDisplay.updateBox.top = display.height;
626 d3dDisplay.updateBox.right = 0;
627 d3dDisplay.updateBox.bottom = 0;
630 d3dSystem.inScene = false;
634 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
638 Bitmap lfbBitmap { };
640 if(LockDisplay(display, null, lfbBitmap, &lfbSurface))
643 if(bitmap.pixelFormat != lfbBitmap.pixelFormat || bitmap.width < w || bitmap.height < h)
646 bitmap.Allocate(null, w,h,w, lfbBitmap.pixelFormat, false);
648 surface = bitmap.GetSurface(0,0,null);
651 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, surface, lfbBitmap, 0, 0, x, y, w, h);
655 UnlockDisplay(display, lfbSurface);
657 lfbBitmap.picture = null;
664 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
667 IDirect3DTexture8_Release((IDirect3DTexture8 *)bitmap.picture);
670 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
675 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
678 D3D8System d3dSystem = displaySystem.driverData;
679 if(bitmap.Convert(null, pixelFormat888, null))
681 IDirect3DTexture8 * texture;
682 uint w = pow2i(Min(bitmap.width, 512)), h = pow2i(Min(bitmap.height, 512));
684 if(!IDirect3DDevice8_CreateTexture(d3dSystem.d3dDevice, w, h, mipMaps ? log2i(Max(w+1, h+1)) : 1, 0,
685 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture))
691 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
693 D3DSURFACE_DESC desc;
694 D3DLOCKED_RECT lockedRect;
696 if(!IDirect3DTexture8_GetLevelDesc(texture, level, &desc) &&
697 !IDirect3DTexture8_LockRect(texture, level, &lockedRect, null, 0))
702 mipMap.width = desc.Width;
703 mipMap.height = desc.Height;
704 mipMap.picture = lockedRect.pBits;
707 case D3DFMT_R5G6B5: mipMap.pixelFormat = pixelFormat565; break;
708 case D3DFMT_A8R8G8B8: mipMap.pixelFormat = pixelFormat888; break;
709 case D3DFMT_A1R5G5B5: mipMap.pixelFormat = pixelFormat555; break;
715 mipMap.stride = lockedRect.Pitch >> GetColorDepthShifts(mipMap.pixelFormat);
717 mipSurface = mipMap.GetSurface(0,0,null);
720 if(mipMap.width != bitmap.width || mipMap.height != bitmap.height)
721 mipSurface.Filter(bitmap, 0,0, 0,0, mipMap.width, mipMap.height, bitmap.width, bitmap.height);
724 //FillBytesBy4(mipMap.picture, bitmap.picture, mipMap.width * mipMap.height);
725 mipSurface.Blit(bitmap, 0,0, 0,0, bitmap.width, bitmap.height);
732 mipMap.picture = null;
735 IDirect3DTexture8_UnlockRect(texture, level);
740 bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
741 bitmap.driver = displaySystem.driver;
742 bitmap.picture = (void *)texture;
745 FreeBitmap(displaySystem, bitmap);
751 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
754 D3D8Display d3dDisplay = display.driverData;
755 DisplaySystem displaySystem = display.displaySystem;
756 D3D8System d3dSystem = displaySystem.driverData;
757 D3D8Surface d3dSurface = surface.driverData = D3D8Surface { };
759 if(d3dSurface && d3dSystem.ready)
761 surface.unclippedBox = surface.box = clip;
762 surface.offset.x = x;
763 surface.offset.y = y;
765 d3dDisplay.updateBox.left = Min(x + clip.left, d3dDisplay.updateBox.left);
766 d3dDisplay.updateBox.top = Min(y + clip.top, d3dDisplay.updateBox.top);
767 d3dDisplay.updateBox.right = Max(x + clip.right, d3dDisplay.updateBox.right);
768 d3dDisplay.updateBox.bottom = Max(y + clip.bottom, d3dDisplay.updateBox.bottom);
770 SetViewportAndMatrices(display, x,y, &surface.box);
777 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
782 void ReleaseSurface(Display display, Surface surface)
784 delete surface.driverData;
787 void Clip(Display display, Surface surface, Box clip)
794 box.Clip(surface.unclippedBox);
798 box = surface.box = surface.unclippedBox;
800 SetViewportAndMatrices(display, surface.offset.x, surface.offset.y, box);
803 void SetForeground(Display display, Surface surface, ColorAlpha color)
808 void SetBackground(Display display, Surface surface, ColorAlpha color)
810 D3D8Surface d3dSurface = surface.driverData;
811 d3dSurface.background = color;
814 ColorAlpha GetPixel(Display display, Surface surface, int x, int y)
819 void PutPixel(Display display, Surface surface,int x,int y)
821 DisplaySystem displaySystem = display.displaySystem;
822 D3D8System d3dSystem = displaySystem.driverData;
823 D3D8Vertex vertex = { (float)x, (float)y, 1.0f, surface.foreground, 0, 0 };
825 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_POINTLIST, 1,
826 &vertex, sizeof(D3D8Vertex));
829 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
831 DisplaySystem displaySystem = display.displaySystem;
832 D3D8System d3dSystem = displaySystem.driverData;
833 D3D8Vertex vertex[2] =
835 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
836 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 }
839 if(x1 == x2) vertex[1].y++;
840 else if(y1 == y2) vertex[1].x++;
842 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 1,
843 vertex, sizeof(D3D8Vertex));
846 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
848 DisplaySystem displaySystem = display.displaySystem;
849 D3D8System d3dSystem = displaySystem.driverData;
850 D3D8Vertex vertex[5] =
852 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
853 { (float)x2, (float)y1, 1.0f, surface.foreground, 0, 0 },
854 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 },
855 { (float)x1, (float)y2, 1.0f, surface.foreground, 0, 0 },
856 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 }
859 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 4,
860 vertex, sizeof(D3D8Vertex));
864 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
866 DisplaySystem displaySystem = display.displaySystem;
867 D3D8System d3dSystem = displaySystem.driverData;
868 D3D8Surface d3dSurface = surface.driverData;
869 D3D8Vertex vertex[4] =
871 { (float)x1, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
872 { (float)x2 + 1.0f, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
873 { (float)x1, (float)y2 + 1.0f, 1.0f, d3dSurface.background, 0, 0 },
874 { (float)x2 + 1.0f, (float)y2 + 1.0f, 1.0f, d3dSurface.background, 0, 0 }
877 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
878 vertex, sizeof(D3D8Vertex));
882 void Clear(Display display, Surface surface, ClearType type)
884 DisplaySystem displaySystem = display.displaySystem;
885 D3D8System d3dSystem = displaySystem.driverData;
886 D3D8Surface d3dSurface = surface.driverData;
887 IDirect3DDevice8_Clear(d3dSystem.d3dDevice, 0, null,
888 ((type == depthBuffer) ? 0 : D3DCLEAR_TARGET) |
889 ((type == colorBuffer) ? 0 : D3DCLEAR_ZBUFFER),
890 d3dSurface.background, 1,0);
893 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
898 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
900 DisplaySystem displaySystem = display.displaySystem;
901 D3D8System d3dSystem = displaySystem.driverData;
902 D3D8Surface d3dSurface = surface.driverData;
903 Color foreground = d3dSurface.writingText ? surface.foreground : white;
904 D3D8Vertex vertex[4] =
906 { (float)dx, (float)dy, 1.0f, foreground,
907 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
908 { (float)(dx+w), (float)dy, 1.0f, foreground,
909 (float)(sx+w)/ (src.width-1), (float)sy/ (src.height-1) },
910 { (float)dx, (float)(dy+h), 1.0f, foreground,
911 (float)sx/ (src.width-1), (float)(sy+h)/ (src.height-1) },
912 { (float)(dx+w), (float)(dy+h), 1.0f, foreground,
913 (float)(sx+w) / (src.width-1), (float)(sy+h)/ (src.height-1) }
916 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture8 *)src.picture);
917 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
918 vertex, sizeof(D3D8Vertex));
919 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, null);
922 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
924 DisplaySystem displaySystem = display.displaySystem;
925 D3D8System d3dSystem = displaySystem.driverData;
926 D3D8Vertex vertex[4] =
928 { (float)dx, (float)dy, 1.0f, surface.foreground,
929 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
930 { (float)(dx+w), (float)dy, 1.0f, surface.foreground,
931 (float)(sx+sw)/ (src.width-1), (float)sy/ (src.height-1) },
932 { (float)dx, (float)(dy+h), 1.0f, surface.foreground,
933 (float)sx/ (src.width-1), (float)(sy+sh)/ (src.height-1) },
934 { (float)(dx+w), (float)(dy+h), 1.0f, surface.foreground,
935 (float)(sx+sw) / (src.width-1), (float)(sy+sh)/ (src.height-1) }
938 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture8 *)src.picture);
939 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
940 vertex, sizeof(D3D8Vertex));
941 IDirect3DDevice8_SetTexture(d3dSystem.d3dDevice, 0, null);
944 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
946 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
949 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
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)
965 Bitmap lfbBitmap { };
966 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
968 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, lfbSurface, src, dx, dy, sx, sy, w, h);
969 UnlockDisplay(display, lfbSurface);
971 lfbBitmap.picture = null;
975 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
977 StretchDI(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
980 void UnloadFont(DisplaySystem displaySystem, Font font)
982 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
985 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
987 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
990 void TextFont(Display display, Surface surface, Font font)
992 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
995 void TextOpacity(Display display, Surface surface, bool opaque)
997 D3D8Surface d3dSurface = surface.driverData;
998 d3dSurface.opaqueText = opaque;
1001 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
1003 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
1006 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
1008 DisplaySystem displaySystem = display.displaySystem;
1009 D3D8System d3dSystem = displaySystem.driverData;
1010 D3D8Surface d3dSurface = surface.driverData;
1012 if(surface.textOpacity)
1015 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
1018 int x1 = x, y1 = y, x2 = x+w-1, y2 = y+h-1;
1019 D3D8Vertex vertex[4] =
1021 { (float)x1, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1022 { (float)x2 + 1.0f, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1023 { (float)x1, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 },
1024 { (float)x2 + 1.0f, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 }
1027 IDirect3DDevice8_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
1028 vertex, sizeof(D3D8Vertex));
1030 //display.displaySystem.driver.Area(display, surface, x, y, x+w-1, y+h-1);
1032 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
1033 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
1034 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MIPFILTER, D3DTEXF_NONE);
1035 d3dSurface.writingText = true;
1037 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
1039 d3dSurface.writingText = false;
1040 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
1041 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
1042 IDirect3DDevice8_SetTextureStageState(d3dSystem.d3dDevice, 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); //NONE);
1045 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
1047 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, width, height);
1050 void DrawingChar(Display display, Surface surface, byte character)
1055 void LineStipple(Display display, Surface surface, uint stipple)
1058 D3D8Display d3dDisplay = display.driverData;
1059 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_LINEPATTERN,
1060 stipple?MDWORD(1,stipple):0);
1064 void SetRenderState(Display display, RenderState state, uint value)
1066 DisplaySystem displaySystem = display.displaySystem;
1067 D3D8System d3dSystem = displaySystem.driverData;
1071 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, value ? TRUE : FALSE);
1074 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_FILLMODE,
1075 ((FillModeValue)value == solid) ? D3DFILL_SOLID : D3DFILL_WIREFRAME);
1078 // IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_USEW : D3DZB_FALSE);
1079 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_TRUE : D3DZB_FALSE);
1082 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZWRITEENABLE, value);
1085 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGCOLOR, value);
1089 float fogDensity = RenderStateFloat { ui = value }.f;
1090 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGDENSITY, RenderStateFloat { fogDensity }.ui);
1094 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_ALPHABLENDENABLE, value);
1097 IDirect3DDevice8_SetRenderState(d3dSystem.d3dDevice, D3DRS_AMBIENT, value);
1102 void SetLight(Display display, int id, Light light)
1104 DisplaySystem displaySystem = display.displaySystem;
1105 D3D8System d3dSystem = displaySystem.driverData;
1106 D3D8Display d3dDisplay = display.driverData;
1109 D3DLIGHT8 d3dLight =
1111 D3DLIGHT_DIRECTIONAL,
1112 // Opacity on the light?
1113 { light.diffuse.r, light.diffuse.g, light.diffuse.b, 1.0f },
1114 { light.specular.r, light.specular.g, light.specular.b, 1.0f },
1115 { light.ambient.r, light.ambient.g, light.ambient.b, 1.0f }
1117 Vector3Df * lightDirection;
1118 Vector3Df vector {0,0,1};
1119 Vector3Df vectorPI {0,0,-1};
1120 Vector3Df direction;
1122 lightDirection = (Vector3Df *)&d3dLight.Direction;
1124 mat.RotationQuaternion(light.orientation);
1126 direction.MultMatrix(vector, mat);
1127 if(!display.display3D || !display.display3D.camera)
1129 d3dLight.Direction.x = direction.x;
1130 d3dLight.Direction.y = direction.y;
1131 d3dLight.Direction.z =-direction.z;
1134 lightDirection->MultMatrix(direction, d3dDisplay.worldMatrix);
1136 d3dDisplay.lights[id] = d3dLight;
1138 IDirect3DDevice8_LightEnable(d3dSystem.d3dDevice, id, TRUE);
1139 IDirect3DDevice8_SetLight(d3dSystem.d3dDevice, id, &d3dDisplay.lights[id]);
1141 direction.MultMatrix(vectorPI, mat);
1142 lightDirection->MultMatrix(direction, d3dDisplay.worldMatrix);
1144 d3dDisplay.lightsPI[id] = d3dLight;
1148 IDirect3DDevice8_LightEnable(d3dSystem.d3dDevice, id, FALSE);
1149 d3dDisplay.lights[id].Type = 0;
1153 void SetCamera(Display display, Surface surface, Camera camera)
1155 DisplaySystem displaySystem = display.displaySystem;
1156 D3D8System d3dSystem = displaySystem.driverData;
1157 D3D8Display d3dDisplay = display.driverData;
1158 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1161 Point topLeft {surface.box.left + surface.offset.x, surface.box.top + surface.offset.y};
1162 Point downRight {surface.box.right + surface.offset.x, surface.box.bottom + surface.offset.y};
1165 surface.offset.x + camera.origin.x,
1166 surface.offset.y + camera.origin.y
1170 float l = (topLeft.x - origin.x) * camera.zMin / camera.focalX;
1171 float r = (downRight.x - origin.x) * camera.zMin / camera.focalX;
1172 float b = (downRight.y - origin.y) * camera.zMin / camera.focalY;
1173 float t = (topLeft.y - origin.y) * camera.zMin / camera.focalY;
1174 float n = camera.zMin;
1175 float f = camera.zMax;
1177 matProj.m[0][0] = 2 * n / (r - l);
1178 matProj.m[0][1] = 0;
1179 matProj.m[0][2] = 0;
1180 matProj.m[0][3] = 0;
1182 matProj.m[1][0] = 0;
1183 matProj.m[1][1] = 2 * n / (t - b);
1184 matProj.m[1][2] = 0;
1185 matProj.m[1][3] = 0;
1187 matProj.m[2][0] = (l + r) / (r - l);
1188 matProj.m[2][1] = (t + b) / (t - b);
1189 matProj.m[2][2] = f / (n - f);
1190 matProj.m[2][3] = -1;
1192 matProj.m[3][0] = 0;
1193 matProj.m[3][1] = 0;
1194 matProj.m[3][2] = n * f / (n - f);
1195 matProj.m[3][3] = 0;
1197 IDirect3DDevice8_SetTransform(d3dDevice, D3DTS_PROJECTION, &matProj);
1199 // *** View Matrix ***
1200 if(!display.display3D.camera)
1201 d3dDisplay.worldMatrix++;
1204 matrix.Scale(1.0f, 1.0f, -1.0f);
1205 d3dDisplay.worldMatrix->Multiply(camera.viewMatrix, matrix);
1207 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1209 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shaders[0]);
1211 // IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_USEW);
1212 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_TRUE);
1213 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZWRITEENABLE, TRUE);
1214 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, FALSE);
1215 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_LIGHTING, TRUE);
1216 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, TRUE);
1218 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1220 else if(display.display3D.camera)
1222 d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
1223 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1224 IDirect3DDevice8_SetTransform(d3dDevice, D3DTS_PROJECTION, &d3dDisplay.projMatrix);
1226 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
1227 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
1228 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
1229 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
1230 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGENABLE, FALSE);
1231 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, FALSE);
1233 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
1234 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
1236 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shader2D);
1238 IDirect3DDevice8_SetTexture(d3dDevice, 0, null);
1242 void ApplyMaterial(Display display, Material material, Mesh mesh)
1244 DisplaySystem displaySystem = display.displaySystem;
1245 D3D8System d3dSystem = displaySystem.driverData;
1246 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1247 D3D8Mesh d3dMesh = mesh.data;
1250 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_FOGENABLE, material.flags.noFog ? FALSE : TRUE);
1253 if(material.baseMap && d3dMesh.texCoords && material.baseMap.driver.displaySystem == displaySystem)
1255 Bitmap map = material.baseMap;
1257 IDirect3DDevice8_SetTexture(d3dDevice, 0, (IDirect3DBaseTexture8 *)map.picture);
1259 if(material.flags.tile)
1261 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
1262 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
1266 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
1267 IDirect3DDevice8_SetTextureStageState(d3dDevice, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
1271 IDirect3DDevice8_SetTexture(d3dDevice, 0, null);
1274 // IDirect3DDevice8_SetMaterial(d3dDevice, (D3DMATERIAL8 *)&material.diffuse);
1277 D3DMATERIAL8 d3dMaterial;
1279 d3dMaterial.Diffuse.r = material.diffuse.r;
1280 d3dMaterial.Diffuse.g = material.diffuse.g;
1281 d3dMaterial.Diffuse.b = material.diffuse.b;
1282 d3dMaterial.Diffuse.a = material.opacity;
1284 d3dMaterial.Ambient.r = material.ambient.r;
1285 d3dMaterial.Ambient.g = material.ambient.g;
1286 d3dMaterial.Ambient.b = material.ambient.b;
1287 d3dMaterial.Ambient.a = 1;
1289 d3dMaterial.Specular.r = material.specular.r;
1290 d3dMaterial.Specular.g = material.specular.g;
1291 d3dMaterial.Specular.b = material.specular.b;
1292 d3dMaterial.Specular.a = 1;
1294 d3dMaterial.Emissive.r = material.emissive.r;
1295 d3dMaterial.Emissive.g = material.emissive.g;
1296 d3dMaterial.Emissive.b = material.emissive.b;
1297 d3dMaterial.Emissive.a = 1;
1299 d3dMaterial.Power = material.power;
1301 IDirect3DDevice8_SetMaterial(d3dDevice, &d3dMaterial); //(D3DMATERIAL8 *)&material.diffuse
1305 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
1307 D3D8Mesh d3dMesh = mesh.data;
1310 if(!(mesh.flags.vertices))
1312 if(d3dMesh.vertices)
1314 IDirect3DVertexBuffer8_Release(d3dMesh.vertices);
1315 d3dMesh.vertices = null;
1317 delete mesh.vertices;
1319 if(!(mesh.flags.normals))
1323 IDirect3DVertexBuffer8_Release(d3dMesh.normals);
1324 d3dMesh.normals = null;
1326 delete mesh.normals;
1328 if(!(mesh.flags.texCoords1))
1330 if(d3dMesh.texCoords)
1332 IDirect3DVertexBuffer8_Release(d3dMesh.texCoords);
1333 d3dMesh.texCoords = null;
1335 delete mesh.texCoords;
1337 if(!(mesh.flags.texCoords2))
1339 if(d3dMesh.texCoords2)
1341 IDirect3DVertexBuffer8_Release(d3dMesh.texCoords2);
1342 d3dMesh.texCoords2 = null;
1344 // delete mesh.texCoords2;
1354 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
1356 D3D8System d3dSystem = displaySystem.driverData;
1357 bool result = false;
1358 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1361 mesh.data = D3D8Mesh { };
1364 D3D8Mesh d3dMesh = mesh.data;
1366 if(mesh.nVertices == nVertices)
1368 if(mesh.flags != flags)
1370 // Same number of vertices, adding features (Leaves the other features pointers alone)
1371 if(flags.vertices && !d3dMesh.vertices)
1373 mesh.vertices = new Vector3Df[nVertices];
1374 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1375 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices))
1378 if(flags.normals && !d3dMesh.normals)
1380 mesh.normals = new Vector3Df[nVertices];
1381 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1382 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals))
1385 if(flags.texCoords1 && !d3dMesh.texCoords)
1387 mesh.texCoords = new Pointf[nVertices];
1388 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * nVertices,
1389 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords))
1396 // New number of vertices, reallocate all current and new features
1397 flags |= mesh.flags;
1399 // Same number of vertices, adding features (Leaves the other features pointers alone)
1402 if(d3dMesh.vertices)
1404 IDirect3DVertexBuffer8_Release(d3dMesh.vertices);
1405 d3dMesh.vertices = null;
1407 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
1408 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1409 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices))
1416 IDirect3DVertexBuffer8_Release(d3dMesh.normals);
1417 d3dMesh.normals = null;
1419 mesh.normals = renew mesh.normals Vector3Df[nVertices];
1420 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1421 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals))
1424 if(flags.texCoords1)
1426 if(d3dMesh.texCoords)
1428 IDirect3DVertexBuffer8_Release(d3dMesh.texCoords);
1429 d3dMesh.texCoords = null;
1431 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
1432 if(IDirect3DDevice8_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * nVertices,
1433 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords))
1441 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1443 D3D8Mesh d3dMesh = mesh.data;
1444 if(!flags) flags = mesh.flags;
1446 if(flags.vertices && mesh.vertices)
1448 Vector3Df * vertices;
1449 if(!IDirect3DVertexBuffer8_Lock(d3dMesh.vertices, 0, 0, (byte **) &vertices, 0))
1451 memcpy(vertices, mesh.vertices, mesh.nVertices * sizeof(Vector3Df));
1452 IDirect3DVertexBuffer8_Unlock(d3dMesh.vertices);
1455 if(flags.normals && mesh.normals)
1457 Vector3Df * normals;
1458 if(!IDirect3DVertexBuffer8_Lock(d3dMesh.normals, 0, 0, (byte **) &normals, 0))
1460 memcpy(normals, mesh.normals, mesh.nVertices * sizeof(Vector3Df));
1461 IDirect3DVertexBuffer8_Unlock(d3dMesh.normals);
1464 if(flags.texCoords1 && mesh.texCoords)
1467 if(!IDirect3DVertexBuffer8_Lock(d3dMesh.texCoords, 0, 0, (byte **) &texCoords, 0))
1469 memcpy(texCoords, mesh.texCoords, mesh.nVertices * sizeof(Pointf));
1470 IDirect3DVertexBuffer8_Unlock(d3dMesh.texCoords);
1475 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1481 void FreeIndices(DisplaySystem displaySystem, D3D8Indices d3dIndices)
1485 if(d3dIndices.buffer)
1486 IDirect3DIndexBuffer8_Release(d3dIndices.buffer);
1487 delete d3dIndices.indices;
1492 void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
1494 D3D8System d3dSystem = displaySystem.driverData;
1495 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1496 D3D8Indices d3dIndices { };
1497 if(d3dIndices && nIndices)
1499 d3dIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
1500 IDirect3DDevice8_CreateIndexBuffer(d3dDevice, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * nIndices, 0, indices32bit ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
1501 D3DPOOL_MANAGED, &d3dIndices.buffer);
1502 d3dIndices.nIndices = nIndices;
1507 void UnlockIndices(DisplaySystem displaySystem, D3D8Indices d3dIndices, bool indices32bit, int nIndices)
1509 uint16 * indexBuffer = null;
1510 if(!IDirect3DIndexBuffer8_Lock(d3dIndices.buffer, 0, 0, (byte **)&indexBuffer, 0))
1512 memcpy(indexBuffer, d3dIndices.indices, indices32bit ? sizeof(uint32) : sizeof(uint16) * d3dIndices.nIndices);
1513 IDirect3DIndexBuffer8_Unlock(d3dIndices.buffer);
1517 uint16 * LockIndices(DisplaySystem displaySystem, D3D8Indices d3dIndices)
1519 return d3dIndices.indices;
1522 void SelectMesh(Display display, Mesh mesh)
1524 DisplaySystem displaySystem = display.displaySystem;
1525 D3D8System d3dSystem = displaySystem.driverData;
1526 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1528 if(mesh && mesh.data)
1531 D3D8Mesh d3dMesh = mesh.data;
1533 IDirect3DDevice8_SetStreamSource(d3dDevice, 0, d3dMesh.vertices, sizeof(Vector3Df));
1536 IDirect3DDevice8_SetStreamSource(d3dDevice, 1, d3dMesh.normals, sizeof(Vector3Df));
1540 IDirect3DDevice8_SetStreamSource(d3dDevice, 1, null, sizeof(Vector3Df));
1541 if(d3dMesh.texCoords)
1543 IDirect3DDevice8_SetStreamSource(d3dDevice, 2, d3dMesh.texCoords, sizeof(Pointf));
1547 IDirect3DDevice8_SetStreamSource(d3dDevice, 2, null, sizeof(Pointf));
1549 IDirect3DDevice8_SetVertexShader(d3dDevice, d3dSystem.shaders[shader]);
1553 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
1555 DisplaySystem displaySystem = display.displaySystem;
1556 D3D8System d3dSystem = displaySystem.driverData;
1557 D3D8Display d3dDisplay = display.driverData;
1558 IDirect3DDevice8 * d3dDevice = d3dSystem.d3dDevice;
1559 if(primitiveTypes[primitive->type.primitiveType])
1561 int numPrimitives = (primitive->type.vertexRange) ? primitive->nVertices : primitive->nIndices;
1564 switch(primitive->type.primitiveType)
1566 case lines: numPrimitives /= 2; break;
1567 case triangles: numPrimitives /= 3; break;
1579 if(primitive->type.vertexRange)
1581 if(primitive->type.primitiveType == quads)
1583 for(c = 0; c<numPrimitives; c++)
1584 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1587 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1591 D3D8Indices indices = primitive->data;
1592 IDirect3DDevice8_SetIndices(d3dDevice, indices.buffer, 0);
1593 if(primitive->type.primitiveType == quads)
1595 for(c = 0; c<numPrimitives; c++)
1596 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, c*4, 2);
1599 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, 0, numPrimitives);
1602 if(display.display3D.material.flags.doubleSided)
1604 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CCW);
1605 if(!display.display3D.material.flags.singleSideLight)
1607 for(c = 0; c<NumberOfLights; c++)
1608 if(d3dDisplay.lights[c].Type)
1609 IDirect3DDevice8_SetLight(d3dDevice, c, &d3dDisplay.lightsPI[c]);
1611 if(primitive->type.vertexRange)
1613 if(primitive->type.primitiveType == quads)
1615 for(c = 0; c<numPrimitives; c++)
1616 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1619 IDirect3DDevice8_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1623 D3D8Indices indices = primitive->data;
1624 IDirect3DDevice8_SetIndices(d3dDevice, indices.buffer, 0);
1625 if(primitive->type.primitiveType == quads)
1627 for(c = 0; c<numPrimitives; c++)
1628 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, c*4, 2);
1631 IDirect3DDevice8_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, mesh.nVertices, 0, numPrimitives);
1634 if(!display.display3D.material.flags.singleSideLight)
1636 for(c = 0; c<NumberOfLights; c++)
1637 if(d3dDisplay.lights[c].Type)
1638 IDirect3DDevice8_SetLight(d3dDevice, c, &d3dDisplay.lights[c]);
1640 IDirect3DDevice8_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1645 void PushMatrix(Display display)
1647 D3D8Display d3dDisplay = display.driverData;
1648 *(d3dDisplay.worldMatrix+1) = *(d3dDisplay.worldMatrix);
1649 d3dDisplay.worldMatrix++;
1652 void PopMatrix(Display display, bool setMatrix)
1654 D3D8Display d3dDisplay = display.driverData;
1655 DisplaySystem displaySystem = display.displaySystem;
1656 D3D8System d3dSystem = displaySystem.driverData;
1658 d3dDisplay.worldMatrix--;
1660 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1663 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
1665 DisplaySystem displaySystem = display.displaySystem;
1666 D3D8System d3dSystem = displaySystem.driverData;
1667 Camera camera = useCamera ? display.display3D.camera : null;
1668 D3D8Display d3dDisplay = display.driverData;
1670 Matrix matrix = transMatrix, temp;
1674 matrix.Scale(1.0f, 1.0f, -1.0f);
1675 *(d3dDisplay.worldMatrix) = matrix;
1681 - camera.cPosition.x,
1682 - camera.cPosition.y,
1683 - camera.cPosition.z);
1684 temp.Multiply(matrix, d3dDisplay.worldMatrix);
1685 *(d3dDisplay.worldMatrix) = temp;
1688 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1691 bool Lock(Display display)
1693 DisplaySystem displaySystem = display.displaySystem;
1694 D3D8System d3dSystem = displaySystem.driverData;
1695 D3D8Display d3dDisplay = display.driverData;
1697 if(d3dDisplay.backBuffer)
1699 IDirect3DDevice8_SetRenderTarget(d3dSystem.d3dDevice, d3dDisplay.backBuffer, d3dDisplay.depthSurface);
1700 IDirect3DDevice8_BeginScene(d3dSystem.d3dDevice);
1702 d3dSystem.inScene = true;
1707 void Unlock(Display display)
1709 DisplaySystem displaySystem = display.displaySystem;
1710 D3D8System d3dSystem = displaySystem.driverData;
1712 if(d3dSystem.inScene)
1714 IDirect3DDevice8_EndScene(d3dSystem.d3dDevice);
1715 d3dSystem.inScene = false;