1 namespace gfx::drivers;
7 #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_DECLS 4
45 static class D3DDisplay : struct
48 IDirect3DSwapChain9 * swapChain;
49 Matrix worldMatrixStack[MATRIX_STACK_SIZE];
52 D3DLIGHT9 lights[NumberOfLights], lightsPI[NumberOfLights];
53 D3DPRESENT_PARAMETERS d3dpp;
54 IDirect3DSurface9 * backBuffer, * depthSurface;
58 static class D3DSystem : struct
61 IDirect3D9 * direct3D;
62 IDirect3DDevice9 * d3dDevice;
63 IDirect3D9 * (WINAPI * direct3DCreate9)(UINT);
65 D3DPRESENT_PARAMETERS d3dpp;
67 IDirect3DVertexDeclaration9 * decls[NUM_VERTEX_DECLS], * decl2D;
74 static class D3DSurface : struct
76 // For compatibility with LFB driver
82 ColorAlpha background;
85 static class D3DMesh : struct
87 IDirect3DVertexBuffer9 * vertices;
88 IDirect3DVertexBuffer9 * normals;
89 IDirect3DVertexBuffer9 * texCoords;
90 IDirect3DVertexBuffer9 * texCoords2;
100 static class D3DIndices : struct
103 IDirect3DIndexBuffer9 * buffer;
107 static int primitiveTypes[RenderPrimitiveType] =
109 D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP, D3DPT_TRIANGLEFAN, D3DPT_TRIANGLEFAN, 0, D3DPT_LINESTRIP
112 static void SetTransformMatrix(IDirect3DDevice9 * device, Matrix matrix)
118 (float)matrix.m[0][0], (float)matrix.m[0][1], (float)matrix.m[0][2], (float)matrix.m[0][3],
119 (float)matrix.m[1][0], (float)matrix.m[1][1], (float)matrix.m[1][2], (float)matrix.m[1][3],
120 (float)matrix.m[2][0], (float)matrix.m[2][1], (float)matrix.m[2][2], (float)matrix.m[2][3],
121 (float)matrix.m[3][0], (float)matrix.m[3][1], (float)matrix.m[3][2], (float)matrix.m[3][3]
125 IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &d3dMat);
128 class Direct3D9DisplayDriver : DisplayDriver
130 class_property(name) = "Direct3D";
133 bool ::LockDisplay(Display display, Surface surface, Bitmap lfbBitmap, Surface * lfbSurface)
136 D3DDisplay d3dDisplay = display.driverData;
138 //if(!IDirect3DDevice9_GetBackBuffer(d3dSystem.d3dDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
140 D3DLOCKED_RECT lockedRect;
141 if(!IDirect3DSurface9_LockRect(d3dDisplay.backBuffer, &lockedRect, null, 0))
144 switch(d3dDisplay.d3dpp.BackBufferFormat)
146 case D3DFMT_A8R8G8B8:
147 case D3DFMT_X8R8G8B8:
148 lfbBitmap.pixelFormat = pixelFormat888;
151 lfbBitmap.pixelFormat = pixelFormat565;
153 case D3DFMT_X1R5G5B5:
154 case D3DFMT_A1R5G5B5:
155 lfbBitmap.pixelFormat = pixelFormat555;
157 case D3DFMT_A4R4G4B4:
158 case D3DFMT_X4R4G4B4:
159 lfbBitmap.pixelFormat = pixelFormat444;
166 lfbBitmap.driver = null;
167 lfbBitmap.displaySystem = null;
168 lfbBitmap.picture = (byte *)lockedRect.pBits;
169 lfbBitmap.transparent = false;
170 lfbBitmap.stride = lockedRect.Pitch >> GetColorDepthShifts(lfbBitmap.pixelFormat);
171 lfbBitmap.width = display.width;
172 lfbBitmap.height = display.height;
174 *lfbSurface = lfbBitmap.GetSurface(surface ? surface.offset.x : 0, surface ? surface.offset.y : 0, surface ? surface.box : null);
178 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
183 void ::UnlockDisplay(Display display, Surface surface)
185 D3DDisplay d3dDisplay = display.driverData;
186 if(d3dDisplay.backBuffer)
188 IDirect3DSurface9_UnlockRect(d3dDisplay.backBuffer);
189 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
194 void ::SetViewportAndMatrices(Display display, int x, int y, Box box)
196 D3DDisplay d3dDisplay = display.driverData;
197 DisplaySystem displaySystem = display.displaySystem;
198 D3DSystem d3dSystem = displaySystem.driverData;
201 D3DVIEWPORT9 viewport;
204 if(box.right < box.left || box.bottom < box.top)
206 viewport.Width = viewport.Height = 1;
207 viewport.X = viewport.Y = MAXDWORD;
211 viewport.X = x + box.left;
212 viewport.Y = y + box.top;
213 viewport.Width = box.right - box.left + 1;
214 viewport.Height = box.bottom - box.top + 1;
216 if(!IDirect3DDevice9_SetViewport(d3dSystem.d3dDevice, &viewport))
218 D3DMATRIX * matProj = &d3dDisplay.projMatrix;
219 Matrix * matWorld = d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
221 matProj->m[0][0] = 2.0f / viewport.Width;
222 matProj->m[1][1] =-2.0f / viewport.Height;
223 matProj->m[2][2] = matProj->m[3][1] = matProj->m[3][3] = 1;
224 matProj->m[3][0] = -1;
226 IDirect3DDevice9_SetTransform(d3dSystem.d3dDevice, D3DTS_PROJECTION, matProj);
228 matWorld->Identity();
229 matWorld->m[3][0] =-box.left;
230 matWorld->m[3][1] =-box.top;
232 SetTransformMatrix(d3dSystem.d3dDevice, matWorld);
238 bool CreateDisplaySystem(DisplaySystem displaySystem)
241 D3DSystem d3dSystem = displaySystem.driverData = D3DSystem { };
244 displaySystem.flags.alpha = true;
245 //if(displaySystem.flags.fullScreen)
246 displaySystem.flags.flipping = true;
247 displaySystem.pixelFormat = pixelFormat888;
249 d3dSystem.d3dDll = LoadLibrary("d3d9.dll");
252 d3dSystem.direct3DCreate9 = (void *)GetProcAddress(d3dSystem.d3dDll, "Direct3DCreate9");
253 if(d3dSystem.direct3DCreate9)
255 if((d3dSystem.direct3D = d3dSystem.direct3DCreate9(D3D_SDK_VERSION)))
257 D3DDISPLAYMODE d3ddm;
258 if(!IDirect3D9_GetAdapterDisplayMode(d3dSystem.direct3D, D3DADAPTER_DEFAULT, &d3ddm))
260 d3dSystem.d3dpp.BackBufferCount = 1;
262 if(displaySystem.flags.fullScreen)
264 d3dSystem.d3dpp.BackBufferWidth = d3ddm.Width;
265 d3dSystem.d3dpp.BackBufferHeight = d3ddm.Height;
266 d3dSystem.d3dpp.hDeviceWindow = displaySystem.window;
270 d3dSystem.d3dpp.hDeviceWindow = d3dSystem.hwnd =
271 CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
272 d3dSystem.d3dpp.Windowed = TRUE;
275 d3dSystem.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
276 d3dSystem.format = d3dSystem.d3dpp.BackBufferFormat = d3ddm.Format;
277 d3dSystem.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
279 if(!IDirect3D9_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
280 d3dSystem.d3dpp.hDeviceWindow,
281 D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE|D3DCREATE_FPU_PRESERVE,
282 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
286 d3dSystem.usage = D3DUSAGE_SOFTWAREPROCESSING;
287 if(!IDirect3D9_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
288 d3dSystem.d3dpp.hDeviceWindow,
289 D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,
290 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
296 D3DVERTEXELEMENT9 vertexDecls[NUM_VERTEX_DECLS][4] =
299 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
303 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
304 { 1, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 },
308 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
309 { 2, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
313 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
314 { 1, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 },
315 { 2, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
320 D3DVERTEXELEMENT9 vertexDecl2D[] =
322 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
323 { 0, (uint16)(3*sizeof(float)), D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 },
324 { 0, (uint16)(3*sizeof(float) + sizeof(uint)), D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
329 for(c = 0; c<NUM_VERTEX_DECLS; c++)
330 if(IDirect3DDevice9_CreateVertexDeclaration(d3dSystem.d3dDevice, vertexDecls[c], &d3dSystem.decls[c]))
333 if(c < NUM_VERTEX_DECLS ||
334 IDirect3DDevice9_CreateVertexDeclaration(d3dSystem.d3dDevice, vertexDecl2D, &d3dSystem.decl2D))
338 d3dSystem.ready = false;
344 Log("Couldn't load library d3d9.dll\n");
345 //LogErrorCode(ERR_MISSING_LIBRARY, "d3d9.dll");
350 void DestroyDisplaySystem(DisplaySystem displaySystem)
352 D3DSystem d3dSystem = displaySystem.driverData;
355 if(d3dSystem.d3dDevice)
356 IDirect3DDevice9_Release(d3dSystem.d3dDevice);
358 if(d3dSystem.direct3D)
359 IDirect3D9_Release(d3dSystem.direct3D);
361 for(c = 0; c<NUM_VERTEX_DECLS; c++)
363 if(d3dSystem.decls[c])
364 IDirect3DVertexDeclaration9_Release(d3dSystem.decls[c]);
368 IDirect3DVertexDeclaration9_Release(d3dSystem.decl2D);
370 FreeLibrary(d3dSystem.d3dDll);
373 displaySystem.driverData = null;
377 void DestroyDisplay(Display display)
379 DisplaySystem displaySystem = display.displaySystem;
380 D3DSystem d3dSystem = displaySystem.driverData;
381 D3DDisplay d3dDisplay = display.driverData;
383 if(d3dSystem.inScene)
385 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
386 d3dSystem.inScene = false;
389 if(d3dDisplay.backBuffer)
390 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
392 if(d3dDisplay.depthSurface)
393 IDirect3DSurface9_Release(d3dDisplay.depthSurface);
395 if(d3dDisplay.swapChain)
396 IDirect3DSwapChain9_Release(d3dDisplay.swapChain);
399 display.driverData = null;
402 bool CreateDisplay(Display display)
405 DisplaySystem displaySystem = display.displaySystem;
406 D3DSystem d3dSystem = displaySystem.driverData;
407 display.driverData = D3DDisplay { };
409 d3dSystem.ready = false;
416 bool DisplaySize(Display display, int width, int height)
419 DisplaySystem displaySystem = display.displaySystem;
420 D3DSystem d3dSystem = displaySystem.driverData;
421 D3DDisplay d3dDisplay = display.driverData;
422 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
424 d3dSystem.ready = false;
426 if(d3dDisplay.backBuffer)
428 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
429 d3dDisplay.backBuffer = null;
432 if(d3dDisplay.depthSurface)
434 IDirect3DSurface9_Release(d3dDisplay.depthSurface);
435 d3dDisplay.depthSurface = null;
438 if(d3dDisplay.swapChain)
440 IDirect3DSwapChain9_Release(d3dDisplay.swapChain);
441 d3dDisplay.swapChain = null;
447 if(displaySystem.flags.fullScreen)
449 d3dSystem.d3dpp.BackBufferWidth = width;
450 d3dSystem.d3dpp.BackBufferHeight = height;
452 result = !IDirect3DDevice9_Reset(d3dSystem.d3dDevice, &d3dSystem.d3dpp);
454 result = !IDirect3DDevice9_GetSwapChain(d3dSystem.d3dDevice, 0, &d3dDisplay.swapChain);
458 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;
459 d3dDisplay.d3dpp.BackBufferWidth = width;
460 d3dDisplay.d3dpp.BackBufferHeight = height;
461 d3dDisplay.d3dpp.Windowed = TRUE;
462 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
463 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
464 d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
466 //d3dDisplay.d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
467 d3dDisplay.d3dpp.BackBufferFormat = d3dSystem.format;
468 d3dDisplay.d3dpp.BackBufferCount = 1;
469 d3dDisplay.d3dpp.hDeviceWindow = display.window;
470 d3dDisplay.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
471 d3dDisplay.d3dpp.PresentationInterval = d3dDisplay.vSync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_DONOTWAIT;
472 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
473 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
475 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
476 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
480 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
481 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
482 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
486 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
487 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
488 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
494 if(!IDirect3DSwapChain9_GetBackBuffer(d3dDisplay.swapChain,
495 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
497 if(!IDirect3DDevice9_CreateDepthStencilSurface(d3dSystem.d3dDevice, width, height,
498 D3DFMT_D16, d3dDisplay.d3dpp.MultiSampleType,0,TRUE,&d3dDisplay.depthSurface, null))
501 d3dSystem.ready = true;
508 float fogDensity = 0;
510 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decl2D);
512 //IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
513 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
514 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
515 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
516 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
517 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
518 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
519 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGTABLEMODE, D3DFOG_EXP);
520 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGDENSITY, RenderStateFloat { fogDensity }.ui);
521 display.ambient = Color { 50,50,50 };
522 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_NORMALIZENORMALS, TRUE);
523 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
525 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
526 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
527 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
528 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
529 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
530 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
532 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
533 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
534 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
536 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
537 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
539 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
544 display.width = width;
545 display.height = height;
546 d3dDisplay.updateBox.left = display.width;
547 d3dDisplay.updateBox.top = display.height;
548 d3dDisplay.updateBox.right = 0;
549 d3dDisplay.updateBox.bottom = 0;
554 void DisplayPosition(Display display, int x, int y)
559 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
563 void RestorePalette(Display display)
567 void StartUpdate(Display display)
571 void EndUpdate(Display display)
575 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
579 void Update(Display display, Box updateBox)
581 DisplaySystem displaySystem = display.displaySystem;
582 D3DSystem d3dSystem = displaySystem.driverData;
583 D3DDisplay d3dDisplay = display.driverData;
586 //eSystem_Sleep(0.05);
587 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
589 if(display.displaySystem.flags.flipping)
591 // IDirect3DDevice9_Present(d3dSystem.d3dDevice, null, null, null, null);
592 IDirect3DSwapChain9_Present(d3dDisplay.swapChain, null, null, null, null, 0);
598 if(updateBox != null)
600 source.left = dest.left = updateBox.left;
601 source.top = dest.top = updateBox.top;
602 source.right = dest.right = updateBox.right+1;
603 source.bottom = dest.bottom = updateBox.bottom+1;
607 source.left = dest.left = d3dDisplay.updateBox.left;
608 source.top = dest.top = d3dDisplay.updateBox.top;
609 source.right = dest.right = d3dDisplay.updateBox.right+1;
610 source.bottom = dest.bottom = d3dDisplay.updateBox.bottom+1;
612 if(dest.bottom > dest.top && dest.right > dest.left)
613 IDirect3DDevice9_Present(d3dSystem.d3dDevice, &source, &dest, null, null);
614 if(updateBox == null)
616 d3dDisplay.updateBox.left = display.width;
617 d3dDisplay.updateBox.top = display.height;
618 d3dDisplay.updateBox.right = 0;
619 d3dDisplay.updateBox.bottom = 0;
622 d3dSystem.inScene = false;
626 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
630 Bitmap lfbBitmap { };
632 if(LockDisplay(display, null, lfbBitmap, &lfbSurface))
635 if(bitmap.pixelFormat != lfbBitmap.pixelFormat || bitmap.width < w || bitmap.height < h)
638 bitmap.Allocate(null, w,h,w, lfbBitmap.pixelFormat, false);
640 surface = bitmap.GetSurface(0, 0, null);
643 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, surface, lfbBitmap, 0, 0, x, y, w, h);
647 UnlockDisplay(display, lfbSurface);
650 lfbBitmap.picture = null;
658 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
661 IDirect3DTexture9_Release((IDirect3DTexture9 *)bitmap.picture);
664 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
669 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
672 D3DSystem d3dSystem = displaySystem.driverData;
673 if(bitmap.Convert(null, pixelFormat888, null))
675 IDirect3DTexture9 * texture;
676 uint w = pow2i(Min(bitmap.width, 512)), h = pow2i(Min(bitmap.height, 512));
678 if(!IDirect3DDevice9_CreateTexture(d3dSystem.d3dDevice, w, h, mipMaps ? log2i(Max(w+1, h+1)) : 1, 0,
679 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, null))
685 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
687 D3DSURFACE_DESC desc;
688 D3DLOCKED_RECT lockedRect;
690 if(!IDirect3DTexture9_GetLevelDesc(texture, level, &desc) &&
691 !IDirect3DTexture9_LockRect(texture, level, &lockedRect, null, 0))
696 mipMap.width = desc.Width;
697 mipMap.height = desc.Height;
698 mipMap.picture = lockedRect.pBits;
701 case D3DFMT_R5G6B5: mipMap.pixelFormat = pixelFormat565; break;
702 case D3DFMT_A8R8G8B8: mipMap.pixelFormat = pixelFormat888; break;
703 case D3DFMT_A1R5G5B5: mipMap.pixelFormat = pixelFormat555; break;
709 mipMap.stride = lockedRect.Pitch >> GetColorDepthShifts(mipMap.pixelFormat);
711 mipSurface = mipMap.GetSurface(0,0,null);
714 if(mipMap.width != bitmap.width || mipMap.height != bitmap.height)
715 mipSurface.Filter(bitmap, 0,0, 0,0, mipMap.width, mipMap.height, bitmap.width, bitmap.height);
718 //FillBytesBy4(mipMap.picture, bitmap.picture, mipMap.width * mipMap.height);
719 mipSurface.Blit(bitmap, 0,0, 0,0, bitmap.width, bitmap.height);
725 IDirect3DTexture9_UnlockRect(texture, level);
727 mipMap.picture = null;
733 bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
734 bitmap.driver = displaySystem.driver;
735 bitmap.picture = (void *)texture;
738 FreeBitmap(displaySystem, bitmap);
744 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
747 D3DDisplay d3dDisplay = display.driverData;
748 DisplaySystem displaySystem = display.displaySystem;
749 D3DSystem d3dSystem = displaySystem.driverData;
750 D3DSurface d3dSurface = surface.driverData = D3DSurface { };
752 if(d3dSurface && d3dSystem.ready)
754 surface.unclippedBox = surface.box = clip;
755 surface.offset.x = x;
756 surface.offset.y = y;
758 d3dDisplay.updateBox.left = Min(x + clip.left, d3dDisplay.updateBox.left);
759 d3dDisplay.updateBox.top = Min(y + clip.top, d3dDisplay.updateBox.top);
760 d3dDisplay.updateBox.right = Max(x + clip.right, d3dDisplay.updateBox.right);
761 d3dDisplay.updateBox.bottom = Max(y + clip.bottom, d3dDisplay.updateBox.bottom);
763 SetViewportAndMatrices(display, x,y, surface.box);
770 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
775 void ReleaseSurface(Display display, Surface surface)
777 delete surface.driverData;
780 void Clip(Display display, Surface surface, Box clip)
787 box.Clip(surface.unclippedBox);
791 box = surface.box = surface.unclippedBox;
793 SetViewportAndMatrices(display, surface.offset.x, surface.offset.y, box);
796 void SetForeground(Display display, Surface surface, ColorAlpha color)
801 void SetBackground(Display display, Surface surface, ColorAlpha color)
803 D3DSurface d3dSurface = surface.driverData;
804 d3dSurface.background = color;
807 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
812 void PutPixel(Display display, Surface surface,int x, int y)
814 DisplaySystem displaySystem = display.displaySystem;
815 D3DSystem d3dSystem = displaySystem.driverData;
816 Vertex vertex { (float)x, (float)y, 1.0f, surface.foreground, 0, 0 };
818 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_POINTLIST, 1,
819 &vertex, sizeof(Vertex));
822 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
824 DisplaySystem displaySystem = display.displaySystem;
825 D3DSystem d3dSystem = displaySystem.driverData;
828 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
829 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 }
849 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 1,
850 vertex, sizeof(Vertex));
853 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
855 DisplaySystem displaySystem = display.displaySystem;
856 D3DSystem d3dSystem = displaySystem.driverData;
859 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
860 { (float)x2, (float)y1, 1.0f, surface.foreground, 0, 0 },
861 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 },
862 { (float)x1, (float)y2, 1.0f, surface.foreground, 0, 0 },
863 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 }
866 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 4,
867 vertex, sizeof(Vertex));
871 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
873 DisplaySystem displaySystem = display.displaySystem;
874 D3DSystem d3dSystem = displaySystem.driverData;
875 D3DSurface d3dSurface = surface.driverData;
879 { (float)x1, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
880 { (float)x2 + 1.0f, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
881 { (float)x1, (float)y2, 1.0f, d3dSurface.background, 0, 0 },
882 { (float)x2 + 1.0f, (float)y2, 1.0f, d3dSurface.background, 0, 0 }
884 { (float)x1, (float)y1 - 0.5f, 1.0f, d3dSurface.background, 0, 0 },
885 { (float)x2 + 1.0f, (float)y1 - 0.5f, 1.0f, d3dSurface.background, 0, 0 },
886 { (float)x1, (float)y2 + 1.5f, 1.0f, d3dSurface.background, 0, 0 },
887 { (float)x2 + 1.0f, (float)y2 + 1.5f, 1.0f, d3dSurface.background, 0, 0 }
890 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
891 vertex, sizeof(Vertex));
894 void Clear(Display display, Surface surface, ClearType type)
896 DisplaySystem displaySystem = display.displaySystem;
897 D3DSystem d3dSystem = displaySystem.driverData;
898 D3DSurface d3dSurface = surface.driverData;
899 IDirect3DDevice9_Clear(d3dSystem.d3dDevice, 0, null,
900 ((type == depthBuffer) ? 0 : D3DCLEAR_TARGET) |
901 ((type == colorBuffer) ? 0 : D3DCLEAR_ZBUFFER),
902 d3dSurface.background, 1,0);
905 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
910 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
912 DisplaySystem displaySystem = display.displaySystem;
913 D3DSystem d3dSystem = displaySystem.driverData;
914 D3DSurface d3dSurface = surface.driverData;
915 Color foreground = d3dSurface.writingText ? surface.foreground : white;
918 { (float)dx, (float)dy, 1.0f, foreground,
919 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
920 { (float)(dx+w), (float)dy, 1.0f, foreground,
921 (float)(sx+w)/ (src.width-1), (float)sy/ (src.height-1) },
922 { (float)dx, (float)(dy+h), 1.0f, foreground,
923 (float)sx/ (src.width-1), (float)(sy+h)/ (src.height-1) },
924 { (float)(dx+w), (float)(dy+h), 1.0f, foreground,
925 (float)(sx+w) / (src.width-1), (float)(sy+h)/ (src.height-1) }
928 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture9 *)src.picture);
929 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
930 vertex, sizeof(Vertex));
931 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, null);
934 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
936 DisplaySystem displaySystem = display.displaySystem;
937 D3DSystem d3dSystem = displaySystem.driverData;
940 { (float)dx, (float)dy, 1.0f, surface.foreground,
941 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
942 { (float)(dx+w), (float)dy, 1.0f, surface.foreground,
943 (float)(sx+sw)/ (src.width-1), (float)sy/ (src.height-1) },
944 { (float)dx, (float)(dy+h), 1.0f, surface.foreground,
945 (float)sx/ (src.width-1), (float)(sy+sh)/ (src.height-1) },
946 { (float)(dx+w), (float)(dy+h), 1.0f, surface.foreground,
947 (float)(sx+sw) / (src.width-1), (float)(sy+sh)/ (src.height-1) }
950 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture9 *)src.picture);
951 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
952 vertex, sizeof(Vertex));
953 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, null);
956 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
958 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
961 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
964 Bitmap lfbBitmap { };
965 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
967 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Stretch(null, lfbSurface, src, dx, dy, sx, sy, w, h, sw, sh);
968 UnlockDisplay(display, lfbSurface);
970 lfbBitmap.picture = null;
974 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
977 Bitmap lfbBitmap { };
978 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
980 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, lfbSurface, src, dx, dy, sx, sy, w, h);
981 UnlockDisplay(display, lfbSurface);
983 lfbBitmap.picture = null;
987 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
989 StretchDI(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
992 void UnloadFont(DisplaySystem displaySystem, Font font)
994 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
997 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
999 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
1002 void TextFont(Display display, Surface surface, Font font)
1004 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
1007 void TextOpacity(Display display, Surface surface, bool opaque)
1009 D3DSurface d3dSurface = surface.driverData;
1010 d3dSurface.opaqueText = opaque;
1013 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
1015 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
1018 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
1020 DisplaySystem displaySystem = display.displaySystem;
1021 D3DSystem d3dSystem = displaySystem.driverData;
1022 D3DSurface d3dSurface = surface.driverData;
1024 if(surface.textOpacity)
1027 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
1029 int x1 = x, y1 = y, x2 = x+w-1, y2 = y+h-1;
1032 { (float)x1, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1033 { (float)x2 + 1.0f, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1034 { (float)x1, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 },
1035 { (float)x2 + 1.0f, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 }
1038 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
1039 vertex, sizeof(Vertex));
1041 //display.displaySystem.driver.Area(display, surface, x, y, x+w-1, y+h-1);
1044 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1045 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1046 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1047 d3dSurface.writingText = true;
1049 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
1051 d3dSurface.writingText = false;
1052 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
1053 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1054 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1057 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
1059 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, width, height);
1062 void DrawingChar(Display display, Surface surface, char character)
1067 void LineStipple(Display display, Surface surface, uint stipple)
1070 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_LINEPATTERN,
1071 stipple?Muint(1,stipple):0);
1076 void SetRenderState(Display display, RenderState state, uint value)
1078 DisplaySystem displaySystem = display.displaySystem;
1079 D3DSystem d3dSystem = displaySystem.driverData;
1080 D3DDisplay d3dDisplay = display.driverData;
1084 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, value ? TRUE : FALSE);
1087 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FILLMODE,
1088 ((FillModeValue)value == solid) ? D3DFILL_SOLID : D3DFILL_WIREFRAME);
1091 // IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_USEW : D3DZB_FALSE);
1092 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_TRUE : D3DZB_FALSE);
1095 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZWRITEENABLE, value);
1098 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGCOLOR, value);
1102 float fogDensity = RenderStateFloat { ui = value }.f;
1103 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGDENSITY, RenderStateFloat { fogDensity }.ui);
1107 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ALPHABLENDENABLE, value);
1110 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_AMBIENT, value);
1114 if(d3dDisplay.vSync != (bool)value)
1116 d3dDisplay.vSync = (bool)value;
1117 DisplaySize(display, display.width, display.height);
1124 void SetLight(Display display, int id, Light light)
1126 DisplaySystem displaySystem = display.displaySystem;
1127 D3DSystem d3dSystem = displaySystem.driverData;
1128 D3DDisplay d3dDisplay = display.driverData;
1131 D3DLIGHT9 d3dLight =
1133 // Opacity on the light?
1134 D3DLIGHT_DIRECTIONAL,
1135 { light.diffuse.r, light.diffuse.g, light.diffuse.b, 1.0f },
1136 { light.specular.r, light.specular.g, light.specular.b, 1.0f },
1137 { light.ambient.r, light.ambient.g, light.ambient.b, 1.0f }
1139 Vector3Df vector {0,0,1};
1140 Vector3Df vectorPI {0,0,-1};
1141 Vector3Df direction;
1143 Vector3Df * lightDirection = (Vector3Df *)&d3dLight.Direction;
1145 mat.RotationQuaternion(light.orientation);
1147 direction.MultMatrix(vector, mat);
1148 if(!display.display3D || !display.display3D.camera)
1150 d3dLight.Direction.x = direction.x;
1151 d3dLight.Direction.y = direction.y;
1152 d3dLight.Direction.z =-direction.z;
1155 lightDirection->MultMatrix(direction, d3dDisplay.worldMatrix);
1157 d3dDisplay.lights[id] = d3dLight;
1159 IDirect3DDevice9_LightEnable(d3dSystem.d3dDevice, id, TRUE);
1160 IDirect3DDevice9_SetLight(d3dSystem.d3dDevice, id, &d3dDisplay.lights[id] /*d3dLight*/);
1162 direction.MultMatrix(vectorPI, mat);
1163 lightDirection->MultMatrix(direction, d3dDisplay.worldMatrix);
1165 d3dDisplay.lightsPI[id] = d3dLight;
1169 IDirect3DDevice9_LightEnable(d3dSystem.d3dDevice, id, FALSE);
1170 d3dDisplay.lights[id].Type = 0;
1174 void SetCamera(Display display, Surface surface, Camera camera)
1176 DisplaySystem displaySystem = display.displaySystem;
1177 D3DSystem d3dSystem = displaySystem.driverData;
1178 D3DDisplay d3dDisplay = display.driverData;
1179 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1182 Point topLeft {surface.box.left + surface.offset.x, surface.box.top + surface.offset.y};
1183 Point downRight {surface.box.right + surface.offset.x, surface.box.bottom + surface.offset.y};
1186 surface.offset.x + camera.origin.x,
1187 surface.offset.y + camera.origin.y
1191 float l = (topLeft.x - origin.x) * camera.zMin / camera.focalX;
1192 float r = (downRight.x - origin.x) * camera.zMin / camera.focalX;
1193 float b = (downRight.y - origin.y) * camera.zMin / camera.focalY;
1194 float t = (topLeft.y - origin.y) * camera.zMin / camera.focalY;
1195 float n = camera.zMin;
1196 float f = camera.zMax;
1198 matProj.m[0][0] = 2 * n / (r - l);
1199 matProj.m[0][1] = 0;
1200 matProj.m[0][2] = 0;
1201 matProj.m[0][3] = 0;
1203 matProj.m[1][0] = 0;
1204 matProj.m[1][1] = 2 * n / (t - b);
1205 matProj.m[1][2] = 0;
1206 matProj.m[1][3] = 0;
1208 matProj.m[2][0] = (l + r) / (r - l);
1209 matProj.m[2][1] = (t + b) / (t - b);
1210 matProj.m[2][2] = f / (n - f);
1211 matProj.m[2][3] = -1;
1213 matProj.m[3][0] = 0;
1214 matProj.m[3][1] = 0;
1215 matProj.m[3][2] = n * f / (n - f);
1216 matProj.m[3][3] = 0;
1218 IDirect3DDevice9_SetTransform(d3dDevice, D3DTS_PROJECTION, &matProj);
1220 // *** View Matrix ***
1221 if(!display.display3D.camera)
1222 d3dDisplay.worldMatrix++;
1225 matrix.Scale(1.0f, 1.0f, -1.0f);
1226 d3dDisplay.worldMatrix->Multiply(camera.viewMatrix, matrix);
1228 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1230 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decls[0]);
1232 // IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_USEW);
1233 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_TRUE);
1234 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZWRITEENABLE, TRUE);
1235 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, FALSE);
1236 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, TRUE);
1237 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, TRUE);
1239 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1241 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
1243 else if(display.display3D.camera)
1245 d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
1246 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1247 IDirect3DDevice9_SetTransform(d3dDevice, D3DTS_PROJECTION, &d3dDisplay.projMatrix);
1249 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
1250 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
1251 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
1252 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
1253 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGENABLE, FALSE);
1254 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, FALSE);
1256 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1257 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1259 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decl2D);
1261 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
1263 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
1267 void ApplyMaterial(Display display, Material material, Mesh mesh)
1269 DisplaySystem displaySystem = display.displaySystem;
1270 D3DSystem d3dSystem = displaySystem.driverData;
1271 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1272 D3DMesh d3dMesh = mesh.data;
1275 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGENABLE, (material.flags.noFog) ? FALSE : TRUE);
1278 if(material.baseMap && d3dMesh.texCoords && material.baseMap.driver.displaySystem == displaySystem)
1280 Bitmap map = material.baseMap;
1282 IDirect3DDevice9_SetTexture(d3dDevice, 0, (IDirect3DBaseTexture9 *)map.picture);
1284 if(material.flags.tile)
1286 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
1287 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
1291 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1292 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1296 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
1299 D3DMATERIAL9 d3dMaterial;
1301 d3dMaterial.Diffuse.r = material.diffuse.r;
1302 d3dMaterial.Diffuse.g = material.diffuse.g;
1303 d3dMaterial.Diffuse.b = material.diffuse.b;
1304 d3dMaterial.Diffuse.a = material.opacity;
1306 d3dMaterial.Ambient.r = material.ambient.r;
1307 d3dMaterial.Ambient.g = material.ambient.g;
1308 d3dMaterial.Ambient.b = material.ambient.b;
1309 d3dMaterial.Ambient.a = 1;
1311 d3dMaterial.Specular.r = material.specular.r;
1312 d3dMaterial.Specular.g = material.specular.g;
1313 d3dMaterial.Specular.b = material.specular.b;
1314 d3dMaterial.Specular.a = 1;
1316 d3dMaterial.Emissive.r = material.emissive.r;
1317 d3dMaterial.Emissive.g = material.emissive.g;
1318 d3dMaterial.Emissive.b = material.emissive.b;
1319 d3dMaterial.Emissive.a = 1;
1321 d3dMaterial.Power = material.power;
1323 IDirect3DDevice9_SetMaterial(d3dDevice, &d3dMaterial); //(D3DMATERIAL9 *)&material.diffuse
1327 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
1329 D3DMesh d3dMesh = mesh.data;
1332 if(!(mesh.flags.vertices))
1334 if(d3dMesh.vertices)
1336 IDirect3DVertexBuffer9_Release(d3dMesh.vertices);
1337 d3dMesh.vertices = null;
1339 delete mesh.vertices;
1341 if(!(mesh.flags.normals))
1345 IDirect3DVertexBuffer9_Release(d3dMesh.normals);
1346 d3dMesh.normals = null;
1348 delete mesh.normals;
1350 if(!(mesh.flags.texCoords1))
1352 if(d3dMesh.texCoords)
1354 IDirect3DVertexBuffer9_Release(d3dMesh.texCoords);
1355 d3dMesh.texCoords = null;
1357 delete mesh.texCoords;
1359 if(!(mesh.flags.texCoords2))
1361 if(d3dMesh.texCoords2)
1363 IDirect3DVertexBuffer9_Release(d3dMesh.texCoords2);
1364 d3dMesh.texCoords2 = null;
1366 // delete mesh.texCoords2;
1376 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh)
1378 D3DSystem d3dSystem = displaySystem.driverData;
1379 bool result = false;
1380 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1383 mesh.data = D3DMesh { };
1386 D3DMesh d3dMesh = mesh.data;
1388 if((mesh.flags.vertices) && !d3dMesh.vertices)
1390 mesh.vertices = new Vector3Df[mesh.nVertices];
1391 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * mesh.nVertices,
1392 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices, null))
1395 if((mesh.flags.normals) && !d3dMesh.normals)
1397 mesh.normals = new Vector3Df[mesh.nVertices];
1398 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * mesh.nVertices,
1399 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals, null))
1402 if((mesh.flags.texCoords1) && !d3dMesh.texCoords)
1404 mesh.texCoords = new Pointf[mesh.nVertices];
1405 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * mesh.nVertices,
1406 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords, null))
1413 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1415 D3DMesh d3dMesh = mesh.data;
1416 if(!flags) flags = mesh.flags;
1418 if(flags.vertices && mesh.vertices)
1420 Vector3Df * vertices;
1421 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.vertices, 0, 0, (void **) &vertices, 0))
1423 memcpy(vertices, mesh.vertices, mesh.nVertices * sizeof(Vector3Df));
1424 IDirect3DVertexBuffer9_Unlock(d3dMesh.vertices);
1427 if(flags.normals && mesh.normals)
1429 Vector3Df * normals;
1430 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.normals, 0, 0, (void **) &normals, 0))
1432 memcpy(normals, mesh.normals, mesh.nVertices * sizeof(Vector3Df));
1433 IDirect3DVertexBuffer9_Unlock(d3dMesh.normals);
1436 if(flags.texCoords1 && mesh.texCoords)
1439 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.texCoords, 0, 0, (void **) &texCoords, 0))
1441 memcpy(texCoords, mesh.texCoords, mesh.nVertices * sizeof(Pointf));
1442 IDirect3DVertexBuffer9_Unlock(d3dMesh.texCoords);
1447 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1453 void FreeIndices(DisplaySystem displaySystem, D3DIndices d3dIndices)
1457 if(d3dIndices.buffer)
1458 IDirect3DIndexBuffer9_Release(d3dIndices.buffer);
1459 delete d3dIndices.indices;
1464 D3DIndices AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
1466 D3DSystem d3dSystem = displaySystem.driverData;
1467 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1468 D3DIndices d3dIndices { };
1469 if(d3dIndices && nIndices)
1471 d3dIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
1472 IDirect3DDevice9_CreateIndexBuffer(d3dDevice, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * nIndices, 0, indices32bit ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
1473 D3DPOOL_MANAGED, &d3dIndices.buffer, null);
1474 d3dIndices.nIndices = nIndices;
1479 void UnlockIndices(DisplaySystem displaySystem, D3DIndices d3dIndices, bool indices32bit, int nIndices)
1481 uint16 * indexBuffer = null;
1482 if(!IDirect3DIndexBuffer9_Lock(d3dIndices.buffer, 0, 0, (void **)&indexBuffer, 0))
1484 memcpy(indexBuffer, d3dIndices.indices, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * d3dIndices.nIndices);
1485 IDirect3DIndexBuffer9_Unlock(d3dIndices.buffer);
1489 uint16 * LockIndices(DisplaySystem displaySystem, D3DIndices d3dIndices)
1491 return d3dIndices.indices;
1494 void SelectMesh(Display display, Mesh mesh)
1496 DisplaySystem displaySystem = display.displaySystem;
1497 D3DSystem d3dSystem = displaySystem.driverData;
1498 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1500 if(mesh && mesh.data)
1503 D3DMesh d3dMesh = mesh.data;
1505 IDirect3DDevice9_SetStreamSource(d3dDevice, 0, d3dMesh.vertices, 0, sizeof(Vector3Df));
1508 IDirect3DDevice9_SetStreamSource(d3dDevice, 1, d3dMesh.normals, 0, sizeof(Vector3Df));
1512 IDirect3DDevice9_SetStreamSource(d3dDevice, 1, null, 0, sizeof(Vector3Df));
1513 if(d3dMesh.texCoords)
1515 IDirect3DDevice9_SetStreamSource(d3dDevice, 2, d3dMesh.texCoords, 0, sizeof(Pointf));
1519 IDirect3DDevice9_SetStreamSource(d3dDevice, 2, null, 0, sizeof(Pointf));
1521 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decls[decl]);
1525 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
1527 DisplaySystem displaySystem = display.displaySystem;
1528 D3DSystem d3dSystem = displaySystem.driverData;
1529 D3DDisplay d3dDisplay = display.driverData;
1530 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1532 if(primitiveTypes[primitive->type.primitiveType])
1534 int numPrimitives = (primitive->type.vertexRange) ? primitive->nVertices : primitive->nIndices;
1537 switch(primitive->type.primitiveType)
1539 case lines: numPrimitives /= 2; break;
1540 case triangles: numPrimitives /= 3; break;
1552 if(primitive->type.vertexRange)
1554 if(primitive->type.primitiveType == quads)
1556 for(c = 0; c<numPrimitives; c++)
1557 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1560 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1564 D3DIndices indices = primitive->data;
1565 IDirect3DDevice9_SetIndices(d3dDevice, indices.buffer);
1566 if(primitive->type.primitiveType == quads)
1568 for(c = 0; c<numPrimitives; c++)
1569 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, c*4, 2);
1572 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, 0, numPrimitives);
1575 if(display.display3D.material.flags.doubleSided)
1577 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CCW);
1578 if(!display.display3D.material.flags.singleSideLight)
1580 for(c = 0; c<NumberOfLights; c++)
1581 if(d3dDisplay.lights[c].Type)
1582 IDirect3DDevice9_SetLight(d3dDevice, c, &d3dDisplay.lightsPI[c]);
1585 if(primitive->type.vertexRange)
1587 if(primitive->type.primitiveType == quads)
1589 for(c = 0; c<numPrimitives; c++)
1590 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1593 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1597 D3DIndices indices = primitive->data;
1598 IDirect3DDevice9_SetIndices(d3dDevice, indices.buffer);
1599 if(primitive->type.primitiveType == quads)
1601 for(c = 0; c<numPrimitives; c++)
1602 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, c*4, 2);
1605 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, 0, numPrimitives);
1607 if(!display.display3D.material.flags.singleSideLight)
1609 for(c = 0; c<NumberOfLights; c++)
1610 if(d3dDisplay.lights[c].Type)
1611 IDirect3DDevice9_SetLight(d3dDevice, c, &d3dDisplay.lights[c]);
1614 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1619 void PushMatrix(Display display)
1621 D3DDisplay d3dDisplay = display.driverData;
1622 *(d3dDisplay.worldMatrix+1) = *(d3dDisplay.worldMatrix);
1623 d3dDisplay.worldMatrix++;
1626 void PopMatrix(Display display, bool setMatrix)
1628 D3DDisplay d3dDisplay = display.driverData;
1629 DisplaySystem displaySystem = display.displaySystem;
1630 D3DSystem d3dSystem = displaySystem.driverData;
1631 d3dDisplay.worldMatrix--;
1633 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1636 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
1638 DisplaySystem displaySystem = display.displaySystem;
1639 D3DSystem d3dSystem = displaySystem.driverData;
1640 Camera camera = useCamera ? display.display3D.camera : null;
1641 D3DDisplay d3dDisplay = display.driverData;
1642 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1644 Matrix matrix = transMatrix, temp;
1648 matrix.Scale(1.0f, 1.0f, -1.0f);
1649 *(d3dDisplay.worldMatrix) = matrix;
1655 - camera.cPosition.x,
1656 - camera.cPosition.y,
1657 - camera.cPosition.z);
1658 temp.Multiply(matrix, d3dDisplay.worldMatrix);
1659 *(d3dDisplay.worldMatrix) = temp;
1662 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1665 bool Lock(Display display)
1667 DisplaySystem displaySystem = display.displaySystem;
1668 D3DSystem d3dSystem = displaySystem.driverData;
1669 D3DDisplay d3dDisplay = display.driverData;
1671 if(d3dDisplay.backBuffer)
1673 IDirect3DDevice9_SetDepthStencilSurface(d3dSystem.d3dDevice, d3dDisplay.depthSurface);
1674 IDirect3DDevice9_SetRenderTarget(d3dSystem.d3dDevice, 0, d3dDisplay.backBuffer);
1675 IDirect3DDevice9_BeginScene(d3dSystem.d3dDevice);
1677 d3dSystem.inScene = true;
1682 void Unlock(Display display)
1684 DisplaySystem displaySystem = display.displaySystem;
1685 D3DSystem d3dSystem = displaySystem.driverData;
1687 if(d3dSystem.inScene)
1689 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
1690 d3dSystem.inScene = false;