1 namespace gfx::drivers;
7 #define D3D_DEBUG_INFO 1
16 #if defined(__MINGW32__)
17 #undef DECLARE_INTERFACE
18 #define DECLARE_INTERFACE(i) \
19 interface i { CONST_VTABLE struct i##Vtbl *lpVtbl; }; \
20 typedef CONST_VTABLE struct i##Vtbl i##Vtbl; \
21 CONST_VTABLE struct i##Vtbl
32 #define MATRIX_STACK_SIZE 32
34 #define NUM_VERTEX_DECLS 4
36 static class D3DDisplay : struct
39 IDirect3DSwapChain9 * swapChain;
40 Matrix worldMatrixStack[MATRIX_STACK_SIZE];
43 D3DLIGHT9 lights[NumberOfLights], lightsPI[NumberOfLights];
44 D3DPRESENT_PARAMETERS d3dpp;
45 IDirect3DSurface9 * backBuffer, * depthSurface;
49 static class D3DSystem : struct
52 IDirect3D9 * direct3D;
53 IDirect3DDevice9 * d3dDevice;
54 IDirect3D9 * (WINAPI * direct3DCreate9)(UINT);
56 D3DPRESENT_PARAMETERS d3dpp;
58 IDirect3DVertexDeclaration9 * decls[NUM_VERTEX_DECLS], * decl2D;
65 static class D3DSurface : struct
67 // For compatibility with LFB driver
73 ColorAlpha background;
76 static class D3DMesh : struct
78 IDirect3DVertexBuffer9 * vertices;
79 IDirect3DVertexBuffer9 * normals;
80 IDirect3DVertexBuffer9 * texCoords;
81 IDirect3DVertexBuffer9 * texCoords2;
91 static class D3DIndices : struct
94 IDirect3DIndexBuffer9 * buffer;
98 static int primitiveTypes[RenderPrimitiveType] =
100 D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP, D3DPT_TRIANGLEFAN, D3DPT_TRIANGLEFAN, 0, D3DPT_LINESTRIP
103 static void SetTransformMatrix(IDirect3DDevice9 * device, Matrix matrix)
109 (float)matrix.m[0][0], (float)matrix.m[0][1], (float)matrix.m[0][2], (float)matrix.m[0][3],
110 (float)matrix.m[1][0], (float)matrix.m[1][1], (float)matrix.m[1][2], (float)matrix.m[1][3],
111 (float)matrix.m[2][0], (float)matrix.m[2][1], (float)matrix.m[2][2], (float)matrix.m[2][3],
112 (float)matrix.m[3][0], (float)matrix.m[3][1], (float)matrix.m[3][2], (float)matrix.m[3][3]
116 IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &d3dMat);
119 class Direct3D9DisplayDriver : DisplayDriver
121 class_property(name) = "Direct3D";
124 bool ::LockDisplay(Display display, Surface surface, Bitmap lfbBitmap, Surface * lfbSurface)
127 DisplaySystem displaySystem = display.displaySystem;
128 D3DSystem d3dSystem = displaySystem.driverData;
129 D3DDisplay d3dDisplay = display.driverData;
131 //if(!IDirect3DDevice9_GetBackBuffer(d3dSystem.d3dDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
133 D3DLOCKED_RECT lockedRect;
134 if(!IDirect3DSurface9_LockRect(d3dDisplay.backBuffer, &lockedRect, null, 0))
136 switch(d3dDisplay.d3dpp.BackBufferFormat)
138 case D3DFMT_A8R8G8B8:
139 case D3DFMT_X8R8G8B8:
140 lfbBitmap.pixelFormat = pixelFormat888;
143 lfbBitmap.pixelFormat = pixelFormat565;
145 case D3DFMT_X1R5G5B5:
146 case D3DFMT_A1R5G5B5:
147 lfbBitmap.pixelFormat = pixelFormat555;
149 case D3DFMT_A4R4G4B4:
150 case D3DFMT_X4R4G4B4:
151 lfbBitmap.pixelFormat = pixelFormat444;
154 lfbBitmap.driver = null;
155 lfbBitmap.displaySystem = null;
156 lfbBitmap.picture = (byte *)lockedRect.pBits;
157 lfbBitmap.transparent = false;
158 lfbBitmap.stride = lockedRect.Pitch >> GetColorDepthShifts(lfbBitmap.pixelFormat);
159 lfbBitmap.width = display.width;
160 lfbBitmap.height = display.height;
162 *lfbSurface = lfbBitmap.GetSurface(surface ? surface.offset.x : 0, surface ? surface.offset.y : 0, surface ? surface.box : null);
166 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
171 void ::UnlockDisplay(Display display, Surface surface)
173 DisplaySystem displaySystem = display.displaySystem;
174 D3DSystem d3dSystem = displaySystem.driverData;
175 D3DDisplay d3dDisplay = display.driverData;
176 if(d3dDisplay.backBuffer)
178 IDirect3DSurface9_UnlockRect(d3dDisplay.backBuffer);
179 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
184 void ::SetViewportAndMatrices(Display display, int x, int y, Box box)
186 D3DDisplay d3dDisplay = display.driverData;
187 DisplaySystem displaySystem = display.displaySystem;
188 D3DSystem d3dSystem = displaySystem.driverData;
191 D3DVIEWPORT9 viewport;
194 if(box.right < box.left || box.bottom < box.top)
196 viewport.Width = viewport.Height = 1;
197 viewport.X = viewport.Y = MAXDWORD;
201 viewport.X = x + box.left;
202 viewport.Y = y + box.top;
203 viewport.Width = box.right - box.left + 1;
204 viewport.Height = box.bottom - box.top + 1;
206 if(!IDirect3DDevice9_SetViewport(d3dSystem.d3dDevice, &viewport))
208 D3DMATRIX * matProj = &d3dDisplay.projMatrix;
209 Matrix * matWorld = d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
211 matProj->m[0][0] = 2.0f / viewport.Width;
212 matProj->m[1][1] =-2.0f / viewport.Height;
213 matProj->m[2][2] = matProj->m[3][1] = matProj->m[3][3] = 1;
214 matProj->m[3][0] = -1;
216 IDirect3DDevice9_SetTransform(d3dSystem.d3dDevice, D3DTS_PROJECTION, matProj);
218 matWorld->Identity();
219 matWorld->m[3][0] =-box.left;
220 matWorld->m[3][1] =-box.top;
222 SetTransformMatrix(d3dSystem.d3dDevice, matWorld);
228 bool CreateDisplaySystem(DisplaySystem displaySystem)
231 D3DSystem d3dSystem = displaySystem.driverData = D3DSystem { };
234 displaySystem.flags.alpha = true;
235 //if(displaySystem.flags.fullScreen)
236 displaySystem.flags.flipping = true;
237 displaySystem.pixelFormat = pixelFormat888;
239 d3dSystem.d3dDll = LoadLibrary("d3d9.dll");
242 d3dSystem.direct3DCreate9 = (void *)GetProcAddress(d3dSystem.d3dDll, "Direct3DCreate9");
243 if(d3dSystem.direct3DCreate9)
245 if(d3dSystem.direct3D = d3dSystem.direct3DCreate9(D3D_SDK_VERSION))
247 D3DDISPLAYMODE d3ddm;
248 if(!IDirect3D9_GetAdapterDisplayMode(d3dSystem.direct3D, D3DADAPTER_DEFAULT, &d3ddm))
250 d3dSystem.d3dpp.BackBufferCount = 1;
252 if(displaySystem.flags.fullScreen)
254 d3dSystem.d3dpp.BackBufferWidth = d3ddm.Width;
255 d3dSystem.d3dpp.BackBufferHeight = d3ddm.Height;
256 d3dSystem.d3dpp.hDeviceWindow = displaySystem.window;
260 d3dSystem.d3dpp.hDeviceWindow = d3dSystem.hwnd =
261 CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
262 d3dSystem.d3dpp.Windowed = TRUE;
265 d3dSystem.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
266 d3dSystem.format = d3dSystem.d3dpp.BackBufferFormat = d3ddm.Format;
267 d3dSystem.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
269 if(!IDirect3D9_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
270 d3dSystem.d3dpp.hDeviceWindow,
271 D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE|D3DCREATE_FPU_PRESERVE,
272 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
276 d3dSystem.usage = D3DUSAGE_SOFTWAREPROCESSING;
277 if(!IDirect3D9_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
278 d3dSystem.d3dpp.hDeviceWindow,
279 D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,
280 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
286 D3DVERTEXELEMENT9 vertexDecls[NUM_VERTEX_DECLS][4] =
289 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
293 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
294 { 1, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 },
298 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
299 { 2, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
303 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
304 { 1, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 },
305 { 2, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
310 D3DVERTEXELEMENT9 vertexDecl2D[] =
312 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
313 { 0, (uint16)(3*sizeof(float)), D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 },
314 { 0, (uint16)(3*sizeof(float) + sizeof(uint)), D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
319 for(c = 0; c<NUM_VERTEX_DECLS; c++)
320 if(IDirect3DDevice9_CreateVertexDeclaration(d3dSystem.d3dDevice, vertexDecls[c], &d3dSystem.decls[c]))
323 if(c < NUM_VERTEX_DECLS ||
324 IDirect3DDevice9_CreateVertexDeclaration(d3dSystem.d3dDevice, vertexDecl2D, &d3dSystem.decl2D))
328 d3dSystem.ready = false;
334 Log("Couldn't load library d3d9.dll\n");
335 //LogErrorCode(ERR_MISSING_LIBRARY, "d3d9.dll");
340 void DestroyDisplaySystem(DisplaySystem displaySystem)
342 D3DSystem d3dSystem = displaySystem.driverData;
345 if(d3dSystem.d3dDevice)
346 IDirect3DDevice9_Release(d3dSystem.d3dDevice);
348 if(d3dSystem.direct3D)
349 IDirect3D9_Release(d3dSystem.direct3D);
351 for(c = 0; c<NUM_VERTEX_DECLS; c++)
353 if(d3dSystem.decls[c])
354 IDirect3DVertexDeclaration9_Release(d3dSystem.decls[c]);
358 IDirect3DVertexDeclaration9_Release(d3dSystem.decl2D);
360 FreeLibrary(d3dSystem.d3dDll);
363 displaySystem.driverData = null;
367 void DestroyDisplay(Display display)
369 DisplaySystem displaySystem = display.displaySystem;
370 D3DSystem d3dSystem = displaySystem.driverData;
371 D3DDisplay d3dDisplay = display.driverData;
373 if(d3dSystem.inScene)
375 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
376 d3dSystem.inScene = false;
379 if(d3dDisplay.backBuffer)
380 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
382 if(d3dDisplay.depthSurface)
383 IDirect3DSurface9_Release(d3dDisplay.depthSurface);
385 if(d3dDisplay.swapChain)
386 IDirect3DSwapChain9_Release(d3dDisplay.swapChain);
389 display.driverData = null;
392 bool CreateDisplay(Display display)
395 DisplaySystem displaySystem = display.displaySystem;
396 D3DSystem d3dSystem = displaySystem.driverData;
397 D3DDisplay d3dDisplay = display.driverData = D3DDisplay { };
399 d3dSystem.ready = false;
406 bool DisplaySize(Display display, int width, int height)
409 DisplaySystem displaySystem = display.displaySystem;
410 D3DSystem d3dSystem = displaySystem.driverData;
411 D3DDisplay d3dDisplay = display.driverData;
412 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
414 d3dSystem.ready = false;
416 if(d3dDisplay.backBuffer)
418 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
419 d3dDisplay.backBuffer = null;
422 if(d3dDisplay.depthSurface)
424 IDirect3DSurface9_Release(d3dDisplay.depthSurface);
425 d3dDisplay.depthSurface = null;
428 if(d3dDisplay.swapChain)
430 IDirect3DSwapChain9_Release(d3dDisplay.swapChain);
431 d3dDisplay.swapChain = null;
437 if(displaySystem.flags.fullScreen)
439 d3dSystem.d3dpp.BackBufferWidth = width;
440 d3dSystem.d3dpp.BackBufferHeight = height;
442 result = !IDirect3DDevice9_Reset(d3dSystem.d3dDevice, &d3dSystem.d3dpp);
444 result = !IDirect3DDevice9_GetSwapChain(d3dSystem.d3dDevice, 0, &d3dDisplay.swapChain);
448 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;
449 d3dDisplay.d3dpp.BackBufferWidth = width;
450 d3dDisplay.d3dpp.BackBufferHeight = height;
451 d3dDisplay.d3dpp.Windowed = TRUE;
452 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
453 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
454 d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
456 //d3dDisplay.d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
457 d3dDisplay.d3dpp.BackBufferFormat = d3dSystem.format;
458 d3dDisplay.d3dpp.BackBufferCount = 1;
459 d3dDisplay.d3dpp.hDeviceWindow = display.window;
460 d3dDisplay.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
461 d3dDisplay.d3dpp.PresentationInterval = d3dDisplay.vSync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_DONOTWAIT;
462 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
463 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
465 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
466 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
470 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
471 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
472 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
476 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
477 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
478 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
484 if(!IDirect3DSwapChain9_GetBackBuffer(d3dDisplay.swapChain,
485 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
487 if(!IDirect3DDevice9_CreateDepthStencilSurface(d3dSystem.d3dDevice, width, height,
488 D3DFMT_D16, d3dDisplay.d3dpp.MultiSampleType,0,TRUE,&d3dDisplay.depthSurface, null))
491 d3dSystem.ready = true;
498 float fogDensity = 0;
500 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decl2D);
502 //IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
503 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
504 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
505 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
506 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
507 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
508 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
509 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGTABLEMODE, D3DFOG_EXP);
510 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGDENSITY, *(uint *)(void *)&fogDensity);
511 display.ambient = Color { 50,50,50 };
512 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_NORMALIZENORMALS, TRUE);
513 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
515 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
516 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
517 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
518 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
519 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
520 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
522 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
523 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
524 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
526 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
527 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
529 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
534 display.width = width;
535 display.height = height;
536 d3dDisplay.updateBox.left = display.width;
537 d3dDisplay.updateBox.top = display.height;
538 d3dDisplay.updateBox.right = 0;
539 d3dDisplay.updateBox.bottom = 0;
544 void DisplayPosition(Display display, int x, int y)
549 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
553 void RestorePalette(Display display)
557 void StartUpdate(Display display)
561 void EndUpdate(Display display)
565 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
569 void Update(Display display, Box updateBox)
571 DisplaySystem displaySystem = display.displaySystem;
572 D3DSystem d3dSystem = displaySystem.driverData;
573 D3DDisplay d3dDisplay = display.driverData;
576 //eSystem_Sleep(0.05);
577 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
579 if(display.displaySystem.flags.flipping)
581 // IDirect3DDevice9_Present(d3dSystem.d3dDevice, null, null, null, null);
582 IDirect3DSwapChain9_Present(d3dDisplay.swapChain, null, null, null, null, 0);
588 if(updateBox != null)
590 source.left = dest.left = updateBox.left;
591 source.top = dest.top = updateBox.top;
592 source.right = dest.right = updateBox.right+1;
593 source.bottom = dest.bottom = updateBox.bottom+1;
597 source.left = dest.left = d3dDisplay.updateBox.left;
598 source.top = dest.top = d3dDisplay.updateBox.top;
599 source.right = dest.right = d3dDisplay.updateBox.right+1;
600 source.bottom = dest.bottom = d3dDisplay.updateBox.bottom+1;
602 if(dest.bottom > dest.top && dest.right > dest.left)
603 IDirect3DDevice9_Present(d3dSystem.d3dDevice, &source, &dest, null, null);
604 if(updateBox == null)
606 d3dDisplay.updateBox.left = display.width;
607 d3dDisplay.updateBox.top = display.height;
608 d3dDisplay.updateBox.right = 0;
609 d3dDisplay.updateBox.bottom = 0;
612 d3dSystem.inScene = false;
616 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
620 Bitmap lfbBitmap { };
622 if(LockDisplay(display, null, lfbBitmap, &lfbSurface))
625 if(bitmap.pixelFormat != lfbBitmap.pixelFormat || bitmap.width < w || bitmap.height < h)
628 bitmap.Allocate(null, w,h,w, lfbBitmap.pixelFormat, false);
630 surface = bitmap.GetSurface(0, 0, null);
633 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, surface, lfbBitmap, 0, 0, x, y, w, h);
637 UnlockDisplay(display, lfbSurface);
640 lfbBitmap.picture = null;
648 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
651 IDirect3DTexture9_Release((IDirect3DTexture9 *)bitmap.picture);
654 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
659 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
662 D3DSystem d3dSystem = displaySystem.driverData;
663 if(bitmap.Convert(null, pixelFormat888, null))
665 IDirect3DTexture9 * texture;
666 uint w = pow2i(Min(bitmap.width, 512)), h = pow2i(Min(bitmap.height, 512));
668 if(!IDirect3DDevice9_CreateTexture(d3dSystem.d3dDevice, w, h, mipMaps ? log2i(Max(w+1, h+1)) : 1, 0,
669 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, null))
675 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
677 D3DSURFACE_DESC desc;
678 D3DLOCKED_RECT lockedRect;
680 if(!IDirect3DTexture9_GetLevelDesc(texture, level, &desc) &&
681 !IDirect3DTexture9_LockRect(texture, level, &lockedRect, null, 0))
686 mipMap.width = desc.Width;
687 mipMap.height = desc.Height;
688 mipMap.picture = lockedRect.pBits;
691 case D3DFMT_R5G6B5: mipMap.pixelFormat = pixelFormat565; break;
692 case D3DFMT_A8R8G8B8: mipMap.pixelFormat = pixelFormat888; break;
693 case D3DFMT_A1R5G5B5: mipMap.pixelFormat = pixelFormat555; break;
695 mipMap.stride = lockedRect.Pitch >> GetColorDepthShifts(mipMap.pixelFormat);
697 mipSurface = mipMap.GetSurface(0,0,null);
700 if(mipMap.width != bitmap.width || mipMap.height != bitmap.height)
701 mipSurface.Filter(bitmap, 0,0, 0,0, mipMap.width, mipMap.height, bitmap.width, bitmap.height);
704 //FillBytesBy4(mipMap.picture, bitmap.picture, mipMap.width * mipMap.height);
705 mipSurface.Blit(bitmap, 0,0, 0,0, bitmap.width, bitmap.height);
710 IDirect3DTexture9_UnlockRect(texture, level);
712 mipMap.picture = null;
718 bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
719 bitmap.driver = displaySystem.driver;
720 bitmap.picture = (void *)texture;
723 FreeBitmap(displaySystem, bitmap);
729 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
732 D3DDisplay d3dDisplay = display.driverData;
733 DisplaySystem displaySystem = display.displaySystem;
734 D3DSystem d3dSystem = displaySystem.driverData;
735 D3DSurface d3dSurface = surface.driverData = D3DSurface { };
737 if(d3dSurface && d3dSystem.ready)
739 surface.unclippedBox = surface.box = clip;
740 surface.offset.x = x;
741 surface.offset.y = y;
743 d3dDisplay.updateBox.left = Min(x + clip.left, d3dDisplay.updateBox.left);
744 d3dDisplay.updateBox.top = Min(y + clip.top, d3dDisplay.updateBox.top);
745 d3dDisplay.updateBox.right = Max(x + clip.right, d3dDisplay.updateBox.right);
746 d3dDisplay.updateBox.bottom = Max(y + clip.bottom, d3dDisplay.updateBox.bottom);
748 SetViewportAndMatrices(display, x,y, surface.box);
755 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
760 void ReleaseSurface(Display display, Surface surface)
762 delete surface.driverData;
765 void Clip(Display display, Surface surface, Box clip)
768 D3DDisplay d3dDisplay = display.driverData;
773 box.Clip(surface.unclippedBox);
777 box = surface.box = surface.unclippedBox;
779 SetViewportAndMatrices(display, surface.offset.x, surface.offset.y, box);
782 void SetForeground(Display display, Surface surface, ColorAlpha color)
787 void SetBackground(Display display, Surface surface, ColorAlpha color)
789 D3DSurface d3dSurface = surface.driverData;
790 d3dSurface.background = color;
793 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
798 void PutPixel(Display display, Surface surface,int x, int y)
800 D3DDisplay d3dDisplay = display.driverData;
801 D3DSurface d3dSurface = surface.driverData;
802 DisplaySystem displaySystem = display.displaySystem;
803 D3DSystem d3dSystem = displaySystem.driverData;
804 Vertex vertex { (float)x, (float)y, 1.0f, surface.foreground, 0, 0 };
806 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_POINTLIST, 1,
807 &vertex, sizeof(Vertex));
810 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
812 D3DSurface d3dSurface = surface.driverData;
813 D3DDisplay d3dDisplay = display.driverData;
814 DisplaySystem displaySystem = display.displaySystem;
815 D3DSystem d3dSystem = displaySystem.driverData;
818 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
819 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 }
839 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 1,
840 vertex, sizeof(Vertex));
843 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
845 DisplaySystem displaySystem = display.displaySystem;
846 D3DSystem d3dSystem = displaySystem.driverData;
847 D3DSurface d3dSurface = surface.driverData;
848 D3DDisplay d3dDisplay = display.driverData;
851 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
852 { (float)x2, (float)y1, 1.0f, surface.foreground, 0, 0 },
853 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 },
854 { (float)x1, (float)y2, 1.0f, surface.foreground, 0, 0 },
855 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 }
858 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 4,
859 vertex, sizeof(Vertex));
863 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
865 DisplaySystem displaySystem = display.displaySystem;
866 D3DSystem d3dSystem = displaySystem.driverData;
867 D3DSurface d3dSurface = surface.driverData;
868 D3DDisplay d3dDisplay = display.driverData;
872 { (float)x1, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
873 { (float)x2 + 1.0f, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
874 { (float)x1, (float)y2, 1.0f, d3dSurface.background, 0, 0 },
875 { (float)x2 + 1.0f, (float)y2, 1.0f, d3dSurface.background, 0, 0 }
877 { (float)x1, (float)y1 - 0.5f, 1.0f, d3dSurface.background, 0, 0 },
878 { (float)x2 + 1.0f, (float)y1 - 0.5f, 1.0f, d3dSurface.background, 0, 0 },
879 { (float)x1, (float)y2 + 1.5f, 1.0f, d3dSurface.background, 0, 0 },
880 { (float)x2 + 1.0f, (float)y2 + 1.5f, 1.0f, d3dSurface.background, 0, 0 }
883 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
884 vertex, sizeof(Vertex));
887 void Clear(Display display, Surface surface, ClearType type)
889 DisplaySystem displaySystem = display.displaySystem;
890 D3DSystem d3dSystem = displaySystem.driverData;
891 D3DSurface d3dSurface = surface.driverData;
892 D3DDisplay d3dDisplay = display.driverData;
893 IDirect3DDevice9_Clear(d3dSystem.d3dDevice, 0, null,
894 ((type == depthBuffer) ? 0 : D3DCLEAR_TARGET) |
895 ((type == colorBuffer) ? 0 : D3DCLEAR_ZBUFFER),
896 d3dSurface.background, 1,0);
899 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
904 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
906 DisplaySystem displaySystem = display.displaySystem;
907 D3DSystem d3dSystem = displaySystem.driverData;
908 D3DSurface d3dSurface = surface.driverData;
909 D3DDisplay d3dDisplay = display.driverData;
910 Color foreground = d3dSurface.writingText ? surface.foreground : white;
913 { (float)dx, (float)dy, 1.0f, foreground,
914 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
915 { (float)(dx+w), (float)dy, 1.0f, foreground,
916 (float)(sx+w)/ (src.width-1), (float)sy/ (src.height-1) },
917 { (float)dx, (float)(dy+h), 1.0f, foreground,
918 (float)sx/ (src.width-1), (float)(sy+h)/ (src.height-1) },
919 { (float)(dx+w), (float)(dy+h), 1.0f, foreground,
920 (float)(sx+w) / (src.width-1), (float)(sy+h)/ (src.height-1) }
923 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture9 *)src.picture);
924 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
925 vertex, sizeof(Vertex));
926 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, null);
929 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
931 DisplaySystem displaySystem = display.displaySystem;
932 D3DSystem d3dSystem = displaySystem.driverData;
933 D3DSurface d3dSurface = surface.driverData;
934 D3DDisplay d3dDisplay = display.driverData;
937 { (float)dx, (float)dy, 1.0f, surface.foreground,
938 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
939 { (float)(dx+w), (float)dy, 1.0f, surface.foreground,
940 (float)(sx+sw)/ (src.width-1), (float)sy/ (src.height-1) },
941 { (float)dx, (float)(dy+h), 1.0f, surface.foreground,
942 (float)sx/ (src.width-1), (float)(sy+sh)/ (src.height-1) },
943 { (float)(dx+w), (float)(dy+h), 1.0f, surface.foreground,
944 (float)(sx+sw) / (src.width-1), (float)(sy+sh)/ (src.height-1) }
947 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture9 *)src.picture);
948 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
949 vertex, sizeof(Vertex));
950 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, null);
953 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
955 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
958 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
960 DisplaySystem displaySystem = display.displaySystem;
961 D3DSystem d3dSystem = displaySystem.driverData;
963 Bitmap lfbBitmap { };
964 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
966 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Stretch(null, lfbSurface, src, dx, dy, sx, sy, w, h, sw, sh);
967 UnlockDisplay(display, lfbSurface);
969 lfbBitmap.picture = null;
973 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
975 DisplaySystem displaySystem = display.displaySystem;
976 D3DSystem d3dSystem = displaySystem.driverData;
978 Bitmap lfbBitmap { };
979 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
981 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, lfbSurface, src, dx, dy, sx, sy, w, h);
982 UnlockDisplay(display, lfbSurface);
984 lfbBitmap.picture = null;
988 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
990 StretchDI(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
993 void UnloadFont(DisplaySystem displaySystem, Font font)
995 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
998 Font LoadFont(DisplaySystem displaySystem, char * faceName, float size, FontFlags flags)
1000 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
1003 void TextFont(Display display, Surface surface, Font font)
1005 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
1008 void TextOpacity(Display display, Surface surface, bool opaque)
1010 D3DSurface d3dSurface = surface.driverData;
1011 d3dSurface.opaqueText = opaque;
1014 void FontExtent(DisplaySystem displaySystem, Font font, char * text, int len, int * width, int * height)
1016 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
1019 void WriteText(Display display, Surface surface, int x, int y, char * text, int len)
1021 DisplaySystem displaySystem = display.displaySystem;
1022 D3DSystem d3dSystem = displaySystem.driverData;
1023 D3DDisplay d3dDisplay = display.driverData;
1024 D3DSurface d3dSurface = surface.driverData;
1026 if(surface.textOpacity)
1029 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
1031 int x1 = x, y1 = y, x2 = x+w-1, y2 = y+h-1;
1034 { (float)x1, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1035 { (float)x2 + 1.0f, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1036 { (float)x1, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 },
1037 { (float)x2 + 1.0f, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 }
1040 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
1041 vertex, sizeof(Vertex));
1043 //display.displaySystem.driver.Area(display, surface, x, y, x+w-1, y+h-1);
1046 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1047 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1048 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1049 d3dSurface.writingText = true;
1051 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
1053 d3dSurface.writingText = false;
1054 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
1055 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1056 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1059 void TextExtent(Display display, Surface surface, char * text, int len, int * width, int * height)
1061 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, width, height);
1064 void DrawingChar(Display display, Surface surface, char character)
1069 void LineStipple(Display display, Surface surface, uint stipple)
1071 D3DDisplay d3dDisplay = display.driverData;
1073 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_LINEPATTERN,
1074 stipple?Muint(1,stipple):0);
1079 void SetRenderState(Display display, RenderState state, uint value)
1081 DisplaySystem displaySystem = display.displaySystem;
1082 D3DSystem d3dSystem = displaySystem.driverData;
1083 D3DDisplay d3dDisplay = display.driverData;
1087 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, value ? TRUE : FALSE);
1090 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FILLMODE,
1091 ((FillModeValue)value == solid) ? D3DFILL_SOLID : D3DFILL_WIREFRAME);
1094 // IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_USEW : D3DZB_FALSE);
1095 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_TRUE : D3DZB_FALSE);
1098 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZWRITEENABLE, value);
1101 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGCOLOR, value);
1105 float fogDensity = *(float *)(void *)&value;
1106 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGDENSITY, *(uint *)(void *)&fogDensity);
1110 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ALPHABLENDENABLE, value);
1113 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_AMBIENT, value);
1117 if(d3dDisplay.vSync != value)
1119 d3dDisplay.vSync = value;
1120 DisplaySize(display, display.width, display.height);
1127 void SetLight(Display display, int id, Light light)
1129 DisplaySystem displaySystem = display.displaySystem;
1130 D3DSystem d3dSystem = displaySystem.driverData;
1131 D3DDisplay d3dDisplay = display.driverData;
1134 D3DLIGHT9 d3dLight =
1136 // Opacity on the light?
1137 D3DLIGHT_DIRECTIONAL,
1138 { light.diffuse.r, light.diffuse.g, light.diffuse.b, 1.0f },
1139 { light.specular.r, light.specular.g, light.specular.b, 1.0f },
1140 { light.ambient.r, light.ambient.g, light.ambient.b, 1.0f },
1142 Vector3Df vector {0,0,1};
1143 Vector3Df vectorPI {0,0,-1};
1144 Vector3Df direction;
1147 mat.RotationQuaternion(light.orientation);
1149 direction.MultMatrix(vector, mat);
1150 if(!display.display3D || !display.display3D.camera)
1152 d3dLight.Direction.x = direction.x;
1153 d3dLight.Direction.y = direction.y;
1154 d3dLight.Direction.z =-direction.z;
1158 // TODO: Precomp problem without the { }
1159 ((Vector3Df *)&d3dLight.Direction)->MultMatrix(direction, d3dDisplay.worldMatrix);
1162 d3dDisplay.lights[id] = d3dLight;
1164 IDirect3DDevice9_LightEnable(d3dSystem.d3dDevice, id, TRUE);
1165 IDirect3DDevice9_SetLight(d3dSystem.d3dDevice, id, &d3dDisplay.lights[id] /*d3dLight*/);
1167 direction.MultMatrix(vectorPI, mat);
1168 ((Vector3Df *)&d3dLight.Direction)->MultMatrix(direction, d3dDisplay.worldMatrix);
1170 d3dDisplay.lightsPI[id] = d3dLight;
1174 IDirect3DDevice9_LightEnable(d3dSystem.d3dDevice, id, FALSE);
1175 d3dDisplay.lights[id].Type = 0;
1179 void SetCamera(Display display, Surface surface, Camera camera)
1181 DisplaySystem displaySystem = display.displaySystem;
1182 D3DSystem d3dSystem = displaySystem.driverData;
1183 D3DDisplay d3dDisplay = display.driverData;
1184 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1187 Point topLeft {surface.box.left + surface.offset.x, surface.box.top + surface.offset.y};
1188 Point downRight {surface.box.right + surface.offset.x, surface.box.bottom + surface.offset.y};
1191 surface.offset.x + camera.origin.x,
1192 surface.offset.y + camera.origin.y
1196 float l = (topLeft.x - origin.x) * camera.zMin / camera.focalX;
1197 float r = (downRight.x - origin.x) * camera.zMin / camera.focalX;
1198 float b = (downRight.y - origin.y) * camera.zMin / camera.focalY;
1199 float t = (topLeft.y - origin.y) * camera.zMin / camera.focalY;
1200 float n = camera.zMin;
1201 float f = camera.zMax;
1203 matProj.m[0][0] = 2 * n / (r - l);
1204 matProj.m[0][1] = 0;
1205 matProj.m[0][2] = 0;
1206 matProj.m[0][3] = 0;
1208 matProj.m[1][0] = 0;
1209 matProj.m[1][1] = 2 * n / (t - b);
1210 matProj.m[1][2] = 0;
1211 matProj.m[1][3] = 0;
1213 matProj.m[2][0] = (l + r) / (r - l);
1214 matProj.m[2][1] = (t + b) / (t - b);
1215 matProj.m[2][2] = f / (n - f);
1216 matProj.m[2][3] = -1;
1218 matProj.m[3][0] = 0;
1219 matProj.m[3][1] = 0;
1220 matProj.m[3][2] = n * f / (n - f);
1221 matProj.m[3][3] = 0;
1223 IDirect3DDevice9_SetTransform(d3dDevice, D3DTS_PROJECTION, &matProj);
1225 // *** View Matrix ***
1226 if(!display.display3D.camera)
1227 d3dDisplay.worldMatrix++;
1230 matrix.Scale(1.0f, 1.0f, -1.0f);
1231 d3dDisplay.worldMatrix->Multiply(camera.viewMatrix, matrix);
1233 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1235 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decls[0]);
1237 // IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_USEW);
1238 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_TRUE);
1239 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZWRITEENABLE, TRUE);
1240 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, FALSE);
1241 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, TRUE);
1242 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, TRUE);
1244 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1246 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
1248 else if(display.display3D.camera)
1250 d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
1251 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1252 IDirect3DDevice9_SetTransform(d3dDevice, D3DTS_PROJECTION, &d3dDisplay.projMatrix);
1254 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
1255 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
1256 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
1257 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
1258 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGENABLE, FALSE);
1259 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, FALSE);
1261 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1262 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1264 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decl2D);
1266 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
1268 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
1272 void ApplyMaterial(Display display, Material material, Mesh mesh)
1274 DisplaySystem displaySystem = display.displaySystem;
1275 D3DSystem d3dSystem = displaySystem.driverData;
1276 D3DDisplay d3dDisplay = display.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.picture);
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 D3DSystem d3dSystem = displaySystem.driverData;
1336 D3DMesh d3dMesh = mesh.data;
1339 if(!(mesh.flags.vertices))
1341 if(d3dMesh.vertices)
1343 IDirect3DVertexBuffer9_Release(d3dMesh.vertices);
1344 d3dMesh.vertices = null;
1346 delete mesh.vertices;
1348 if(!(mesh.flags.normals))
1352 IDirect3DVertexBuffer9_Release(d3dMesh.normals);
1353 d3dMesh.normals = null;
1355 delete mesh.normals;
1357 if(!(mesh.flags.texCoords1))
1359 if(d3dMesh.texCoords)
1361 IDirect3DVertexBuffer9_Release(d3dMesh.texCoords);
1362 d3dMesh.texCoords = null;
1364 delete mesh.texCoords;
1366 if(!(mesh.flags.texCoords2))
1368 if(d3dMesh.texCoords2)
1370 IDirect3DVertexBuffer9_Release(d3dMesh.texCoords2);
1371 d3dMesh.texCoords2 = null;
1373 // delete mesh.texCoords2;
1383 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh)
1385 D3DSystem d3dSystem = displaySystem.driverData;
1386 bool result = false;
1387 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1390 mesh.data = D3DMesh { };
1393 D3DMesh d3dMesh = mesh.data;
1395 if((mesh.flags.vertices) && !d3dMesh.vertices)
1397 mesh.vertices = new Vector3Df[mesh.nVertices];
1398 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * mesh.nVertices,
1399 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices, null))
1402 if((mesh.flags.normals) && !d3dMesh.normals)
1404 mesh.normals = new Vector3Df[mesh.nVertices];
1405 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * mesh.nVertices,
1406 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals, null))
1409 if((mesh.flags.texCoords1) && !d3dMesh.texCoords)
1411 mesh.texCoords = new Pointf[mesh.nVertices];
1412 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * mesh.nVertices,
1413 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords, null))
1420 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1422 D3DSystem d3dSystem = displaySystem.driverData;
1423 D3DMesh d3dMesh = mesh.data;
1424 if(!flags) flags = mesh.flags;
1426 if(flags.vertices && mesh.vertices)
1428 Vector3Df * vertices;
1429 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.vertices, 0, 0, (byte **) &vertices, 0))
1431 memcpy(vertices, mesh.vertices, mesh.nVertices * sizeof(Vector3Df));
1432 IDirect3DVertexBuffer9_Unlock(d3dMesh.vertices);
1435 if(flags.normals && mesh.normals)
1437 Vector3Df * normals;
1438 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.normals, 0, 0, (byte **) &normals, 0))
1440 memcpy(normals, mesh.normals, mesh.nVertices * sizeof(Vector3Df));
1441 IDirect3DVertexBuffer9_Unlock(d3dMesh.normals);
1444 if(flags.texCoords1 && mesh.texCoords)
1447 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.texCoords, 0, 0, (byte **) &texCoords, 0))
1449 memcpy(texCoords, mesh.texCoords, mesh.nVertices * sizeof(Pointf));
1450 IDirect3DVertexBuffer9_Unlock(d3dMesh.texCoords);
1455 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1461 void FreeIndices(DisplaySystem displaySystem, D3DIndices d3dIndices)
1465 if(d3dIndices.buffer)
1466 IDirect3DIndexBuffer9_Release(d3dIndices.buffer);
1467 delete d3dIndices.indices;
1472 D3DIndices AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
1474 D3DSystem d3dSystem = displaySystem.driverData;
1475 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1476 D3DIndices d3dIndices { };
1477 if(d3dIndices && nIndices)
1479 d3dIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
1480 IDirect3DDevice9_CreateIndexBuffer(d3dDevice, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * nIndices, 0, indices32bit ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
1481 D3DPOOL_MANAGED, &d3dIndices.buffer, null);
1482 d3dIndices.nIndices = nIndices;
1487 void UnlockIndices(DisplaySystem displaySystem, D3DIndices d3dIndices, bool indices32bit, int nIndices)
1489 uint16 * indexBuffer = null;
1490 if(!IDirect3DIndexBuffer9_Lock(d3dIndices.buffer, 0, 0, (byte **)&indexBuffer, 0))
1492 memcpy(indexBuffer, d3dIndices.indices, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * d3dIndices.nIndices);
1493 IDirect3DIndexBuffer9_Unlock(d3dIndices.buffer);
1497 uint16 * LockIndices(DisplaySystem displaySystem, D3DIndices d3dIndices)
1499 return d3dIndices.indices;
1502 void SelectMesh(Display display, Mesh mesh)
1504 DisplaySystem displaySystem = display.displaySystem;
1505 D3DSystem d3dSystem = displaySystem.driverData;
1506 D3DDisplay d3dDisplay = display.driverData;
1507 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1509 if(mesh && mesh.data)
1512 D3DMesh d3dMesh = mesh.data;
1514 IDirect3DDevice9_SetStreamSource(d3dSystem.d3dDevice, 0, d3dMesh.vertices, 0, sizeof(Vector3Df));
1517 IDirect3DDevice9_SetStreamSource(d3dSystem.d3dDevice, 1, d3dMesh.normals, 0, sizeof(Vector3Df));
1521 IDirect3DDevice9_SetStreamSource(d3dSystem.d3dDevice, 1, null, 0, sizeof(Vector3Df));
1522 if(d3dMesh.texCoords)
1524 IDirect3DDevice9_SetStreamSource(d3dSystem.d3dDevice, 2, d3dMesh.texCoords, 0, sizeof(Pointf));
1528 IDirect3DDevice9_SetStreamSource(d3dSystem.d3dDevice, 2, null, 0, sizeof(Pointf));
1530 IDirect3DDevice9_SetVertexDeclaration(d3dSystem.d3dDevice, d3dSystem.decls[decl]);
1534 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
1536 DisplaySystem displaySystem = display.displaySystem;
1537 D3DSystem d3dSystem = displaySystem.driverData;
1538 D3DDisplay d3dDisplay = display.driverData;
1539 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1541 if(primitiveTypes[primitive->type.primitiveType])
1543 int numPrimitives = (primitive->type.vertexRange) ? primitive->nVertices : primitive->nIndices;
1546 switch(primitive->type.primitiveType)
1548 case lines: numPrimitives /= 2; break;
1549 case triangles: numPrimitives /= 3; break;
1561 if(primitive->type.vertexRange)
1563 if(primitive->type.primitiveType == quads)
1565 for(c = 0; c<numPrimitives; c++)
1566 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1569 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1573 D3DIndices indices = primitive->data;
1574 IDirect3DDevice9_SetIndices(d3dDevice, indices.buffer);
1575 if(primitive->type.primitiveType == quads)
1577 for(c = 0; c<numPrimitives; c++)
1578 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, c*4, 2);
1581 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, 0, numPrimitives);
1584 if(display.display3D.material.flags.doubleSided)
1586 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CCW);
1587 if(!display.display3D.material.flags.singleSideLight)
1589 for(c = 0; c<NumberOfLights; c++)
1590 if(d3dDisplay.lights[c].Type)
1591 IDirect3DDevice9_SetLight(d3dDevice, c, &d3dDisplay.lightsPI[c]);
1594 if(primitive->type.vertexRange)
1596 if(primitive->type.primitiveType == quads)
1598 for(c = 0; c<numPrimitives; c++)
1599 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1602 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1606 D3DIndices indices = primitive->data;
1607 IDirect3DDevice9_SetIndices(d3dDevice, indices.buffer);
1608 if(primitive->type.primitiveType == quads)
1610 for(c = 0; c<numPrimitives; c++)
1611 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, c*4, 2);
1614 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, 0, numPrimitives);
1616 if(!display.display3D.material.flags.singleSideLight)
1618 for(c = 0; c<NumberOfLights; c++)
1619 if(d3dDisplay.lights[c].Type)
1620 IDirect3DDevice9_SetLight(d3dDevice, c, &d3dDisplay.lights[c]);
1623 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1628 void PushMatrix(Display display)
1630 D3DDisplay d3dDisplay = display.driverData;
1631 *(d3dDisplay.worldMatrix+1) = *(d3dDisplay.worldMatrix);
1632 d3dDisplay.worldMatrix++;
1635 void PopMatrix(Display display, bool setMatrix)
1637 D3DDisplay d3dDisplay = display.driverData;
1638 DisplaySystem displaySystem = display.displaySystem;
1639 D3DSystem d3dSystem = displaySystem.driverData;
1640 d3dDisplay.worldMatrix--;
1642 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1645 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
1647 DisplaySystem displaySystem = display.displaySystem;
1648 D3DSystem d3dSystem = displaySystem.driverData;
1649 Camera camera = useCamera ? display.display3D.camera : null;
1650 D3DDisplay d3dDisplay = display.driverData;
1651 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1653 Matrix matrix = transMatrix, temp;
1657 matrix.Scale(1.0f, 1.0f, -1.0f);
1658 *(d3dDisplay.worldMatrix) = matrix;
1664 - camera.cPosition.x,
1665 - camera.cPosition.y,
1666 - camera.cPosition.z);
1667 temp.Multiply(matrix, d3dDisplay.worldMatrix);
1668 *(d3dDisplay.worldMatrix) = temp;
1671 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1674 bool Lock(Display display)
1676 DisplaySystem displaySystem = display.displaySystem;
1677 D3DSystem d3dSystem = displaySystem.driverData;
1678 D3DDisplay d3dDisplay = display.driverData;
1680 if(d3dDisplay.backBuffer)
1682 IDirect3DDevice9_SetDepthStencilSurface(d3dSystem.d3dDevice, d3dDisplay.depthSurface);
1683 IDirect3DDevice9_SetRenderTarget(d3dSystem.d3dDevice, 0, d3dDisplay.backBuffer);
1684 IDirect3DDevice9_BeginScene(d3dSystem.d3dDevice);
1686 d3dSystem.inScene = true;
1691 void Unlock(Display display)
1693 DisplaySystem displaySystem = display.displaySystem;
1694 D3DSystem d3dSystem = displaySystem.driverData;
1695 D3DDisplay d3dDisplay = display.driverData;
1697 if(d3dSystem.inScene)
1699 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
1700 d3dSystem.inScene = false;