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
87 ColorAlpha background;
90 static class D3DMesh : struct
92 IDirect3DVertexBuffer9 * vertices;
93 IDirect3DVertexBuffer9 * normals;
94 IDirect3DVertexBuffer9 * texCoords;
95 IDirect3DVertexBuffer9 * texCoords2;
105 static class D3DIndices : struct
108 IDirect3DIndexBuffer9 * buffer;
112 static int primitiveTypes[RenderPrimitiveType] =
114 D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP, D3DPT_TRIANGLEFAN, D3DPT_TRIANGLEFAN, 0, D3DPT_LINESTRIP
117 static void SetTransformMatrix(IDirect3DDevice9 * device, Matrix matrix)
123 (float)matrix.m[0][0], (float)matrix.m[0][1], (float)matrix.m[0][2], (float)matrix.m[0][3],
124 (float)matrix.m[1][0], (float)matrix.m[1][1], (float)matrix.m[1][2], (float)matrix.m[1][3],
125 (float)matrix.m[2][0], (float)matrix.m[2][1], (float)matrix.m[2][2], (float)matrix.m[2][3],
126 (float)matrix.m[3][0], (float)matrix.m[3][1], (float)matrix.m[3][2], (float)matrix.m[3][3]
130 IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &d3dMat);
133 class Direct3D9DisplayDriver : DisplayDriver
135 class_property(name) = "Direct3D";
138 bool ::LockDisplay(Display display, Surface surface, Bitmap lfbBitmap, Surface * lfbSurface)
141 D3DDisplay d3dDisplay = display.driverData;
143 //if(!IDirect3DDevice9_GetBackBuffer(d3dSystem.d3dDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
145 D3DLOCKED_RECT lockedRect;
146 if(!IDirect3DSurface9_LockRect(d3dDisplay.backBuffer, &lockedRect, null, 0))
149 switch(d3dDisplay.d3dpp.BackBufferFormat)
151 case D3DFMT_A8R8G8B8:
152 case D3DFMT_X8R8G8B8:
153 lfbBitmap.pixelFormat = pixelFormat888;
156 lfbBitmap.pixelFormat = pixelFormat565;
158 case D3DFMT_X1R5G5B5:
159 case D3DFMT_A1R5G5B5:
160 lfbBitmap.pixelFormat = pixelFormat555;
162 case D3DFMT_A4R4G4B4:
163 case D3DFMT_X4R4G4B4:
164 lfbBitmap.pixelFormat = pixelFormat444;
171 lfbBitmap.driver = null;
172 lfbBitmap.displaySystem = null;
173 lfbBitmap.picture = (byte *)lockedRect.pBits;
174 lfbBitmap.transparent = false;
175 lfbBitmap.stride = lockedRect.Pitch >> GetColorDepthShifts(lfbBitmap.pixelFormat);
176 lfbBitmap.width = display.width;
177 lfbBitmap.height = display.height;
179 *lfbSurface = lfbBitmap.GetSurface(surface ? surface.offset.x : 0, surface ? surface.offset.y : 0, surface ? surface.box : null);
183 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
188 void ::UnlockDisplay(Display display, Surface surface)
190 D3DDisplay d3dDisplay = display.driverData;
191 if(d3dDisplay.backBuffer)
193 IDirect3DSurface9_UnlockRect(d3dDisplay.backBuffer);
194 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
199 void ::SetViewportAndMatrices(Display display, int x, int y, Box box)
201 D3DDisplay d3dDisplay = display.driverData;
202 DisplaySystem displaySystem = display.displaySystem;
203 D3DSystem d3dSystem = displaySystem.driverData;
206 D3DVIEWPORT9 viewport;
209 if(box.right < box.left || box.bottom < box.top)
211 viewport.Width = viewport.Height = 1;
212 viewport.X = viewport.Y = MAXDWORD;
216 viewport.X = x + box.left;
217 viewport.Y = y + box.top;
218 viewport.Width = box.right - box.left + 1;
219 viewport.Height = box.bottom - box.top + 1;
221 if(!IDirect3DDevice9_SetViewport(d3dSystem.d3dDevice, &viewport))
223 D3DMATRIX * matProj = &d3dDisplay.projMatrix;
224 Matrix * matWorld = d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
226 matProj->m[0][0] = 2.0f / viewport.Width;
227 matProj->m[1][1] =-2.0f / viewport.Height;
228 matProj->m[2][2] = matProj->m[3][1] = matProj->m[3][3] = 1;
229 matProj->m[3][0] = -1;
231 IDirect3DDevice9_SetTransform(d3dSystem.d3dDevice, D3DTS_PROJECTION, matProj);
233 matWorld->Identity();
234 matWorld->m[3][0] =-box.left;
235 matWorld->m[3][1] =-box.top;
237 SetTransformMatrix(d3dSystem.d3dDevice, matWorld);
243 bool CreateDisplaySystem(DisplaySystem displaySystem)
246 D3DSystem d3dSystem = displaySystem.driverData = D3DSystem { };
249 displaySystem.flags.alpha = true;
250 //if(displaySystem.flags.fullScreen)
251 displaySystem.flags.flipping = true;
252 displaySystem.pixelFormat = pixelFormat888;
254 d3dSystem.d3dDll = LoadLibrary("d3d9.dll");
257 d3dSystem.direct3DCreate9 = (void *)GetProcAddress(d3dSystem.d3dDll, "Direct3DCreate9");
258 if(d3dSystem.direct3DCreate9)
260 if((d3dSystem.direct3D = d3dSystem.direct3DCreate9(D3D_SDK_VERSION)))
262 D3DDISPLAYMODE d3ddm;
263 if(!IDirect3D9_GetAdapterDisplayMode(d3dSystem.direct3D, D3DADAPTER_DEFAULT, &d3ddm))
265 d3dSystem.d3dpp.BackBufferCount = 1;
267 if(displaySystem.flags.fullScreen)
269 d3dSystem.d3dpp.BackBufferWidth = d3ddm.Width;
270 d3dSystem.d3dpp.BackBufferHeight = d3ddm.Height;
271 d3dSystem.d3dpp.hDeviceWindow = displaySystem.window;
275 d3dSystem.d3dpp.hDeviceWindow = d3dSystem.hwnd =
276 CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
277 d3dSystem.d3dpp.Windowed = TRUE;
280 d3dSystem.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
281 d3dSystem.format = d3dSystem.d3dpp.BackBufferFormat = d3ddm.Format;
282 d3dSystem.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
284 if(!IDirect3D9_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
285 d3dSystem.d3dpp.hDeviceWindow,
286 D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE|D3DCREATE_FPU_PRESERVE,
287 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
291 d3dSystem.usage = D3DUSAGE_SOFTWAREPROCESSING;
292 if(!IDirect3D9_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
293 d3dSystem.d3dpp.hDeviceWindow,
294 D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,
295 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
301 D3DVERTEXELEMENT9 vertexDecls[NUM_VERTEX_DECLS][4] =
304 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
308 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
309 { 1, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 },
313 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
314 { 2, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
318 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
319 { 1, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 },
320 { 2, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
325 D3DVERTEXELEMENT9 vertexDecl2D[] =
327 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
328 { 0, (uint16)(3*sizeof(float)), D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 },
329 { 0, (uint16)(3*sizeof(float) + sizeof(uint)), D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
334 for(c = 0; c<NUM_VERTEX_DECLS; c++)
335 if(IDirect3DDevice9_CreateVertexDeclaration(d3dSystem.d3dDevice, vertexDecls[c], &d3dSystem.decls[c]))
338 if(c < NUM_VERTEX_DECLS ||
339 IDirect3DDevice9_CreateVertexDeclaration(d3dSystem.d3dDevice, vertexDecl2D, &d3dSystem.decl2D))
343 d3dSystem.ready = false;
349 Log("Couldn't load library d3d9.dll\n");
350 //LogErrorCode(ERR_MISSING_LIBRARY, "d3d9.dll");
355 void DestroyDisplaySystem(DisplaySystem displaySystem)
357 D3DSystem d3dSystem = displaySystem.driverData;
360 if(d3dSystem.d3dDevice)
361 IDirect3DDevice9_Release(d3dSystem.d3dDevice);
363 if(d3dSystem.direct3D)
364 IDirect3D9_Release(d3dSystem.direct3D);
366 for(c = 0; c<NUM_VERTEX_DECLS; c++)
368 if(d3dSystem.decls[c])
369 IDirect3DVertexDeclaration9_Release(d3dSystem.decls[c]);
373 IDirect3DVertexDeclaration9_Release(d3dSystem.decl2D);
375 FreeLibrary(d3dSystem.d3dDll);
378 displaySystem.driverData = null;
382 void DestroyDisplay(Display display)
384 DisplaySystem displaySystem = display.displaySystem;
385 D3DSystem d3dSystem = displaySystem.driverData;
386 D3DDisplay d3dDisplay = display.driverData;
388 if(d3dSystem.inScene)
390 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
391 d3dSystem.inScene = false;
394 if(d3dDisplay.backBuffer)
395 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
397 if(d3dDisplay.depthSurface)
398 IDirect3DSurface9_Release(d3dDisplay.depthSurface);
400 if(d3dDisplay.swapChain)
401 IDirect3DSwapChain9_Release(d3dDisplay.swapChain);
404 display.driverData = null;
407 bool CreateDisplay(Display display)
410 DisplaySystem displaySystem = display.displaySystem;
411 D3DSystem d3dSystem = displaySystem.driverData;
412 display.driverData = D3DDisplay { };
414 d3dSystem.ready = false;
421 bool DisplaySize(Display display, int width, int height)
424 DisplaySystem displaySystem = display.displaySystem;
425 D3DSystem d3dSystem = displaySystem.driverData;
426 D3DDisplay d3dDisplay = display.driverData;
427 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
429 d3dSystem.ready = false;
431 if(d3dDisplay.backBuffer)
433 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
434 d3dDisplay.backBuffer = null;
437 if(d3dDisplay.depthSurface)
439 IDirect3DSurface9_Release(d3dDisplay.depthSurface);
440 d3dDisplay.depthSurface = null;
443 if(d3dDisplay.swapChain)
445 IDirect3DSwapChain9_Release(d3dDisplay.swapChain);
446 d3dDisplay.swapChain = null;
452 if(displaySystem.flags.fullScreen)
454 d3dSystem.d3dpp.BackBufferWidth = width;
455 d3dSystem.d3dpp.BackBufferHeight = height;
457 result = !IDirect3DDevice9_Reset(d3dSystem.d3dDevice, &d3dSystem.d3dpp);
459 result = !IDirect3DDevice9_GetSwapChain(d3dSystem.d3dDevice, 0, &d3dDisplay.swapChain);
463 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;
464 d3dDisplay.d3dpp.BackBufferWidth = width;
465 d3dDisplay.d3dpp.BackBufferHeight = height;
466 d3dDisplay.d3dpp.Windowed = TRUE;
467 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
468 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
469 d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
471 //d3dDisplay.d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
472 d3dDisplay.d3dpp.BackBufferFormat = d3dSystem.format;
473 d3dDisplay.d3dpp.BackBufferCount = 1;
474 d3dDisplay.d3dpp.hDeviceWindow = display.window;
475 d3dDisplay.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
476 d3dDisplay.d3dpp.PresentationInterval = d3dDisplay.vSync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_DONOTWAIT;
477 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
478 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
480 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
481 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
485 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
486 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
487 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
491 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
492 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
493 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
499 if(!IDirect3DSwapChain9_GetBackBuffer(d3dDisplay.swapChain,
500 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
502 if(!IDirect3DDevice9_CreateDepthStencilSurface(d3dSystem.d3dDevice, width, height,
503 D3DFMT_D16, d3dDisplay.d3dpp.MultiSampleType,0,TRUE,&d3dDisplay.depthSurface, null))
506 d3dSystem.ready = true;
513 float fogDensity = 0;
515 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decl2D);
517 //IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
518 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
519 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
520 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
521 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
522 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
523 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
524 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGTABLEMODE, D3DFOG_EXP);
525 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGDENSITY, RenderStateFloat { fogDensity }.ui);
526 display.ambient = Color { 50,50,50 };
527 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_NORMALIZENORMALS, TRUE);
528 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
530 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
531 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
532 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
533 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
534 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
535 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
537 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
538 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
539 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
541 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
542 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
544 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
549 display.width = width;
550 display.height = height;
551 d3dDisplay.updateBox.left = display.width;
552 d3dDisplay.updateBox.top = display.height;
553 d3dDisplay.updateBox.right = 0;
554 d3dDisplay.updateBox.bottom = 0;
559 void DisplayPosition(Display display, int x, int y)
564 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
568 void RestorePalette(Display display)
572 void StartUpdate(Display display)
576 void EndUpdate(Display display)
580 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
584 void Update(Display display, Box updateBox)
586 DisplaySystem displaySystem = display.displaySystem;
587 D3DSystem d3dSystem = displaySystem.driverData;
588 D3DDisplay d3dDisplay = display.driverData;
591 //eSystem_Sleep(0.05);
592 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
594 if(display.displaySystem.flags.flipping)
596 // IDirect3DDevice9_Present(d3dSystem.d3dDevice, null, null, null, null);
597 IDirect3DSwapChain9_Present(d3dDisplay.swapChain, null, null, null, null, 0);
603 if(updateBox != null)
605 source.left = dest.left = updateBox.left;
606 source.top = dest.top = updateBox.top;
607 source.right = dest.right = updateBox.right+1;
608 source.bottom = dest.bottom = updateBox.bottom+1;
612 source.left = dest.left = d3dDisplay.updateBox.left;
613 source.top = dest.top = d3dDisplay.updateBox.top;
614 source.right = dest.right = d3dDisplay.updateBox.right+1;
615 source.bottom = dest.bottom = d3dDisplay.updateBox.bottom+1;
617 if(dest.bottom > dest.top && dest.right > dest.left)
618 IDirect3DDevice9_Present(d3dSystem.d3dDevice, &source, &dest, null, null);
619 if(updateBox == null)
621 d3dDisplay.updateBox.left = display.width;
622 d3dDisplay.updateBox.top = display.height;
623 d3dDisplay.updateBox.right = 0;
624 d3dDisplay.updateBox.bottom = 0;
627 d3dSystem.inScene = false;
631 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
635 Bitmap lfbBitmap { };
637 if(LockDisplay(display, null, lfbBitmap, &lfbSurface))
640 if(bitmap.pixelFormat != lfbBitmap.pixelFormat || bitmap.width < w || bitmap.height < h)
643 bitmap.Allocate(null, w,h,w, lfbBitmap.pixelFormat, false);
645 surface = bitmap.GetSurface(0, 0, null);
648 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, surface, lfbBitmap, 0, 0, x, y, w, h);
652 UnlockDisplay(display, lfbSurface);
655 lfbBitmap.picture = null;
663 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
665 if(bitmap.driverData)
666 IDirect3DTexture9_Release((IDirect3DTexture9 *)bitmap.driverData);
669 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
674 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps, int cubeMapFace)
677 D3DSystem d3dSystem = displaySystem.driverData;
678 if(!cubeMapFace && bitmap.Convert(null, pixelFormat888, null))
680 IDirect3DTexture9 * texture;
681 uint w = pow2i(Min(bitmap.width, 512)), h = pow2i(Min(bitmap.height, 512));
683 if(!IDirect3DDevice9_CreateTexture(d3dSystem.d3dDevice, w, h, mipMaps ? log2i(Max(w+1, h+1)) : 1, 0,
684 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, null))
690 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
692 D3DSURFACE_DESC desc;
693 D3DLOCKED_RECT lockedRect;
695 if(!IDirect3DTexture9_GetLevelDesc(texture, level, &desc) &&
696 !IDirect3DTexture9_LockRect(texture, level, &lockedRect, null, 0))
701 mipMap.width = desc.Width;
702 mipMap.height = desc.Height;
703 mipMap.picture = lockedRect.pBits;
706 case D3DFMT_R5G6B5: mipMap.pixelFormat = pixelFormat565; break;
707 case D3DFMT_A8R8G8B8: mipMap.pixelFormat = pixelFormat888; break;
708 case D3DFMT_A1R5G5B5: mipMap.pixelFormat = pixelFormat555; break;
714 mipMap.stride = lockedRect.Pitch >> GetColorDepthShifts(mipMap.pixelFormat);
716 mipSurface = mipMap.GetSurface(0,0,null);
719 if(mipMap.width != bitmap.width || mipMap.height != bitmap.height)
720 mipSurface.Filter(bitmap, 0,0, 0,0, mipMap.width, mipMap.height, bitmap.width, bitmap.height);
723 //FillBytesBy4(mipMap.picture, bitmap.picture, mipMap.width * mipMap.height);
724 mipSurface.Blit(bitmap, 0,0, 0,0, bitmap.width, bitmap.height);
730 IDirect3DTexture9_UnlockRect(texture, level);
732 mipMap.picture = null;
738 bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
739 bitmap.driver = displaySystem.driver;
740 bitmap.driverData = (void *)texture;
743 FreeBitmap(displaySystem, bitmap);
749 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
752 D3DDisplay d3dDisplay = display.driverData;
753 DisplaySystem displaySystem = display.displaySystem;
754 D3DSystem d3dSystem = displaySystem.driverData;
755 D3DSurface d3dSurface = surface.driverData = D3DSurface { };
757 if(d3dSurface && d3dSystem.ready)
759 surface.unclippedBox = surface.box = clip;
760 surface.offset.x = x;
761 surface.offset.y = y;
763 d3dDisplay.updateBox.left = Min(x + clip.left, d3dDisplay.updateBox.left);
764 d3dDisplay.updateBox.top = Min(y + clip.top, d3dDisplay.updateBox.top);
765 d3dDisplay.updateBox.right = Max(x + clip.right, d3dDisplay.updateBox.right);
766 d3dDisplay.updateBox.bottom = Max(y + clip.bottom, d3dDisplay.updateBox.bottom);
768 SetViewportAndMatrices(display, x,y, surface.box);
775 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
780 void ReleaseSurface(Display display, Surface surface)
782 delete surface.driverData;
785 void Clip(Display display, Surface surface, Box clip)
792 box.Clip(surface.unclippedBox);
796 box = surface.box = surface.unclippedBox;
798 SetViewportAndMatrices(display, surface.offset.x, surface.offset.y, box);
801 void SetForeground(Display display, Surface surface, ColorAlpha color)
806 void SetBackground(Display display, Surface surface, ColorAlpha color)
808 D3DSurface d3dSurface = surface.driverData;
809 d3dSurface.background = color;
812 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
817 void PutPixel(Display display, Surface surface,int x, int y)
819 DisplaySystem displaySystem = display.displaySystem;
820 D3DSystem d3dSystem = displaySystem.driverData;
821 Vertex vertex { (float)x, (float)y, 1.0f, surface.foreground, 0, 0 };
823 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_POINTLIST, 1,
824 &vertex, sizeof(Vertex));
827 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
829 DisplaySystem displaySystem = display.displaySystem;
830 D3DSystem d3dSystem = displaySystem.driverData;
833 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
834 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 }
854 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 1,
855 vertex, sizeof(Vertex));
858 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
860 DisplaySystem displaySystem = display.displaySystem;
861 D3DSystem d3dSystem = displaySystem.driverData;
864 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
865 { (float)x2, (float)y1, 1.0f, surface.foreground, 0, 0 },
866 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 },
867 { (float)x1, (float)y2, 1.0f, surface.foreground, 0, 0 },
868 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 }
871 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 4,
872 vertex, sizeof(Vertex));
876 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
878 DisplaySystem displaySystem = display.displaySystem;
879 D3DSystem d3dSystem = displaySystem.driverData;
880 D3DSurface d3dSurface = surface.driverData;
884 { (float)x1, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
885 { (float)x2 + 1.0f, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
886 { (float)x1, (float)y2, 1.0f, d3dSurface.background, 0, 0 },
887 { (float)x2 + 1.0f, (float)y2, 1.0f, d3dSurface.background, 0, 0 }
889 { (float)x1, (float)y1 - 0.5f, 1.0f, d3dSurface.background, 0, 0 },
890 { (float)x2 + 1.0f, (float)y1 - 0.5f, 1.0f, d3dSurface.background, 0, 0 },
891 { (float)x1, (float)y2 + 1.5f, 1.0f, d3dSurface.background, 0, 0 },
892 { (float)x2 + 1.0f, (float)y2 + 1.5f, 1.0f, d3dSurface.background, 0, 0 }
895 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
896 vertex, sizeof(Vertex));
899 void Clear(Display display, Surface surface, ClearType type)
901 DisplaySystem displaySystem = display.displaySystem;
902 D3DSystem d3dSystem = displaySystem.driverData;
903 D3DSurface d3dSurface = surface.driverData;
904 IDirect3DDevice9_Clear(d3dSystem.d3dDevice, 0, null,
905 ((type == depthBuffer) ? 0 : D3DCLEAR_TARGET) |
906 ((type == colorBuffer) ? 0 : D3DCLEAR_ZBUFFER),
907 d3dSurface.background, 1,0);
910 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
915 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
917 DisplaySystem displaySystem = display.displaySystem;
918 D3DSystem d3dSystem = displaySystem.driverData;
919 D3DSurface d3dSurface = surface.driverData;
920 Color foreground = d3dSurface.writingText ? surface.foreground : white;
923 { (float)dx, (float)dy, 1.0f, foreground,
924 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
925 { (float)(dx+w), (float)dy, 1.0f, foreground,
926 (float)(sx+w)/ (src.width-1), (float)sy/ (src.height-1) },
927 { (float)dx, (float)(dy+h), 1.0f, foreground,
928 (float)sx/ (src.width-1), (float)(sy+h)/ (src.height-1) },
929 { (float)(dx+w), (float)(dy+h), 1.0f, foreground,
930 (float)(sx+w) / (src.width-1), (float)(sy+h)/ (src.height-1) }
933 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture9 *)src.driverData);
934 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
935 vertex, sizeof(Vertex));
936 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, null);
939 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
941 DisplaySystem displaySystem = display.displaySystem;
942 D3DSystem d3dSystem = displaySystem.driverData;
945 { (float)dx, (float)dy, 1.0f, surface.foreground,
946 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
947 { (float)(dx+w), (float)dy, 1.0f, surface.foreground,
948 (float)(sx+sw)/ (src.width-1), (float)sy/ (src.height-1) },
949 { (float)dx, (float)(dy+h), 1.0f, surface.foreground,
950 (float)sx/ (src.width-1), (float)(sy+sh)/ (src.height-1) },
951 { (float)(dx+w), (float)(dy+h), 1.0f, surface.foreground,
952 (float)(sx+sw) / (src.width-1), (float)(sy+sh)/ (src.height-1) }
955 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture9 *)src.driverData);
956 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
957 vertex, sizeof(Vertex));
958 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, null);
961 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
963 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
966 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
969 Bitmap lfbBitmap { };
970 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
972 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Stretch(null, lfbSurface, src, dx, dy, sx, sy, w, h, sw, sh);
973 UnlockDisplay(display, lfbSurface);
975 lfbBitmap.picture = null;
979 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
982 Bitmap lfbBitmap { };
983 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
985 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, lfbSurface, src, dx, dy, sx, sy, w, h);
986 UnlockDisplay(display, lfbSurface);
988 lfbBitmap.picture = null;
992 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
994 StretchDI(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
997 void UnloadFont(DisplaySystem displaySystem, Font font)
999 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
1002 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
1004 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags, outlineSize, outlineFade);
1007 void TextFont(Display display, Surface surface, Font font)
1009 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
1012 void TextOpacity(Display display, Surface surface, bool opaque)
1014 D3DSurface d3dSurface = surface.driverData;
1015 d3dSurface.opaqueText = opaque;
1018 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
1020 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height, prevGlyph, rPrevGlyph, adv);
1023 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
1025 DisplaySystem displaySystem = display.displaySystem;
1026 D3DSystem d3dSystem = displaySystem.driverData;
1027 D3DSurface d3dSurface = surface.driverData;
1029 if(surface.textOpacity)
1032 FontExtent(display.displaySystem, surface.font, text, len, &w, &h, prevGlyph, rPrevGlyph, &adv);
1035 int x1 = x, y1 = y, x2 = x+w-1, y2 = y+h-1;
1038 { (float)x1, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1039 { (float)x2 + 1.0f, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1040 { (float)x1, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 },
1041 { (float)x2 + 1.0f, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 }
1044 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
1045 vertex, sizeof(Vertex));
1047 //display.displaySystem.driver.Area(display, surface, x, y, x+w-1, y+h-1);
1050 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1051 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1052 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1053 d3dSurface.writingText = true;
1055 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
1057 d3dSurface.writingText = false;
1058 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
1059 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1060 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1063 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
1065 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, width, height, prevGlyph, rPrevGlyph, adv);
1068 void DrawingChar(Display display, Surface surface, char character)
1073 void LineStipple(Display display, Surface surface, uint stipple)
1076 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_LINEPATTERN,
1077 stipple?Muint(1,stipple):0);
1082 void SetRenderState(Display display, RenderState state, uint value)
1084 DisplaySystem displaySystem = display.displaySystem;
1085 D3DSystem d3dSystem = displaySystem.driverData;
1086 D3DDisplay d3dDisplay = display.driverData;
1090 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, value ? TRUE : FALSE);
1093 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FILLMODE,
1094 ((FillModeValue)value == solid) ? D3DFILL_SOLID : D3DFILL_WIREFRAME);
1097 // IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_USEW : D3DZB_FALSE);
1098 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_TRUE : D3DZB_FALSE);
1101 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZWRITEENABLE, value);
1104 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGCOLOR, value);
1108 float fogDensity = RenderStateFloat { ui = value }.f;
1109 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGDENSITY, RenderStateFloat { fogDensity }.ui);
1113 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ALPHABLENDENABLE, value);
1116 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_AMBIENT, value);
1120 if(d3dDisplay.vSync != (bool)value)
1122 d3dDisplay.vSync = (bool)value;
1123 DisplaySize(display, display.width, display.height);
1130 void SetLight(Display display, int id, Light light)
1132 DisplaySystem displaySystem = display.displaySystem;
1133 D3DSystem d3dSystem = displaySystem.driverData;
1134 D3DDisplay d3dDisplay = display.driverData;
1137 D3DLIGHT9 d3dLight =
1139 // Opacity on the light?
1140 D3DLIGHT_DIRECTIONAL,
1141 { light.diffuse.r, light.diffuse.g, light.diffuse.b, 1.0f },
1142 { light.specular.r, light.specular.g, light.specular.b, 1.0f },
1143 { light.ambient.r, light.ambient.g, light.ambient.b, 1.0f }
1145 Vector3Df vector {0,0,1};
1146 Vector3Df vectorPI {0,0,-1};
1147 Vector3Df direction;
1149 Vector3Df * lightDirection = (Vector3Df *)&d3dLight.Direction;
1151 mat.RotationQuaternion(light.orientation);
1153 direction.MultMatrix(vector, mat);
1154 if(!display.display3D || !display.display3D.camera)
1156 d3dLight.Direction.x = direction.x;
1157 d3dLight.Direction.y = direction.y;
1158 d3dLight.Direction.z =-direction.z;
1161 lightDirection->MultMatrix(direction, d3dDisplay.worldMatrix);
1163 d3dDisplay.lights[id] = d3dLight;
1165 IDirect3DDevice9_LightEnable(d3dSystem.d3dDevice, id, TRUE);
1166 IDirect3DDevice9_SetLight(d3dSystem.d3dDevice, id, &d3dDisplay.lights[id] /*d3dLight*/);
1168 direction.MultMatrix(vectorPI, mat);
1169 lightDirection->MultMatrix(direction, d3dDisplay.worldMatrix);
1171 d3dDisplay.lightsPI[id] = d3dLight;
1175 IDirect3DDevice9_LightEnable(d3dSystem.d3dDevice, id, FALSE);
1176 d3dDisplay.lights[id].Type = 0;
1180 void SetCamera(Display display, Surface surface, Camera camera)
1182 DisplaySystem displaySystem = display.displaySystem;
1183 D3DSystem d3dSystem = displaySystem.driverData;
1184 D3DDisplay d3dDisplay = display.driverData;
1185 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1188 Point topLeft {surface.box.left + surface.offset.x, surface.box.top + surface.offset.y};
1189 Point downRight {surface.box.right + surface.offset.x, surface.box.bottom + surface.offset.y};
1192 surface.offset.x + camera.origin.x,
1193 surface.offset.y + camera.origin.y
1197 float l = (topLeft.x - origin.x) * camera.zMin / camera.focalX;
1198 float r = (downRight.x - origin.x) * camera.zMin / camera.focalX;
1199 float b = (downRight.y - origin.y) * camera.zMin / camera.focalY;
1200 float t = (topLeft.y - origin.y) * camera.zMin / camera.focalY;
1201 float n = camera.zMin;
1202 float f = camera.zMax;
1204 matProj.m[0][0] = 2 * n / (r - l);
1205 matProj.m[0][1] = 0;
1206 matProj.m[0][2] = 0;
1207 matProj.m[0][3] = 0;
1209 matProj.m[1][0] = 0;
1210 matProj.m[1][1] = 2 * n / (t - b);
1211 matProj.m[1][2] = 0;
1212 matProj.m[1][3] = 0;
1214 matProj.m[2][0] = (l + r) / (r - l);
1215 matProj.m[2][1] = (t + b) / (t - b);
1216 matProj.m[2][2] = f / (n - f);
1217 matProj.m[2][3] = -1;
1219 matProj.m[3][0] = 0;
1220 matProj.m[3][1] = 0;
1221 matProj.m[3][2] = n * f / (n - f);
1222 matProj.m[3][3] = 0;
1224 IDirect3DDevice9_SetTransform(d3dDevice, D3DTS_PROJECTION, &matProj);
1226 // *** View Matrix ***
1227 if(!display.display3D.camera)
1228 d3dDisplay.worldMatrix++;
1231 matrix.Scale(1.0f, 1.0f, -1.0f);
1232 d3dDisplay.worldMatrix->Multiply(camera.viewMatrix, matrix);
1234 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1236 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decls[0]);
1238 // IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_USEW);
1239 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_TRUE);
1240 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZWRITEENABLE, TRUE);
1241 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, FALSE);
1242 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, TRUE);
1243 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, TRUE);
1245 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1247 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
1249 else if(display.display3D.camera)
1251 d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
1252 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1253 IDirect3DDevice9_SetTransform(d3dDevice, D3DTS_PROJECTION, &d3dDisplay.projMatrix);
1255 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
1256 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
1257 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
1258 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
1259 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGENABLE, FALSE);
1260 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, FALSE);
1262 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1263 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1265 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decl2D);
1267 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
1269 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
1273 void ApplyMaterial(Display display, Material material, Mesh mesh)
1275 DisplaySystem displaySystem = display.displaySystem;
1276 D3DSystem d3dSystem = displaySystem.driverData;
1277 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1278 D3DMesh d3dMesh = mesh.data;
1281 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGENABLE, (material.flags.noFog) ? FALSE : TRUE);
1284 if(material.baseMap && d3dMesh.texCoords && material.baseMap.driver.displaySystem == displaySystem)
1286 Bitmap map = material.baseMap;
1288 IDirect3DDevice9_SetTexture(d3dDevice, 0, (IDirect3DBaseTexture9 *)map.driverData);
1290 if(material.flags.tile)
1292 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
1293 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
1297 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1298 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1302 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
1305 D3DMATERIAL9 d3dMaterial;
1307 d3dMaterial.Diffuse.r = material.diffuse.r;
1308 d3dMaterial.Diffuse.g = material.diffuse.g;
1309 d3dMaterial.Diffuse.b = material.diffuse.b;
1310 d3dMaterial.Diffuse.a = material.opacity;
1312 d3dMaterial.Ambient.r = material.ambient.r;
1313 d3dMaterial.Ambient.g = material.ambient.g;
1314 d3dMaterial.Ambient.b = material.ambient.b;
1315 d3dMaterial.Ambient.a = 1;
1317 d3dMaterial.Specular.r = material.specular.r;
1318 d3dMaterial.Specular.g = material.specular.g;
1319 d3dMaterial.Specular.b = material.specular.b;
1320 d3dMaterial.Specular.a = 1;
1322 d3dMaterial.Emissive.r = material.emissive.r;
1323 d3dMaterial.Emissive.g = material.emissive.g;
1324 d3dMaterial.Emissive.b = material.emissive.b;
1325 d3dMaterial.Emissive.a = 1;
1327 d3dMaterial.Power = material.power;
1329 IDirect3DDevice9_SetMaterial(d3dDevice, &d3dMaterial); //(D3DMATERIAL9 *)&material.diffuse
1333 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
1335 D3DMesh d3dMesh = mesh.data;
1338 if(!(mesh.flags.vertices))
1340 if(d3dMesh.vertices)
1342 IDirect3DVertexBuffer9_Release(d3dMesh.vertices);
1343 d3dMesh.vertices = null;
1345 delete mesh.vertices;
1347 if(!(mesh.flags.normals))
1351 IDirect3DVertexBuffer9_Release(d3dMesh.normals);
1352 d3dMesh.normals = null;
1354 delete mesh.normals;
1356 if(!(mesh.flags.texCoords1))
1358 if(d3dMesh.texCoords)
1360 IDirect3DVertexBuffer9_Release(d3dMesh.texCoords);
1361 d3dMesh.texCoords = null;
1363 delete mesh.texCoords;
1365 if(!(mesh.flags.texCoords2))
1367 if(d3dMesh.texCoords2)
1369 IDirect3DVertexBuffer9_Release(d3dMesh.texCoords2);
1370 d3dMesh.texCoords2 = null;
1372 // delete mesh.texCoords2;
1382 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
1384 D3DSystem d3dSystem = displaySystem.driverData;
1385 bool result = false;
1386 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1389 mesh.data = D3DMesh { };
1392 D3DMesh d3dMesh = mesh.data;
1394 if(mesh.nVertices == nVertices)
1396 if(mesh.flags != flags)
1398 // Same number of vertices, adding features (Leaves the other features pointers alone)
1399 if(flags.vertices && !d3dMesh.vertices)
1401 mesh.vertices = new Vector3Df[nVertices];
1402 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1403 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices, null))
1406 if(flags.normals && !d3dMesh.normals)
1408 mesh.normals = new Vector3Df[nVertices];
1409 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1410 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals, null))
1413 if(flags.texCoords1 && !d3dMesh.texCoords)
1415 mesh.texCoords = new Pointf[nVertices];
1416 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * nVertices,
1417 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords, null))
1424 // New number of vertices, reallocate all current and new features
1425 flags |= mesh.flags;
1427 // Same number of vertices, adding features (Leaves the other features pointers alone)
1430 if(d3dMesh.vertices)
1432 IDirect3DVertexBuffer9_Release(d3dMesh.vertices);
1433 d3dMesh.vertices = null;
1435 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
1436 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1437 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices, null))
1444 IDirect3DVertexBuffer9_Release(d3dMesh.normals);
1445 d3dMesh.normals = null;
1447 mesh.normals = renew mesh.normals Vector3Df[nVertices];
1448 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * nVertices,
1449 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals, null))
1452 if(flags.texCoords1)
1454 if(d3dMesh.texCoords)
1456 IDirect3DVertexBuffer9_Release(d3dMesh.texCoords);
1457 d3dMesh.texCoords = null;
1459 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
1460 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * nVertices,
1461 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords, null))
1469 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1471 D3DMesh d3dMesh = mesh.data;
1472 if(!flags) flags = mesh.flags;
1474 if(flags.vertices && mesh.vertices)
1476 Vector3Df * vertices;
1477 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.vertices, 0, 0, (void **) &vertices, 0))
1479 memcpy(vertices, mesh.vertices, mesh.nVertices * sizeof(Vector3Df));
1480 IDirect3DVertexBuffer9_Unlock(d3dMesh.vertices);
1483 if(flags.normals && mesh.normals)
1485 Vector3Df * normals;
1486 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.normals, 0, 0, (void **) &normals, 0))
1488 memcpy(normals, mesh.normals, mesh.nVertices * sizeof(Vector3Df));
1489 IDirect3DVertexBuffer9_Unlock(d3dMesh.normals);
1492 if(flags.texCoords1 && mesh.texCoords)
1495 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.texCoords, 0, 0, (void **) &texCoords, 0))
1497 memcpy(texCoords, mesh.texCoords, mesh.nVertices * sizeof(Pointf));
1498 IDirect3DVertexBuffer9_Unlock(d3dMesh.texCoords);
1503 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1509 void FreeIndices(DisplaySystem displaySystem, D3DIndices d3dIndices)
1513 if(d3dIndices.buffer)
1514 IDirect3DIndexBuffer9_Release(d3dIndices.buffer);
1515 delete d3dIndices.indices;
1520 D3DIndices AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
1522 D3DSystem d3dSystem = displaySystem.driverData;
1523 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1524 D3DIndices d3dIndices { };
1525 if(d3dIndices && nIndices)
1527 d3dIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
1528 IDirect3DDevice9_CreateIndexBuffer(d3dDevice, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * nIndices, 0, indices32bit ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
1529 D3DPOOL_MANAGED, &d3dIndices.buffer, null);
1530 d3dIndices.nIndices = nIndices;
1535 void UnlockIndices(DisplaySystem displaySystem, D3DIndices d3dIndices, bool indices32bit, int nIndices)
1537 uint16 * indexBuffer = null;
1538 if(!IDirect3DIndexBuffer9_Lock(d3dIndices.buffer, 0, 0, (void **)&indexBuffer, 0))
1540 memcpy(indexBuffer, d3dIndices.indices, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * d3dIndices.nIndices);
1541 IDirect3DIndexBuffer9_Unlock(d3dIndices.buffer);
1545 uint16 * LockIndices(DisplaySystem displaySystem, D3DIndices d3dIndices)
1547 return d3dIndices.indices;
1550 void SelectMesh(Display display, Mesh mesh)
1552 DisplaySystem displaySystem = display.displaySystem;
1553 D3DSystem d3dSystem = displaySystem.driverData;
1554 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1556 if(mesh && mesh.data)
1559 D3DMesh d3dMesh = mesh.data;
1561 IDirect3DDevice9_SetStreamSource(d3dDevice, 0, d3dMesh.vertices, 0, sizeof(Vector3Df));
1564 IDirect3DDevice9_SetStreamSource(d3dDevice, 1, d3dMesh.normals, 0, sizeof(Vector3Df));
1568 IDirect3DDevice9_SetStreamSource(d3dDevice, 1, null, 0, sizeof(Vector3Df));
1569 if(d3dMesh.texCoords)
1571 IDirect3DDevice9_SetStreamSource(d3dDevice, 2, d3dMesh.texCoords, 0, sizeof(Pointf));
1575 IDirect3DDevice9_SetStreamSource(d3dDevice, 2, null, 0, sizeof(Pointf));
1577 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decls[decl]);
1581 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
1583 DisplaySystem displaySystem = display.displaySystem;
1584 D3DSystem d3dSystem = displaySystem.driverData;
1585 D3DDisplay d3dDisplay = display.driverData;
1586 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1588 if(primitiveTypes[primitive->type.primitiveType])
1590 int numPrimitives = (primitive->type.vertexRange) ? primitive->nVertices : primitive->nIndices;
1593 switch(primitive->type.primitiveType)
1595 case lines: numPrimitives /= 2; break;
1596 case triangles: numPrimitives /= 3; break;
1608 if(primitive->type.vertexRange)
1610 if(primitive->type.primitiveType == quads)
1612 for(c = 0; c<numPrimitives; c++)
1613 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1616 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1620 D3DIndices indices = primitive->data;
1621 IDirect3DDevice9_SetIndices(d3dDevice, indices.buffer);
1622 if(primitive->type.primitiveType == quads)
1624 for(c = 0; c<numPrimitives; c++)
1625 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, c*4, 2);
1628 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, 0, numPrimitives);
1631 if(display.display3D.material.flags.doubleSided)
1633 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CCW);
1634 if(!display.display3D.material.flags.singleSideLight)
1636 for(c = 0; c<NumberOfLights; c++)
1637 if(d3dDisplay.lights[c].Type)
1638 IDirect3DDevice9_SetLight(d3dDevice, c, &d3dDisplay.lightsPI[c]);
1641 if(primitive->type.vertexRange)
1643 if(primitive->type.primitiveType == quads)
1645 for(c = 0; c<numPrimitives; c++)
1646 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1649 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1653 D3DIndices indices = primitive->data;
1654 IDirect3DDevice9_SetIndices(d3dDevice, indices.buffer);
1655 if(primitive->type.primitiveType == quads)
1657 for(c = 0; c<numPrimitives; c++)
1658 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, c*4, 2);
1661 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, 0, numPrimitives);
1663 if(!display.display3D.material.flags.singleSideLight)
1665 for(c = 0; c<NumberOfLights; c++)
1666 if(d3dDisplay.lights[c].Type)
1667 IDirect3DDevice9_SetLight(d3dDevice, c, &d3dDisplay.lights[c]);
1670 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1675 void PushMatrix(Display display)
1677 D3DDisplay d3dDisplay = display.driverData;
1678 *(d3dDisplay.worldMatrix+1) = *(d3dDisplay.worldMatrix);
1679 d3dDisplay.worldMatrix++;
1682 void PopMatrix(Display display, bool setMatrix)
1684 D3DDisplay d3dDisplay = display.driverData;
1685 DisplaySystem displaySystem = display.displaySystem;
1686 D3DSystem d3dSystem = displaySystem.driverData;
1687 d3dDisplay.worldMatrix--;
1689 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1692 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
1694 DisplaySystem displaySystem = display.displaySystem;
1695 D3DSystem d3dSystem = displaySystem.driverData;
1696 Camera camera = useCamera ? display.display3D.camera : null;
1697 D3DDisplay d3dDisplay = display.driverData;
1698 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1700 Matrix matrix = transMatrix, temp;
1704 matrix.Scale(1.0f, 1.0f, -1.0f);
1705 *(d3dDisplay.worldMatrix) = matrix;
1711 - camera.cPosition.x,
1712 - camera.cPosition.y,
1713 - camera.cPosition.z);
1714 temp.Multiply(matrix, d3dDisplay.worldMatrix);
1715 *(d3dDisplay.worldMatrix) = temp;
1718 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1721 bool Lock(Display display)
1723 DisplaySystem displaySystem = display.displaySystem;
1724 D3DSystem d3dSystem = displaySystem.driverData;
1725 D3DDisplay d3dDisplay = display.driverData;
1727 if(d3dDisplay.backBuffer)
1729 IDirect3DDevice9_SetDepthStencilSurface(d3dSystem.d3dDevice, d3dDisplay.depthSurface);
1730 IDirect3DDevice9_SetRenderTarget(d3dSystem.d3dDevice, 0, d3dDisplay.backBuffer);
1731 IDirect3DDevice9_BeginScene(d3dSystem.d3dDevice);
1733 d3dSystem.inScene = true;
1738 void Unlock(Display display)
1740 DisplaySystem displaySystem = display.displaySystem;
1741 D3DSystem d3dSystem = displaySystem.driverData;
1743 if(d3dSystem.inScene)
1745 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
1746 d3dSystem.inScene = false;