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