1 namespace gfx::drivers;
7 #ifndef D3DPRESENT_DONOTWAIT
8 #define D3DPRESENT_DONOTWAIT 0x00000001L
11 #define D3D_DEBUG_INFO 1
13 #define Method _Method
17 #define String _String
20 #define Platform _Platform
24 #if defined(__MINGW32__) && !defined(_W64)
25 #undef DECLARE_INTERFACE
26 #define DECLARE_INTERFACE(i) \
27 interface i { CONST_VTABLE struct i##Vtbl *lpVtbl; }; \
28 typedef CONST_VTABLE struct i##Vtbl i##Vtbl; \
29 CONST_VTABLE struct i##Vtbl
45 #define MATRIX_STACK_SIZE 32
47 #define NUM_VERTEX_DECLS 4
49 static class D3DDisplay : struct
52 IDirect3DSwapChain9 * swapChain;
53 Matrix worldMatrixStack[MATRIX_STACK_SIZE];
56 D3DLIGHT9 lights[NumberOfLights], lightsPI[NumberOfLights];
57 D3DPRESENT_PARAMETERS d3dpp;
58 IDirect3DSurface9 * backBuffer, * depthSurface;
62 static class D3DSystem : struct
65 IDirect3D9 * direct3D;
66 IDirect3DDevice9 * d3dDevice;
67 IDirect3D9 * (WINAPI * direct3DCreate9)(UINT);
69 D3DPRESENT_PARAMETERS d3dpp;
71 IDirect3DVertexDeclaration9 * decls[NUM_VERTEX_DECLS], * decl2D;
78 static class D3DSurface : struct
80 // For compatibility with LFB driver
86 ColorAlpha background;
89 static class D3DMesh : struct
91 IDirect3DVertexBuffer9 * vertices;
92 IDirect3DVertexBuffer9 * normals;
93 IDirect3DVertexBuffer9 * texCoords;
94 IDirect3DVertexBuffer9 * texCoords2;
104 static class D3DIndices : struct
107 IDirect3DIndexBuffer9 * buffer;
111 static int primitiveTypes[RenderPrimitiveType] =
113 D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP, D3DPT_TRIANGLEFAN, D3DPT_TRIANGLEFAN, 0, D3DPT_LINESTRIP
116 static void SetTransformMatrix(IDirect3DDevice9 * device, Matrix matrix)
122 (float)matrix.m[0][0], (float)matrix.m[0][1], (float)matrix.m[0][2], (float)matrix.m[0][3],
123 (float)matrix.m[1][0], (float)matrix.m[1][1], (float)matrix.m[1][2], (float)matrix.m[1][3],
124 (float)matrix.m[2][0], (float)matrix.m[2][1], (float)matrix.m[2][2], (float)matrix.m[2][3],
125 (float)matrix.m[3][0], (float)matrix.m[3][1], (float)matrix.m[3][2], (float)matrix.m[3][3]
129 IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &d3dMat);
132 class Direct3D9DisplayDriver : DisplayDriver
134 class_property(name) = "Direct3D";
137 bool ::LockDisplay(Display display, Surface surface, Bitmap lfbBitmap, Surface * lfbSurface)
140 D3DDisplay d3dDisplay = display.driverData;
142 //if(!IDirect3DDevice9_GetBackBuffer(d3dSystem.d3dDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
144 D3DLOCKED_RECT lockedRect;
145 if(!IDirect3DSurface9_LockRect(d3dDisplay.backBuffer, &lockedRect, null, 0))
148 switch(d3dDisplay.d3dpp.BackBufferFormat)
150 case D3DFMT_A8R8G8B8:
151 case D3DFMT_X8R8G8B8:
152 lfbBitmap.pixelFormat = pixelFormat888;
155 lfbBitmap.pixelFormat = pixelFormat565;
157 case D3DFMT_X1R5G5B5:
158 case D3DFMT_A1R5G5B5:
159 lfbBitmap.pixelFormat = pixelFormat555;
161 case D3DFMT_A4R4G4B4:
162 case D3DFMT_X4R4G4B4:
163 lfbBitmap.pixelFormat = pixelFormat444;
170 lfbBitmap.driver = null;
171 lfbBitmap.displaySystem = null;
172 lfbBitmap.picture = (byte *)lockedRect.pBits;
173 lfbBitmap.transparent = false;
174 lfbBitmap.stride = lockedRect.Pitch >> GetColorDepthShifts(lfbBitmap.pixelFormat);
175 lfbBitmap.width = display.width;
176 lfbBitmap.height = display.height;
178 *lfbSurface = lfbBitmap.GetSurface(surface ? surface.offset.x : 0, surface ? surface.offset.y : 0, surface ? surface.box : null);
182 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
187 void ::UnlockDisplay(Display display, Surface surface)
189 D3DDisplay d3dDisplay = display.driverData;
190 if(d3dDisplay.backBuffer)
192 IDirect3DSurface9_UnlockRect(d3dDisplay.backBuffer);
193 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
198 void ::SetViewportAndMatrices(Display display, int x, int y, Box box)
200 D3DDisplay d3dDisplay = display.driverData;
201 DisplaySystem displaySystem = display.displaySystem;
202 D3DSystem d3dSystem = displaySystem.driverData;
205 D3DVIEWPORT9 viewport;
208 if(box.right < box.left || box.bottom < box.top)
210 viewport.Width = viewport.Height = 1;
211 viewport.X = viewport.Y = MAXDWORD;
215 viewport.X = x + box.left;
216 viewport.Y = y + box.top;
217 viewport.Width = box.right - box.left + 1;
218 viewport.Height = box.bottom - box.top + 1;
220 if(!IDirect3DDevice9_SetViewport(d3dSystem.d3dDevice, &viewport))
222 D3DMATRIX * matProj = &d3dDisplay.projMatrix;
223 Matrix * matWorld = d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
225 matProj->m[0][0] = 2.0f / viewport.Width;
226 matProj->m[1][1] =-2.0f / viewport.Height;
227 matProj->m[2][2] = matProj->m[3][1] = matProj->m[3][3] = 1;
228 matProj->m[3][0] = -1;
230 IDirect3DDevice9_SetTransform(d3dSystem.d3dDevice, D3DTS_PROJECTION, matProj);
232 matWorld->Identity();
233 matWorld->m[3][0] =-box.left;
234 matWorld->m[3][1] =-box.top;
236 SetTransformMatrix(d3dSystem.d3dDevice, matWorld);
242 bool CreateDisplaySystem(DisplaySystem displaySystem)
245 D3DSystem d3dSystem = displaySystem.driverData = D3DSystem { };
248 displaySystem.flags.alpha = true;
249 //if(displaySystem.flags.fullScreen)
250 displaySystem.flags.flipping = true;
251 displaySystem.pixelFormat = pixelFormat888;
253 d3dSystem.d3dDll = LoadLibrary("d3d9.dll");
256 d3dSystem.direct3DCreate9 = (void *)GetProcAddress(d3dSystem.d3dDll, "Direct3DCreate9");
257 if(d3dSystem.direct3DCreate9)
259 if((d3dSystem.direct3D = d3dSystem.direct3DCreate9(D3D_SDK_VERSION)))
261 D3DDISPLAYMODE d3ddm;
262 if(!IDirect3D9_GetAdapterDisplayMode(d3dSystem.direct3D, D3DADAPTER_DEFAULT, &d3ddm))
264 d3dSystem.d3dpp.BackBufferCount = 1;
266 if(displaySystem.flags.fullScreen)
268 d3dSystem.d3dpp.BackBufferWidth = d3ddm.Width;
269 d3dSystem.d3dpp.BackBufferHeight = d3ddm.Height;
270 d3dSystem.d3dpp.hDeviceWindow = displaySystem.window;
274 d3dSystem.d3dpp.hDeviceWindow = d3dSystem.hwnd =
275 CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
276 d3dSystem.d3dpp.Windowed = TRUE;
279 d3dSystem.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
280 d3dSystem.format = d3dSystem.d3dpp.BackBufferFormat = d3ddm.Format;
281 d3dSystem.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
283 if(!IDirect3D9_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
284 d3dSystem.d3dpp.hDeviceWindow,
285 D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE|D3DCREATE_FPU_PRESERVE,
286 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
290 d3dSystem.usage = D3DUSAGE_SOFTWAREPROCESSING;
291 if(!IDirect3D9_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
292 d3dSystem.d3dpp.hDeviceWindow,
293 D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,
294 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
300 D3DVERTEXELEMENT9 vertexDecls[NUM_VERTEX_DECLS][4] =
303 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
307 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
308 { 1, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 },
312 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
313 { 2, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
317 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
318 { 1, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 },
319 { 2, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
324 D3DVERTEXELEMENT9 vertexDecl2D[] =
326 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
327 { 0, (uint16)(3*sizeof(float)), D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 },
328 { 0, (uint16)(3*sizeof(float) + sizeof(uint)), D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
333 for(c = 0; c<NUM_VERTEX_DECLS; c++)
334 if(IDirect3DDevice9_CreateVertexDeclaration(d3dSystem.d3dDevice, vertexDecls[c], &d3dSystem.decls[c]))
337 if(c < NUM_VERTEX_DECLS ||
338 IDirect3DDevice9_CreateVertexDeclaration(d3dSystem.d3dDevice, vertexDecl2D, &d3dSystem.decl2D))
342 d3dSystem.ready = false;
348 Log("Couldn't load library d3d9.dll\n");
349 //LogErrorCode(ERR_MISSING_LIBRARY, "d3d9.dll");
354 void DestroyDisplaySystem(DisplaySystem displaySystem)
356 D3DSystem d3dSystem = displaySystem.driverData;
359 if(d3dSystem.d3dDevice)
360 IDirect3DDevice9_Release(d3dSystem.d3dDevice);
362 if(d3dSystem.direct3D)
363 IDirect3D9_Release(d3dSystem.direct3D);
365 for(c = 0; c<NUM_VERTEX_DECLS; c++)
367 if(d3dSystem.decls[c])
368 IDirect3DVertexDeclaration9_Release(d3dSystem.decls[c]);
372 IDirect3DVertexDeclaration9_Release(d3dSystem.decl2D);
374 FreeLibrary(d3dSystem.d3dDll);
377 displaySystem.driverData = null;
381 void DestroyDisplay(Display display)
383 DisplaySystem displaySystem = display.displaySystem;
384 D3DSystem d3dSystem = displaySystem.driverData;
385 D3DDisplay d3dDisplay = display.driverData;
387 if(d3dSystem.inScene)
389 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
390 d3dSystem.inScene = false;
393 if(d3dDisplay.backBuffer)
394 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
396 if(d3dDisplay.depthSurface)
397 IDirect3DSurface9_Release(d3dDisplay.depthSurface);
399 if(d3dDisplay.swapChain)
400 IDirect3DSwapChain9_Release(d3dDisplay.swapChain);
403 display.driverData = null;
406 bool CreateDisplay(Display display)
409 DisplaySystem displaySystem = display.displaySystem;
410 D3DSystem d3dSystem = displaySystem.driverData;
411 display.driverData = D3DDisplay { };
413 d3dSystem.ready = false;
420 bool DisplaySize(Display display, int width, int height)
423 DisplaySystem displaySystem = display.displaySystem;
424 D3DSystem d3dSystem = displaySystem.driverData;
425 D3DDisplay d3dDisplay = display.driverData;
426 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
428 d3dSystem.ready = false;
430 if(d3dDisplay.backBuffer)
432 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
433 d3dDisplay.backBuffer = null;
436 if(d3dDisplay.depthSurface)
438 IDirect3DSurface9_Release(d3dDisplay.depthSurface);
439 d3dDisplay.depthSurface = null;
442 if(d3dDisplay.swapChain)
444 IDirect3DSwapChain9_Release(d3dDisplay.swapChain);
445 d3dDisplay.swapChain = null;
451 if(displaySystem.flags.fullScreen)
453 d3dSystem.d3dpp.BackBufferWidth = width;
454 d3dSystem.d3dpp.BackBufferHeight = height;
456 result = !IDirect3DDevice9_Reset(d3dSystem.d3dDevice, &d3dSystem.d3dpp);
458 result = !IDirect3DDevice9_GetSwapChain(d3dSystem.d3dDevice, 0, &d3dDisplay.swapChain);
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 = d3dDisplay.vSync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_DONOTWAIT;
476 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
477 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
479 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
480 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
484 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
485 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
486 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
490 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
491 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
492 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
498 if(!IDirect3DSwapChain9_GetBackBuffer(d3dDisplay.swapChain,
499 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
501 if(!IDirect3DDevice9_CreateDepthStencilSurface(d3dSystem.d3dDevice, width, height,
502 D3DFMT_D16, d3dDisplay.d3dpp.MultiSampleType,0,TRUE,&d3dDisplay.depthSurface, null))
505 d3dSystem.ready = true;
512 float fogDensity = 0;
514 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decl2D);
516 //IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
517 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
518 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
519 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
520 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
521 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
522 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
523 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGTABLEMODE, D3DFOG_EXP);
524 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGDENSITY, RenderStateFloat { fogDensity }.ui);
525 display.ambient = Color { 50,50,50 };
526 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_NORMALIZENORMALS, TRUE);
527 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
529 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
530 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
531 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
532 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
533 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
534 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
536 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
537 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
538 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
540 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
541 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
543 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
548 display.width = width;
549 display.height = height;
550 d3dDisplay.updateBox.left = display.width;
551 d3dDisplay.updateBox.top = display.height;
552 d3dDisplay.updateBox.right = 0;
553 d3dDisplay.updateBox.bottom = 0;
558 void DisplayPosition(Display display, int x, int y)
563 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
567 void RestorePalette(Display display)
571 void StartUpdate(Display display)
575 void EndUpdate(Display display)
579 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
583 void Update(Display display, Box updateBox)
585 DisplaySystem displaySystem = display.displaySystem;
586 D3DSystem d3dSystem = displaySystem.driverData;
587 D3DDisplay d3dDisplay = display.driverData;
590 //eSystem_Sleep(0.05);
591 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
593 if(display.displaySystem.flags.flipping)
595 // IDirect3DDevice9_Present(d3dSystem.d3dDevice, null, null, null, null);
596 IDirect3DSwapChain9_Present(d3dDisplay.swapChain, null, null, null, null, 0);
602 if(updateBox != null)
604 source.left = dest.left = updateBox.left;
605 source.top = dest.top = updateBox.top;
606 source.right = dest.right = updateBox.right+1;
607 source.bottom = dest.bottom = updateBox.bottom+1;
611 source.left = dest.left = d3dDisplay.updateBox.left;
612 source.top = dest.top = d3dDisplay.updateBox.top;
613 source.right = dest.right = d3dDisplay.updateBox.right+1;
614 source.bottom = dest.bottom = d3dDisplay.updateBox.bottom+1;
616 if(dest.bottom > dest.top && dest.right > dest.left)
617 IDirect3DDevice9_Present(d3dSystem.d3dDevice, &source, &dest, null, null);
618 if(updateBox == null)
620 d3dDisplay.updateBox.left = display.width;
621 d3dDisplay.updateBox.top = display.height;
622 d3dDisplay.updateBox.right = 0;
623 d3dDisplay.updateBox.bottom = 0;
626 d3dSystem.inScene = false;
630 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
634 Bitmap lfbBitmap { };
636 if(LockDisplay(display, null, lfbBitmap, &lfbSurface))
639 if(bitmap.pixelFormat != lfbBitmap.pixelFormat || bitmap.width < w || bitmap.height < h)
642 bitmap.Allocate(null, w,h,w, lfbBitmap.pixelFormat, false);
644 surface = bitmap.GetSurface(0, 0, null);
647 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, surface, lfbBitmap, 0, 0, x, y, w, h);
651 UnlockDisplay(display, lfbSurface);
654 lfbBitmap.picture = null;
662 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
665 IDirect3DTexture9_Release((IDirect3DTexture9 *)bitmap.picture);
668 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
673 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
676 D3DSystem d3dSystem = displaySystem.driverData;
677 if(bitmap.Convert(null, pixelFormat888, null))
679 IDirect3DTexture9 * texture;
680 uint w = pow2i(Min(bitmap.width, 512)), h = pow2i(Min(bitmap.height, 512));
682 if(!IDirect3DDevice9_CreateTexture(d3dSystem.d3dDevice, w, h, mipMaps ? log2i(Max(w+1, h+1)) : 1, 0,
683 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, null))
689 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
691 D3DSURFACE_DESC desc;
692 D3DLOCKED_RECT lockedRect;
694 if(!IDirect3DTexture9_GetLevelDesc(texture, level, &desc) &&
695 !IDirect3DTexture9_LockRect(texture, level, &lockedRect, null, 0))
700 mipMap.width = desc.Width;
701 mipMap.height = desc.Height;
702 mipMap.picture = lockedRect.pBits;
705 case D3DFMT_R5G6B5: mipMap.pixelFormat = pixelFormat565; break;
706 case D3DFMT_A8R8G8B8: mipMap.pixelFormat = pixelFormat888; break;
707 case D3DFMT_A1R5G5B5: mipMap.pixelFormat = pixelFormat555; break;
713 mipMap.stride = lockedRect.Pitch >> GetColorDepthShifts(mipMap.pixelFormat);
715 mipSurface = mipMap.GetSurface(0,0,null);
718 if(mipMap.width != bitmap.width || mipMap.height != bitmap.height)
719 mipSurface.Filter(bitmap, 0,0, 0,0, mipMap.width, mipMap.height, bitmap.width, bitmap.height);
722 //FillBytesBy4(mipMap.picture, bitmap.picture, mipMap.width * mipMap.height);
723 mipSurface.Blit(bitmap, 0,0, 0,0, bitmap.width, bitmap.height);
729 IDirect3DTexture9_UnlockRect(texture, level);
731 mipMap.picture = null;
737 bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
738 bitmap.driver = displaySystem.driver;
739 bitmap.picture = (void *)texture;
742 FreeBitmap(displaySystem, bitmap);
748 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
751 D3DDisplay d3dDisplay = display.driverData;
752 DisplaySystem displaySystem = display.displaySystem;
753 D3DSystem d3dSystem = displaySystem.driverData;
754 D3DSurface d3dSurface = surface.driverData = D3DSurface { };
756 if(d3dSurface && d3dSystem.ready)
758 surface.unclippedBox = surface.box = clip;
759 surface.offset.x = x;
760 surface.offset.y = y;
762 d3dDisplay.updateBox.left = Min(x + clip.left, d3dDisplay.updateBox.left);
763 d3dDisplay.updateBox.top = Min(y + clip.top, d3dDisplay.updateBox.top);
764 d3dDisplay.updateBox.right = Max(x + clip.right, d3dDisplay.updateBox.right);
765 d3dDisplay.updateBox.bottom = Max(y + clip.bottom, d3dDisplay.updateBox.bottom);
767 SetViewportAndMatrices(display, x,y, surface.box);
774 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
779 void ReleaseSurface(Display display, Surface surface)
781 delete surface.driverData;
784 void Clip(Display display, Surface surface, Box clip)
791 box.Clip(surface.unclippedBox);
795 box = surface.box = surface.unclippedBox;
797 SetViewportAndMatrices(display, surface.offset.x, surface.offset.y, box);
800 void SetForeground(Display display, Surface surface, ColorAlpha color)
805 void SetBackground(Display display, Surface surface, ColorAlpha color)
807 D3DSurface d3dSurface = surface.driverData;
808 d3dSurface.background = color;
811 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
816 void PutPixel(Display display, Surface surface,int x, int y)
818 DisplaySystem displaySystem = display.displaySystem;
819 D3DSystem d3dSystem = displaySystem.driverData;
820 Vertex vertex { (float)x, (float)y, 1.0f, surface.foreground, 0, 0 };
822 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_POINTLIST, 1,
823 &vertex, sizeof(Vertex));
826 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
828 DisplaySystem displaySystem = display.displaySystem;
829 D3DSystem d3dSystem = displaySystem.driverData;
832 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
833 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 }
853 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 1,
854 vertex, sizeof(Vertex));
857 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
859 DisplaySystem displaySystem = display.displaySystem;
860 D3DSystem d3dSystem = displaySystem.driverData;
863 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
864 { (float)x2, (float)y1, 1.0f, surface.foreground, 0, 0 },
865 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 },
866 { (float)x1, (float)y2, 1.0f, surface.foreground, 0, 0 },
867 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 }
870 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 4,
871 vertex, sizeof(Vertex));
875 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
877 DisplaySystem displaySystem = display.displaySystem;
878 D3DSystem d3dSystem = displaySystem.driverData;
879 D3DSurface d3dSurface = surface.driverData;
883 { (float)x1, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
884 { (float)x2 + 1.0f, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
885 { (float)x1, (float)y2, 1.0f, d3dSurface.background, 0, 0 },
886 { (float)x2 + 1.0f, (float)y2, 1.0f, d3dSurface.background, 0, 0 }
888 { (float)x1, (float)y1 - 0.5f, 1.0f, d3dSurface.background, 0, 0 },
889 { (float)x2 + 1.0f, (float)y1 - 0.5f, 1.0f, d3dSurface.background, 0, 0 },
890 { (float)x1, (float)y2 + 1.5f, 1.0f, d3dSurface.background, 0, 0 },
891 { (float)x2 + 1.0f, (float)y2 + 1.5f, 1.0f, d3dSurface.background, 0, 0 }
894 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
895 vertex, sizeof(Vertex));
898 void Clear(Display display, Surface surface, ClearType type)
900 DisplaySystem displaySystem = display.displaySystem;
901 D3DSystem d3dSystem = displaySystem.driverData;
902 D3DSurface d3dSurface = surface.driverData;
903 IDirect3DDevice9_Clear(d3dSystem.d3dDevice, 0, null,
904 ((type == depthBuffer) ? 0 : D3DCLEAR_TARGET) |
905 ((type == colorBuffer) ? 0 : D3DCLEAR_ZBUFFER),
906 d3dSurface.background, 1,0);
909 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
914 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
916 DisplaySystem displaySystem = display.displaySystem;
917 D3DSystem d3dSystem = displaySystem.driverData;
918 D3DSurface d3dSurface = surface.driverData;
919 Color foreground = d3dSurface.writingText ? surface.foreground : white;
922 { (float)dx, (float)dy, 1.0f, foreground,
923 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
924 { (float)(dx+w), (float)dy, 1.0f, foreground,
925 (float)(sx+w)/ (src.width-1), (float)sy/ (src.height-1) },
926 { (float)dx, (float)(dy+h), 1.0f, foreground,
927 (float)sx/ (src.width-1), (float)(sy+h)/ (src.height-1) },
928 { (float)(dx+w), (float)(dy+h), 1.0f, foreground,
929 (float)(sx+w) / (src.width-1), (float)(sy+h)/ (src.height-1) }
932 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture9 *)src.picture);
933 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
934 vertex, sizeof(Vertex));
935 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, null);
938 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
940 DisplaySystem displaySystem = display.displaySystem;
941 D3DSystem d3dSystem = displaySystem.driverData;
944 { (float)dx, (float)dy, 1.0f, surface.foreground,
945 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
946 { (float)(dx+w), (float)dy, 1.0f, surface.foreground,
947 (float)(sx+sw)/ (src.width-1), (float)sy/ (src.height-1) },
948 { (float)dx, (float)(dy+h), 1.0f, surface.foreground,
949 (float)sx/ (src.width-1), (float)(sy+sh)/ (src.height-1) },
950 { (float)(dx+w), (float)(dy+h), 1.0f, surface.foreground,
951 (float)(sx+sw) / (src.width-1), (float)(sy+sh)/ (src.height-1) }
954 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture9 *)src.picture);
955 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
956 vertex, sizeof(Vertex));
957 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, null);
960 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
962 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
965 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
968 Bitmap lfbBitmap { };
969 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
971 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Stretch(null, lfbSurface, src, dx, dy, sx, sy, w, h, sw, sh);
972 UnlockDisplay(display, lfbSurface);
974 lfbBitmap.picture = null;
978 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
981 Bitmap lfbBitmap { };
982 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
984 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, lfbSurface, src, dx, dy, sx, sy, w, h);
985 UnlockDisplay(display, lfbSurface);
987 lfbBitmap.picture = null;
991 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
993 StretchDI(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
996 void UnloadFont(DisplaySystem displaySystem, Font font)
998 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
1001 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
1003 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
1006 void TextFont(Display display, Surface surface, Font font)
1008 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
1011 void TextOpacity(Display display, Surface surface, bool opaque)
1013 D3DSurface d3dSurface = surface.driverData;
1014 d3dSurface.opaqueText = opaque;
1017 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
1019 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
1022 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
1024 DisplaySystem displaySystem = display.displaySystem;
1025 D3DSystem d3dSystem = displaySystem.driverData;
1026 D3DSurface d3dSurface = surface.driverData;
1028 if(surface.textOpacity)
1031 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
1033 int x1 = x, y1 = y, x2 = x+w-1, y2 = y+h-1;
1036 { (float)x1, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1037 { (float)x2 + 1.0f, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1038 { (float)x1, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 },
1039 { (float)x2 + 1.0f, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 }
1042 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
1043 vertex, sizeof(Vertex));
1045 //display.displaySystem.driver.Area(display, surface, x, y, x+w-1, y+h-1);
1048 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1049 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1050 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1051 d3dSurface.writingText = true;
1053 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
1055 d3dSurface.writingText = false;
1056 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
1057 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1058 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1061 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
1063 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, width, height);
1066 void DrawingChar(Display display, Surface surface, char character)
1071 void LineStipple(Display display, Surface surface, uint stipple)
1074 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_LINEPATTERN,
1075 stipple?Muint(1,stipple):0);
1080 void SetRenderState(Display display, RenderState state, uint value)
1082 DisplaySystem displaySystem = display.displaySystem;
1083 D3DSystem d3dSystem = displaySystem.driverData;
1084 D3DDisplay d3dDisplay = display.driverData;
1088 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, value ? TRUE : FALSE);
1091 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FILLMODE,
1092 ((FillModeValue)value == solid) ? D3DFILL_SOLID : D3DFILL_WIREFRAME);
1095 // IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_USEW : D3DZB_FALSE);
1096 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_TRUE : D3DZB_FALSE);
1099 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZWRITEENABLE, value);
1102 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGCOLOR, value);
1106 float fogDensity = RenderStateFloat { ui = value }.f;
1107 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGDENSITY, RenderStateFloat { fogDensity }.ui);
1111 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ALPHABLENDENABLE, value);
1114 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_AMBIENT, value);
1118 if(d3dDisplay.vSync != (bool)value)
1120 d3dDisplay.vSync = (bool)value;
1121 DisplaySize(display, display.width, display.height);
1128 void SetLight(Display display, int id, Light light)
1130 DisplaySystem displaySystem = display.displaySystem;
1131 D3DSystem d3dSystem = displaySystem.driverData;
1132 D3DDisplay d3dDisplay = display.driverData;
1135 D3DLIGHT9 d3dLight =
1137 // Opacity on the light?
1138 D3DLIGHT_DIRECTIONAL,
1139 { light.diffuse.r, light.diffuse.g, light.diffuse.b, 1.0f },
1140 { light.specular.r, light.specular.g, light.specular.b, 1.0f },
1141 { light.ambient.r, light.ambient.g, light.ambient.b, 1.0f }
1143 Vector3Df vector {0,0,1};
1144 Vector3Df vectorPI {0,0,-1};
1145 Vector3Df direction;
1147 Vector3Df * lightDirection = (Vector3Df *)&d3dLight.Direction;
1149 mat.RotationQuaternion(light.orientation);
1151 direction.MultMatrix(vector, mat);
1152 if(!display.display3D || !display.display3D.camera)
1154 d3dLight.Direction.x = direction.x;
1155 d3dLight.Direction.y = direction.y;
1156 d3dLight.Direction.z =-direction.z;
1159 lightDirection->MultMatrix(direction, d3dDisplay.worldMatrix);
1161 d3dDisplay.lights[id] = d3dLight;
1163 IDirect3DDevice9_LightEnable(d3dSystem.d3dDevice, id, TRUE);
1164 IDirect3DDevice9_SetLight(d3dSystem.d3dDevice, id, &d3dDisplay.lights[id] /*d3dLight*/);
1166 direction.MultMatrix(vectorPI, mat);
1167 lightDirection->MultMatrix(direction, d3dDisplay.worldMatrix);
1169 d3dDisplay.lightsPI[id] = d3dLight;
1173 IDirect3DDevice9_LightEnable(d3dSystem.d3dDevice, id, FALSE);
1174 d3dDisplay.lights[id].Type = 0;
1178 void SetCamera(Display display, Surface surface, Camera camera)
1180 DisplaySystem displaySystem = display.displaySystem;
1181 D3DSystem d3dSystem = displaySystem.driverData;
1182 D3DDisplay d3dDisplay = display.driverData;
1183 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1186 Point topLeft {surface.box.left + surface.offset.x, surface.box.top + surface.offset.y};
1187 Point downRight {surface.box.right + surface.offset.x, surface.box.bottom + surface.offset.y};
1190 surface.offset.x + camera.origin.x,
1191 surface.offset.y + camera.origin.y
1195 float l = (topLeft.x - origin.x) * camera.zMin / camera.focalX;
1196 float r = (downRight.x - origin.x) * camera.zMin / camera.focalX;
1197 float b = (downRight.y - origin.y) * camera.zMin / camera.focalY;
1198 float t = (topLeft.y - origin.y) * camera.zMin / camera.focalY;
1199 float n = camera.zMin;
1200 float f = camera.zMax;
1202 matProj.m[0][0] = 2 * n / (r - l);
1203 matProj.m[0][1] = 0;
1204 matProj.m[0][2] = 0;
1205 matProj.m[0][3] = 0;
1207 matProj.m[1][0] = 0;
1208 matProj.m[1][1] = 2 * n / (t - b);
1209 matProj.m[1][2] = 0;
1210 matProj.m[1][3] = 0;
1212 matProj.m[2][0] = (l + r) / (r - l);
1213 matProj.m[2][1] = (t + b) / (t - b);
1214 matProj.m[2][2] = f / (n - f);
1215 matProj.m[2][3] = -1;
1217 matProj.m[3][0] = 0;
1218 matProj.m[3][1] = 0;
1219 matProj.m[3][2] = n * f / (n - f);
1220 matProj.m[3][3] = 0;
1222 IDirect3DDevice9_SetTransform(d3dDevice, D3DTS_PROJECTION, &matProj);
1224 // *** View Matrix ***
1225 if(!display.display3D.camera)
1226 d3dDisplay.worldMatrix++;
1229 matrix.Scale(1.0f, 1.0f, -1.0f);
1230 d3dDisplay.worldMatrix->Multiply(camera.viewMatrix, matrix);
1232 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1234 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decls[0]);
1236 // IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_USEW);
1237 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_TRUE);
1238 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZWRITEENABLE, TRUE);
1239 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, FALSE);
1240 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, TRUE);
1241 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, TRUE);
1243 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1245 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
1247 else if(display.display3D.camera)
1249 d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
1250 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1251 IDirect3DDevice9_SetTransform(d3dDevice, D3DTS_PROJECTION, &d3dDisplay.projMatrix);
1253 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
1254 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
1255 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
1256 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
1257 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGENABLE, FALSE);
1258 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, FALSE);
1260 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1261 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1263 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decl2D);
1265 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
1267 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
1271 void ApplyMaterial(Display display, Material material, Mesh mesh)
1273 DisplaySystem displaySystem = display.displaySystem;
1274 D3DSystem d3dSystem = displaySystem.driverData;
1275 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1276 D3DMesh d3dMesh = mesh.data;
1279 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGENABLE, (material.flags.noFog) ? FALSE : TRUE);
1282 if(material.baseMap && d3dMesh.texCoords && material.baseMap.driver.displaySystem == displaySystem)
1284 Bitmap map = material.baseMap;
1286 IDirect3DDevice9_SetTexture(d3dDevice, 0, (IDirect3DBaseTexture9 *)map.picture);
1288 if(material.flags.tile)
1290 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
1291 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
1295 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1296 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1300 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
1303 D3DMATERIAL9 d3dMaterial;
1305 d3dMaterial.Diffuse.r = material.diffuse.r;
1306 d3dMaterial.Diffuse.g = material.diffuse.g;
1307 d3dMaterial.Diffuse.b = material.diffuse.b;
1308 d3dMaterial.Diffuse.a = material.opacity;
1310 d3dMaterial.Ambient.r = material.ambient.r;
1311 d3dMaterial.Ambient.g = material.ambient.g;
1312 d3dMaterial.Ambient.b = material.ambient.b;
1313 d3dMaterial.Ambient.a = 1;
1315 d3dMaterial.Specular.r = material.specular.r;
1316 d3dMaterial.Specular.g = material.specular.g;
1317 d3dMaterial.Specular.b = material.specular.b;
1318 d3dMaterial.Specular.a = 1;
1320 d3dMaterial.Emissive.r = material.emissive.r;
1321 d3dMaterial.Emissive.g = material.emissive.g;
1322 d3dMaterial.Emissive.b = material.emissive.b;
1323 d3dMaterial.Emissive.a = 1;
1325 d3dMaterial.Power = material.power;
1327 IDirect3DDevice9_SetMaterial(d3dDevice, &d3dMaterial); //(D3DMATERIAL9 *)&material.diffuse
1331 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
1333 D3DMesh d3dMesh = mesh.data;
1336 if(!(mesh.flags.vertices))
1338 if(d3dMesh.vertices)
1340 IDirect3DVertexBuffer9_Release(d3dMesh.vertices);
1341 d3dMesh.vertices = null;
1343 delete mesh.vertices;
1345 if(!(mesh.flags.normals))
1349 IDirect3DVertexBuffer9_Release(d3dMesh.normals);
1350 d3dMesh.normals = null;
1352 delete mesh.normals;
1354 if(!(mesh.flags.texCoords1))
1356 if(d3dMesh.texCoords)
1358 IDirect3DVertexBuffer9_Release(d3dMesh.texCoords);
1359 d3dMesh.texCoords = null;
1361 delete mesh.texCoords;
1363 if(!(mesh.flags.texCoords2))
1365 if(d3dMesh.texCoords2)
1367 IDirect3DVertexBuffer9_Release(d3dMesh.texCoords2);
1368 d3dMesh.texCoords2 = null;
1370 // delete mesh.texCoords2;
1380 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh)
1382 D3DSystem d3dSystem = displaySystem.driverData;
1383 bool result = false;
1384 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1387 mesh.data = D3DMesh { };
1390 D3DMesh d3dMesh = mesh.data;
1392 if((mesh.flags.vertices) && !d3dMesh.vertices)
1394 mesh.vertices = new Vector3Df[mesh.nVertices];
1395 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * mesh.nVertices,
1396 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices, null))
1399 if((mesh.flags.normals) && !d3dMesh.normals)
1401 mesh.normals = new Vector3Df[mesh.nVertices];
1402 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * mesh.nVertices,
1403 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals, null))
1406 if((mesh.flags.texCoords1) && !d3dMesh.texCoords)
1408 mesh.texCoords = new Pointf[mesh.nVertices];
1409 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * mesh.nVertices,
1410 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords, null))
1417 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1419 D3DMesh d3dMesh = mesh.data;
1420 if(!flags) flags = mesh.flags;
1422 if(flags.vertices && mesh.vertices)
1424 Vector3Df * vertices;
1425 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.vertices, 0, 0, (void **) &vertices, 0))
1427 memcpy(vertices, mesh.vertices, mesh.nVertices * sizeof(Vector3Df));
1428 IDirect3DVertexBuffer9_Unlock(d3dMesh.vertices);
1431 if(flags.normals && mesh.normals)
1433 Vector3Df * normals;
1434 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.normals, 0, 0, (void **) &normals, 0))
1436 memcpy(normals, mesh.normals, mesh.nVertices * sizeof(Vector3Df));
1437 IDirect3DVertexBuffer9_Unlock(d3dMesh.normals);
1440 if(flags.texCoords1 && mesh.texCoords)
1443 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.texCoords, 0, 0, (void **) &texCoords, 0))
1445 memcpy(texCoords, mesh.texCoords, mesh.nVertices * sizeof(Pointf));
1446 IDirect3DVertexBuffer9_Unlock(d3dMesh.texCoords);
1451 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1457 void FreeIndices(DisplaySystem displaySystem, D3DIndices d3dIndices)
1461 if(d3dIndices.buffer)
1462 IDirect3DIndexBuffer9_Release(d3dIndices.buffer);
1463 delete d3dIndices.indices;
1468 D3DIndices AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
1470 D3DSystem d3dSystem = displaySystem.driverData;
1471 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1472 D3DIndices d3dIndices { };
1473 if(d3dIndices && nIndices)
1475 d3dIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
1476 IDirect3DDevice9_CreateIndexBuffer(d3dDevice, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * nIndices, 0, indices32bit ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
1477 D3DPOOL_MANAGED, &d3dIndices.buffer, null);
1478 d3dIndices.nIndices = nIndices;
1483 void UnlockIndices(DisplaySystem displaySystem, D3DIndices d3dIndices, bool indices32bit, int nIndices)
1485 uint16 * indexBuffer = null;
1486 if(!IDirect3DIndexBuffer9_Lock(d3dIndices.buffer, 0, 0, (void **)&indexBuffer, 0))
1488 memcpy(indexBuffer, d3dIndices.indices, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * d3dIndices.nIndices);
1489 IDirect3DIndexBuffer9_Unlock(d3dIndices.buffer);
1493 uint16 * LockIndices(DisplaySystem displaySystem, D3DIndices d3dIndices)
1495 return d3dIndices.indices;
1498 void SelectMesh(Display display, Mesh mesh)
1500 DisplaySystem displaySystem = display.displaySystem;
1501 D3DSystem d3dSystem = displaySystem.driverData;
1502 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1504 if(mesh && mesh.data)
1507 D3DMesh d3dMesh = mesh.data;
1509 IDirect3DDevice9_SetStreamSource(d3dDevice, 0, d3dMesh.vertices, 0, sizeof(Vector3Df));
1512 IDirect3DDevice9_SetStreamSource(d3dDevice, 1, d3dMesh.normals, 0, sizeof(Vector3Df));
1516 IDirect3DDevice9_SetStreamSource(d3dDevice, 1, null, 0, sizeof(Vector3Df));
1517 if(d3dMesh.texCoords)
1519 IDirect3DDevice9_SetStreamSource(d3dDevice, 2, d3dMesh.texCoords, 0, sizeof(Pointf));
1523 IDirect3DDevice9_SetStreamSource(d3dDevice, 2, null, 0, sizeof(Pointf));
1525 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decls[decl]);
1529 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
1531 DisplaySystem displaySystem = display.displaySystem;
1532 D3DSystem d3dSystem = displaySystem.driverData;
1533 D3DDisplay d3dDisplay = display.driverData;
1534 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1536 if(primitiveTypes[primitive->type.primitiveType])
1538 int numPrimitives = (primitive->type.vertexRange) ? primitive->nVertices : primitive->nIndices;
1541 switch(primitive->type.primitiveType)
1543 case lines: numPrimitives /= 2; break;
1544 case triangles: numPrimitives /= 3; break;
1556 if(primitive->type.vertexRange)
1558 if(primitive->type.primitiveType == quads)
1560 for(c = 0; c<numPrimitives; c++)
1561 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1564 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1568 D3DIndices indices = primitive->data;
1569 IDirect3DDevice9_SetIndices(d3dDevice, indices.buffer);
1570 if(primitive->type.primitiveType == quads)
1572 for(c = 0; c<numPrimitives; c++)
1573 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, c*4, 2);
1576 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, 0, numPrimitives);
1579 if(display.display3D.material.flags.doubleSided)
1581 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CCW);
1582 if(!display.display3D.material.flags.singleSideLight)
1584 for(c = 0; c<NumberOfLights; c++)
1585 if(d3dDisplay.lights[c].Type)
1586 IDirect3DDevice9_SetLight(d3dDevice, c, &d3dDisplay.lightsPI[c]);
1589 if(primitive->type.vertexRange)
1591 if(primitive->type.primitiveType == quads)
1593 for(c = 0; c<numPrimitives; c++)
1594 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1597 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1601 D3DIndices indices = primitive->data;
1602 IDirect3DDevice9_SetIndices(d3dDevice, indices.buffer);
1603 if(primitive->type.primitiveType == quads)
1605 for(c = 0; c<numPrimitives; c++)
1606 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, c*4, 2);
1609 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, 0, numPrimitives);
1611 if(!display.display3D.material.flags.singleSideLight)
1613 for(c = 0; c<NumberOfLights; c++)
1614 if(d3dDisplay.lights[c].Type)
1615 IDirect3DDevice9_SetLight(d3dDevice, c, &d3dDisplay.lights[c]);
1618 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1623 void PushMatrix(Display display)
1625 D3DDisplay d3dDisplay = display.driverData;
1626 *(d3dDisplay.worldMatrix+1) = *(d3dDisplay.worldMatrix);
1627 d3dDisplay.worldMatrix++;
1630 void PopMatrix(Display display, bool setMatrix)
1632 D3DDisplay d3dDisplay = display.driverData;
1633 DisplaySystem displaySystem = display.displaySystem;
1634 D3DSystem d3dSystem = displaySystem.driverData;
1635 d3dDisplay.worldMatrix--;
1637 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1640 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
1642 DisplaySystem displaySystem = display.displaySystem;
1643 D3DSystem d3dSystem = displaySystem.driverData;
1644 Camera camera = useCamera ? display.display3D.camera : null;
1645 D3DDisplay d3dDisplay = display.driverData;
1646 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1648 Matrix matrix = transMatrix, temp;
1652 matrix.Scale(1.0f, 1.0f, -1.0f);
1653 *(d3dDisplay.worldMatrix) = matrix;
1659 - camera.cPosition.x,
1660 - camera.cPosition.y,
1661 - camera.cPosition.z);
1662 temp.Multiply(matrix, d3dDisplay.worldMatrix);
1663 *(d3dDisplay.worldMatrix) = temp;
1666 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1669 bool Lock(Display display)
1671 DisplaySystem displaySystem = display.displaySystem;
1672 D3DSystem d3dSystem = displaySystem.driverData;
1673 D3DDisplay d3dDisplay = display.driverData;
1675 if(d3dDisplay.backBuffer)
1677 IDirect3DDevice9_SetDepthStencilSurface(d3dSystem.d3dDevice, d3dDisplay.depthSurface);
1678 IDirect3DDevice9_SetRenderTarget(d3dSystem.d3dDevice, 0, d3dDisplay.backBuffer);
1679 IDirect3DDevice9_BeginScene(d3dSystem.d3dDevice);
1681 d3dSystem.inScene = true;
1686 void Unlock(Display display)
1688 DisplaySystem displaySystem = display.displaySystem;
1689 D3DSystem d3dSystem = displaySystem.driverData;
1691 if(d3dSystem.inScene)
1693 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
1694 d3dSystem.inScene = false;