1 namespace gfx::drivers;
7 #define D3D_DEBUG_INFO 1
13 #define String _String
16 #define Platform _Platform
20 #if defined(__MINGW32__) && !defined(_W64)
21 #undef DECLARE_INTERFACE
22 #define DECLARE_INTERFACE(i) \
23 interface i { CONST_VTABLE struct i##Vtbl *lpVtbl; }; \
24 typedef CONST_VTABLE struct i##Vtbl i##Vtbl; \
25 CONST_VTABLE struct i##Vtbl
41 #define MATRIX_STACK_SIZE 32
43 #define NUM_VERTEX_DECLS 4
45 static class D3DDisplay : struct
48 IDirect3DSwapChain9 * swapChain;
49 Matrix worldMatrixStack[MATRIX_STACK_SIZE];
52 D3DLIGHT9 lights[NumberOfLights], lightsPI[NumberOfLights];
53 D3DPRESENT_PARAMETERS d3dpp;
54 IDirect3DSurface9 * backBuffer, * depthSurface;
58 static class D3DSystem : struct
61 IDirect3D9 * direct3D;
62 IDirect3DDevice9 * d3dDevice;
63 IDirect3D9 * (WINAPI * direct3DCreate9)(UINT);
65 D3DPRESENT_PARAMETERS d3dpp;
67 IDirect3DVertexDeclaration9 * decls[NUM_VERTEX_DECLS], * decl2D;
74 static class D3DSurface : struct
76 // For compatibility with LFB driver
82 ColorAlpha background;
85 static class D3DMesh : struct
87 IDirect3DVertexBuffer9 * vertices;
88 IDirect3DVertexBuffer9 * normals;
89 IDirect3DVertexBuffer9 * texCoords;
90 IDirect3DVertexBuffer9 * texCoords2;
100 static class D3DIndices : struct
103 IDirect3DIndexBuffer9 * buffer;
107 static int primitiveTypes[RenderPrimitiveType] =
109 D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP, D3DPT_TRIANGLEFAN, D3DPT_TRIANGLEFAN, 0, D3DPT_LINESTRIP
112 static void SetTransformMatrix(IDirect3DDevice9 * device, Matrix matrix)
118 (float)matrix.m[0][0], (float)matrix.m[0][1], (float)matrix.m[0][2], (float)matrix.m[0][3],
119 (float)matrix.m[1][0], (float)matrix.m[1][1], (float)matrix.m[1][2], (float)matrix.m[1][3],
120 (float)matrix.m[2][0], (float)matrix.m[2][1], (float)matrix.m[2][2], (float)matrix.m[2][3],
121 (float)matrix.m[3][0], (float)matrix.m[3][1], (float)matrix.m[3][2], (float)matrix.m[3][3]
125 IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &d3dMat);
128 class Direct3D9DisplayDriver : DisplayDriver
130 class_property(name) = "Direct3D";
133 bool ::LockDisplay(Display display, Surface surface, Bitmap lfbBitmap, Surface * lfbSurface)
136 DisplaySystem displaySystem = display.displaySystem;
137 D3DSystem d3dSystem = displaySystem.driverData;
138 D3DDisplay d3dDisplay = display.driverData;
140 //if(!IDirect3DDevice9_GetBackBuffer(d3dSystem.d3dDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
142 D3DLOCKED_RECT lockedRect;
143 if(!IDirect3DSurface9_LockRect(d3dDisplay.backBuffer, &lockedRect, null, 0))
145 switch(d3dDisplay.d3dpp.BackBufferFormat)
147 case D3DFMT_A8R8G8B8:
148 case D3DFMT_X8R8G8B8:
149 lfbBitmap.pixelFormat = pixelFormat888;
152 lfbBitmap.pixelFormat = pixelFormat565;
154 case D3DFMT_X1R5G5B5:
155 case D3DFMT_A1R5G5B5:
156 lfbBitmap.pixelFormat = pixelFormat555;
158 case D3DFMT_A4R4G4B4:
159 case D3DFMT_X4R4G4B4:
160 lfbBitmap.pixelFormat = pixelFormat444;
163 lfbBitmap.driver = null;
164 lfbBitmap.displaySystem = null;
165 lfbBitmap.picture = (byte *)lockedRect.pBits;
166 lfbBitmap.transparent = false;
167 lfbBitmap.stride = lockedRect.Pitch >> GetColorDepthShifts(lfbBitmap.pixelFormat);
168 lfbBitmap.width = display.width;
169 lfbBitmap.height = display.height;
171 *lfbSurface = lfbBitmap.GetSurface(surface ? surface.offset.x : 0, surface ? surface.offset.y : 0, surface ? surface.box : null);
175 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
180 void ::UnlockDisplay(Display display, Surface surface)
182 DisplaySystem displaySystem = display.displaySystem;
183 D3DSystem d3dSystem = displaySystem.driverData;
184 D3DDisplay d3dDisplay = display.driverData;
185 if(d3dDisplay.backBuffer)
187 IDirect3DSurface9_UnlockRect(d3dDisplay.backBuffer);
188 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
193 void ::SetViewportAndMatrices(Display display, int x, int y, Box box)
195 D3DDisplay d3dDisplay = display.driverData;
196 DisplaySystem displaySystem = display.displaySystem;
197 D3DSystem d3dSystem = displaySystem.driverData;
200 D3DVIEWPORT9 viewport;
203 if(box.right < box.left || box.bottom < box.top)
205 viewport.Width = viewport.Height = 1;
206 viewport.X = viewport.Y = MAXDWORD;
210 viewport.X = x + box.left;
211 viewport.Y = y + box.top;
212 viewport.Width = box.right - box.left + 1;
213 viewport.Height = box.bottom - box.top + 1;
215 if(!IDirect3DDevice9_SetViewport(d3dSystem.d3dDevice, &viewport))
217 D3DMATRIX * matProj = &d3dDisplay.projMatrix;
218 Matrix * matWorld = d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
220 matProj->m[0][0] = 2.0f / viewport.Width;
221 matProj->m[1][1] =-2.0f / viewport.Height;
222 matProj->m[2][2] = matProj->m[3][1] = matProj->m[3][3] = 1;
223 matProj->m[3][0] = -1;
225 IDirect3DDevice9_SetTransform(d3dSystem.d3dDevice, D3DTS_PROJECTION, matProj);
227 matWorld->Identity();
228 matWorld->m[3][0] =-box.left;
229 matWorld->m[3][1] =-box.top;
231 SetTransformMatrix(d3dSystem.d3dDevice, matWorld);
237 bool CreateDisplaySystem(DisplaySystem displaySystem)
240 D3DSystem d3dSystem = displaySystem.driverData = D3DSystem { };
243 displaySystem.flags.alpha = true;
244 //if(displaySystem.flags.fullScreen)
245 displaySystem.flags.flipping = true;
246 displaySystem.pixelFormat = pixelFormat888;
248 d3dSystem.d3dDll = LoadLibrary("d3d9.dll");
251 d3dSystem.direct3DCreate9 = (void *)GetProcAddress(d3dSystem.d3dDll, "Direct3DCreate9");
252 if(d3dSystem.direct3DCreate9)
254 if(d3dSystem.direct3D = d3dSystem.direct3DCreate9(D3D_SDK_VERSION))
256 D3DDISPLAYMODE d3ddm;
257 if(!IDirect3D9_GetAdapterDisplayMode(d3dSystem.direct3D, D3DADAPTER_DEFAULT, &d3ddm))
259 d3dSystem.d3dpp.BackBufferCount = 1;
261 if(displaySystem.flags.fullScreen)
263 d3dSystem.d3dpp.BackBufferWidth = d3ddm.Width;
264 d3dSystem.d3dpp.BackBufferHeight = d3ddm.Height;
265 d3dSystem.d3dpp.hDeviceWindow = displaySystem.window;
269 d3dSystem.d3dpp.hDeviceWindow = d3dSystem.hwnd =
270 CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
271 d3dSystem.d3dpp.Windowed = TRUE;
274 d3dSystem.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
275 d3dSystem.format = d3dSystem.d3dpp.BackBufferFormat = d3ddm.Format;
276 d3dSystem.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
278 if(!IDirect3D9_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
279 d3dSystem.d3dpp.hDeviceWindow,
280 D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE|D3DCREATE_FPU_PRESERVE,
281 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
285 d3dSystem.usage = D3DUSAGE_SOFTWAREPROCESSING;
286 if(!IDirect3D9_CreateDevice(d3dSystem.direct3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
287 d3dSystem.d3dpp.hDeviceWindow,
288 D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,
289 &d3dSystem.d3dpp, &d3dSystem.d3dDevice))
295 D3DVERTEXELEMENT9 vertexDecls[NUM_VERTEX_DECLS][4] =
298 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
302 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
303 { 1, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 },
307 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
308 { 2, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
312 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
313 { 1, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 },
314 { 2, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
319 D3DVERTEXELEMENT9 vertexDecl2D[] =
321 { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
322 { 0, (uint16)(3*sizeof(float)), D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 },
323 { 0, (uint16)(3*sizeof(float) + sizeof(uint)), D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
328 for(c = 0; c<NUM_VERTEX_DECLS; c++)
329 if(IDirect3DDevice9_CreateVertexDeclaration(d3dSystem.d3dDevice, vertexDecls[c], &d3dSystem.decls[c]))
332 if(c < NUM_VERTEX_DECLS ||
333 IDirect3DDevice9_CreateVertexDeclaration(d3dSystem.d3dDevice, vertexDecl2D, &d3dSystem.decl2D))
337 d3dSystem.ready = false;
343 Log("Couldn't load library d3d9.dll\n");
344 //LogErrorCode(ERR_MISSING_LIBRARY, "d3d9.dll");
349 void DestroyDisplaySystem(DisplaySystem displaySystem)
351 D3DSystem d3dSystem = displaySystem.driverData;
354 if(d3dSystem.d3dDevice)
355 IDirect3DDevice9_Release(d3dSystem.d3dDevice);
357 if(d3dSystem.direct3D)
358 IDirect3D9_Release(d3dSystem.direct3D);
360 for(c = 0; c<NUM_VERTEX_DECLS; c++)
362 if(d3dSystem.decls[c])
363 IDirect3DVertexDeclaration9_Release(d3dSystem.decls[c]);
367 IDirect3DVertexDeclaration9_Release(d3dSystem.decl2D);
369 FreeLibrary(d3dSystem.d3dDll);
372 displaySystem.driverData = null;
376 void DestroyDisplay(Display display)
378 DisplaySystem displaySystem = display.displaySystem;
379 D3DSystem d3dSystem = displaySystem.driverData;
380 D3DDisplay d3dDisplay = display.driverData;
382 if(d3dSystem.inScene)
384 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
385 d3dSystem.inScene = false;
388 if(d3dDisplay.backBuffer)
389 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
391 if(d3dDisplay.depthSurface)
392 IDirect3DSurface9_Release(d3dDisplay.depthSurface);
394 if(d3dDisplay.swapChain)
395 IDirect3DSwapChain9_Release(d3dDisplay.swapChain);
398 display.driverData = null;
401 bool CreateDisplay(Display display)
404 DisplaySystem displaySystem = display.displaySystem;
405 D3DSystem d3dSystem = displaySystem.driverData;
406 D3DDisplay d3dDisplay = display.driverData = D3DDisplay { };
408 d3dSystem.ready = false;
415 bool DisplaySize(Display display, int width, int height)
418 DisplaySystem displaySystem = display.displaySystem;
419 D3DSystem d3dSystem = displaySystem.driverData;
420 D3DDisplay d3dDisplay = display.driverData;
421 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
423 d3dSystem.ready = false;
425 if(d3dDisplay.backBuffer)
427 IDirect3DSurface9_Release(d3dDisplay.backBuffer);
428 d3dDisplay.backBuffer = null;
431 if(d3dDisplay.depthSurface)
433 IDirect3DSurface9_Release(d3dDisplay.depthSurface);
434 d3dDisplay.depthSurface = null;
437 if(d3dDisplay.swapChain)
439 IDirect3DSwapChain9_Release(d3dDisplay.swapChain);
440 d3dDisplay.swapChain = null;
446 if(displaySystem.flags.fullScreen)
448 d3dSystem.d3dpp.BackBufferWidth = width;
449 d3dSystem.d3dpp.BackBufferHeight = height;
451 result = !IDirect3DDevice9_Reset(d3dSystem.d3dDevice, &d3dSystem.d3dpp);
453 result = !IDirect3DDevice9_GetSwapChain(d3dSystem.d3dDevice, 0, &d3dDisplay.swapChain);
457 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;
458 d3dDisplay.d3dpp.BackBufferWidth = width;
459 d3dDisplay.d3dpp.BackBufferHeight = height;
460 d3dDisplay.d3dpp.Windowed = TRUE;
461 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
462 //d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
463 d3dDisplay.d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
465 //d3dDisplay.d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
466 d3dDisplay.d3dpp.BackBufferFormat = d3dSystem.format;
467 d3dDisplay.d3dpp.BackBufferCount = 1;
468 d3dDisplay.d3dpp.hDeviceWindow = display.window;
469 d3dDisplay.d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
470 d3dDisplay.d3dpp.PresentationInterval = d3dDisplay.vSync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_DONOTWAIT;
471 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
472 //d3dDisplay.d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
474 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
475 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
479 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
480 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
481 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
485 d3dDisplay.d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
486 result = !IDirect3DDevice9_CreateAdditionalSwapChain(d3dSystem.d3dDevice,
487 &d3dDisplay.d3dpp, &d3dDisplay.swapChain);
493 if(!IDirect3DSwapChain9_GetBackBuffer(d3dDisplay.swapChain,
494 0, D3DBACKBUFFER_TYPE_MONO, &d3dDisplay.backBuffer))
496 if(!IDirect3DDevice9_CreateDepthStencilSurface(d3dSystem.d3dDevice, width, height,
497 D3DFMT_D16, d3dDisplay.d3dpp.MultiSampleType,0,TRUE,&d3dDisplay.depthSurface, null))
500 d3dSystem.ready = true;
507 float fogDensity = 0;
509 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decl2D);
511 //IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
512 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
513 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
514 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
515 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
516 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
517 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
518 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGTABLEMODE, D3DFOG_EXP);
519 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGDENSITY, *(uint *)(void *)&fogDensity);
520 display.ambient = Color { 50,50,50 };
521 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_NORMALIZENORMALS, TRUE);
522 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
524 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
525 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
526 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
527 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
528 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
529 IDirect3DDevice9_SetTextureStageState(d3dDevice, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
531 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
532 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
533 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
535 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
536 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
538 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
543 display.width = width;
544 display.height = height;
545 d3dDisplay.updateBox.left = display.width;
546 d3dDisplay.updateBox.top = display.height;
547 d3dDisplay.updateBox.right = 0;
548 d3dDisplay.updateBox.bottom = 0;
553 void DisplayPosition(Display display, int x, int y)
558 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
562 void RestorePalette(Display display)
566 void StartUpdate(Display display)
570 void EndUpdate(Display display)
574 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
578 void Update(Display display, Box updateBox)
580 DisplaySystem displaySystem = display.displaySystem;
581 D3DSystem d3dSystem = displaySystem.driverData;
582 D3DDisplay d3dDisplay = display.driverData;
585 //eSystem_Sleep(0.05);
586 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
588 if(display.displaySystem.flags.flipping)
590 // IDirect3DDevice9_Present(d3dSystem.d3dDevice, null, null, null, null);
591 IDirect3DSwapChain9_Present(d3dDisplay.swapChain, null, null, null, null, 0);
597 if(updateBox != null)
599 source.left = dest.left = updateBox.left;
600 source.top = dest.top = updateBox.top;
601 source.right = dest.right = updateBox.right+1;
602 source.bottom = dest.bottom = updateBox.bottom+1;
606 source.left = dest.left = d3dDisplay.updateBox.left;
607 source.top = dest.top = d3dDisplay.updateBox.top;
608 source.right = dest.right = d3dDisplay.updateBox.right+1;
609 source.bottom = dest.bottom = d3dDisplay.updateBox.bottom+1;
611 if(dest.bottom > dest.top && dest.right > dest.left)
612 IDirect3DDevice9_Present(d3dSystem.d3dDevice, &source, &dest, null, null);
613 if(updateBox == null)
615 d3dDisplay.updateBox.left = display.width;
616 d3dDisplay.updateBox.top = display.height;
617 d3dDisplay.updateBox.right = 0;
618 d3dDisplay.updateBox.bottom = 0;
621 d3dSystem.inScene = false;
625 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
629 Bitmap lfbBitmap { };
631 if(LockDisplay(display, null, lfbBitmap, &lfbSurface))
634 if(bitmap.pixelFormat != lfbBitmap.pixelFormat || bitmap.width < w || bitmap.height < h)
637 bitmap.Allocate(null, w,h,w, lfbBitmap.pixelFormat, false);
639 surface = bitmap.GetSurface(0, 0, null);
642 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, surface, lfbBitmap, 0, 0, x, y, w, h);
646 UnlockDisplay(display, lfbSurface);
649 lfbBitmap.picture = null;
657 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
660 IDirect3DTexture9_Release((IDirect3DTexture9 *)bitmap.picture);
663 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
668 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
671 D3DSystem d3dSystem = displaySystem.driverData;
672 if(bitmap.Convert(null, pixelFormat888, null))
674 IDirect3DTexture9 * texture;
675 uint w = pow2i(Min(bitmap.width, 512)), h = pow2i(Min(bitmap.height, 512));
677 if(!IDirect3DDevice9_CreateTexture(d3dSystem.d3dDevice, w, h, mipMaps ? log2i(Max(w+1, h+1)) : 1, 0,
678 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, null))
684 for(level = 0; result && (w >= 1 || h >= 1); level++, w >>= 1, h >>= 1)
686 D3DSURFACE_DESC desc;
687 D3DLOCKED_RECT lockedRect;
689 if(!IDirect3DTexture9_GetLevelDesc(texture, level, &desc) &&
690 !IDirect3DTexture9_LockRect(texture, level, &lockedRect, null, 0))
695 mipMap.width = desc.Width;
696 mipMap.height = desc.Height;
697 mipMap.picture = lockedRect.pBits;
700 case D3DFMT_R5G6B5: mipMap.pixelFormat = pixelFormat565; break;
701 case D3DFMT_A8R8G8B8: mipMap.pixelFormat = pixelFormat888; break;
702 case D3DFMT_A1R5G5B5: mipMap.pixelFormat = pixelFormat555; break;
704 mipMap.stride = lockedRect.Pitch >> GetColorDepthShifts(mipMap.pixelFormat);
706 mipSurface = mipMap.GetSurface(0,0,null);
709 if(mipMap.width != bitmap.width || mipMap.height != bitmap.height)
710 mipSurface.Filter(bitmap, 0,0, 0,0, mipMap.width, mipMap.height, bitmap.width, bitmap.height);
713 //FillBytesBy4(mipMap.picture, bitmap.picture, mipMap.width * mipMap.height);
714 mipSurface.Blit(bitmap, 0,0, 0,0, bitmap.width, bitmap.height);
719 IDirect3DTexture9_UnlockRect(texture, level);
721 mipMap.picture = null;
727 bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
728 bitmap.driver = displaySystem.driver;
729 bitmap.picture = (void *)texture;
732 FreeBitmap(displaySystem, bitmap);
738 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
741 D3DDisplay d3dDisplay = display.driverData;
742 DisplaySystem displaySystem = display.displaySystem;
743 D3DSystem d3dSystem = displaySystem.driverData;
744 D3DSurface d3dSurface = surface.driverData = D3DSurface { };
746 if(d3dSurface && d3dSystem.ready)
748 surface.unclippedBox = surface.box = clip;
749 surface.offset.x = x;
750 surface.offset.y = y;
752 d3dDisplay.updateBox.left = Min(x + clip.left, d3dDisplay.updateBox.left);
753 d3dDisplay.updateBox.top = Min(y + clip.top, d3dDisplay.updateBox.top);
754 d3dDisplay.updateBox.right = Max(x + clip.right, d3dDisplay.updateBox.right);
755 d3dDisplay.updateBox.bottom = Max(y + clip.bottom, d3dDisplay.updateBox.bottom);
757 SetViewportAndMatrices(display, x,y, surface.box);
764 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
769 void ReleaseSurface(Display display, Surface surface)
771 delete surface.driverData;
774 void Clip(Display display, Surface surface, Box clip)
777 D3DDisplay d3dDisplay = display.driverData;
782 box.Clip(surface.unclippedBox);
786 box = surface.box = surface.unclippedBox;
788 SetViewportAndMatrices(display, surface.offset.x, surface.offset.y, box);
791 void SetForeground(Display display, Surface surface, ColorAlpha color)
796 void SetBackground(Display display, Surface surface, ColorAlpha color)
798 D3DSurface d3dSurface = surface.driverData;
799 d3dSurface.background = color;
802 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
807 void PutPixel(Display display, Surface surface,int x, int y)
809 D3DDisplay d3dDisplay = display.driverData;
810 D3DSurface d3dSurface = surface.driverData;
811 DisplaySystem displaySystem = display.displaySystem;
812 D3DSystem d3dSystem = displaySystem.driverData;
813 Vertex vertex { (float)x, (float)y, 1.0f, surface.foreground, 0, 0 };
815 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_POINTLIST, 1,
816 &vertex, sizeof(Vertex));
819 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
821 D3DSurface d3dSurface = surface.driverData;
822 D3DDisplay d3dDisplay = display.driverData;
823 DisplaySystem displaySystem = display.displaySystem;
824 D3DSystem d3dSystem = displaySystem.driverData;
827 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
828 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 }
848 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 1,
849 vertex, sizeof(Vertex));
852 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
854 DisplaySystem displaySystem = display.displaySystem;
855 D3DSystem d3dSystem = displaySystem.driverData;
856 D3DSurface d3dSurface = surface.driverData;
857 D3DDisplay d3dDisplay = display.driverData;
860 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 },
861 { (float)x2, (float)y1, 1.0f, surface.foreground, 0, 0 },
862 { (float)x2, (float)y2, 1.0f, surface.foreground, 0, 0 },
863 { (float)x1, (float)y2, 1.0f, surface.foreground, 0, 0 },
864 { (float)x1, (float)y1, 1.0f, surface.foreground, 0, 0 }
867 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_LINESTRIP, 4,
868 vertex, sizeof(Vertex));
872 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
874 DisplaySystem displaySystem = display.displaySystem;
875 D3DSystem d3dSystem = displaySystem.driverData;
876 D3DSurface d3dSurface = surface.driverData;
877 D3DDisplay d3dDisplay = display.driverData;
881 { (float)x1, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
882 { (float)x2 + 1.0f, (float)y1, 1.0f, d3dSurface.background, 0, 0 },
883 { (float)x1, (float)y2, 1.0f, d3dSurface.background, 0, 0 },
884 { (float)x2 + 1.0f, (float)y2, 1.0f, d3dSurface.background, 0, 0 }
886 { (float)x1, (float)y1 - 0.5f, 1.0f, d3dSurface.background, 0, 0 },
887 { (float)x2 + 1.0f, (float)y1 - 0.5f, 1.0f, d3dSurface.background, 0, 0 },
888 { (float)x1, (float)y2 + 1.5f, 1.0f, d3dSurface.background, 0, 0 },
889 { (float)x2 + 1.0f, (float)y2 + 1.5f, 1.0f, d3dSurface.background, 0, 0 }
892 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
893 vertex, sizeof(Vertex));
896 void Clear(Display display, Surface surface, ClearType type)
898 DisplaySystem displaySystem = display.displaySystem;
899 D3DSystem d3dSystem = displaySystem.driverData;
900 D3DSurface d3dSurface = surface.driverData;
901 D3DDisplay d3dDisplay = display.driverData;
902 IDirect3DDevice9_Clear(d3dSystem.d3dDevice, 0, null,
903 ((type == depthBuffer) ? 0 : D3DCLEAR_TARGET) |
904 ((type == colorBuffer) ? 0 : D3DCLEAR_ZBUFFER),
905 d3dSurface.background, 1,0);
908 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
913 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
915 DisplaySystem displaySystem = display.displaySystem;
916 D3DSystem d3dSystem = displaySystem.driverData;
917 D3DSurface d3dSurface = surface.driverData;
918 D3DDisplay d3dDisplay = display.driverData;
919 Color foreground = d3dSurface.writingText ? surface.foreground : white;
922 { (float)dx, (float)dy, 1.0f, foreground,
923 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
924 { (float)(dx+w), (float)dy, 1.0f, foreground,
925 (float)(sx+w)/ (src.width-1), (float)sy/ (src.height-1) },
926 { (float)dx, (float)(dy+h), 1.0f, foreground,
927 (float)sx/ (src.width-1), (float)(sy+h)/ (src.height-1) },
928 { (float)(dx+w), (float)(dy+h), 1.0f, foreground,
929 (float)(sx+w) / (src.width-1), (float)(sy+h)/ (src.height-1) }
932 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture9 *)src.picture);
933 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
934 vertex, sizeof(Vertex));
935 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, null);
938 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
940 DisplaySystem displaySystem = display.displaySystem;
941 D3DSystem d3dSystem = displaySystem.driverData;
942 D3DSurface d3dSurface = surface.driverData;
943 D3DDisplay d3dDisplay = display.driverData;
946 { (float)dx, (float)dy, 1.0f, surface.foreground,
947 (float)sx / (src.width-1), (float)sy/ (src.height-1) },
948 { (float)(dx+w), (float)dy, 1.0f, surface.foreground,
949 (float)(sx+sw)/ (src.width-1), (float)sy/ (src.height-1) },
950 { (float)dx, (float)(dy+h), 1.0f, surface.foreground,
951 (float)sx/ (src.width-1), (float)(sy+sh)/ (src.height-1) },
952 { (float)(dx+w), (float)(dy+h), 1.0f, surface.foreground,
953 (float)(sx+sw) / (src.width-1), (float)(sy+sh)/ (src.height-1) }
956 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, (IDirect3DBaseTexture9 *)src.picture);
957 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
958 vertex, sizeof(Vertex));
959 IDirect3DDevice9_SetTexture(d3dSystem.d3dDevice, 0, null);
962 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
964 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
967 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 DisplaySystem displaySystem = display.displaySystem;
970 D3DSystem d3dSystem = displaySystem.driverData;
972 Bitmap lfbBitmap { };
973 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
975 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Stretch(null, lfbSurface, src, dx, dy, sx, sy, w, h, sw, sh);
976 UnlockDisplay(display, lfbSurface);
978 lfbBitmap.picture = null;
982 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
984 DisplaySystem displaySystem = display.displaySystem;
985 D3DSystem d3dSystem = displaySystem.driverData;
987 Bitmap lfbBitmap { };
988 if(LockDisplay(display, surface, lfbBitmap, &lfbSurface))
990 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(null, lfbSurface, src, dx, dy, sx, sy, w, h);
991 UnlockDisplay(display, lfbSurface);
993 lfbBitmap.picture = null;
997 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
999 StretchDI(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
1002 void UnloadFont(DisplaySystem displaySystem, Font font)
1004 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
1007 Font LoadFont(DisplaySystem displaySystem, char * faceName, float size, FontFlags flags)
1009 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
1012 void TextFont(Display display, Surface surface, Font font)
1014 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
1017 void TextOpacity(Display display, Surface surface, bool opaque)
1019 D3DSurface d3dSurface = surface.driverData;
1020 d3dSurface.opaqueText = opaque;
1023 void FontExtent(DisplaySystem displaySystem, Font font, char * text, int len, int * width, int * height)
1025 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
1028 void WriteText(Display display, Surface surface, int x, int y, char * text, int len)
1030 DisplaySystem displaySystem = display.displaySystem;
1031 D3DSystem d3dSystem = displaySystem.driverData;
1032 D3DDisplay d3dDisplay = display.driverData;
1033 D3DSurface d3dSurface = surface.driverData;
1035 if(surface.textOpacity)
1038 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
1040 int x1 = x, y1 = y, x2 = x+w-1, y2 = y+h-1;
1043 { (float)x1, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1044 { (float)x2 + 1.0f, (float)y1 /*- 0.5*/, 1.0f, d3dSurface.background, 0, 0 },
1045 { (float)x1, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 },
1046 { (float)x2 + 1.0f, (float)y2 /*+ 1.5f*/, 1.0f, d3dSurface.background, 0, 0 }
1049 IDirect3DDevice9_DrawPrimitiveUP(d3dSystem.d3dDevice, D3DPT_TRIANGLESTRIP, 2,
1050 vertex, sizeof(Vertex));
1052 //display.displaySystem.driver.Area(display, surface, x, y, x+w-1, y+h-1);
1055 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1056 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1057 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1058 d3dSurface.writingText = true;
1060 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
1062 d3dSurface.writingText = false;
1063 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
1064 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1065 IDirect3DDevice9_SetSamplerState(d3dSystem.d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1068 void TextExtent(Display display, Surface surface, char * text, int len, int * width, int * height)
1070 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, width, height);
1073 void DrawingChar(Display display, Surface surface, char character)
1078 void LineStipple(Display display, Surface surface, uint stipple)
1080 D3DDisplay d3dDisplay = display.driverData;
1082 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_LINEPATTERN,
1083 stipple?Muint(1,stipple):0);
1088 void SetRenderState(Display display, RenderState state, uint value)
1090 DisplaySystem displaySystem = display.displaySystem;
1091 D3DSystem d3dSystem = displaySystem.driverData;
1092 D3DDisplay d3dDisplay = display.driverData;
1096 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, value ? TRUE : FALSE);
1099 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FILLMODE,
1100 ((FillModeValue)value == solid) ? D3DFILL_SOLID : D3DFILL_WIREFRAME);
1103 // IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_USEW : D3DZB_FALSE);
1104 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZENABLE, value ? D3DZB_TRUE : D3DZB_FALSE);
1107 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ZWRITEENABLE, value);
1110 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGCOLOR, value);
1114 float fogDensity = *(float *)(void *)&value;
1115 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_FOGDENSITY, *(uint *)(void *)&fogDensity);
1119 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_ALPHABLENDENABLE, value);
1122 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_AMBIENT, value);
1126 if(d3dDisplay.vSync != value)
1128 d3dDisplay.vSync = value;
1129 DisplaySize(display, display.width, display.height);
1136 void SetLight(Display display, int id, Light light)
1138 DisplaySystem displaySystem = display.displaySystem;
1139 D3DSystem d3dSystem = displaySystem.driverData;
1140 D3DDisplay d3dDisplay = display.driverData;
1143 D3DLIGHT9 d3dLight =
1145 // Opacity on the light?
1146 D3DLIGHT_DIRECTIONAL,
1147 { light.diffuse.r, light.diffuse.g, light.diffuse.b, 1.0f },
1148 { light.specular.r, light.specular.g, light.specular.b, 1.0f },
1149 { light.ambient.r, light.ambient.g, light.ambient.b, 1.0f },
1151 Vector3Df vector {0,0,1};
1152 Vector3Df vectorPI {0,0,-1};
1153 Vector3Df direction;
1156 mat.RotationQuaternion(light.orientation);
1158 direction.MultMatrix(vector, mat);
1159 if(!display.display3D || !display.display3D.camera)
1161 d3dLight.Direction.x = direction.x;
1162 d3dLight.Direction.y = direction.y;
1163 d3dLight.Direction.z =-direction.z;
1167 // TODO: Precomp problem without the { }
1168 ((Vector3Df *)&d3dLight.Direction)->MultMatrix(direction, d3dDisplay.worldMatrix);
1171 d3dDisplay.lights[id] = d3dLight;
1173 IDirect3DDevice9_LightEnable(d3dSystem.d3dDevice, id, TRUE);
1174 IDirect3DDevice9_SetLight(d3dSystem.d3dDevice, id, &d3dDisplay.lights[id] /*d3dLight*/);
1176 direction.MultMatrix(vectorPI, mat);
1177 ((Vector3Df *)&d3dLight.Direction)->MultMatrix(direction, d3dDisplay.worldMatrix);
1179 d3dDisplay.lightsPI[id] = d3dLight;
1183 IDirect3DDevice9_LightEnable(d3dSystem.d3dDevice, id, FALSE);
1184 d3dDisplay.lights[id].Type = 0;
1188 void SetCamera(Display display, Surface surface, Camera camera)
1190 DisplaySystem displaySystem = display.displaySystem;
1191 D3DSystem d3dSystem = displaySystem.driverData;
1192 D3DDisplay d3dDisplay = display.driverData;
1193 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1196 Point topLeft {surface.box.left + surface.offset.x, surface.box.top + surface.offset.y};
1197 Point downRight {surface.box.right + surface.offset.x, surface.box.bottom + surface.offset.y};
1200 surface.offset.x + camera.origin.x,
1201 surface.offset.y + camera.origin.y
1205 float l = (topLeft.x - origin.x) * camera.zMin / camera.focalX;
1206 float r = (downRight.x - origin.x) * camera.zMin / camera.focalX;
1207 float b = (downRight.y - origin.y) * camera.zMin / camera.focalY;
1208 float t = (topLeft.y - origin.y) * camera.zMin / camera.focalY;
1209 float n = camera.zMin;
1210 float f = camera.zMax;
1212 matProj.m[0][0] = 2 * n / (r - l);
1213 matProj.m[0][1] = 0;
1214 matProj.m[0][2] = 0;
1215 matProj.m[0][3] = 0;
1217 matProj.m[1][0] = 0;
1218 matProj.m[1][1] = 2 * n / (t - b);
1219 matProj.m[1][2] = 0;
1220 matProj.m[1][3] = 0;
1222 matProj.m[2][0] = (l + r) / (r - l);
1223 matProj.m[2][1] = (t + b) / (t - b);
1224 matProj.m[2][2] = f / (n - f);
1225 matProj.m[2][3] = -1;
1227 matProj.m[3][0] = 0;
1228 matProj.m[3][1] = 0;
1229 matProj.m[3][2] = n * f / (n - f);
1230 matProj.m[3][3] = 0;
1232 IDirect3DDevice9_SetTransform(d3dDevice, D3DTS_PROJECTION, &matProj);
1234 // *** View Matrix ***
1235 if(!display.display3D.camera)
1236 d3dDisplay.worldMatrix++;
1239 matrix.Scale(1.0f, 1.0f, -1.0f);
1240 d3dDisplay.worldMatrix->Multiply(camera.viewMatrix, matrix);
1242 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1244 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decls[0]);
1246 // IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_USEW);
1247 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, D3DZB_TRUE);
1248 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZWRITEENABLE, TRUE);
1249 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, FALSE);
1250 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, TRUE);
1251 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, TRUE);
1253 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1255 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
1257 else if(display.display3D.camera)
1259 d3dDisplay.worldMatrix = d3dDisplay.worldMatrixStack;
1260 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1261 IDirect3DDevice9_SetTransform(d3dDevice, D3DTS_PROJECTION, &d3dDisplay.projMatrix);
1263 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_NONE);
1264 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ZENABLE, FALSE);
1265 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
1266 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHABLENDENABLE, TRUE);
1267 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGENABLE, FALSE);
1268 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SPECULARENABLE, FALSE);
1270 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1271 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1273 IDirect3DDevice9_SetVertexDeclaration(d3dDevice, d3dSystem.decl2D);
1275 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
1277 IDirect3DDevice9_SetRenderState(d3dSystem.d3dDevice, D3DRS_MULTISAMPLEANTIALIAS, FALSE);
1281 void ApplyMaterial(Display display, Material material, Mesh mesh)
1283 DisplaySystem displaySystem = display.displaySystem;
1284 D3DSystem d3dSystem = displaySystem.driverData;
1285 D3DDisplay d3dDisplay = display.driverData;
1286 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1287 D3DMesh d3dMesh = mesh.data;
1290 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_FOGENABLE, (material.flags.noFog) ? FALSE : TRUE);
1293 if(material.baseMap && d3dMesh.texCoords && material.baseMap.driver.displaySystem == displaySystem)
1295 Bitmap map = material.baseMap;
1297 IDirect3DDevice9_SetTexture(d3dDevice, 0, (IDirect3DBaseTexture9 *)map.picture);
1299 if(material.flags.tile)
1301 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
1302 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
1306 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1307 IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1311 IDirect3DDevice9_SetTexture(d3dDevice, 0, null);
1314 D3DMATERIAL9 d3dMaterial;
1316 d3dMaterial.Diffuse.r = material.diffuse.r;
1317 d3dMaterial.Diffuse.g = material.diffuse.g;
1318 d3dMaterial.Diffuse.b = material.diffuse.b;
1319 d3dMaterial.Diffuse.a = material.opacity;
1321 d3dMaterial.Ambient.r = material.ambient.r;
1322 d3dMaterial.Ambient.g = material.ambient.g;
1323 d3dMaterial.Ambient.b = material.ambient.b;
1324 d3dMaterial.Ambient.a = 1;
1326 d3dMaterial.Specular.r = material.specular.r;
1327 d3dMaterial.Specular.g = material.specular.g;
1328 d3dMaterial.Specular.b = material.specular.b;
1329 d3dMaterial.Specular.a = 1;
1331 d3dMaterial.Emissive.r = material.emissive.r;
1332 d3dMaterial.Emissive.g = material.emissive.g;
1333 d3dMaterial.Emissive.b = material.emissive.b;
1334 d3dMaterial.Emissive.a = 1;
1336 d3dMaterial.Power = material.power;
1338 IDirect3DDevice9_SetMaterial(d3dDevice, &d3dMaterial); //(D3DMATERIAL9 *)&material.diffuse
1342 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
1344 D3DSystem d3dSystem = displaySystem.driverData;
1345 D3DMesh d3dMesh = mesh.data;
1348 if(!(mesh.flags.vertices))
1350 if(d3dMesh.vertices)
1352 IDirect3DVertexBuffer9_Release(d3dMesh.vertices);
1353 d3dMesh.vertices = null;
1355 delete mesh.vertices;
1357 if(!(mesh.flags.normals))
1361 IDirect3DVertexBuffer9_Release(d3dMesh.normals);
1362 d3dMesh.normals = null;
1364 delete mesh.normals;
1366 if(!(mesh.flags.texCoords1))
1368 if(d3dMesh.texCoords)
1370 IDirect3DVertexBuffer9_Release(d3dMesh.texCoords);
1371 d3dMesh.texCoords = null;
1373 delete mesh.texCoords;
1375 if(!(mesh.flags.texCoords2))
1377 if(d3dMesh.texCoords2)
1379 IDirect3DVertexBuffer9_Release(d3dMesh.texCoords2);
1380 d3dMesh.texCoords2 = null;
1382 // delete mesh.texCoords2;
1392 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh)
1394 D3DSystem d3dSystem = displaySystem.driverData;
1395 bool result = false;
1396 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1399 mesh.data = D3DMesh { };
1402 D3DMesh d3dMesh = mesh.data;
1404 if((mesh.flags.vertices) && !d3dMesh.vertices)
1406 mesh.vertices = new Vector3Df[mesh.nVertices];
1407 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * mesh.nVertices,
1408 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.vertices, null))
1411 if((mesh.flags.normals) && !d3dMesh.normals)
1413 mesh.normals = new Vector3Df[mesh.nVertices];
1414 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Vector3Df) * mesh.nVertices,
1415 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.normals, null))
1418 if((mesh.flags.texCoords1) && !d3dMesh.texCoords)
1420 mesh.texCoords = new Pointf[mesh.nVertices];
1421 if(IDirect3DDevice9_CreateVertexBuffer(d3dDevice, sizeof(Pointf) * mesh.nVertices,
1422 d3dSystem.usage, 0, D3DPOOL_MANAGED, &d3dMesh.texCoords, null))
1429 void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1431 D3DSystem d3dSystem = displaySystem.driverData;
1432 D3DMesh d3dMesh = mesh.data;
1433 if(!flags) flags = mesh.flags;
1435 if(flags.vertices && mesh.vertices)
1437 Vector3Df * vertices;
1438 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.vertices, 0, 0, (byte **) &vertices, 0))
1440 memcpy(vertices, mesh.vertices, mesh.nVertices * sizeof(Vector3Df));
1441 IDirect3DVertexBuffer9_Unlock(d3dMesh.vertices);
1444 if(flags.normals && mesh.normals)
1446 Vector3Df * normals;
1447 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.normals, 0, 0, (byte **) &normals, 0))
1449 memcpy(normals, mesh.normals, mesh.nVertices * sizeof(Vector3Df));
1450 IDirect3DVertexBuffer9_Unlock(d3dMesh.normals);
1453 if(flags.texCoords1 && mesh.texCoords)
1456 if(!IDirect3DVertexBuffer9_Lock(d3dMesh.texCoords, 0, 0, (byte **) &texCoords, 0))
1458 memcpy(texCoords, mesh.texCoords, mesh.nVertices * sizeof(Pointf));
1459 IDirect3DVertexBuffer9_Unlock(d3dMesh.texCoords);
1464 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1470 void FreeIndices(DisplaySystem displaySystem, D3DIndices d3dIndices)
1474 if(d3dIndices.buffer)
1475 IDirect3DIndexBuffer9_Release(d3dIndices.buffer);
1476 delete d3dIndices.indices;
1481 D3DIndices AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
1483 D3DSystem d3dSystem = displaySystem.driverData;
1484 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1485 D3DIndices d3dIndices { };
1486 if(d3dIndices && nIndices)
1488 d3dIndices.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
1489 IDirect3DDevice9_CreateIndexBuffer(d3dDevice, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * nIndices, 0, indices32bit ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
1490 D3DPOOL_MANAGED, &d3dIndices.buffer, null);
1491 d3dIndices.nIndices = nIndices;
1496 void UnlockIndices(DisplaySystem displaySystem, D3DIndices d3dIndices, bool indices32bit, int nIndices)
1498 uint16 * indexBuffer = null;
1499 if(!IDirect3DIndexBuffer9_Lock(d3dIndices.buffer, 0, 0, (byte **)&indexBuffer, 0))
1501 memcpy(indexBuffer, d3dIndices.indices, (indices32bit ? sizeof(uint32) : sizeof(uint16)) * d3dIndices.nIndices);
1502 IDirect3DIndexBuffer9_Unlock(d3dIndices.buffer);
1506 uint16 * LockIndices(DisplaySystem displaySystem, D3DIndices d3dIndices)
1508 return d3dIndices.indices;
1511 void SelectMesh(Display display, Mesh mesh)
1513 DisplaySystem displaySystem = display.displaySystem;
1514 D3DSystem d3dSystem = displaySystem.driverData;
1515 D3DDisplay d3dDisplay = display.driverData;
1516 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1518 if(mesh && mesh.data)
1521 D3DMesh d3dMesh = mesh.data;
1523 IDirect3DDevice9_SetStreamSource(d3dSystem.d3dDevice, 0, d3dMesh.vertices, 0, sizeof(Vector3Df));
1526 IDirect3DDevice9_SetStreamSource(d3dSystem.d3dDevice, 1, d3dMesh.normals, 0, sizeof(Vector3Df));
1530 IDirect3DDevice9_SetStreamSource(d3dSystem.d3dDevice, 1, null, 0, sizeof(Vector3Df));
1531 if(d3dMesh.texCoords)
1533 IDirect3DDevice9_SetStreamSource(d3dSystem.d3dDevice, 2, d3dMesh.texCoords, 0, sizeof(Pointf));
1537 IDirect3DDevice9_SetStreamSource(d3dSystem.d3dDevice, 2, null, 0, sizeof(Pointf));
1539 IDirect3DDevice9_SetVertexDeclaration(d3dSystem.d3dDevice, d3dSystem.decls[decl]);
1543 void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
1545 DisplaySystem displaySystem = display.displaySystem;
1546 D3DSystem d3dSystem = displaySystem.driverData;
1547 D3DDisplay d3dDisplay = display.driverData;
1548 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1550 if(primitiveTypes[primitive->type.primitiveType])
1552 int numPrimitives = (primitive->type.vertexRange) ? primitive->nVertices : primitive->nIndices;
1555 switch(primitive->type.primitiveType)
1557 case lines: numPrimitives /= 2; break;
1558 case triangles: numPrimitives /= 3; break;
1570 if(primitive->type.vertexRange)
1572 if(primitive->type.primitiveType == quads)
1574 for(c = 0; c<numPrimitives; c++)
1575 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1578 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1582 D3DIndices indices = primitive->data;
1583 IDirect3DDevice9_SetIndices(d3dDevice, indices.buffer);
1584 if(primitive->type.primitiveType == quads)
1586 for(c = 0; c<numPrimitives; c++)
1587 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, c*4, 2);
1590 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, 0, numPrimitives);
1593 if(display.display3D.material.flags.doubleSided)
1595 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CCW);
1596 if(!display.display3D.material.flags.singleSideLight)
1598 for(c = 0; c<NumberOfLights; c++)
1599 if(d3dDisplay.lights[c].Type)
1600 IDirect3DDevice9_SetLight(d3dDevice, c, &d3dDisplay.lightsPI[c]);
1603 if(primitive->type.vertexRange)
1605 if(primitive->type.primitiveType == quads)
1607 for(c = 0; c<numPrimitives; c++)
1608 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first+c*4, 2);
1611 IDirect3DDevice9_DrawPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], primitive->first, numPrimitives);
1615 D3DIndices indices = primitive->data;
1616 IDirect3DDevice9_SetIndices(d3dDevice, indices.buffer);
1617 if(primitive->type.primitiveType == quads)
1619 for(c = 0; c<numPrimitives; c++)
1620 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, c*4, 2);
1623 IDirect3DDevice9_DrawIndexedPrimitive(d3dDevice, primitiveTypes[primitive->type.primitiveType], 0, 0, mesh.nVertices, 0, numPrimitives);
1625 if(!display.display3D.material.flags.singleSideLight)
1627 for(c = 0; c<NumberOfLights; c++)
1628 if(d3dDisplay.lights[c].Type)
1629 IDirect3DDevice9_SetLight(d3dDevice, c, &d3dDisplay.lights[c]);
1632 IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_CULLMODE, D3DCULL_CW);
1637 void PushMatrix(Display display)
1639 D3DDisplay d3dDisplay = display.driverData;
1640 *(d3dDisplay.worldMatrix+1) = *(d3dDisplay.worldMatrix);
1641 d3dDisplay.worldMatrix++;
1644 void PopMatrix(Display display, bool setMatrix)
1646 D3DDisplay d3dDisplay = display.driverData;
1647 DisplaySystem displaySystem = display.displaySystem;
1648 D3DSystem d3dSystem = displaySystem.driverData;
1649 d3dDisplay.worldMatrix--;
1651 SetTransformMatrix(d3dSystem.d3dDevice, d3dDisplay.worldMatrix);
1654 void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
1656 DisplaySystem displaySystem = display.displaySystem;
1657 D3DSystem d3dSystem = displaySystem.driverData;
1658 Camera camera = useCamera ? display.display3D.camera : null;
1659 D3DDisplay d3dDisplay = display.driverData;
1660 IDirect3DDevice9 * d3dDevice = d3dSystem.d3dDevice;
1662 Matrix matrix = transMatrix, temp;
1666 matrix.Scale(1.0f, 1.0f, -1.0f);
1667 *(d3dDisplay.worldMatrix) = matrix;
1673 - camera.cPosition.x,
1674 - camera.cPosition.y,
1675 - camera.cPosition.z);
1676 temp.Multiply(matrix, d3dDisplay.worldMatrix);
1677 *(d3dDisplay.worldMatrix) = temp;
1680 SetTransformMatrix(d3dDevice, d3dDisplay.worldMatrix);
1683 bool Lock(Display display)
1685 DisplaySystem displaySystem = display.displaySystem;
1686 D3DSystem d3dSystem = displaySystem.driverData;
1687 D3DDisplay d3dDisplay = display.driverData;
1689 if(d3dDisplay.backBuffer)
1691 IDirect3DDevice9_SetDepthStencilSurface(d3dSystem.d3dDevice, d3dDisplay.depthSurface);
1692 IDirect3DDevice9_SetRenderTarget(d3dSystem.d3dDevice, 0, d3dDisplay.backBuffer);
1693 IDirect3DDevice9_BeginScene(d3dSystem.d3dDevice);
1695 d3dSystem.inScene = true;
1700 void Unlock(Display display)
1702 DisplaySystem displaySystem = display.displaySystem;
1703 D3DSystem d3dSystem = displaySystem.driverData;
1704 D3DDisplay d3dDisplay = display.driverData;
1706 if(d3dSystem.inScene)
1708 IDirect3DDevice9_EndScene(d3dSystem.d3dDevice);
1709 d3dSystem.inScene = false;