DX11GraphicsApi.cpp 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237
  1. #include "DX11GraphicsApi.h"
  2. #include <d3d11.h>
  3. #include <dxgi1_5.h>
  4. #include "Camera3D.h"
  5. #include "DLLRegister.h"
  6. #include "DX11Buffer.h"
  7. #include "DX11Shader.h"
  8. #include "Globals.h"
  9. #include "Image.h"
  10. #include "Logging.h"
  11. #include "Screen.h"
  12. #include "Texture.h"
  13. #include "TextureList.h"
  14. #include "TextureModel.h"
  15. #include "UIPixelShader.h"
  16. #include "UIVertexShader.h"
  17. #include "Window.h"
  18. #include "World3D.h"
  19. using namespace Framework;
  20. struct TextureEffect
  21. {
  22. bool enabled;
  23. float percentage;
  24. };
  25. DirectX11::DirectX11()
  26. : GraphicsApi(DIRECTX11),
  27. d3d11Device(0),
  28. d3d11Context(0),
  29. d3d11SpawChain(0),
  30. uiTexture(0),
  31. vertexShader(0),
  32. pixelShader(0),
  33. sampleState(0),
  34. rtview(0),
  35. dsView(0),
  36. depthStencilBuffer(0),
  37. depthStencilState(0),
  38. depthDisabledStencilState(0),
  39. blendStateAlphaBlend(0),
  40. vp(0),
  41. texturModel(0),
  42. texturRegister(new TextureList()),
  43. texturRS(0),
  44. meshRS(0),
  45. defaultTexture(0),
  46. diffuseLights(0),
  47. pointLights(0),
  48. indexBuffers(0),
  49. vertexBuffers(0)
  50. {}
  51. DirectX11::~DirectX11()
  52. {
  53. for (int i = 0; i <= lastModelId; i++)
  54. {
  55. indexBuffers[i]->release();
  56. vertexBuffers[i]->release();
  57. }
  58. delete[] indexBuffers;
  59. delete[] vertexBuffers;
  60. if (diffuseLights) diffuseLights->release();
  61. if (pointLights) pointLights->release();
  62. if (defaultTexture) defaultTexture->release();
  63. if (texturRS) texturRS->Release();
  64. if (meshRS) meshRS->Release();
  65. if (texturModel) texturModel->release();
  66. texturRegister->release();
  67. if (blendStateAlphaBlend)
  68. {
  69. blendStateAlphaBlend->Release();
  70. blendStateAlphaBlend = NULL;
  71. }
  72. if (uiTexture)
  73. {
  74. uiTexture->release();
  75. uiTexture = NULL;
  76. }
  77. if (sampleState)
  78. {
  79. sampleState->Release();
  80. sampleState = NULL;
  81. }
  82. if (pixelShader)
  83. {
  84. pixelShader->release();
  85. pixelShader = NULL;
  86. }
  87. if (vertexShader)
  88. {
  89. vertexShader->release();
  90. vertexShader = NULL;
  91. }
  92. if (depthDisabledStencilState)
  93. {
  94. depthDisabledStencilState->Release();
  95. depthDisabledStencilState = NULL;
  96. }
  97. delete vp;
  98. vp = 0;
  99. if (dsView)
  100. {
  101. dsView->Release();
  102. dsView = NULL;
  103. }
  104. if (depthStencilState)
  105. {
  106. depthStencilState->Release();
  107. depthStencilState = NULL;
  108. }
  109. if (depthStencilBuffer)
  110. {
  111. depthStencilBuffer->Release();
  112. depthStencilBuffer = NULL;
  113. }
  114. if (rtview)
  115. {
  116. rtview->Release();
  117. rtview = NULL;
  118. }
  119. if (d3d11SpawChain)
  120. {
  121. d3d11SpawChain->Release();
  122. d3d11SpawChain = NULL;
  123. }
  124. if (d3d11Device)
  125. {
  126. d3d11Device->Release();
  127. d3d11Device = NULL;
  128. }
  129. if (d3d11Context)
  130. {
  131. d3d11Context->Release();
  132. d3d11Context = NULL;
  133. getDLLRegister()->releaseDLL("d3d11.dll");
  134. getDLLRegister()->releaseDLL("dxgi.dll");
  135. }
  136. }
  137. typedef HRESULT(__stdcall* CreateDXGIFactory2Function)(UINT, REFIID, void**);
  138. typedef HRESULT(__stdcall* D3D11CreateDeviceAndSwapChainFunction)(IDXGIAdapter*,
  139. D3D_DRIVER_TYPE,
  140. HMODULE,
  141. UINT,
  142. const D3D_FEATURE_LEVEL*,
  143. UINT,
  144. UINT,
  145. const DXGI_SWAP_CHAIN_DESC*,
  146. IDXGISwapChain**,
  147. ID3D11Device**,
  148. D3D_FEATURE_LEVEL*,
  149. ID3D11DeviceContext**);
  150. void DirectX11::initialize(
  151. NativeWindow* fenster, Vec2<int> backBufferSize, bool fullScreen)
  152. {
  153. GraphicsApi::initialize(fenster, backBufferSize, fullScreen);
  154. //--------------------------------------------------------------------
  155. // Create Device
  156. HINSTANCE dxgiDLL = getDLLRegister()->loadDLL("dxgi.dll", "dxgi.dll");
  157. if (!dxgiDLL)
  158. {
  159. WMessageBox(fenster->getWindowHandle(),
  160. new Text("Fehler"),
  161. new Text("dxgi.dll konnte nicht gefunden werden."),
  162. MB_ICONERROR);
  163. return;
  164. }
  165. CreateDXGIFactory2Function createFactory
  166. = (CreateDXGIFactory2Function)GetProcAddress(
  167. dxgiDLL, "CreateDXGIFactory2");
  168. if (!createFactory)
  169. {
  170. getDLLRegister()->releaseDLL("dxgi.dll");
  171. WMessageBox(fenster->getWindowHandle(),
  172. new Text("Fehler"),
  173. new Text(
  174. "Der Einstiegspunkt CreateDXGIFactory2 fon dxgi.dll konnte "
  175. "nicht gefunden werden."),
  176. MB_ICONERROR);
  177. return;
  178. }
  179. IDXGIFactory5* factory;
  180. HRESULT res = createFactory(0, __uuidof(IDXGIFactory5), (void**)&factory);
  181. if (FAILED(res))
  182. {
  183. getDLLRegister()->releaseDLL("dxgi.dll");
  184. Logging::error() << "ERROR DXGI: createFactory returned " << res
  185. << "\n";
  186. WMessageBox(fenster->getWindowHandle(),
  187. new Text("Fehler"),
  188. new Text("createFactory ist Fehlgeschlagen."),
  189. MB_ICONERROR);
  190. return;
  191. }
  192. // search for gpu with max dedicated memory
  193. IDXGIAdapter* adapter = 0;
  194. IDXGIAdapter* usedAdapter = 0;
  195. unsigned __int64 dedicatedMemoryCount = 0;
  196. for (UINT adapterID = 0;
  197. DXGI_ERROR_NOT_FOUND != factory->EnumAdapters(adapterID, &adapter);
  198. ++adapterID)
  199. {
  200. DXGI_ADAPTER_DESC desc;
  201. adapter->GetDesc(&desc);
  202. if (dedicatedMemoryCount > desc.DedicatedVideoMemory)
  203. {
  204. continue;
  205. }
  206. dedicatedMemoryCount = desc.DedicatedVideoMemory;
  207. if (usedAdapter) usedAdapter->Release();
  208. usedAdapter = adapter;
  209. }
  210. HINSTANCE dll = getDLLRegister()->loadDLL("d3d11.dll", "d3d11.dll");
  211. if (!dll)
  212. {
  213. WMessageBox(fenster->getWindowHandle(),
  214. new Text("Fehler"),
  215. new Text("DirectX 11 konnte nicht gefunden werden."),
  216. MB_ICONERROR);
  217. return;
  218. }
  219. D3D11CreateDeviceAndSwapChainFunction createDeviceAndSwapChain
  220. = (D3D11CreateDeviceAndSwapChainFunction)GetProcAddress(
  221. dll, "D3D11CreateDeviceAndSwapChain");
  222. if (!createDeviceAndSwapChain)
  223. {
  224. getDLLRegister()->releaseDLL("d3d11.dll");
  225. getDLLRegister()->releaseDLL("dxgi.dll");
  226. WMessageBox(fenster->getWindowHandle(),
  227. new Text("Fehler"),
  228. new Text("Der Einstiegspunkt D3D11CreateDeviceAndSwapChain fon "
  229. "DirectX 11 konnte nicht gefunden werden."),
  230. MB_ICONERROR);
  231. return;
  232. }
  233. // create a struct to hold information about the swap chain
  234. DXGI_SWAP_CHAIN_DESC scd;
  235. // clear out the struct for use
  236. ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
  237. scd.Windowed = !fullScreen;
  238. scd.BufferCount = 2;
  239. scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  240. scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  241. scd.SampleDesc.Count = 1; // multisampling setting
  242. scd.SampleDesc.Quality = 0; // vendor-specific flag
  243. scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
  244. scd.OutputWindow = fenster ? fenster->getWindowHandle() : 0;
  245. scd.BufferDesc.Width = this->backBufferSize.x;
  246. scd.BufferDesc.Height = this->backBufferSize.y; // windowed/full-screen mode
  247. D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
  248. D3D_FEATURE_LEVEL support = D3D_FEATURE_LEVEL_11_0;
  249. // create a device, device context and swap chain using the information in
  250. // the scd struct
  251. UINT flag = 0;
  252. #ifdef _DEBUG
  253. if (debugDX) flag |= D3D11_CREATE_DEVICE_DEBUG;
  254. #endif
  255. HRESULT result = createDeviceAndSwapChain(usedAdapter,
  256. D3D_DRIVER_TYPE_UNKNOWN,
  257. NULL,
  258. flag,
  259. &featureLevel,
  260. 1,
  261. D3D11_SDK_VERSION,
  262. &scd,
  263. &d3d11SpawChain,
  264. &d3d11Device,
  265. &support,
  266. &d3d11Context);
  267. if (result != S_OK)
  268. {
  269. getDLLRegister()->releaseDLL("d3d11.dll");
  270. getDLLRegister()->releaseDLL("dxgi.dll");
  271. Logging::error() << "ERROR: D3D11CreateDeviceAndSwapChain returned "
  272. << result << "\n";
  273. WMessageBox(fenster->getWindowHandle(),
  274. new Text("Fehler"),
  275. new Text("DirectX 11 konnte nicht initialisiert werden."),
  276. MB_ICONERROR);
  277. return;
  278. }
  279. ID3D11Texture2D* backBufferPtr;
  280. // Get the pointer to the back buffer.
  281. result = d3d11SpawChain->GetBuffer(
  282. 0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
  283. if (result != S_OK)
  284. {
  285. Logging::error() << "ERROR: d3d11SpawChain->GetBuffer returned "
  286. << result << "\n";
  287. WMessageBox(fenster->getWindowHandle(),
  288. new Text("Fehler"),
  289. new Text("DirectX 11 konnte nicht initialisiert werden."),
  290. MB_ICONERROR);
  291. return;
  292. }
  293. vp = new D3D11_VIEWPORT();
  294. memset(vp, 0, sizeof(D3D11_VIEWPORT));
  295. vp->Width = (float)this->backBufferSize.x;
  296. vp->Height = (float)this->backBufferSize.y;
  297. vp->MinDepth = 0.0f;
  298. vp->MaxDepth = 1.0f;
  299. deviceLock.lock();
  300. d3d11Context->RSSetViewports(1, vp);
  301. deviceLock.unlock();
  302. // Create the render target view with the back buffer pointer.
  303. deviceLock.lock();
  304. result = d3d11Device->CreateRenderTargetView(backBufferPtr, NULL, &rtview);
  305. deviceLock.unlock();
  306. if (result != S_OK)
  307. {
  308. Logging::error()
  309. << "ERROR: d3d11Device->CreateRenderTargetView returned " << result
  310. << "\n";
  311. WMessageBox(fenster->getWindowHandle(),
  312. new Text("Fehler"),
  313. new Text("DirectX 11 konnte nicht initialisiert werden."),
  314. MB_ICONERROR);
  315. return;
  316. }
  317. // Release pointer to the back buffer as we no longer need it.
  318. backBufferPtr->Release();
  319. // Initialize the description of the depth buffer.
  320. D3D11_TEXTURE2D_DESC depthBufferDesc;
  321. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
  322. // Set up the description of the depth buffer.
  323. depthBufferDesc.Width = this->backBufferSize.x;
  324. depthBufferDesc.Height = this->backBufferSize.y;
  325. depthBufferDesc.MipLevels = 1;
  326. depthBufferDesc.ArraySize = 1;
  327. depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
  328. depthBufferDesc.SampleDesc.Count = 1;
  329. depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
  330. depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
  331. // Create the texture for the depth buffer using the filled out description.
  332. deviceLock.lock();
  333. result = d3d11Device->CreateTexture2D(
  334. &depthBufferDesc, NULL, &depthStencilBuffer);
  335. deviceLock.unlock();
  336. if (result != S_OK)
  337. {
  338. Logging::error() << "ERROR: d3d11Device->CreateTexture2D returned "
  339. << result << "\n";
  340. WMessageBox(fenster->getWindowHandle(),
  341. new Text("Fehler"),
  342. new Text("DirectX 11 konnte nicht initialisiert werden."),
  343. MB_ICONERROR);
  344. return;
  345. }
  346. // Initialize the description of the stencil state.
  347. D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
  348. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
  349. // Set up the description of the stencil state.
  350. depthStencilDesc.DepthEnable = true;
  351. depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
  352. depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
  353. depthStencilDesc.StencilEnable = true;
  354. depthStencilDesc.StencilReadMask = 0xFF;
  355. depthStencilDesc.StencilWriteMask = 0xFF;
  356. // Stencil operations if pixel is front-facing.
  357. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
  358. depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
  359. depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
  360. depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
  361. // Stencil operations if pixel is back-facing.
  362. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
  363. depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
  364. depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
  365. depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
  366. // Create the depth stencil state.
  367. deviceLock.lock();
  368. result = d3d11Device->CreateDepthStencilState(
  369. &depthStencilDesc, &depthStencilState);
  370. deviceLock.unlock();
  371. if (result != S_OK)
  372. {
  373. Logging::error()
  374. << "ERROR: d3d11Device->CreateDepthStencilState returned " << result
  375. << "\n";
  376. WMessageBox(fenster->getWindowHandle(),
  377. new Text("Fehler"),
  378. new Text("DirectX 11 konnte nicht initialisiert werden."),
  379. MB_ICONERROR);
  380. return;
  381. }
  382. deviceLock.lock();
  383. d3d11Context->OMSetDepthStencilState(depthStencilState, 1);
  384. deviceLock.unlock();
  385. // Initialize the depth stencil view.
  386. D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
  387. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
  388. // Set up the depth stencil view description.
  389. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
  390. depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
  391. // Create the depth stencil view.
  392. deviceLock.lock();
  393. result = d3d11Device->CreateDepthStencilView(
  394. depthStencilBuffer, &depthStencilViewDesc, &dsView);
  395. deviceLock.unlock();
  396. if (result != S_OK)
  397. {
  398. Logging::error()
  399. << "ERROR: d3d11Device->CreateDepthStencilView returned " << result
  400. << "\n";
  401. WMessageBox(fenster->getWindowHandle(),
  402. new Text("Fehler"),
  403. new Text("DirectX 11 konnte nicht initialisiert werden."),
  404. MB_ICONERROR);
  405. return;
  406. }
  407. deviceLock.lock();
  408. d3d11Context->OMSetRenderTargets(1, &rtview, dsView);
  409. deviceLock.unlock();
  410. D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc;
  411. // Clear the second depth stencil state before setting the parameters.
  412. ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc));
  413. // Now create a second depth stencil state which turns off the Z buffer for
  414. // 2D rendering. The only difference is that DepthEnable is set to false,
  415. // all other parameters are the same as the other depth stencil state.
  416. depthDisabledStencilDesc.DepthEnable = false;
  417. depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
  418. depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
  419. depthDisabledStencilDesc.StencilEnable = true;
  420. depthDisabledStencilDesc.StencilReadMask = 0xFF;
  421. depthDisabledStencilDesc.StencilWriteMask = 0xFF;
  422. depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
  423. depthDisabledStencilDesc.FrontFace.StencilDepthFailOp
  424. = D3D11_STENCIL_OP_INCR;
  425. depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
  426. depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
  427. depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
  428. depthDisabledStencilDesc.BackFace.StencilDepthFailOp
  429. = D3D11_STENCIL_OP_DECR;
  430. depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
  431. depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
  432. // Create the state using the device.
  433. deviceLock.lock();
  434. result = d3d11Device->CreateDepthStencilState(
  435. &depthDisabledStencilDesc, &depthDisabledStencilState);
  436. deviceLock.unlock();
  437. if (result != S_OK)
  438. {
  439. Logging::error()
  440. << "ERROR: d3d11Device->CreateDepthStencilState returned " << result
  441. << "\n";
  442. WMessageBox(fenster->getWindowHandle(),
  443. new Text("Fehler"),
  444. new Text("DirectX 11 konnte nicht initialisiert werden."),
  445. MB_ICONERROR);
  446. return;
  447. }
  448. //-------------------------------------------------
  449. // Shaders
  450. vertexShader = initializeVertexShader(
  451. (unsigned char*)UIVertexShader, sizeof(UIVertexShader));
  452. pixelShader = initializePixelShader(
  453. (unsigned char*)UIPixelShader, sizeof(UIPixelShader));
  454. // Create a texture sampler state description.
  455. D3D11_SAMPLER_DESC samplerDesc;
  456. samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
  457. samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
  458. samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
  459. samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
  460. samplerDesc.MipLODBias = 0.0f;
  461. samplerDesc.MaxAnisotropy = 1;
  462. samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
  463. samplerDesc.BorderColor[0] = 0;
  464. samplerDesc.BorderColor[1] = 0;
  465. samplerDesc.BorderColor[2] = 0;
  466. samplerDesc.BorderColor[3] = 0;
  467. samplerDesc.MinLOD = 0;
  468. samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
  469. // Create the texture sampler state.
  470. deviceLock.lock();
  471. result = d3d11Device->CreateSamplerState(&samplerDesc, &sampleState);
  472. deviceLock.unlock();
  473. if (result != S_OK)
  474. {
  475. Logging::error() << "ERROR: d3d11Device->CreateSamplerState returned "
  476. << result << "\n";
  477. WMessageBox(fenster->getWindowHandle(),
  478. new Text("Fehler"),
  479. new Text("DirectX 11 konnte nicht initialisiert werden."),
  480. MB_ICONERROR);
  481. return;
  482. }
  483. //---------------------------------------------------------------
  484. // Framework Backbuffer Texture
  485. Image* renderB = new Image(1);
  486. renderB->setAlpha3D(1);
  487. renderB->newImage(this->backBufferSize.x, this->backBufferSize.y, 0);
  488. uiTexture = createOrGetTexture("_f_Render_Image", renderB);
  489. ((DX11Texture*)uiTexture)->setUseMips(0);
  490. texturModel = new TextureModel(this, "_framework_gui_");
  491. texturModel->setSize(this->backBufferSize);
  492. texturModel->setTexture(dynamic_cast<Texture*>(uiTexture->getThis()));
  493. D3D11_BLEND_DESC blendState;
  494. ZeroMemory(&blendState, sizeof(D3D11_BLEND_DESC));
  495. blendState.AlphaToCoverageEnable = false;
  496. blendState.IndependentBlendEnable = false;
  497. blendState.RenderTarget[0].BlendEnable = true;
  498. blendState.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
  499. blendState.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
  500. blendState.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
  501. blendState.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
  502. blendState.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
  503. blendState.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
  504. blendState.RenderTarget[0].RenderTargetWriteMask
  505. = D3D11_COLOR_WRITE_ENABLE_ALL;
  506. deviceLock.lock();
  507. d3d11Device->CreateBlendState(&blendState, &blendStateAlphaBlend);
  508. d3d11Context->OMSetBlendState(blendStateAlphaBlend, 0, 0xFFFFFFFF);
  509. deviceLock.unlock();
  510. // Setup Render Objekt
  511. vertexShader->useShader();
  512. deviceLock.lock();
  513. d3d11Context->PSSetSamplers(0, 1, &sampleState);
  514. deviceLock.unlock();
  515. pixelShader->useShader();
  516. D3D11_RASTERIZER_DESC rasterDesc;
  517. ZeroMemory(&rasterDesc, sizeof(rasterDesc));
  518. rasterDesc.AntialiasedLineEnable = false;
  519. rasterDesc.CullMode = D3D11_CULL_BACK;
  520. rasterDesc.DepthBiasClamp = 0.0f;
  521. rasterDesc.DepthClipEnable = true;
  522. rasterDesc.FillMode = D3D11_FILL_SOLID;
  523. rasterDesc.FrontCounterClockwise = false;
  524. rasterDesc.MultisampleEnable = false;
  525. rasterDesc.ScissorEnable = false;
  526. rasterDesc.SlopeScaledDepthBias = 0.0f;
  527. deviceLock.lock();
  528. d3d11Device->CreateRasterizerState(&rasterDesc, &texturRS);
  529. deviceLock.unlock();
  530. ZeroMemory(&rasterDesc, sizeof(rasterDesc));
  531. rasterDesc.AntialiasedLineEnable = false;
  532. rasterDesc.CullMode = D3D11_CULL_BACK;
  533. rasterDesc.DepthBiasClamp = 0.0f;
  534. rasterDesc.DepthClipEnable = true;
  535. rasterDesc.FillMode = D3D11_FILL_WIREFRAME;
  536. rasterDesc.FrontCounterClockwise = false;
  537. rasterDesc.MultisampleEnable = false;
  538. rasterDesc.ScissorEnable = false;
  539. rasterDesc.SlopeScaledDepthBias = 0.0f;
  540. deviceLock.lock();
  541. d3d11Device->CreateRasterizerState(&rasterDesc, &meshRS);
  542. d3d11Context->RSSetState(texturRS);
  543. deviceLock.unlock();
  544. Image* b = new Image();
  545. b->newImage(10, 10, 0xFFFFFFFF);
  546. defaultTexture = createOrGetTexture("_default_textur", b);
  547. diffuseLights = new DX11StructuredBuffer(
  548. sizeof(DiffuseLight), d3d11Device, d3d11Context, deviceLock);
  549. pointLights = new DX11StructuredBuffer(
  550. sizeof(PointLight), d3d11Device, d3d11Context, deviceLock);
  551. }
  552. void DirectX11::beginFrame(bool fill2D, bool fill3D, int fillColor)
  553. {
  554. if (fill2D) uiTexture->zImage()->setColor(fillColor);
  555. if (fill3D || true)
  556. {
  557. float color[4];
  558. // Setup the color to clear the buffer.
  559. color[0] = ((fillColor >> 16) & 0xFF) / 255.f; // R
  560. color[1] = ((fillColor >> 8) & 0xFF) / 255.f; // G
  561. color[2] = (fillColor & 0xFF) / 255.f; // B
  562. color[3] = ((fillColor >> 24) & 0xFF) / 255.f; // A
  563. deviceLock.lock();
  564. d3d11Context->ClearRenderTargetView(rtview, color);
  565. deviceLock.unlock();
  566. }
  567. deviceLock.lock();
  568. // Bind the render target view and depth stencil buffer to the output render
  569. // pipeline.
  570. d3d11Context->OMSetRenderTargets(1, &rtview, dsView);
  571. // Clear the depth buffer.
  572. d3d11Context->ClearDepthStencilView(
  573. dsView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
  574. // Set the depth stencil state.
  575. d3d11Context->OMSetDepthStencilState(depthStencilState, 1);
  576. deviceLock.unlock();
  577. }
  578. void DirectX11::renderObject(Model3D* zObj)
  579. {
  580. if (!zObj->zModelData()) return;
  581. int curId = zObj->zModelData()->getId();
  582. if (curId < 0 || curId > lastModelId)
  583. {
  584. Framework::Logging::warning()
  585. << "DirectX11::renderObject: Model ID out of range: " << curId
  586. << " The model was not properly registered with DirectX11 during "
  587. "its creation. It can not be rendered by DirectX11.";
  588. return;
  589. }
  590. if (zObj->zModelData()->wasIndexBufferChanged())
  591. {
  592. this->indexBuffers[curId]->setData(
  593. (void*)zObj->zModelData()->getIndexBuffer());
  594. this->indexBuffers[curId]->setLength(
  595. zObj->zModelData()->getIndexCount() * sizeof(int));
  596. this->indexBuffers[curId]->copyToGPU();
  597. zObj->zModelData()->setIndexBufferChanged(0);
  598. }
  599. if (zObj->zModelData()->wasVertexBufferChanged())
  600. {
  601. this->vertexBuffers[curId]->setData(
  602. (void*)zObj->zModelData()->zVertexBuffer());
  603. this->vertexBuffers[curId]->setLength(
  604. zObj->zModelData()->getVertexCount() * sizeof(Vertex3D));
  605. this->vertexBuffers[curId]->copyToGPU();
  606. zObj->zModelData()->setVertexBufferChanged(0);
  607. }
  608. Mat4<float> trans = Mat4<float>::identity();
  609. int anz = zObj->calculateMatrices(trans, matrixBuffer);
  610. if (vertexShader)
  611. vertexShader->fillConstBuffer(
  612. (char*)matrixBuffer, 0, sizeof(Mat4<float>) * anz);
  613. float matirialBuffer[3]; // light factors (phong model)
  614. matirialBuffer[0] = zObj->getAmbientFactor();
  615. matirialBuffer[1] = zObj->getDiffusFactor();
  616. matirialBuffer[2] = zObj->getSpecularFactor();
  617. if (pixelShader)
  618. pixelShader->fillConstBuffer(
  619. (char*)matirialBuffer, 1, sizeof(float) * 3);
  620. unsigned int offset = 0;
  621. unsigned int es = (unsigned)this->vertexBuffers[curId]->getElementLength();
  622. ID3D11Buffer* vBuffer = this->vertexBuffers[curId]->zBuffer();
  623. deviceLock.lock();
  624. d3d11Context->IASetVertexBuffers(0, 1, &vBuffer, &es, &offset);
  625. deviceLock.unlock();
  626. Model3DTexture* zTexture = zObj->zTexture();
  627. int ind = 0;
  628. int current = 0;
  629. if (zObj->zEffectTexture())
  630. {
  631. ID3D11ShaderResourceView* v[1];
  632. DX11Texture* zEffectTexture = (DX11Texture*)zObj->zEffectTexture();
  633. if (zEffectTexture && zEffectTexture->needsUpdate())
  634. zEffectTexture->updateTextur();
  635. v[0] = *zEffectTexture;
  636. deviceLock.lock();
  637. d3d11Context->PSSetShaderResources(3, 1, v);
  638. deviceLock.unlock();
  639. TextureEffect e = {1, zObj->getEffectPercentage()};
  640. if (pixelShader)
  641. pixelShader->fillConstBuffer((char*)&e, 3, sizeof(TextureEffect));
  642. }
  643. else
  644. {
  645. TextureEffect e = {0, 0.f};
  646. if (pixelShader)
  647. pixelShader->fillConstBuffer((char*)&e, 3, sizeof(TextureEffect));
  648. }
  649. DXGI_FORMAT f = DXGI_FORMAT_R32_UINT;
  650. if (this->indexBuffers[curId]->getElementLength() == 2)
  651. f = DXGI_FORMAT_R16_UINT;
  652. if (this->indexBuffers[curId]->getElementLength() == 1)
  653. f = DXGI_FORMAT_R8_UINT;
  654. deviceLock.lock();
  655. d3d11Context->IASetIndexBuffer(this->indexBuffers[curId]->zBuffer(), f, 0);
  656. d3d11Context->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  657. deviceLock.unlock();
  658. zObj->beforeRender(this, vertexShader, pixelShader);
  659. for (auto i = zObj->zModelData()->getPolygons(); i; ++i)
  660. {
  661. if (zObj->needRenderPolygon(ind))
  662. {
  663. Texture* t = zTexture->zPolygonTexture(ind);
  664. if (t && t->needsUpdate()) t->updateTextur();
  665. if (t)
  666. {
  667. ID3D11ShaderResourceView* v[3];
  668. v[0] = *(DX11Texture*)t;
  669. v[1] = *diffuseLights;
  670. v[2] = *pointLights;
  671. deviceLock.lock();
  672. d3d11Context->PSSetShaderResources(0, 3, v);
  673. d3d11Context->DrawIndexed(i->indexAnz, current, 0);
  674. deviceLock.unlock();
  675. }
  676. else
  677. {
  678. deviceLock.lock();
  679. d3d11Context->RSSetState(meshRS);
  680. ID3D11ShaderResourceView* v[3];
  681. v[0] = *(DX11Texture*)defaultTexture;
  682. v[1] = *diffuseLights;
  683. v[2] = *pointLights;
  684. d3d11Context->PSSetShaderResources(0, 3, v);
  685. d3d11Context->DrawIndexed(i->indexAnz, current, 0);
  686. d3d11Context->RSSetState(texturRS);
  687. deviceLock.unlock();
  688. }
  689. }
  690. ind++;
  691. current += i->indexAnz;
  692. }
  693. zObj->afterRender(this, pixelShader, vertexShader);
  694. }
  695. // Checks whether a sphere is in the visible space of the world and needs to be
  696. // drawn
  697. // pos: The center of the sphere
  698. // radius: The radius of the sphere
  699. // dist: A pointer to a float where the square of the distance to the
  700. // camera position is stored if this function returns true and
  701. // the pointer is not 0
  702. bool DirectX11::isInFrustrum(
  703. const Vec3<float>& pos, float radius, float* dist) const
  704. {
  705. for (int i = 0; i < 6; i++)
  706. {
  707. if (frustrum[i] * pos + radius < 0) return 0;
  708. }
  709. if (dist) *dist = kamPos.distance(pos);
  710. return 1;
  711. }
  712. bool DirectX11::isInFrustrum(
  713. const Vec3<float>& pos, Vec3<float> radius, float* dist) const
  714. {
  715. for (int i = 0; i < 6; i++)
  716. {
  717. float r = abs(frustrum[i].normal() * radius);
  718. if (frustrum[i] * pos + r < 0) return 0;
  719. }
  720. if (dist) *dist = kamPos.distance(pos);
  721. return 1;
  722. }
  723. void DirectX11::renderKamera(Cam3D* zKamera)
  724. {
  725. deviceLock.lock();
  726. d3d11Context->RSSetViewports(1, (D3D11_VIEWPORT*)zKamera->zViewPort());
  727. deviceLock.unlock();
  728. Mat4<float> tmp = zKamera->getProjectionMatrix() * zKamera->getViewMatrix();
  729. frustrum[0].x = tmp.elements[3][0] + tmp.elements[0][0];
  730. frustrum[0].y = tmp.elements[3][1] + tmp.elements[0][1];
  731. frustrum[0].z = tmp.elements[3][2] + tmp.elements[0][2];
  732. frustrum[0].w = tmp.elements[3][3] + tmp.elements[0][3];
  733. frustrum[1].x = tmp.elements[3][0] - tmp.elements[0][0];
  734. frustrum[1].y = tmp.elements[3][1] - tmp.elements[0][1];
  735. frustrum[1].z = tmp.elements[3][2] - tmp.elements[0][2];
  736. frustrum[1].w = tmp.elements[3][3] - tmp.elements[0][3];
  737. frustrum[2].x = tmp.elements[3][0] - tmp.elements[1][0];
  738. frustrum[2].y = tmp.elements[3][1] - tmp.elements[1][1];
  739. frustrum[2].z = tmp.elements[3][2] - tmp.elements[1][2];
  740. frustrum[2].w = tmp.elements[3][3] - tmp.elements[1][3];
  741. frustrum[3].x = tmp.elements[3][0] + tmp.elements[1][0];
  742. frustrum[3].y = tmp.elements[3][1] + tmp.elements[1][1];
  743. frustrum[3].z = tmp.elements[3][2] + tmp.elements[1][2];
  744. frustrum[3].w = tmp.elements[3][3] + tmp.elements[1][3];
  745. frustrum[4].x = tmp.elements[2][0];
  746. frustrum[4].y = tmp.elements[2][1];
  747. frustrum[4].z = tmp.elements[2][2];
  748. frustrum[4].w = tmp.elements[2][3];
  749. frustrum[5].x = tmp.elements[3][0] - tmp.elements[2][0];
  750. frustrum[5].y = tmp.elements[3][1] - tmp.elements[2][1];
  751. frustrum[5].z = tmp.elements[3][2] - tmp.elements[2][2];
  752. frustrum[5].w = tmp.elements[3][3] - tmp.elements[2][3];
  753. for (int i = 0; i < 6; i++)
  754. frustrum[i].normalize();
  755. viewAndProj[0] = zKamera->getViewMatrix();
  756. viewAndProj[1] = zKamera->getProjectionMatrix();
  757. kamPos = zKamera->getWorldPosition();
  758. if (vertexShader)
  759. vertexShader->fillConstBuffer(
  760. (char*)viewAndProj, 1, sizeof(Mat4<float>) * 2);
  761. if (pixelShader)
  762. pixelShader->fillConstBuffer((char*)&kamPos, 0, sizeof(float) * 3);
  763. World3D* w = zKamera->zWorld();
  764. w->readLock().lock();
  765. int lc[] = {w->getDiffuseLightCount(), w->getPointLightCount()};
  766. pixelShader->fillConstBuffer((char*)lc, 2, sizeof(int) * 2);
  767. w->copyLight(diffuseLights, pointLights);
  768. int maxDist = 0;
  769. int minDist = 0x7FFFFFFF;
  770. Array<Model3D*> alphaModels;
  771. Array<int> distances;
  772. w->render([this, &minDist, &maxDist, &alphaModels, &lc, &distances](
  773. Model3D* obj) {
  774. float dist;
  775. if (isInFrustrum(obj->getPos(), obj->getRadius(), &dist))
  776. {
  777. if ((int)dist > maxDist) maxDist = (int)dist;
  778. if ((int)dist < minDist) minDist = (int)dist;
  779. if (obj->hasAlpha())
  780. {
  781. alphaModels.add(obj);
  782. distances.add((int)dist);
  783. }
  784. else
  785. {
  786. pixelShader->fillConstBuffer((char*)lc, 2, sizeof(int) * 2);
  787. renderObject(obj);
  788. }
  789. }
  790. });
  791. maxDist++;
  792. if (alphaModels.getEntryCount())
  793. {
  794. int size = maxDist - minDist;
  795. int* index = new int[size];
  796. memset(index, 0, size * 4);
  797. Model3D** sorted = new Model3D*[size * alphaModels.getEntryCount()];
  798. auto dist = distances.begin();
  799. for (auto obj : alphaModels)
  800. {
  801. sorted[dist.val() * alphaModels.getEntryCount()
  802. + index[dist.val()]++] = obj;
  803. dist++;
  804. }
  805. for (int i = 0; i < size; i++)
  806. {
  807. for (int j = 0; j < index[i]; j++)
  808. {
  809. renderObject(sorted[i * alphaModels.getEntryCount() + j]);
  810. }
  811. }
  812. delete[] index;
  813. delete[] sorted;
  814. }
  815. w->readLock().unlock();
  816. }
  817. void DirectX11::renderKamera(Cam3D* zKamera, Texture* zTarget)
  818. {
  819. ID3D11RenderTargetView* texturRtView;
  820. DX11Texture* d11Textur = dynamic_cast<DX11Texture*>(zTarget);
  821. if (!d11Textur)
  822. throw "incompatible textur object was passed to renderKamera of "
  823. "DirectX11 GPU API";
  824. d11Textur->setRenderTarget(1);
  825. if (d11Textur->needsUpdate()) d11Textur->updateTextur();
  826. D3D11_TEXTURE2D_DESC depthBufferDesc;
  827. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
  828. // Set up the description of the depth buffer.
  829. depthBufferDesc.Width = zTarget->zImage()->getWidth();
  830. depthBufferDesc.Height = zTarget->zImage()->getHeight();
  831. depthBufferDesc.MipLevels = 1;
  832. depthBufferDesc.ArraySize = 1;
  833. depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
  834. depthBufferDesc.SampleDesc.Count = 1;
  835. depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
  836. depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
  837. ID3D11Texture2D* txtDepthStencilBuffer;
  838. // Create the texture for the depth buffer using the filled out description.
  839. deviceLock.lock();
  840. HRESULT result = d3d11Device->CreateTexture2D(
  841. &depthBufferDesc, NULL, &txtDepthStencilBuffer);
  842. deviceLock.unlock();
  843. if (result != S_OK) throw "could not create depth Stencil buffer";
  844. // Initialize the depth stencil view.
  845. D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
  846. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
  847. // Set up the depth stencil view description.
  848. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
  849. depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
  850. ID3D11DepthStencilView* txtDsView;
  851. // Create the depth stencil view.
  852. deviceLock.lock();
  853. result = d3d11Device->CreateDepthStencilView(
  854. txtDepthStencilBuffer, &depthStencilViewDesc, &txtDsView);
  855. deviceLock.unlock();
  856. if (result != S_OK) throw "could not create depth stencil view";
  857. D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
  858. renderTargetViewDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
  859. renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
  860. renderTargetViewDesc.Texture2D.MipSlice = 0;
  861. deviceLock.lock();
  862. result = d3d11Device->CreateRenderTargetView(
  863. (ID3D11Texture2D*)*d11Textur, &renderTargetViewDesc, &texturRtView);
  864. deviceLock.unlock();
  865. if (result != S_OK)
  866. throw "could not create render target view for given texture";
  867. deviceLock.lock();
  868. d3d11Context->OMSetRenderTargets(1, &texturRtView, txtDsView);
  869. float color[4] = {0, 0, 0, 0};
  870. d3d11Context->ClearRenderTargetView(texturRtView, color);
  871. d3d11Context->ClearDepthStencilView(
  872. txtDsView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
  873. deviceLock.unlock();
  874. renderKamera(zKamera);
  875. result = d3d11SpawChain->Present(0, 0);
  876. if (result != S_OK) throw "could not present the rendered content";
  877. deviceLock.lock();
  878. d3d11Context->OMSetRenderTargets(1, &rtview, dsView);
  879. deviceLock.unlock();
  880. texturRtView->Release();
  881. txtDsView->Release();
  882. txtDepthStencilBuffer->Release();
  883. }
  884. void DirectX11::presentFrame()
  885. {
  886. // Set the depth stencil state.
  887. deviceLock.lock();
  888. d3d11Context->OMSetDepthStencilState(depthDisabledStencilState, 1);
  889. deviceLock.unlock();
  890. uiTexture->updateTextur();
  891. deviceLock.lock();
  892. d3d11Context->RSSetViewports(1, vp);
  893. deviceLock.unlock();
  894. float screenAspect = (float)backBufferSize.x / (float)backBufferSize.y;
  895. Mat4<float> view
  896. = view.translation(Vec3<float>(0.f, 0.f, backBufferSize.y * 1.2075f));
  897. viewAndProj[0] = view;
  898. viewAndProj[1]
  899. = view.projektion((float)PI / 4.0f, screenAspect, 0.1f, 10000.f);
  900. kamPos = Vec3<float>(0.f, 0.f, backBufferSize.y * 1.2075f);
  901. if (vertexShader)
  902. vertexShader->fillConstBuffer(
  903. (char*)viewAndProj, 1, sizeof(Mat4<float>) * 2);
  904. if (pixelShader)
  905. pixelShader->fillConstBuffer((char*)&kamPos, 0, sizeof(float) * 3);
  906. if (fenster && !IsIconic(fenster->getWindowHandle()))
  907. renderObject(texturModel);
  908. HRESULT result = d3d11SpawChain->Present(0, 0);
  909. if (!SUCCEEDED(result))
  910. {
  911. deviceLock.lock();
  912. HRESULT res = d3d11Device->GetDeviceRemovedReason();
  913. deviceLock.unlock();
  914. WMessageBox(fenster ? fenster->getWindowHandle() : 0,
  915. new Text("Fehler"),
  916. new Text("Es ist ein Fehler beim rendern aufgetreten."),
  917. MB_ICONERROR);
  918. }
  919. }
  920. Image* DirectX11::zUIRenderImage() const
  921. {
  922. return uiTexture->zImage();
  923. }
  924. Texture* DirectX11::createOrGetTexture(const char* name, Image* b)
  925. {
  926. if (!d3d11Device)
  927. {
  928. if (b) b->release();
  929. return 0;
  930. }
  931. if (texturRegister->hasTexture(name))
  932. {
  933. Texture* ret = texturRegister->getTexture(name);
  934. if (b) ret->setImageZ(b);
  935. return ret;
  936. }
  937. Texture* ret = new DX11Texture(d3d11Device, d3d11Context, deviceLock);
  938. if (b) ret->setImageZ(b);
  939. texturRegister->addTexture(dynamic_cast<Texture*>(ret->getThis()), name);
  940. return ret;
  941. }
  942. typedef HRESULT(__stdcall* CreateDXGIFactory2Function)(UINT, REFIID, void**);
  943. typedef HRESULT(__stdcall* D3D11CreateDeviceFunction)(IDXGIAdapter*,
  944. D3D_DRIVER_TYPE,
  945. HMODULE,
  946. UINT,
  947. D3D_FEATURE_LEVEL*,
  948. UINT,
  949. UINT,
  950. ID3D11Device**,
  951. D3D_FEATURE_LEVEL*,
  952. ID3D11DeviceContext**);
  953. bool DirectX11::isAvailable()
  954. {
  955. HINSTANCE dxgiDLL = getDLLRegister()->loadDLL("dxgi.dll", "dxgi.dll");
  956. if (!dxgiDLL) return 0;
  957. HINSTANCE d3d11DLL = getDLLRegister()->loadDLL("d3d11.dll", "d3d11.dll");
  958. if (!d3d11DLL)
  959. {
  960. getDLLRegister()->releaseDLL("dxgi.dll");
  961. return 0;
  962. }
  963. CreateDXGIFactory2Function createFactory
  964. = (CreateDXGIFactory2Function)GetProcAddress(
  965. dxgiDLL, "CreateDXGIFactory2");
  966. if (!createFactory)
  967. {
  968. getDLLRegister()->releaseDLL("dxgi.dll");
  969. getDLLRegister()->releaseDLL("d3d11.dll");
  970. return 0;
  971. }
  972. D3D11CreateDeviceFunction createDevice
  973. = (D3D11CreateDeviceFunction)GetProcAddress(
  974. d3d11DLL, "D3D11CreateDevice");
  975. if (!createDevice)
  976. {
  977. getDLLRegister()->releaseDLL("dxgi.dll");
  978. getDLLRegister()->releaseDLL("d3d11.dll");
  979. return 0;
  980. }
  981. IDXGIFactory4* factory;
  982. UINT createFactoryFlags = 0;
  983. #if defined(_DEBUG)
  984. createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
  985. #endif
  986. HRESULT res = createFactory(
  987. createFactoryFlags, __uuidof(IDXGIFactory4), (void**)&factory);
  988. if (FAILED(res))
  989. {
  990. getDLLRegister()->releaseDLL("dxgi.dll");
  991. getDLLRegister()->releaseDLL("d3d11.dll");
  992. return 0;
  993. }
  994. int index = 0;
  995. UINT flag = 0;
  996. #ifdef _DEBUG
  997. flag |= D3D11_CREATE_DEVICE_DEBUG;
  998. #endif
  999. do
  1000. {
  1001. IDXGIAdapter1* current;
  1002. res = factory->EnumAdapters1(index++, &current);
  1003. if (res == S_OK)
  1004. {
  1005. DXGI_ADAPTER_DESC1 dxgiAdapterDesc1;
  1006. current->GetDesc1(&dxgiAdapterDesc1);
  1007. ID3D11Device* device = 0;
  1008. ID3D11DeviceContext* context = 0;
  1009. D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_0;
  1010. if ((dxgiAdapterDesc1.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) == 0
  1011. && SUCCEEDED(createDevice(current,
  1012. D3D_DRIVER_TYPE_UNKNOWN,
  1013. 0,
  1014. flag,
  1015. &level,
  1016. 1,
  1017. D3D11_SDK_VERSION,
  1018. &device,
  1019. 0,
  1020. &context)))
  1021. {
  1022. context->Release();
  1023. device->Release();
  1024. current->Release();
  1025. factory->Release();
  1026. getDLLRegister()->releaseDLL("dxgi.dll");
  1027. getDLLRegister()->releaseDLL("d3d11.dll");
  1028. return 1;
  1029. }
  1030. current->Release();
  1031. }
  1032. } while (res != DXGI_ERROR_NOT_FOUND);
  1033. factory->Release();
  1034. getDLLRegister()->releaseDLL("dxgi.dll");
  1035. getDLLRegister()->releaseDLL("d3d11.dll");
  1036. return 0;
  1037. }
  1038. DX11Buffer* DirectX11::createIndexBuffer()
  1039. {
  1040. return new DX11Buffer(sizeof(int),
  1041. d3d11Device,
  1042. d3d11Context,
  1043. D3D11_BIND_INDEX_BUFFER,
  1044. deviceLock);
  1045. }
  1046. DX11Buffer* DirectX11::createVertexBuffer()
  1047. {
  1048. return new DX11Buffer(sizeof(Vertex3D),
  1049. d3d11Device,
  1050. d3d11Context,
  1051. D3D11_BIND_VERTEX_BUFFER,
  1052. deviceLock);
  1053. }
  1054. DX11VertexShader* DirectX11::initializeVertexShader(
  1055. unsigned char* byteCode, int size)
  1056. {
  1057. DX11VertexShader* vertexShader
  1058. = new DX11VertexShader(d3d11Device, d3d11Context, deviceLock);
  1059. vertexShader->setCompiledByteArray(byteCode, size);
  1060. D3D11_INPUT_ELEMENT_DESC polygonLayout[5];
  1061. // Create the vertex input layout description.
  1062. // This setup needs to match the VertexType stucture in the ModelClass and
  1063. // in the shader.
  1064. polygonLayout[0].SemanticName = "POSITION";
  1065. polygonLayout[0].SemanticIndex = 0;
  1066. polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
  1067. polygonLayout[0].InputSlot = 0;
  1068. polygonLayout[0].AlignedByteOffset = 0;
  1069. polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  1070. polygonLayout[0].InstanceDataStepRate = 0;
  1071. polygonLayout[1].SemanticName = "TEXCOORD";
  1072. polygonLayout[1].SemanticIndex = 0;
  1073. polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT;
  1074. polygonLayout[1].InputSlot = 0;
  1075. polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
  1076. polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  1077. polygonLayout[1].InstanceDataStepRate = 0;
  1078. polygonLayout[2].SemanticName = "NORMAL";
  1079. polygonLayout[2].SemanticIndex = 0;
  1080. polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
  1081. polygonLayout[2].InputSlot = 0;
  1082. polygonLayout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
  1083. polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  1084. polygonLayout[2].InstanceDataStepRate = 0;
  1085. polygonLayout[3].SemanticName = "KNOCHEN_ID";
  1086. polygonLayout[3].SemanticIndex = 0;
  1087. polygonLayout[3].Format = DXGI_FORMAT_R32_UINT;
  1088. polygonLayout[3].InputSlot = 0;
  1089. polygonLayout[3].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
  1090. polygonLayout[3].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  1091. polygonLayout[3].InstanceDataStepRate = 0;
  1092. polygonLayout[4].SemanticName = "VERTEX_ID";
  1093. polygonLayout[4].SemanticIndex = 0;
  1094. polygonLayout[4].Format = DXGI_FORMAT_R32_UINT;
  1095. polygonLayout[4].InputSlot = 0;
  1096. polygonLayout[4].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
  1097. polygonLayout[4].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  1098. polygonLayout[4].InstanceDataStepRate = 0;
  1099. vertexShader->createInputLayout(polygonLayout, 5);
  1100. vertexShader->createConstBuffer(sizeof(Mat4<float>) * MAX_KNOCHEN_ANZ,
  1101. vertexShader
  1102. ->getFirstUninitializedBufferIndex()); // matrices for skeleton
  1103. // animations
  1104. vertexShader->createConstBuffer(sizeof(Mat4<float>) * 2,
  1105. vertexShader
  1106. ->getFirstUninitializedBufferIndex()); // View and Projection Matrix
  1107. return vertexShader;
  1108. }
  1109. DX11PixelShader* DirectX11::initializePixelShader(
  1110. unsigned char* byteCode, int size)
  1111. {
  1112. DX11PixelShader* pixelShader
  1113. = new DX11PixelShader(d3d11Device, d3d11Context, deviceLock);
  1114. pixelShader->setCompiledByteArray((unsigned char*)byteCode, size);
  1115. pixelShader->createConstBuffer(sizeof(float) * 3,
  1116. pixelShader->getFirstUninitializedBufferIndex()); // Camera position
  1117. pixelShader->createConstBuffer(sizeof(float) * 3,
  1118. pixelShader->getFirstUninitializedBufferIndex()); // material constants
  1119. // using phong model
  1120. pixelShader->createConstBuffer(
  1121. sizeof(int) * 2, pixelShader->getFirstUninitializedBufferIndex());
  1122. pixelShader->createConstBuffer(
  1123. sizeof(TextureEffect), pixelShader->getFirstUninitializedBufferIndex());
  1124. // TODO: Remove Following Test Code
  1125. int lc[] = {0, 0};
  1126. pixelShader->fillConstBuffer((char*)lc, 2, sizeof(int) * 2);
  1127. TextureEffect e = {0, 0.f};
  1128. pixelShader->fillConstBuffer((char*)&e, 3, sizeof(TextureEffect));
  1129. return pixelShader;
  1130. }
  1131. ID3D11DeviceContext* DirectX11::zContext()
  1132. {
  1133. return d3d11Context;
  1134. }
  1135. DXBuffer* DirectX11::createStructuredBuffer(int eSize)
  1136. {
  1137. return new DX11StructuredBuffer(
  1138. eSize, d3d11Device, d3d11Context, deviceLock);
  1139. }
  1140. Model3DData* DirectX11::createModel(const char* name)
  1141. {
  1142. Model3DData* result = GraphicsApi::createModel(name);
  1143. if (result)
  1144. {
  1145. DX11Buffer** newIndexBuffers = new DX11Buffer*[lastModelId + 1];
  1146. DX11Buffer** newVertexBuffers = new DX11Buffer*[lastModelId + 1];
  1147. memcpy(
  1148. newIndexBuffers, indexBuffers, sizeof(DX11Buffer*) * lastModelId);
  1149. memcpy(
  1150. newVertexBuffers, vertexBuffers, sizeof(DX11Buffer*) * lastModelId);
  1151. indexBuffers[lastModelId] = createIndexBuffer();
  1152. vertexBuffers[lastModelId] = createVertexBuffer();
  1153. }
  1154. return result;
  1155. }