DX11GraphicsApi.cpp 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234
  1. #include <d3d11.h>
  2. #include <dxgi1_5.h>
  3. #include "Camera3D.h"
  4. #include "DLLRegister.h"
  5. #include "DXBuffer.h"
  6. #include "Globals.h"
  7. #include "GraphicsApi.h"
  8. #include "Image.h"
  9. #include "Logging.h"
  10. #include "Model3DList.h"
  11. #include "Shader.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. }
  598. if (zObj->zModelData()->wasVertexBufferChanged())
  599. {
  600. this->vertexBuffers[curId]->setData(
  601. (void*)zObj->zModelData()->zVertexBuffer());
  602. this->vertexBuffers[curId]->setLength(
  603. zObj->zModelData()->getVertexCount() * sizeof(Vertex3D));
  604. this->vertexBuffers[curId]->copyToGPU();
  605. }
  606. Mat4<float> trans = Mat4<float>::identity();
  607. int anz = zObj->calculateMatrices(trans, matrixBuffer);
  608. if (vertexShader)
  609. vertexShader->fillConstBuffer(
  610. (char*)matrixBuffer, 0, sizeof(Mat4<float>) * anz);
  611. float matirialBuffer[3]; // light factors (phong model)
  612. matirialBuffer[0] = zObj->getAmbientFactor();
  613. matirialBuffer[1] = zObj->getDiffusFactor();
  614. matirialBuffer[2] = zObj->getSpecularFactor();
  615. if (pixelShader)
  616. pixelShader->fillConstBuffer(
  617. (char*)matirialBuffer, 1, sizeof(float) * 3);
  618. unsigned int offset = 0;
  619. unsigned int es = (unsigned)this->vertexBuffers[curId]->getElementLength();
  620. ID3D11Buffer* vBuffer = this->vertexBuffers[curId]->zBuffer();
  621. deviceLock.lock();
  622. d3d11Context->IASetVertexBuffers(0, 1, &vBuffer, &es, &offset);
  623. deviceLock.unlock();
  624. Model3DTexture* zTexture = zObj->zTexture();
  625. int ind = 0;
  626. int current = 0;
  627. if (zObj->zEffectTexture())
  628. {
  629. ID3D11ShaderResourceView* v[1];
  630. DX11Texture* zEffectTexture = (DX11Texture*)zObj->zEffectTexture();
  631. if (zEffectTexture && zEffectTexture->needsUpdate())
  632. zEffectTexture->updateTextur();
  633. v[0] = *zEffectTexture;
  634. deviceLock.lock();
  635. d3d11Context->PSSetShaderResources(3, 1, v);
  636. deviceLock.unlock();
  637. TextureEffect e = {1, zObj->getEffectPercentage()};
  638. if (pixelShader)
  639. pixelShader->fillConstBuffer((char*)&e, 3, sizeof(TextureEffect));
  640. }
  641. else
  642. {
  643. TextureEffect e = {0, 0.f};
  644. if (pixelShader)
  645. pixelShader->fillConstBuffer((char*)&e, 3, sizeof(TextureEffect));
  646. }
  647. DXGI_FORMAT f = DXGI_FORMAT_R32_UINT;
  648. if (this->indexBuffers[curId]->getElementLength() == 2)
  649. f = DXGI_FORMAT_R16_UINT;
  650. if (this->indexBuffers[curId]->getElementLength() == 1)
  651. f = DXGI_FORMAT_R8_UINT;
  652. deviceLock.lock();
  653. d3d11Context->IASetIndexBuffer(this->indexBuffers[curId]->zBuffer(), f, 0);
  654. d3d11Context->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  655. deviceLock.unlock();
  656. zObj->beforeRender(this, vertexShader, pixelShader);
  657. for (auto i = zObj->zModelData()->getPolygons(); i; ++i)
  658. {
  659. if (zObj->needRenderPolygon(ind))
  660. {
  661. Texture* t = zTexture->zPolygonTexture(ind);
  662. if (t && t->needsUpdate()) t->updateTextur();
  663. if (t)
  664. {
  665. ID3D11ShaderResourceView* v[3];
  666. v[0] = *(DX11Texture*)t;
  667. v[1] = *diffuseLights;
  668. v[2] = *pointLights;
  669. deviceLock.lock();
  670. d3d11Context->PSSetShaderResources(0, 3, v);
  671. d3d11Context->DrawIndexed(i->indexAnz, current, 0);
  672. deviceLock.unlock();
  673. }
  674. else
  675. {
  676. deviceLock.lock();
  677. d3d11Context->RSSetState(meshRS);
  678. ID3D11ShaderResourceView* v[3];
  679. v[0] = *(DX11Texture*)defaultTexture;
  680. v[1] = *diffuseLights;
  681. v[2] = *pointLights;
  682. d3d11Context->PSSetShaderResources(0, 3, v);
  683. d3d11Context->DrawIndexed(i->indexAnz, current, 0);
  684. d3d11Context->RSSetState(texturRS);
  685. deviceLock.unlock();
  686. }
  687. }
  688. ind++;
  689. current += i->indexAnz;
  690. }
  691. zObj->afterRender(this, pixelShader, vertexShader);
  692. }
  693. // Checks whether a sphere is in the visible space of the world and needs to be
  694. // drawn
  695. // pos: The center of the sphere
  696. // radius: The radius of the sphere
  697. // dist: A pointer to a float where the square of the distance to the
  698. // camera position is stored if this function returns true and
  699. // the pointer is not 0
  700. bool DirectX11::isInFrustrum(
  701. const Vec3<float>& pos, float radius, float* dist) const
  702. {
  703. for (int i = 0; i < 6; i++)
  704. {
  705. if (frustrum[i] * pos + radius < 0) return 0;
  706. }
  707. if (dist) *dist = kamPos.distance(pos);
  708. return 1;
  709. }
  710. bool DirectX11::isInFrustrum(
  711. const Vec3<float>& pos, Vec3<float> radius, float* dist) const
  712. {
  713. for (int i = 0; i < 6; i++)
  714. {
  715. float r = abs(frustrum[i].normal() * radius);
  716. if (frustrum[i] * pos + r < 0) return 0;
  717. }
  718. if (dist) *dist = kamPos.distance(pos);
  719. return 1;
  720. }
  721. void DirectX11::renderKamera(Cam3D* zKamera)
  722. {
  723. deviceLock.lock();
  724. d3d11Context->RSSetViewports(1, (D3D11_VIEWPORT*)zKamera->zViewPort());
  725. deviceLock.unlock();
  726. Mat4<float> tmp = zKamera->getProjectionMatrix() * zKamera->getViewMatrix();
  727. frustrum[0].x = tmp.elements[3][0] + tmp.elements[0][0];
  728. frustrum[0].y = tmp.elements[3][1] + tmp.elements[0][1];
  729. frustrum[0].z = tmp.elements[3][2] + tmp.elements[0][2];
  730. frustrum[0].w = tmp.elements[3][3] + tmp.elements[0][3];
  731. frustrum[1].x = tmp.elements[3][0] - tmp.elements[0][0];
  732. frustrum[1].y = tmp.elements[3][1] - tmp.elements[0][1];
  733. frustrum[1].z = tmp.elements[3][2] - tmp.elements[0][2];
  734. frustrum[1].w = tmp.elements[3][3] - tmp.elements[0][3];
  735. frustrum[2].x = tmp.elements[3][0] - tmp.elements[1][0];
  736. frustrum[2].y = tmp.elements[3][1] - tmp.elements[1][1];
  737. frustrum[2].z = tmp.elements[3][2] - tmp.elements[1][2];
  738. frustrum[2].w = tmp.elements[3][3] - tmp.elements[1][3];
  739. frustrum[3].x = tmp.elements[3][0] + tmp.elements[1][0];
  740. frustrum[3].y = tmp.elements[3][1] + tmp.elements[1][1];
  741. frustrum[3].z = tmp.elements[3][2] + tmp.elements[1][2];
  742. frustrum[3].w = tmp.elements[3][3] + tmp.elements[1][3];
  743. frustrum[4].x = tmp.elements[2][0];
  744. frustrum[4].y = tmp.elements[2][1];
  745. frustrum[4].z = tmp.elements[2][2];
  746. frustrum[4].w = tmp.elements[2][3];
  747. frustrum[5].x = tmp.elements[3][0] - tmp.elements[2][0];
  748. frustrum[5].y = tmp.elements[3][1] - tmp.elements[2][1];
  749. frustrum[5].z = tmp.elements[3][2] - tmp.elements[2][2];
  750. frustrum[5].w = tmp.elements[3][3] - tmp.elements[2][3];
  751. for (int i = 0; i < 6; i++)
  752. frustrum[i].normalize();
  753. viewAndProj[0] = zKamera->getViewMatrix();
  754. viewAndProj[1] = zKamera->getProjectionMatrix();
  755. kamPos = zKamera->getWorldPosition();
  756. if (vertexShader)
  757. vertexShader->fillConstBuffer(
  758. (char*)viewAndProj, 1, sizeof(Mat4<float>) * 2);
  759. if (pixelShader)
  760. pixelShader->fillConstBuffer((char*)&kamPos, 0, sizeof(float) * 3);
  761. World3D* w = zKamera->zWorld();
  762. w->readLock().lock();
  763. int lc[] = {w->getDiffuseLightCount(), w->getPointLightCount()};
  764. pixelShader->fillConstBuffer((char*)lc, 2, sizeof(int) * 2);
  765. w->copyLight(diffuseLights, pointLights);
  766. int maxDist = 0;
  767. int minDist = 0x7FFFFFFF;
  768. Array<Model3D*> alphaModels;
  769. Array<int> distances;
  770. w->render([this, &minDist, &maxDist, &alphaModels, &lc, &distances](
  771. Model3D* obj) {
  772. float dist;
  773. if (isInFrustrum(obj->getPos(), obj->getRadius(), &dist))
  774. {
  775. if ((int)dist > maxDist) maxDist = (int)dist;
  776. if ((int)dist < minDist) minDist = (int)dist;
  777. if (obj->hasAlpha())
  778. {
  779. alphaModels.add(obj);
  780. distances.add((int)dist);
  781. }
  782. else
  783. {
  784. pixelShader->fillConstBuffer((char*)lc, 2, sizeof(int) * 2);
  785. renderObject(obj);
  786. }
  787. }
  788. });
  789. maxDist++;
  790. if (alphaModels.getEntryCount())
  791. {
  792. int size = maxDist - minDist;
  793. int* index = new int[size];
  794. memset(index, 0, size * 4);
  795. Model3D** sorted = new Model3D*[size * alphaModels.getEntryCount()];
  796. auto dist = distances.begin();
  797. for (auto obj : alphaModels)
  798. {
  799. sorted[dist.val() * alphaModels.getEntryCount()
  800. + index[dist.val()]++] = obj;
  801. dist++;
  802. }
  803. for (int i = 0; i < size; i++)
  804. {
  805. for (int j = 0; j < index[i]; j++)
  806. {
  807. renderObject(sorted[i * alphaModels.getEntryCount() + j]);
  808. }
  809. }
  810. delete[] index;
  811. delete[] sorted;
  812. }
  813. w->readLock().unlock();
  814. }
  815. void DirectX11::renderKamera(Cam3D* zKamera, Texture* zTarget)
  816. {
  817. ID3D11RenderTargetView* texturRtView;
  818. DX11Texture* d11Textur = dynamic_cast<DX11Texture*>(zTarget);
  819. if (!d11Textur)
  820. throw "incompatible textur object was passed to renderKamera of "
  821. "DirectX11 GPU API";
  822. d11Textur->setRenderTarget(1);
  823. if (d11Textur->needsUpdate()) d11Textur->updateTextur();
  824. D3D11_TEXTURE2D_DESC depthBufferDesc;
  825. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
  826. // Set up the description of the depth buffer.
  827. depthBufferDesc.Width = zTarget->zImage()->getWidth();
  828. depthBufferDesc.Height = zTarget->zImage()->getHeight();
  829. depthBufferDesc.MipLevels = 1;
  830. depthBufferDesc.ArraySize = 1;
  831. depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
  832. depthBufferDesc.SampleDesc.Count = 1;
  833. depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
  834. depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
  835. ID3D11Texture2D* txtDepthStencilBuffer;
  836. // Create the texture for the depth buffer using the filled out description.
  837. deviceLock.lock();
  838. HRESULT result = d3d11Device->CreateTexture2D(
  839. &depthBufferDesc, NULL, &txtDepthStencilBuffer);
  840. deviceLock.unlock();
  841. if (result != S_OK) throw "could not create depth Stencil buffer";
  842. // Initialize the depth stencil view.
  843. D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
  844. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
  845. // Set up the depth stencil view description.
  846. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
  847. depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
  848. ID3D11DepthStencilView* txtDsView;
  849. // Create the depth stencil view.
  850. deviceLock.lock();
  851. result = d3d11Device->CreateDepthStencilView(
  852. txtDepthStencilBuffer, &depthStencilViewDesc, &txtDsView);
  853. deviceLock.unlock();
  854. if (result != S_OK) throw "could not create depth stencil view";
  855. D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
  856. renderTargetViewDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
  857. renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
  858. renderTargetViewDesc.Texture2D.MipSlice = 0;
  859. deviceLock.lock();
  860. result = d3d11Device->CreateRenderTargetView(
  861. (ID3D11Texture2D*)*d11Textur, &renderTargetViewDesc, &texturRtView);
  862. deviceLock.unlock();
  863. if (result != S_OK)
  864. throw "could not create render target view for given texture";
  865. deviceLock.lock();
  866. d3d11Context->OMSetRenderTargets(1, &texturRtView, txtDsView);
  867. float color[4] = {0, 0, 0, 0};
  868. d3d11Context->ClearRenderTargetView(texturRtView, color);
  869. d3d11Context->ClearDepthStencilView(
  870. txtDsView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
  871. deviceLock.unlock();
  872. renderKamera(zKamera);
  873. result = d3d11SpawChain->Present(0, 0);
  874. if (result != S_OK) throw "could not present the rendered content";
  875. deviceLock.lock();
  876. d3d11Context->OMSetRenderTargets(1, &rtview, dsView);
  877. deviceLock.unlock();
  878. texturRtView->Release();
  879. txtDsView->Release();
  880. txtDepthStencilBuffer->Release();
  881. }
  882. void DirectX11::presentFrame()
  883. {
  884. // Set the depth stencil state.
  885. deviceLock.lock();
  886. d3d11Context->OMSetDepthStencilState(depthDisabledStencilState, 1);
  887. deviceLock.unlock();
  888. uiTexture->updateTextur();
  889. deviceLock.lock();
  890. d3d11Context->RSSetViewports(1, vp);
  891. deviceLock.unlock();
  892. float screenAspect = (float)backBufferSize.x / (float)backBufferSize.y;
  893. Mat4<float> view
  894. = view.translation(Vec3<float>(0.f, 0.f, backBufferSize.y * 1.2075f));
  895. viewAndProj[0] = view;
  896. viewAndProj[1]
  897. = view.projektion((float)PI / 4.0f, screenAspect, 0.1f, 10000.f);
  898. kamPos = Vec3<float>(0.f, 0.f, backBufferSize.y * 1.2075f);
  899. if (vertexShader)
  900. vertexShader->fillConstBuffer(
  901. (char*)viewAndProj, 1, sizeof(Mat4<float>) * 2);
  902. if (pixelShader)
  903. pixelShader->fillConstBuffer((char*)&kamPos, 0, sizeof(float) * 3);
  904. if (fenster && !IsIconic(fenster->getWindowHandle()))
  905. renderObject(texturModel);
  906. HRESULT result = d3d11SpawChain->Present(0, 0);
  907. if (!SUCCEEDED(result))
  908. {
  909. deviceLock.lock();
  910. HRESULT res = d3d11Device->GetDeviceRemovedReason();
  911. deviceLock.unlock();
  912. WMessageBox(fenster ? fenster->getWindowHandle() : 0,
  913. new Text("Fehler"),
  914. new Text("Es ist ein Fehler beim rendern aufgetreten."),
  915. MB_ICONERROR);
  916. }
  917. }
  918. Image* DirectX11::zUIRenderImage() const
  919. {
  920. return uiTexture->zImage();
  921. }
  922. Texture* DirectX11::createOrGetTexture(const char* name, Image* b)
  923. {
  924. if (!d3d11Device)
  925. {
  926. if (b) b->release();
  927. return 0;
  928. }
  929. if (texturRegister->hasTexture(name))
  930. {
  931. Texture* ret = texturRegister->getTexture(name);
  932. if (b) ret->setImageZ(b);
  933. return ret;
  934. }
  935. Texture* ret = new DX11Texture(d3d11Device, d3d11Context, deviceLock);
  936. if (b) ret->setImageZ(b);
  937. texturRegister->addTexture(dynamic_cast<Texture*>(ret->getThis()), name);
  938. return ret;
  939. }
  940. typedef HRESULT(__stdcall* CreateDXGIFactory2Function)(UINT, REFIID, void**);
  941. typedef HRESULT(__stdcall* D3D11CreateDeviceFunction)(IDXGIAdapter*,
  942. D3D_DRIVER_TYPE,
  943. HMODULE,
  944. UINT,
  945. D3D_FEATURE_LEVEL*,
  946. UINT,
  947. UINT,
  948. ID3D11Device**,
  949. D3D_FEATURE_LEVEL*,
  950. ID3D11DeviceContext**);
  951. bool DirectX11::isAvailable()
  952. {
  953. HINSTANCE dxgiDLL = getDLLRegister()->loadDLL("dxgi.dll", "dxgi.dll");
  954. if (!dxgiDLL) return 0;
  955. HINSTANCE d3d11DLL = getDLLRegister()->loadDLL("d3d11.dll", "d3d11.dll");
  956. if (!d3d11DLL)
  957. {
  958. getDLLRegister()->releaseDLL("dxgi.dll");
  959. return 0;
  960. }
  961. CreateDXGIFactory2Function createFactory
  962. = (CreateDXGIFactory2Function)GetProcAddress(
  963. dxgiDLL, "CreateDXGIFactory2");
  964. if (!createFactory)
  965. {
  966. getDLLRegister()->releaseDLL("dxgi.dll");
  967. getDLLRegister()->releaseDLL("d3d11.dll");
  968. return 0;
  969. }
  970. D3D11CreateDeviceFunction createDevice
  971. = (D3D11CreateDeviceFunction)GetProcAddress(
  972. d3d11DLL, "D3D11CreateDevice");
  973. if (!createDevice)
  974. {
  975. getDLLRegister()->releaseDLL("dxgi.dll");
  976. getDLLRegister()->releaseDLL("d3d11.dll");
  977. return 0;
  978. }
  979. IDXGIFactory4* factory;
  980. UINT createFactoryFlags = 0;
  981. #if defined(_DEBUG)
  982. createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
  983. #endif
  984. HRESULT res = createFactory(
  985. createFactoryFlags, __uuidof(IDXGIFactory4), (void**)&factory);
  986. if (FAILED(res))
  987. {
  988. getDLLRegister()->releaseDLL("dxgi.dll");
  989. getDLLRegister()->releaseDLL("d3d11.dll");
  990. return 0;
  991. }
  992. int index = 0;
  993. UINT flag = 0;
  994. #ifdef _DEBUG
  995. flag |= D3D11_CREATE_DEVICE_DEBUG;
  996. #endif
  997. do
  998. {
  999. IDXGIAdapter1* current;
  1000. res = factory->EnumAdapters1(index++, &current);
  1001. if (res == S_OK)
  1002. {
  1003. DXGI_ADAPTER_DESC1 dxgiAdapterDesc1;
  1004. current->GetDesc1(&dxgiAdapterDesc1);
  1005. ID3D11Device* device = 0;
  1006. ID3D11DeviceContext* context = 0;
  1007. D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_0;
  1008. if ((dxgiAdapterDesc1.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) == 0
  1009. && SUCCEEDED(createDevice(current,
  1010. D3D_DRIVER_TYPE_UNKNOWN,
  1011. 0,
  1012. flag,
  1013. &level,
  1014. 1,
  1015. D3D11_SDK_VERSION,
  1016. &device,
  1017. 0,
  1018. &context)))
  1019. {
  1020. context->Release();
  1021. device->Release();
  1022. current->Release();
  1023. factory->Release();
  1024. getDLLRegister()->releaseDLL("dxgi.dll");
  1025. getDLLRegister()->releaseDLL("d3d11.dll");
  1026. return 1;
  1027. }
  1028. current->Release();
  1029. }
  1030. } while (res != DXGI_ERROR_NOT_FOUND);
  1031. factory->Release();
  1032. getDLLRegister()->releaseDLL("dxgi.dll");
  1033. getDLLRegister()->releaseDLL("d3d11.dll");
  1034. return 0;
  1035. }
  1036. DX11Buffer* DirectX11::createIndexBuffer()
  1037. {
  1038. return new DX11Buffer(sizeof(int),
  1039. d3d11Device,
  1040. d3d11Context,
  1041. D3D11_BIND_INDEX_BUFFER,
  1042. deviceLock);
  1043. }
  1044. DX11Buffer* DirectX11::createVertexBuffer()
  1045. {
  1046. return new DX11Buffer(sizeof(Vertex3D),
  1047. d3d11Device,
  1048. d3d11Context,
  1049. D3D11_BIND_VERTEX_BUFFER,
  1050. deviceLock);
  1051. }
  1052. DX11VertexShader* DirectX11::initializeVertexShader(
  1053. unsigned char* byteCode, int size)
  1054. {
  1055. DX11VertexShader* vertexShader
  1056. = new DX11VertexShader(d3d11Device, d3d11Context, deviceLock);
  1057. vertexShader->setCompiledByteArray(byteCode, size);
  1058. D3D11_INPUT_ELEMENT_DESC polygonLayout[5];
  1059. // Create the vertex input layout description.
  1060. // This setup needs to match the VertexType stucture in the ModelClass and
  1061. // in the shader.
  1062. polygonLayout[0].SemanticName = "POSITION";
  1063. polygonLayout[0].SemanticIndex = 0;
  1064. polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
  1065. polygonLayout[0].InputSlot = 0;
  1066. polygonLayout[0].AlignedByteOffset = 0;
  1067. polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  1068. polygonLayout[0].InstanceDataStepRate = 0;
  1069. polygonLayout[1].SemanticName = "TEXCOORD";
  1070. polygonLayout[1].SemanticIndex = 0;
  1071. polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT;
  1072. polygonLayout[1].InputSlot = 0;
  1073. polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
  1074. polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  1075. polygonLayout[1].InstanceDataStepRate = 0;
  1076. polygonLayout[2].SemanticName = "NORMAL";
  1077. polygonLayout[2].SemanticIndex = 0;
  1078. polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
  1079. polygonLayout[2].InputSlot = 0;
  1080. polygonLayout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
  1081. polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  1082. polygonLayout[2].InstanceDataStepRate = 0;
  1083. polygonLayout[3].SemanticName = "KNOCHEN_ID";
  1084. polygonLayout[3].SemanticIndex = 0;
  1085. polygonLayout[3].Format = DXGI_FORMAT_R32_UINT;
  1086. polygonLayout[3].InputSlot = 0;
  1087. polygonLayout[3].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
  1088. polygonLayout[3].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  1089. polygonLayout[3].InstanceDataStepRate = 0;
  1090. polygonLayout[4].SemanticName = "VERTEX_ID";
  1091. polygonLayout[4].SemanticIndex = 0;
  1092. polygonLayout[4].Format = DXGI_FORMAT_R32_UINT;
  1093. polygonLayout[4].InputSlot = 0;
  1094. polygonLayout[4].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
  1095. polygonLayout[4].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  1096. polygonLayout[4].InstanceDataStepRate = 0;
  1097. vertexShader->createInputLayout(polygonLayout, 5);
  1098. vertexShader->createConstBuffer(sizeof(Mat4<float>) * MAX_KNOCHEN_ANZ,
  1099. vertexShader
  1100. ->getFirstUninitializedBufferIndex()); // matrices for skeleton
  1101. // animations
  1102. vertexShader->createConstBuffer(sizeof(Mat4<float>) * 2,
  1103. vertexShader
  1104. ->getFirstUninitializedBufferIndex()); // View and Projection Matrix
  1105. return vertexShader;
  1106. }
  1107. DX11PixelShader* DirectX11::initializePixelShader(
  1108. unsigned char* byteCode, int size)
  1109. {
  1110. DX11PixelShader* pixelShader
  1111. = new DX11PixelShader(d3d11Device, d3d11Context, deviceLock);
  1112. pixelShader->setCompiledByteArray((unsigned char*)byteCode, size);
  1113. pixelShader->createConstBuffer(sizeof(float) * 3,
  1114. pixelShader->getFirstUninitializedBufferIndex()); // Camera position
  1115. pixelShader->createConstBuffer(sizeof(float) * 3,
  1116. pixelShader->getFirstUninitializedBufferIndex()); // material constants
  1117. // using phong model
  1118. pixelShader->createConstBuffer(
  1119. sizeof(int) * 2, pixelShader->getFirstUninitializedBufferIndex());
  1120. pixelShader->createConstBuffer(
  1121. sizeof(TextureEffect), pixelShader->getFirstUninitializedBufferIndex());
  1122. // TODO: Remove Following Test Code
  1123. int lc[] = {0, 0};
  1124. pixelShader->fillConstBuffer((char*)lc, 2, sizeof(int) * 2);
  1125. TextureEffect e = {0, 0.f};
  1126. pixelShader->fillConstBuffer((char*)&e, 3, sizeof(TextureEffect));
  1127. return pixelShader;
  1128. }
  1129. ID3D11DeviceContext* DirectX11::zContext()
  1130. {
  1131. return d3d11Context;
  1132. }
  1133. DXBuffer* DirectX11::createStructuredBuffer(int eSize)
  1134. {
  1135. return new DX11StructuredBuffer(
  1136. eSize, d3d11Device, d3d11Context, deviceLock);
  1137. }
  1138. Model3DData* DirectX11::createModel(const char* name)
  1139. {
  1140. Model3DData* result = GraphicsApi::createModel(name);
  1141. if (result)
  1142. {
  1143. DX11Buffer** newIndexBuffers = new DX11Buffer*[lastModelId + 1];
  1144. DX11Buffer** newVertexBuffers = new DX11Buffer*[lastModelId + 1];
  1145. memcpy(
  1146. newIndexBuffers, indexBuffers, sizeof(DX11Buffer*) * lastModelId);
  1147. memcpy(
  1148. newVertexBuffers, vertexBuffers, sizeof(DX11Buffer*) * lastModelId);
  1149. indexBuffers[lastModelId] = createIndexBuffer();
  1150. vertexBuffers[lastModelId] = createVertexBuffer();
  1151. }
  1152. return result;
  1153. }