/src/renderer/device.cpp

https://bitbucket.org/vivkin/gam3b00bs/ · C++ · 724 lines · 552 code · 128 blank · 44 comment · 75 complexity · 2a96d442cb91dd78c234e1173e777418 MD5 · raw file

  1. #include "device.h"
  2. #include "log.h"
  3. #include <ASSERT.h>
  4. //-----------------------------------------------------------------------------
  5. namespace renderer
  6. {
  7. //-----------------------------------------------------------------------------
  8. #ifndef SAFE_RELEASE
  9. #define SAFE_RELEASE(p) if(p)p->Release();p=0;
  10. #endif
  11. //-----------------------------------------------------------------------------
  12. #define MAX_BUFFERS 128
  13. #define MAX_TEXTURES 128
  14. //-----------------------------------------------------------------------------
  15. vbuffer_t vertex_buffers[MAX_BUFFERS];
  16. uint32 vertex_buffers_count = 0;
  17. //-----------------------------------------------------------------------------
  18. ibuffer_t index_buffers[MAX_BUFFERS];
  19. uint32 index_buffers_count = 0;
  20. //-----------------------------------------------------------------------------
  21. texture_t textures[MAX_TEXTURES];
  22. uint32 textures_count = 0;
  23. //-----------------------------------------------------------------------------
  24. vertex_layout_t vertex_decls[VE_MAX_COUNT] = {0};
  25. //-----------------------------------------------------------------------------
  26. sampler_state_t samplers[MAX_SAMPLERS];
  27. //-----------------------------------------------------------------------------
  28. renderer_desc_t renderer_desc;
  29. LPDIRECT3D9 d3d;
  30. LPDIRECT3DDEVICE9 d3d_device;
  31. D3DPRESENT_PARAMETERS d3d_presentParams;
  32. D3DCAPS9 d3d_deviceCaps;
  33. D3DADAPTER_IDENTIFIER9 d3d_deviceIdentifier;
  34. bool g_device_lost = false;
  35. //-----------------------------------------------------------------------------
  36. LPDIRECT3DDEVICE9 device_get()
  37. {
  38. return d3d_device;
  39. }
  40. //-----------------------------------------------------------------------------
  41. void on_lost_device()
  42. {
  43. for( uint32 i=0; i<index_buffers_count; i++ )
  44. if( index_buffers[i].dynamic )
  45. index_buffers[i].buffer->Release();
  46. for( uint32 i=0; i<vertex_buffers_count; i++ )
  47. if( vertex_buffers[i].dynamic )
  48. vertex_buffers[i].buffer->Release();
  49. }
  50. //-----------------------------------------------------------------------------
  51. void on_reset_device()
  52. {
  53. for( uint32 i=0; i<index_buffers_count; i++ )
  54. if( index_buffers[i].dynamic )
  55. {
  56. HRESULT hr = d3d_device->CreateIndexBuffer( index_buffers[i].size, D3DUSAGE_DYNAMIC, (D3DFORMAT)index_buffers[i].type, D3DPOOL_DEFAULT, &index_buffers[i].buffer, 0 );
  57. if( FAILED(hr) )
  58. {
  59. log_write("Error: unable to restore vertex buffer");
  60. continue;
  61. }
  62. void* pbuf;
  63. ibuffer_lock( &index_buffers[i], &pbuf );
  64. memcpy(pbuf, index_buffers[i].data, index_buffers[i].size);
  65. ibuffer_unlock( &index_buffers[i] );
  66. }
  67. for( uint32 i=0; i<vertex_buffers_count; i++ )
  68. if( vertex_buffers[i].dynamic )
  69. {
  70. HRESULT hr = d3d_device->CreateVertexBuffer( vertex_buffers[i].size, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &vertex_buffers[i].buffer, 0 );
  71. if( FAILED(hr) )
  72. {
  73. log_write("Error: unable to restore vertex buffer");
  74. continue;
  75. }
  76. void* pbuf;
  77. vbuffer_lock( &vertex_buffers[i], &pbuf );
  78. memcpy(pbuf, vertex_buffers[i].data, vertex_buffers[i].size);
  79. vbuffer_unlock( &vertex_buffers[i] );
  80. }
  81. }
  82. //-----------------------------------------------------------------------------
  83. void set_initial_states()
  84. {
  85. d3d_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
  86. d3d_device->SetRenderState(D3DRS_LIGHTING, TRUE);
  87. d3d_device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
  88. d3d_device->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);
  89. if( renderer_desc.multisampling > 0 )
  90. {
  91. d3d_device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
  92. d3d_device->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE , TRUE);
  93. }
  94. };
  95. //-----------------------------------------------------------------------------
  96. uint32 create_device()
  97. {
  98. HRESULT hr;
  99. d3d_presentParams.PresentationInterval = renderer_desc.vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
  100. d3d_presentParams.Windowed = renderer_desc.windowed;
  101. d3d_presentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
  102. d3d_presentParams.EnableAutoDepthStencil = true;
  103. d3d_presentParams.hDeviceWindow = (HWND)renderer_desc.window;
  104. if( renderer_desc.windowed )
  105. {
  106. D3DDISPLAYMODE sys_display_mode;
  107. hr = d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &sys_display_mode);
  108. if( FAILED(hr) )
  109. return ERR_NO_SYS_DISPLAY_MODE;
  110. d3d_presentParams.BackBufferFormat = sys_display_mode.Format;
  111. d3d_presentParams.BackBufferCount = 1;
  112. }
  113. else
  114. {
  115. d3d_presentParams.BackBufferFormat = D3DFMT_X8R8G8B8;
  116. d3d_presentParams.BackBufferWidth = renderer_desc.width;
  117. d3d_presentParams.BackBufferHeight = renderer_desc.height;
  118. d3d_presentParams.FullScreen_RefreshRateInHz = renderer_desc.refresh_rate;
  119. d3d_presentParams.BackBufferCount = 1;
  120. }
  121. d3d_presentParams.AutoDepthStencilFormat = renderer_desc.depth;
  122. uint32 multisampling_max = 16;
  123. while( FAILED(d3d->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d_presentParams.BackBufferFormat, d3d_presentParams.Windowed, (D3DMULTISAMPLE_TYPE)multisampling_max, 0))
  124. || FAILED(d3d->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d_presentParams.AutoDepthStencilFormat, d3d_presentParams.Windowed, (D3DMULTISAMPLE_TYPE)multisampling_max, 0)) )
  125. {
  126. multisampling_max--;
  127. if( multisampling_max == 0 )
  128. break;
  129. }
  130. if( renderer_desc.multisampling > multisampling_max )
  131. renderer_desc.multisampling = multisampling_max;
  132. if( renderer_desc.multisampling > 0 )
  133. d3d_presentParams.MultiSampleType = (D3DMULTISAMPLE_TYPE)renderer_desc.multisampling;
  134. hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d_presentParams.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3d_presentParams, &d3d_device);
  135. if( FAILED(hr) )
  136. {
  137. hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d_presentParams.hDeviceWindow, D3DCREATE_MIXED_VERTEXPROCESSING, &d3d_presentParams, &d3d_device);
  138. if( FAILED(hr) )
  139. {
  140. hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d_presentParams.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3d_presentParams, &d3d_device);
  141. if( FAILED(hr) )
  142. return ERR_NO_DEVICE;
  143. }
  144. }
  145. hr = d3d->GetAdapterIdentifier(D3DADAPTER_DEFAULT , 0, &d3d_deviceIdentifier);
  146. if( FAILED(hr) )
  147. return ERR_NO_DEV_ID;
  148. log_write("Device: %s", d3d_deviceIdentifier.Description);
  149. log_write("Driver: %s", d3d_deviceIdentifier.Driver);
  150. log_write("Version: %d.%d.%d.%d\n",
  151. HIWORD(d3d_deviceIdentifier.DriverVersion.HighPart),
  152. LOWORD(d3d_deviceIdentifier.DriverVersion.HighPart),
  153. HIWORD(d3d_deviceIdentifier.DriverVersion.LowPart),
  154. LOWORD(d3d_deviceIdentifier.DriverVersion.LowPart));
  155. set_initial_states();
  156. return 0;
  157. }
  158. //-----------------------------------------------------------------------------
  159. uint32 init( const renderer_desc_t& desc )
  160. {
  161. ASSERT( d3d == 0 ); // wrong renderer state
  162. ASSERT( d3d_device == 0 ); // wrong renderer state
  163. HRESULT hr;
  164. uint32 res;
  165. memcpy( &renderer_desc, &desc, sizeof(renderer_desc_t) );
  166. d3d = Direct3DCreate9(D3D_SDK_VERSION);
  167. if( !d3d )
  168. {
  169. log_write("ERROR: failed to create D3D");
  170. return ERR_NO_D3D;
  171. }
  172. hr = d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3d_deviceCaps);
  173. if( FAILED(hr) )
  174. {
  175. log_write("ERROR: unable to get device caps");
  176. term();
  177. return ERR_NO_CAPS;
  178. }
  179. res = create_device();
  180. if( res )
  181. {
  182. log_write("ERROR: unable to create device");
  183. term();
  184. return res;
  185. }
  186. // init samplers
  187. // default sampler
  188. samplers[SAMPLER_DEFAULT].address_u = D3DTADDRESS_WRAP;
  189. samplers[SAMPLER_DEFAULT].address_v = D3DTADDRESS_WRAP;
  190. samplers[SAMPLER_DEFAULT].filter_mag = D3DTEXF_ANISOTROPIC;
  191. samplers[SAMPLER_DEFAULT].filter_min = D3DTEXF_ANISOTROPIC;
  192. samplers[SAMPLER_DEFAULT].filter_anisotropy_level = 4;
  193. samplers[SAMPLER_DEFAULT].filter_mip = D3DTEXF_LINEAR;
  194. samplers[SAMPLER_DEFAULT].mipmap_lod_bias = 0;
  195. samplers[SAMPLER_LIGHTMAP].address_u = D3DTADDRESS_CLAMP;
  196. samplers[SAMPLER_LIGHTMAP].address_v = D3DTADDRESS_CLAMP;
  197. samplers[SAMPLER_LIGHTMAP].filter_mag = D3DTEXF_LINEAR;
  198. samplers[SAMPLER_LIGHTMAP].filter_min = D3DTEXF_LINEAR;
  199. // samplers[SAMPLER_LIGHTMAP].filter_anisotropy_level = 4;
  200. samplers[SAMPLER_LIGHTMAP].filter_mip = D3DTEXF_LINEAR;
  201. samplers[SAMPLER_LIGHTMAP].mipmap_lod_bias = 0;
  202. samplers[SAMPLER_GUI].address_u = D3DTADDRESS_WRAP;
  203. samplers[SAMPLER_GUI].address_v = D3DTADDRESS_WRAP;
  204. samplers[SAMPLER_GUI].filter_mag = D3DTEXF_POINT;
  205. samplers[SAMPLER_GUI].filter_min = D3DTEXF_POINT;
  206. // samplers[SAMPLER_GUI].filter_anisotropy_level = 4;
  207. samplers[SAMPLER_GUI].filter_mip = D3DTEXF_NONE;
  208. samplers[SAMPLER_GUI].mipmap_lod_bias = 0;
  209. return 0;
  210. }
  211. //-----------------------------------------------------------------------------
  212. void term()
  213. {
  214. for( uint32 i=0; i<textures_count; i++ )
  215. {
  216. SAFE_RELEASE( textures[i].texture );
  217. }
  218. for( uint32 i=0; i<index_buffers_count; i++ )
  219. {
  220. SAFE_RELEASE( index_buffers[i].buffer );
  221. if( index_buffers[i].dynamic )
  222. free(index_buffers[i].data);
  223. }
  224. for( uint32 i=0; i<vertex_buffers_count; i++ )
  225. {
  226. SAFE_RELEASE( vertex_buffers[i].buffer );
  227. if( vertex_buffers[i].dynamic )
  228. free(vertex_buffers[i].data);
  229. }
  230. SAFE_RELEASE( d3d_device );
  231. SAFE_RELEASE( d3d );
  232. }
  233. //-----------------------------------------------------------------------------
  234. bool begin()
  235. {
  236. ASSERT( d3d_device );
  237. HRESULT hr;
  238. hr = d3d_device->TestCooperativeLevel();
  239. if( hr == D3DERR_DEVICELOST )
  240. {
  241. g_device_lost = true;
  242. on_lost_device();
  243. return false;
  244. }
  245. if( hr == D3DERR_DEVICENOTRESET )
  246. {
  247. if( reset() )
  248. return false;
  249. g_device_lost = false;
  250. on_reset_device();
  251. }
  252. d3d_device->BeginScene();
  253. return true;
  254. }
  255. //-----------------------------------------------------------------------------
  256. void end()
  257. {
  258. ASSERT( d3d_device );
  259. d3d_device->EndScene();
  260. d3d_device->Present(0, 0, 0, 0);
  261. }
  262. //-----------------------------------------------------------------------------
  263. void clear( uint32 color, float depth, uint8 stencil )
  264. {
  265. ASSERT( d3d_device );
  266. if( renderer_desc.depth == D3DFMT_D24S8 )
  267. d3d_device->Clear(0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET | D3DCLEAR_STENCIL, color, depth, stencil);
  268. else
  269. d3d_device->Clear(0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, color, depth, 0);
  270. }
  271. //-----------------------------------------------------------------------------
  272. void render( const render_op& rop )
  273. {
  274. ASSERT(d3d_device);
  275. d3d_device->SetMaterial(&rop.material.material);
  276. d3d_device->SetTexture(0, rop.material.stages[0].texture->texture);
  277. d3d_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  278. if( rop.material.stages[1].texture )
  279. {
  280. d3d_device->SetTexture(1, rop.material.stages[1].texture->texture);
  281. d3d_device->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL );
  282. d3d_device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD );
  283. d3d_device->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  284. d3d_device->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT );
  285. }
  286. else
  287. {
  288. d3d_device->SetTexture(1, 0);
  289. }
  290. D3DXMATRIX world((float*)&rop.transformation);
  291. d3d_device->SetTransform(D3DTS_WORLD, &world);
  292. d3d_device->SetVertexDeclaration(rop.vertex_layout->decl);
  293. d3d_device->SetIndices(rop.ib->buffer);
  294. d3d_device->SetStreamSource(0, rop.vb->buffer, rop.vertex_offset, rop.vertex_size);
  295. d3d_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, rop.vertex_count, rop.index_offset, rop.index_count / 3);
  296. }
  297. //-----------------------------------------------------------------------------
  298. void set_environment_state( const environment_state_t& e_state )
  299. {
  300. ASSERT(d3d_device);
  301. for( uint32 i=0; i<8; i++ )
  302. {
  303. if( e_state.light_enable[i] )
  304. {
  305. d3d_device->LightEnable(i, true);
  306. d3d_device->SetLight(i, &e_state.light[i]);
  307. }
  308. }
  309. }
  310. //-----------------------------------------------------------------------------
  311. void set_view( const D3DXMATRIX& view )
  312. {
  313. ASSERT( d3d_device );
  314. d3d_device->SetTransform(D3DTS_VIEW, &view);
  315. }
  316. //-----------------------------------------------------------------------------
  317. void set_projection( const D3DXMATRIX& proj )
  318. {
  319. ASSERT( d3d_device );
  320. d3d_device->SetTransform(D3DTS_PROJECTION, &proj);
  321. }
  322. //-----------------------------------------------------------------------------
  323. void set_camera( const camera_t& camera )
  324. {
  325. ASSERT( d3d_device );
  326. d3d_device->SetTransform(D3DTS_VIEW, &camera.view);
  327. d3d_device->SetTransform(D3DTS_PROJECTION, &camera.projection);
  328. }
  329. //-----------------------------------------------------------------------------
  330. sampler_state create_sampler_state( const sampler_state_t& desc )
  331. {
  332. ASSERT(0);
  333. return 0;
  334. }
  335. //-----------------------------------------------------------------------------
  336. state_group create_state_group( const state_group_desc_t& desc )
  337. {
  338. ASSERT(0);
  339. return 0;
  340. }
  341. //-----------------------------------------------------------------------------
  342. uint32 reset()
  343. {
  344. ASSERT( d3d_device );
  345. HRESULT hr;
  346. hr = d3d_device->Reset(&d3d_presentParams);
  347. if( FAILED(hr) )
  348. {
  349. log_write("ERROR: Unable to reset device");
  350. return ERR_CANT_RESET;
  351. }
  352. set_initial_states();
  353. return 0;
  354. }
  355. //-----------------------------------------------------------------------------
  356. texture_h texture_create( const byte* data, uint32 data_size )
  357. {
  358. ASSERT(data);
  359. ASSERT(d3d_device);
  360. ASSERT(textures_count < MAX_TEXTURES);
  361. D3DXIMAGE_INFO info;
  362. HRESULT hr = D3DXCreateTextureFromFileInMemoryEx( d3d_device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
  363. 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, &info, 0, &textures[textures_count].texture );
  364. if( FAILED(hr) )
  365. {
  366. log_write("Error: unable to create texture");
  367. return 0;
  368. }
  369. textures[textures_count].width = info.Width;
  370. textures[textures_count].height = info.Height;
  371. return &textures[textures_count++];
  372. }
  373. //-----------------------------------------------------------------------------
  374. vbuffer_h vbuffer_create( uint32 size, const byte* init_data, uint32 usage )
  375. {
  376. ASSERT(d3d_device);
  377. ASSERT(size > 0);
  378. ASSERT(vertex_buffers_count < MAX_BUFFERS);
  379. vbuffer_h buffer = &vertex_buffers[vertex_buffers_count];
  380. D3DPOOL pool = D3DPOOL_MANAGED;
  381. if( usage & D3DUSAGE_DYNAMIC )
  382. {
  383. buffer->data = (byte*)malloc(size);
  384. buffer->dynamic = true;
  385. pool = D3DPOOL_DEFAULT;
  386. }
  387. HRESULT hr = d3d_device->CreateVertexBuffer( size, usage, 0, pool, &buffer->buffer, 0 );
  388. if( FAILED(hr) )
  389. {
  390. log_write("Error: unable to create vertex buffer");
  391. return 0;
  392. }
  393. buffer->size = size;
  394. if( init_data )
  395. {
  396. void* pbuf;
  397. vbuffer_lock( buffer, &pbuf );
  398. memcpy(pbuf, init_data, size);
  399. vbuffer_unlock( buffer );
  400. if( usage & D3DUSAGE_DYNAMIC )
  401. memcpy(buffer->data, init_data, size);
  402. }
  403. vertex_buffers_count++;
  404. return buffer;
  405. }
  406. //-----------------------------------------------------------------------------
  407. uint32 vbuffer_lock( vbuffer_h buffer, void** mem, uint32 length, uint32 offset )
  408. {
  409. ASSERT(buffer);
  410. ASSERT(buffer->buffer);
  411. if( !length )
  412. length = buffer->size;
  413. ASSERT(length > 0);
  414. if( g_device_lost )
  415. {
  416. ASSERT( buffer->data );
  417. *mem = buffer->data + offset;
  418. return 0;
  419. }
  420. HRESULT hr = buffer->buffer->Lock(offset, length, mem, 0);
  421. if( FAILED(hr) )
  422. {
  423. log_write("Error: unable to lock vertex buffer");
  424. return 1;
  425. }
  426. return 0;
  427. }
  428. //-----------------------------------------------------------------------------
  429. uint32 vbuffer_unlock( vbuffer_h buffer )
  430. {
  431. ASSERT(buffer);
  432. ASSERT(buffer->buffer);
  433. HRESULT hr = buffer->buffer->Unlock();
  434. if( FAILED(hr) )
  435. {
  436. log_write("ERROR: unable to unlock vertex buffer");
  437. return 1;
  438. }
  439. return 0;
  440. }
  441. //-----------------------------------------------------------------------------
  442. ibuffer_h ibuffer_create( IB_TYPE type, uint32 size, const byte* init_data, uint32 usage )
  443. {
  444. ASSERT(d3d_device);
  445. ASSERT(size > 0);
  446. ASSERT(index_buffers_count < MAX_BUFFERS);
  447. ASSERT(type != IB_NONE);
  448. ibuffer_h buffer = &index_buffers[index_buffers_count];
  449. D3DPOOL pool = D3DPOOL_MANAGED;
  450. if( usage & D3DUSAGE_DYNAMIC )
  451. {
  452. buffer->data = (byte*)malloc(size);
  453. buffer->dynamic = true;
  454. pool = D3DPOOL_DEFAULT;
  455. }
  456. HRESULT hr = d3d_device->CreateIndexBuffer( size, usage, (D3DFORMAT)type, pool, &buffer->buffer, 0 );
  457. if( FAILED(hr) )
  458. {
  459. log_write("Error: unable to create index buffer");
  460. return 0;
  461. }
  462. buffer->size = size;
  463. buffer->type = type;
  464. if( init_data )
  465. {
  466. void* pbuf;
  467. ibuffer_lock( buffer, &pbuf );
  468. memcpy(pbuf, init_data, size);
  469. ibuffer_unlock( buffer );
  470. if( usage & D3DUSAGE_DYNAMIC )
  471. memcpy(buffer->data, init_data, size);
  472. }
  473. index_buffers_count++;
  474. return buffer;
  475. }
  476. //-----------------------------------------------------------------------------
  477. uint32 ibuffer_lock( ibuffer_h buffer, void** mem, uint32 length, uint32 offset )
  478. {
  479. ASSERT(buffer);
  480. ASSERT(buffer->buffer);
  481. if( !length )
  482. length = buffer->size;
  483. ASSERT(length > 0);
  484. if( !length )
  485. length = buffer->size;
  486. ASSERT(length > 0);
  487. if( g_device_lost )
  488. {
  489. ASSERT( buffer->data );
  490. *mem = buffer->data + offset;
  491. return 0;
  492. }
  493. HRESULT hr = buffer->buffer->Lock(offset, length, mem, 0);
  494. if( FAILED(hr) )
  495. {
  496. log_write("Error: unable to lock index buffer");
  497. return 1;
  498. }
  499. return 0;
  500. }
  501. //-----------------------------------------------------------------------------
  502. uint32 ibuffer_unlock( ibuffer_h buffer )
  503. {
  504. ASSERT(buffer);
  505. ASSERT(buffer->buffer);
  506. HRESULT hr = buffer->buffer->Unlock();
  507. if( FAILED(hr) )
  508. {
  509. log_write("Error: unable to unlock index buffer");
  510. return 1;
  511. }
  512. return 0;
  513. }
  514. //-----------------------------------------------------------------------------
  515. vertex_layout_h get_vertex_layout( uint32 vertex_type )
  516. {
  517. ASSERT(vertex_type < VE_MAX_COUNT);
  518. ASSERT(d3d_device);
  519. if( !vertex_decls[vertex_type].decl )
  520. {
  521. D3DVERTEXELEMENT9 decl[8];
  522. uint16 element_count = 0;
  523. uint16 stride = 0;
  524. if( vertex_type & VE_POSITION )
  525. {
  526. D3DVERTEXELEMENT9 str = { 0, stride, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 };
  527. decl[element_count] = str;
  528. element_count++;
  529. stride += sizeof(float) * 3;
  530. }
  531. if( vertex_type & VE_POSITION_RHW )
  532. {
  533. D3DVERTEXELEMENT9 str = { 0, stride, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 };
  534. decl[element_count] = str;
  535. element_count++;
  536. stride += sizeof(float) * 4;
  537. }
  538. if( vertex_type & VE_NORMAL )
  539. {
  540. D3DVERTEXELEMENT9 str = { 0, stride, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 };
  541. decl[element_count] = str;
  542. element_count++;
  543. stride += sizeof(float) * 3;
  544. }
  545. if( vertex_type & VE_COLOR )
  546. {
  547. D3DVERTEXELEMENT9 str = { 0, stride, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 };
  548. decl[element_count] = str;
  549. element_count++;
  550. stride += sizeof(uint32);
  551. }
  552. if( vertex_type & VE_TEXTURE0 )
  553. {
  554. D3DVERTEXELEMENT9 str = { 0, stride, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 };
  555. decl[element_count] = str;
  556. element_count++;
  557. stride += sizeof(float) * 2;
  558. }
  559. if( vertex_type & VE_TEXTURE1 )
  560. {
  561. D3DVERTEXELEMENT9 str = { 0, stride, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 };
  562. decl[element_count] = str;
  563. element_count++;
  564. stride += sizeof(float) * 2;
  565. }
  566. D3DVERTEXELEMENT9 str = D3DDECL_END();
  567. decl[element_count] = str;
  568. HRESULT hr;
  569. hr = d3d_device->CreateVertexDeclaration(decl, &vertex_decls[vertex_type].decl);
  570. if( FAILED(hr) )
  571. {
  572. log_write("Error: unable to create vertex declaration %X", vertex_type);
  573. return 0;
  574. }
  575. // vertex_sizes[vertex_type] = stride;
  576. vertex_decls[vertex_type].fvf = vertex_type;
  577. }
  578. // if( out_size )
  579. // *out_size = vertex_sizes[vertex_type];
  580. return &vertex_decls[vertex_type];
  581. }
  582. //-----------------------------------------------------------------------------
  583. void set_sampler( uint32 id, SAMPLER_TYPE sampler )
  584. {
  585. d3d_device->SetSamplerState(id, D3DSAMP_MIPFILTER, samplers[sampler].filter_mip);
  586. d3d_device->SetSamplerState(id, D3DSAMP_MINFILTER, samplers[sampler].filter_min);
  587. d3d_device->SetSamplerState(id, D3DSAMP_MAGFILTER, samplers[sampler].filter_mag);
  588. if( samplers[sampler].filter_min == D3DTEXF_ANISOTROPIC ||
  589. samplers[sampler].filter_mag == D3DTEXF_ANISOTROPIC)
  590. d3d_device->SetSamplerState(id, D3DSAMP_MAXANISOTROPY, samplers[sampler].filter_anisotropy_level);
  591. d3d_device->SetSamplerState(id, D3DSAMP_MIPMAPLODBIAS, samplers[sampler].mipmap_lod_bias);
  592. d3d_device->SetSamplerState(id, D3DSAMP_ADDRESSU, samplers[sampler].address_u);
  593. d3d_device->SetSamplerState(id, D3DSAMP_ADDRESSV, samplers[sampler].address_v);
  594. }
  595. //-----------------------------------------------------------------------------
  596. }