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, MeshFeatures flags, int nVertices)
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.nVertices == nVertices)
1394 if(mesh.flags != flags)
1396 // Same number of vertices, adding features (Leaves the other features pointers alone)
1397 if(flags.vertices && !d3dMesh.vertices)
1399 mesh.vertices = new Vector3Df[nVertices];
1400 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1401 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices, null))
1404 if(flags.normals && !d3dMesh.normals)
1406 mesh.normals = new Vector3Df[nVertices];
1407 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1408 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals, null))
1411 if(flags.texCoords1 && !d3dMesh.texCoords)
1413 mesh.texCoords = new Pointf[nVertices];
1414 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * nVertices,
1415 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords, null))
1422 // New number of vertices, reallocate all current and new features
1423 flags |= mesh.flags;
1425 // Same number of vertices, adding features (Leaves the other features pointers alone)
1428 if(d3dMesh.vertices)
1430 IDirect3DVertexBuffer9_Release(d3dMesh.vertices);
1431 d3dMesh.vertices = null;
1433 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
1434 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1435 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices, null))
1442 IDirect3DVertexBuffer9_Release(d3dMesh.normals);
1443 d3dMesh.normals = null;
1445 mesh.normals = renew mesh.normals Vector3Df[nVertices];
1446 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1447 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals, null))
1450 if(flags.texCoords1)
1452 if(d3dMesh.texCoords)
1454 IDirect3DVertexBuffer9_Release(d3dMesh.texCoords);
1455 d3dMesh.texCoords = null;
1457 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
1458 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * nVertices,
1459 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords, null))
1467 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1469 D3DMesh d3dMesh = mesh.data;
1470 if(!flags) flags = mesh.flags;
1472 if(flags.vertices && mesh.vertices)
1474 Vector3Df * vertices;
1475 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.vertices, 0, 0, (void **) &vertices, 0))
1477 memcpy(vertices, mesh.vertices, mesh.nVertices * sizeof(Vector3Df));
1478 IDirect3DVertexBuffer9_Unlock(d3dMesh.vertices);
1481 if(flags.normals && mesh.normals)
1483 Vector3Df * normals;
1484 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.normals, 0, 0, (void **) &normals, 0))
1486 memcpy(normals, mesh.normals, mesh.nVertices * sizeof(Vector3Df));
1487 IDirect3DVertexBuffer9_Unlock(d3dMesh.normals);
1490 if(flags.texCoords1 && mesh.texCoords)
1493 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.texCoords, 0, 0, (void **) &texCoords, 0))
1495 memcpy(texCoords, mesh.texCoords, mesh.nVertices * sizeof(Pointf));
1496 IDirect3DVertexBuffer9_Unlock(d3dMesh.texCoords);
1501 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1507 void FreeIndices(DisplaySystem displaySystem, D3DIndices d3dIndices)
1511 if(d3dIndices.buffer)
1512 IDirect3DIndexBuffer9_Release(d3dIndices.buffer);
1513 delete d3dIndices.indices;
1518 D3DIndices AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
1520 D3DSystem d3dSystem = displaySystem.driverData;
1521 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1522 D3DIndices d3dIndices { };
1523 if(d3dIndices && nIndices)
1525 d3dIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
1526 IDirect3DDevice9_CreateIndexBuffer(d3dDevice, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * nIndices, 0, indices32bit ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
1527 D3DPOOL_MANAGED, &d3dIndices.buffer, null);
1528 d3dIndices.nIndices = nIndices;
1533 void UnlockIndices(DisplaySystem displaySystem, D3DIndices d3dIndices, bool indices32bit, int nIndices)
1535 uint16 * indexBuffer = null;
1536 if(!IDirect3DIndexBuffer9_Lock(d3dIndices.buffer, 0, 0, (void **)&indexBuffer, 0))
1538 memcpy(indexBuffer, d3dIndices.indices, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * d3dIndices.nIndices);
1539 IDirect3DIndexBuffer9_Unlock(d3dIndices.buffer);
1543 uint16 * LockIndices(DisplaySystem displaySystem, D3DIndices d3dIndices)
1545 return d3dIndices.indices;
1548 void SelectMesh(Display display, Mesh mesh)
1550 DisplaySystem displaySystem = display.displaySystem;
1551 D3DSystem d3dSystem = displaySystem.driverData;
1552 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1554 if(mesh && mesh.data)
1557 D3DMesh d3dMesh = mesh.data;
1559 IDirect3DDevice9_SetStreamSource(d3dDevice, 0, d3dMesh.vertices, 0, sizeof(Vector3Df));
1562 IDirect3DDevice9_SetStreamSource(d3dDevice, 1, d3dMesh.normals, 0, sizeof(Vector3Df));
1566 IDirect3DDevice9_SetStreamSource(d3dDevice, 1, null, 0, sizeof(Vector3Df));
1567 if(d3dMesh.texCoords)
1569 IDirect3DDevice9_SetStreamSource(d3dDevice, 2, d3dMesh.texCoords, 0, sizeof(Pointf));
1573 IDirect3DDevice9_SetStreamSource(d3dDevice, 2, null, 0, sizeof(Pointf));
1575 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decls[decl]);
1579 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
1581 DisplaySystem displaySystem = display.displaySystem;
1582 D3DSystem d3dSystem = displaySystem.driverData;
1583 D3DDisplay d3dDisplay = display.driverData;
1584 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1586 if(primitiveTypes[primitive->type.primitiveType])
1588 int numPrimitives = (primitive->type.vertexRange) ? primitive->nVertices : primitive->nIndices;
1591 switch(primitive->type.primitiveType)
1593 case lines: numPrimitives /= 2; break;
1594 case triangles: numPrimitives /= 3; break;
1606 if(primitive->type.vertexRange)
1608 if(primitive->type.primitiveType == quads)
1610 for(c = 0; c<numPrimitives; c++)
1611 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1614 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1618 D3DIndices indices = primitive->data;
1619 IDirect3DDevice9_SetIndices(d3dDevice, indices.buffer);
1620 if(primitive->type.primitiveType == quads)
1622 for(c = 0; c<numPrimitives; c++)
1623 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, c*4, 2);
1626 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, 0, numPrimitives);
1629 if(display.display3D.material.flags.doubleSided)
1631 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CCW);
1632 if(!display.display3D.material.flags.singleSideLight)
1634 for(c = 0; c<NumberOfLights; c++)
1635 if(d3dDisplay.lights[c].Type)
1636 IDirect3DDevice9_SetLight(d3dDevice, c, &d3dDisplay.lightsPI[c]);
1639 if(primitive->type.vertexRange)
1641 if(primitive->type.primitiveType == quads)
1643 for(c = 0; c<numPrimitives; c++)
1644 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1647 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1651 D3DIndices indices = primitive->data;
1652 IDirect3DDevice9_SetIndices(d3dDevice, indices.buffer);
1653 if(primitive->type.primitiveType == quads)
1655 for(c = 0; c<numPrimitives; c++)
1656 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, c*4, 2);
1659 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, 0, numPrimitives);
1661 if(!display.display3D.material.flags.singleSideLight)
1663 for(c = 0; c<NumberOfLights; c++)
1664 if(d3dDisplay.lights[c].Type)
1665 IDirect3DDevice9_SetLight(d3dDevice, c, &d3dDisplay.lights[c]);
1668 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1673 void PushMatrix(Display display)
1675 D3DDisplay d3dDisplay = display.driverData;
1676 *(d3dDisplay.worldMatrix+1) = *(d3dDisplay.worldMatrix);
1677 d3dDisplay.worldMatrix++;
1680 void PopMatrix(Display display, bool setMatrix)
1682 D3DDisplay d3dDisplay = display.driverData;
1683 DisplaySystem displaySystem = display.displaySystem;
1684 D3DSystem d3dSystem = displaySystem.driverData;
1685 d3dDisplay.worldMatrix--;
1687 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1690 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
1692 DisplaySystem displaySystem = display.displaySystem;
1693 D3DSystem d3dSystem = displaySystem.driverData;
1694 Camera camera = useCamera ? display.display3D.camera : null;
1695 D3DDisplay d3dDisplay = display.driverData;
1696 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1698 Matrix matrix = transMatrix, temp;
1702 matrix.Scale(1.0f, 1.0f, -1.0f);
1703 *(d3dDisplay.worldMatrix) = matrix;
1709 - camera.cPosition.x,
1710 - camera.cPosition.y,
1711 - camera.cPosition.z);
1712 temp.Multiply(matrix, d3dDisplay.worldMatrix);
1713 *(d3dDisplay.worldMatrix) = temp;
1716 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1719 bool Lock(Display display)
1721 DisplaySystem displaySystem = display.displaySystem;
1722 D3DSystem d3dSystem = displaySystem.driverData;
1723 D3DDisplay d3dDisplay = display.driverData;
1725 if(d3dDisplay.backBuffer)
1727 IDirect3DDevice9_SetDepthStencilSurface(d3dSystem.d3dDevice, d3dDisplay.depthSurface);
1728 IDirect3DDevice9_SetRenderTarget(d3dSystem.d3dDevice, 0, d3dDisplay.backBuffer);
1729 IDirect3DDevice9_BeginScene(d3dSystem.d3dDevice);
1731 d3dSystem.inScene = true;
1736 void Unlock(Display display)
1738 DisplaySystem displaySystem = display.displaySystem;
1739 D3DSystem d3dSystem = displaySystem.driverData;
1741 if(d3dSystem.inScene)
1743 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
1744 d3dSystem.inScene = false;