PageRenderTime 62ms CodeModel.GetById 11ms app.highlight 45ms RepoModel.GetById 1ms app.codeStats 1ms

/src/renderer/device.cpp

https://bitbucket.org/vivkin/gam3b00bs/
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}