16 #include "dxGraphicsStateGuardian9.h" 17 #include "config_dxgsg9.h" 18 #include "displayRegion.h" 19 #include "renderBuffer.h" 21 #include "graphicsWindow.h" 22 #include "graphicsEngine.h" 24 #include "ambientLight.h" 25 #include "directionalLight.h" 26 #include "pointLight.h" 27 #include "spotlight.h" 28 #include "textureAttrib.h" 29 #include "texGenAttrib.h" 30 #include "shadeModelAttrib.h" 31 #include "cullFaceAttrib.h" 32 #include "transparencyAttrib.h" 33 #include "alphaTestAttrib.h" 34 #include "depthTestAttrib.h" 35 #include "depthWriteAttrib.h" 36 #include "colorWriteAttrib.h" 37 #include "texMatrixAttrib.h" 38 #include "materialAttrib.h" 39 #include "renderModeAttrib.h" 40 #include "rescaleNormalAttrib.h" 41 #include "fogAttrib.h" 42 #include "depthOffsetAttrib.h" 43 #include "lightAttrib.h" 44 #include "stencilAttrib.h" 45 #include "scissorAttrib.h" 46 #include "clipPlaneAttrib.h" 48 #include "throw_event.h" 49 #include "geomVertexFormat.h" 50 #include "geomVertexData.h" 51 #include "geomTriangles.h" 52 #include "geomTristrips.h" 53 #include "geomTrifans.h" 54 #include "geomLines.h" 55 #include "geomLinestrips.h" 56 #include "geomPoints.h" 57 #include "geomVertexReader.h" 58 #include "dxGeomMunger9.h" 59 #include "config_gobj.h" 60 #include "dxVertexBufferContext9.h" 61 #include "dxIndexBufferContext9.h" 62 #include "dxOcclusionQueryContext9.h" 63 #include "pStatTimer.h" 64 #include "pStatCollector.h" 65 #include "wdxGraphicsBuffer9.h" 66 #include "config_pgraph.h" 67 #include "shaderGenerator.h" 69 #include "Cg/cgD3D9.h" 76 #define tostring(x) #x 77 #define SDK_VERSION(major,minor) tostring(major) << "." << tostring(minor) 78 #define DIRECTX_SDK_VERSION SDK_VERSION (_DXSDK_PRODUCT_MAJOR, _DXSDK_PRODUCT_MINOR) << "." << SDK_VERSION (_DXSDK_BUILD_MAJOR, _DXSDK_BUILD_MINOR) 80 TypeHandle DXGraphicsStateGuardian9::_type_handle;
82 D3DMATRIX DXGraphicsStateGuardian9::_d3d_ident_mat;
84 unsigned char *DXGraphicsStateGuardian9::_temp_buffer = NULL;
85 unsigned char *DXGraphicsStateGuardian9::_safe_buffer_start = NULL;
88 LPDIRECT3DDEVICE9 DXGraphicsStateGuardian9::_cg_device = NULL;
91 #define __D3DLIGHT_RANGE_MAX ((PN_stdfloat)sqrt(FLT_MAX)) //for some reason this is missing in dx9 hdrs 93 #define MY_D3DRGBA(r, g, b, a) ((D3DCOLOR) D3DCOLOR_COLORVALUE(r, g, b, a)) 100 DXGraphicsStateGuardian9::
104 if (dxgsg9_cat.is_debug()) {
106 <<
"DXGraphicsStateGuardian9 " <<
this <<
" constructing\n";
116 _dx_is_ready =
false;
117 _vertex_blending_enabled =
false;
118 _overlay_windows_supported =
false;
119 _tex_stats_retrieval_impossible =
false;
120 _supports_render_texture =
false;
122 _active_ibuffer = NULL;
127 ZeroMemory(&_d3d_ident_mat,
sizeof(D3DMATRIX));
128 _d3d_ident_mat._11 = _d3d_ident_mat._22 = _d3d_ident_mat._33 = _d3d_ident_mat._44 = 1.0f;
130 _cur_read_pixel_buffer = RenderBuffer::T_front;
134 _copy_texture_inverted =
true;
136 _gsg_managed_textures = dx_management | dx_texture_management;
137 _gsg_managed_vertex_buffers = dx_management;
138 _gsg_managed_index_buffers = dx_management;
141 _num_bound_streams = 0;
143 _vertex_shader_version_major = 0;
144 _vertex_shader_version_minor = 0;
145 _pixel_shader_version_major = 0;
146 _pixel_shader_version_minor = 0;
148 _vertex_shader_profile = 0;
149 _pixel_shader_profile = 0;
151 _vertex_shader_maximum_constants = 0;
153 _supports_stream_offset =
false;
160 atexit (atexit_function);
168 DXGraphicsStateGuardian9::
169 ~DXGraphicsStateGuardian9() {
170 if (dxgsg9_cat.is_debug()) {
172 <<
"DXGraphicsStateGuardian9 " <<
this <<
" destructing\n";
175 if (IS_VALID_PTR(_d3d_device)) {
176 _d3d_device->SetTexture(0, NULL);
179 free_nondx_resources();
201 << *dtc->
get_texture() <<
" is stored in an unsupported compressed format.\n";
219 set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
222 if (!update_texture(tc,
false)) {
224 set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
235 set_sampler_state(i, D3DSAMP_SRGBTEXTURE, TRUE);
237 set_sampler_state(i, D3DSAMP_SRGBTEXTURE, FALSE);
240 set_sampler_state(i, D3DSAMP_ADDRESSU,
243 set_sampler_state(i, D3DSAMP_ADDRESSV,
246 set_sampler_state(i, D3DSAMP_ADDRESSW,
252 set_sampler_state(i, D3DSAMP_BORDERCOLOR, border_color);
257 if (aniso_degree >= 1) {
258 set_sampler_state(i, D3DSAMP_MAXANISOTROPY, aniso_degree);
261 int supports_anisotropic_mag_filter;
262 D3DTEXTUREFILTERTYPE new_mag_filter;
264 supports_anisotropic_mag_filter = (_screen -> _d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) != 0;
265 if (aniso_degree <= 1 || supports_anisotropic_mag_filter == 0) {
266 new_mag_filter = ((ft != SamplerState::FT_nearest) ? D3DTEXF_LINEAR : D3DTEXF_POINT);
268 new_mag_filter = D3DTEXF_ANISOTROPIC;
272 hr = set_sampler_state(i, D3DSAMP_MAGFILTER, new_mag_filter);
275 <<
"ERROR: set_sampler_state (D3DSAMP_MAGFILTER, " 276 << new_mag_filter <<
") failed for sampler: " << sampler << endl;
287 new_mip_filter = D3DTEXF_NONE;
292 new_mip_filter = D3DTEXF_NONE;
295 if (aniso_degree >= 2) {
296 new_min_filter = D3DTEXF_ANISOTROPIC;
299 set_sampler_state(i, D3DSAMP_MINFILTER, new_min_filter);
300 set_sampler_state(i, D3DSAMP_MIPFILTER, new_mip_filter);
303 set_sampler_state(i, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&lod_bias);
332 if (!upload_texture(dtc, force)) {
336 <<
"Unable to re-create texture " << *tex << endl;
340 dtc->
enqueue_lru(&_prepared_objects->_graphics_memory_lru);
356 << *tex <<
" is stored in an unsupported compressed format.\n";
364 if (_effective_incomplete_render && !force) {
368 !_loader.is_null()) {
371 async_reload_texture(dtc);
375 return dtc->create_simple_texture(*_screen);
414 for (
int view = 0; view < num_views; ++view) {
437 case Shader::SL_GLSL:
439 <<
"Tried to load GLSL shader, but GLSL shaders not supported by Direct3D 9.\n";
444 if (_supports_basic_shaders) {
448 <<
"Tried to load Cg shader, but basic shaders not supported.\n";
453 <<
"Tried to load Cg shader, but Cg support not compiled in.\n";
459 <<
"Tried to load shader with unsupported shader language!\n";
496 if (_screen->_managed_vertex_buffers) {
497 pool = D3DPOOL_MANAGED;
498 usage = D3DUSAGE_WRITEONLY;
500 pool = D3DPOOL_DEFAULT;
501 usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC;
512 hr = _screen->_d3d_device->CreateVertexBuffer(num_bytes, usage, dvbc->_fvf, pool, &dvbc->_vbuffer, NULL);
515 while (check_dx_allocation(hr, num_bytes, attempts));
519 if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) {
521 <<
"creating vertex buffer " << dvbc->_vbuffer <<
": " 530 <<
"CreateVertexBuffer failed" << D3DERRORSTRING(hr);
532 dvbc->_vbuffer = NULL;
550 if (dvbc->was_modified(reader)) {
551 int num_bytes = reader->get_data_size_bytes();
553 if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) {
555 <<
"copying " << num_bytes
556 <<
" bytes into vertex buffer " << dvbc->_vbuffer <<
"\n";
560 if ( num_bytes != 0 ) {
562 if (client_pointer == NULL) {
566 PStatTimer timer(_load_vertex_buffer_pcollector, reader->get_current_thread());
569 if (dvbc->changed_size(reader)) {
572 dvbc->create_vbuffer(*_screen, reader);
578 if (_screen->_managed_vertex_buffers) {
579 hr = dvbc->_vbuffer->Lock(0, num_bytes, (
void **) &local_pointer, 0);
581 hr = dvbc->_vbuffer->Lock(0, num_bytes, (
void **) &local_pointer, D3DLOCK_DISCARD);
585 <<
"VertexBuffer::Lock failed" << D3DERRORSTRING(hr);
589 memcpy(local_pointer, client_pointer, num_bytes);
591 dvbc->_vbuffer->Unlock();
593 _data_transferred_pcollector.add_level(num_bytes);
596 dvbc->mark_loaded(reader);
598 dvbc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
617 if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) {
619 <<
"deleting vertex buffer " << dvbc->_vbuffer <<
"\n";
623 dvbc->_vbuffer->Release();
624 dvbc->_vbuffer = NULL;
655 if (!apply_vertex_buffer(vbc, array_reader, force)) {
693 if (dibc->_ibuffer == NULL) {
697 if (dibc->_ibuffer != NULL) {
703 _d3d_device->SetIndices(dibc->_ibuffer);
704 _active_ibuffer = dibc;
708 _d3d_device->SetIndices(NULL);
709 _active_ibuffer = NULL;
725 _active_ibuffer = NULL;
728 if (_active_ibuffer != dibc) {
729 _d3d_device->SetIndices(dibc->_ibuffer);
730 _active_ibuffer = dibc;
734 dibc->
enqueue_lru(&_prepared_objects->_graphics_memory_lru);
771 nassertv(_supports_occlusion_query);
774 IDirect3DQuery9 *query;
775 HRESULT hr = _d3d_device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &query);
778 <<
"Occlusion query failed.\n";
784 if (dxgsg9_cat.is_debug()) {
786 <<
"beginning occlusion query " << query <<
"\n";
789 query->Issue(D3DISSUE_BEGIN);
790 _current_occlusion_query = queryobj;
803 end_occlusion_query() {
812 if (dxgsg9_cat.is_debug()) {
814 <<
"ending occlusion query " << query <<
"\n";
817 _current_occlusion_query = NULL;
818 query->Issue(D3DISSUE_END);
832 return GeomMunger::register_munger(munger, current_thread);
844 DWORD main_flags = 0;
853 set_state_and_transform(RenderState::make_empty(), _internal_transform);
855 D3DCOLOR color_clear_value = LColor_to_D3DCOLOR(clearable->
get_clear_color());
861 main_flags |= D3DCLEAR_TARGET;
865 aux_flags |= D3DCLEAR_ZBUFFER;
866 nassertv(_screen->_presentation_params.EnableAutoDepthStencil);
871 if (_screen->_presentation_params.EnableAutoDepthStencil &&
872 IS_STENCIL_FORMAT(_screen->_presentation_params.AutoDepthStencilFormat)) {
873 aux_flags |= D3DCLEAR_STENCIL;
877 if ((main_flags | aux_flags) != 0) {
878 HRESULT hr = _d3d_device->Clear(0, NULL, main_flags | aux_flags, color_clear_value,
879 depth_clear_value, stencil_clear_value);
880 if (FAILED(hr) && main_flags == D3DCLEAR_TARGET && aux_flags != 0) {
883 hr = _d3d_device->Clear(0, NULL, D3DCLEAR_TARGET, color_clear_value,
884 depth_clear_value, stencil_clear_value);
889 aux_flags |= D3DCLEAR_ZBUFFER;
890 HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, color_clear_value,
891 depth_clear_value, stencil_clear_value);
894 <<
"Unable to clear depth buffer; removing.\n";
900 aux_flags |= D3DCLEAR_STENCIL;
901 HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_STENCIL, color_clear_value,
902 stencil_clear_value, stencil_clear_value);
905 <<
"Unable to clear stencil buffer; removing.\n";
908 _supports_stencil =
false;
916 <<
"clear_buffer failed: Clear returned " << D3DERRORSTRING(hr);
936 D3DVIEWPORT9 vp = { l, u, w, h, 0.0f, 1.0f };
937 _current_viewport = vp;
938 HRESULT hr = _d3d_device->SetViewport(&_current_viewport);
941 <<
"_screen->_swap_chain = " << _screen->_swap_chain <<
" _swap_chain = " << _swap_chain <<
"\n";
943 <<
"SetViewport(" << l <<
", " << u <<
", " << w <<
", " << h
944 <<
") failed" << D3DERRORSTRING(hr);
947 _d3d_device->GetViewport(&vp_old);
949 <<
"GetViewport(" << vp_old.X <<
", " << vp_old.Y <<
", " << vp_old.Width <<
", " 950 << vp_old.Height <<
") returned: Trying to set that vp---->\n";
951 hr = _d3d_device->SetViewport(&vp_old);
952 set_render_state(D3DRS_SCISSORTESTENABLE, FALSE);
955 dxgsg9_cat.error() <<
"Failed again\n";
956 throw_event(
"panda3d-render-error");
961 if (_screen->_can_direct_disable_color_writes) {
962 set_render_state(D3DRS_COLORWRITEENABLE, _color_write_mask);
977 CPT(TransformState) DXGraphicsStateGuardian9::
978 calc_projection_mat(
const Lens *lens) {
979 if (lens == (
Lens *)NULL) {
1001 if (_scene_setup->get_inverted()) {
1007 return TransformState::make_mat(result);
1024 LMatrix4f mat = LCAST(
float, _projection_mat->get_mat());
1026 _d3d_device->SetTransform(D3DTS_PROJECTION,
1028 return SUCCEEDED(hr);
1049 if (_d3d_device == NULL) {
1051 <<
this <<
"::begin_frame(): no device.\n";
1055 HRESULT hr = _d3d_device->BeginScene();
1058 if (hr == D3DERR_DEVICELOST) {
1059 if (dxgsg9_cat.is_debug()) {
1061 <<
"BeginScene returns D3DERR_DEVICELOST" << endl;
1064 check_cooperative_level();
1068 <<
"BeginScene failed, unhandled error hr == " 1069 << D3DERRORSTRING(hr) << endl;
1070 throw_event(
"panda3d-render-error");
1075 if (_current_properties->get_srgb_color()) {
1076 set_render_state(D3DRS_SRGBWRITEENABLE, TRUE);
1078 set_render_state(D3DRS_SRGBWRITEENABLE, FALSE);
1143 if (_vertex_array_shader_context != 0) {
1144 _vertex_array_shader_context->disable_shader_vertex_arrays(
this);
1145 _vertex_array_shader = (
Shader *)NULL;
1148 if (_texture_binding_shader_context != 0) {
1149 _texture_binding_shader_context->disable_shader_texture_bindings(
this);
1150 _texture_binding_shader = (
Shader *)NULL;
1151 _texture_binding_shader_context = (CLP(
ShaderContext) *)NULL;
1153 if (_current_shader_context != 0) {
1154 _current_shader_context->unbind(
this);
1155 _current_shader = (
Shader *)NULL;
1193 HRESULT hr = _d3d_device->EndScene();
1196 if (hr == D3DERR_DEVICELOST) {
1197 if (dxgsg9_cat.is_debug()) {
1199 <<
"EndScene returns DeviceLost\n";
1201 check_cooperative_level();
1205 <<
"EndScene failed, unhandled error hr == " << D3DERRORSTRING(hr);
1206 throw_event(
"panda3d-render-error");
1211 #if defined(DO_PSTATS) 1212 if (_texmgrmem_total_pcollector.is_active()) {
1213 #define TICKS_PER_GETTEXINFO (2.5*1000) // 2.5 second interval 1214 static DWORD last_tick_count = 0;
1215 DWORD cur_tick_count = GetTickCount();
1217 if (cur_tick_count - last_tick_count > TICKS_PER_GETTEXINFO) {
1218 last_tick_count = cur_tick_count;
1219 report_texmgr_stats();
1244 data_reader, force)) {
1249 const GeomVertexFormat *format = _data_reader->get_format();
1252 data_reader->get_format()->get_animation();
1263 set_render_state(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
1266 set_render_state(D3DRS_VERTEXBLEND, D3DVBF_1WEIGHTS);
1269 set_render_state(D3DRS_VERTEXBLEND, D3DVBF_2WEIGHTS);
1272 set_render_state(D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
1278 set_render_state(D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE);
1280 set_render_state(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
1283 const TransformTable *table = data_reader->get_transform_table();
1288 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)mat.
get_data();
1289 _d3d_device->SetTransform(D3DTS_WORLDMATRIX(i), d3d_mat);
1294 _transform_stale =
true;
1296 _vertex_blending_enabled =
true;
1300 if (_vertex_blending_enabled) {
1301 set_render_state(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
1302 set_render_state(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
1303 _vertex_blending_enabled =
false;
1306 if (_transform_stale && !_data_reader->is_vertex_transformed()) {
1307 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)_internal_transform->get_mat().get_data();
1308 _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
1309 _transform_stale =
false;
1313 if (_data_reader->is_vertex_transformed()) {
1322 _d3d_device->SetTransform(D3DTS_WORLD, &_d3d_ident_mat);
1328 _transform_stale =
true;
1330 _d3d_device->SetTransform(D3DTS_PROJECTION, (
const D3DMATRIX *)rescale_mat.
get_data());
1333 if (_current_shader_context == 0 ) {
1335 if (_vertex_array_shader_context != 0) {
1336 _vertex_array_shader_context->disable_shader_vertex_arrays(
this);
1338 if (!update_standard_vertex_arrays(force)) {
1343 if (_vertex_array_shader_context == 0) {
1344 disable_standard_vertex_arrays();
1345 if (!_current_shader_context->update_shader_vertex_arrays(NULL,
this, force)) {
1349 if (!_current_shader_context->
1350 update_shader_vertex_arrays(_vertex_array_shader_context,
this, force)) {
1356 _vertex_array_shader = _current_shader;
1357 _vertex_array_shader_context = _current_shader_context;
1372 update_standard_vertex_arrays(
bool force) {
1377 int number_of_arrays = _data_reader->get_num_arrays();
1378 for (
int array_index = 0; array_index < number_of_arrays; ++array_index ) {
1380 if ( array_reader == NULL ) {
1381 dxgsg9_cat.error() <<
"Unable to get reader for array " << array_index <<
"\n";
1387 if (!setup_array_data(dvbc, array_reader, force)) {
1388 dxgsg9_cat.error() <<
"Unable to setup vertex buffer for array " << array_index <<
"\n";
1393 const GeomVertexArrayFormat* array_format = array_reader->get_array_format();
1394 hr = _d3d_device->SetStreamSource( array_index, dvbc->_vbuffer, 0, array_format->get_stride() );
1396 dxgsg9_cat.error() <<
"SetStreamSource failed" << D3DERRORSTRING(hr);
1404 hr = _d3d_device->SetFVF( fvf );
1406 dxgsg9_cat.error() <<
"SetFVF failed" << D3DERRORSTRING(hr);
1423 disable_standard_vertex_arrays() {
1424 for (
int array_index = 0; array_index < _num_bound_streams; ++array_index )
1426 _d3d_device->SetStreamSource( array_index, NULL, 0, 0 );
1428 _num_bound_streams = 0;
1440 _vertices_tri_pcollector.add_level(reader->get_num_vertices());
1441 _primitive_batches_tri_pcollector.add_level(1);
1443 if (reader->is_indexed()) {
1444 int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
1445 int max_vertex = reader->get_max_vertex();
1450 if (!apply_index_buffer(ibc, reader, force)) {
1454 _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,
1456 min_vertex, max_vertex - min_vertex + 1,
1457 0, reader->get_num_primitives() );
1461 const unsigned char *index_pointer = reader->get_read_pointer(force);
1462 if (index_pointer == NULL) {
1465 D3DFORMAT index_type = get_index_type(reader->get_index_type());
1466 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1467 if (vertex_pointer == NULL) {
1471 draw_indexed_primitive_up( D3DPT_TRIANGLELIST,
1472 min_vertex, max_vertex,
1473 reader->get_num_primitives(),
1474 index_pointer, index_type, vertex_pointer,
1475 _data_reader->get_format()->get_array(0)->get_stride() );
1479 _d3d_device->DrawPrimitive( D3DPT_TRIANGLELIST,
1480 reader->get_first_vertex(),
1481 reader->get_num_primitives() );
1485 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1486 if (vertex_pointer == NULL) {
1490 draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(),
1491 reader->get_first_vertex(),
1492 reader->get_num_vertices(), vertex_pointer,
1493 _data_reader->get_format()->get_array(0)->get_stride());
1509 if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) {
1512 _vertices_tristrip_pcollector.add_level(reader->get_num_vertices());
1513 _primitive_batches_tristrip_pcollector.add_level(1);
1515 if (reader->is_indexed()) {
1516 int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
1517 int max_vertex = reader->get_max_vertex();
1522 if (!apply_index_buffer(ibc, reader, force)) {
1526 _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP,
1528 min_vertex, max_vertex - min_vertex + 1,
1529 0, reader->get_num_vertices() - 2 );
1533 const unsigned char *index_pointer = reader->get_read_pointer(force);
1534 if (index_pointer == NULL) {
1537 D3DFORMAT index_type = get_index_type(reader->get_index_type());
1538 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1539 if (vertex_pointer == NULL) {
1543 draw_indexed_primitive_up
1544 (D3DPT_TRIANGLESTRIP,
1545 min_vertex, max_vertex,
1546 reader->get_num_vertices() - 2,
1547 index_pointer, index_type, vertex_pointer,
1548 _data_reader->get_format()->get_array(0)->get_stride());
1552 _d3d_device->DrawPrimitive( D3DPT_TRIANGLESTRIP,
1553 reader->get_first_vertex(),
1554 reader->get_num_vertices() - 2 );
1558 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1559 if (vertex_pointer == NULL) {
1562 draw_primitive_up(D3DPT_TRIANGLESTRIP,
1563 reader->get_num_vertices() - 2,
1564 reader->get_first_vertex(),
1565 reader->get_num_vertices(), vertex_pointer,
1566 _data_reader->get_format()->get_array(0)->get_stride());
1572 CPTA_int ends = reader->get_ends();
1573 _primitive_batches_tristrip_pcollector.add_level(ends.size());
1575 if (reader->is_indexed()) {
1576 CPTA_int ends = reader->get_ends();
1577 int index_stride = reader->get_index_stride();
1578 _primitive_batches_tristrip_pcollector.add_level(ends.size());
1582 nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
1583 reader->get_maxs()->get_num_rows() == (int)ends.size(),
false);
1588 if (!apply_index_buffer(ibc, reader, force)) {
1592 unsigned int start = 0;
1593 for (
size_t i = 0; i < ends.size(); i++) {
1594 _vertices_tristrip_pcollector.add_level(ends[i] - start);
1595 unsigned int min = mins.get_data1i();
1596 unsigned int max = maxs.get_data1i();
1597 _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP,
1600 start, ends[i] - start - 2 );
1601 start = ends[i] + 2;
1606 int stride = _data_reader->get_format()->get_array(0)->get_stride();
1607 const unsigned char *index_pointer = reader->get_read_pointer(force);
1608 if (index_pointer == NULL) {
1611 D3DFORMAT index_type = get_index_type(reader->get_index_type());
1612 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1613 if (vertex_pointer == NULL) {
1617 unsigned int start = 0;
1618 for (
size_t i = 0; i < ends.size(); i++) {
1619 _vertices_tristrip_pcollector.add_level(ends[i] - start);
1620 unsigned int min = mins.get_data1i();
1621 unsigned int max = maxs.get_data1i();
1622 draw_indexed_primitive_up
1623 (D3DPT_TRIANGLESTRIP,
1625 ends[i] - start - 2,
1626 index_pointer + start * index_stride, index_type,
1627 vertex_pointer, stride);
1629 start = ends[i] + 2;
1633 unsigned int first_vertex = reader->get_first_vertex();
1636 unsigned int start = 0;
1637 for (
size_t i = 0; i < ends.size(); i++) {
1638 _vertices_tristrip_pcollector.add_level(ends[i] - start);
1639 _d3d_device->DrawPrimitive( D3DPT_TRIANGLESTRIP,
1640 first_vertex + start,
1641 ends[i] - start - 2 );
1642 start = ends[i] + 2;
1647 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1648 if (vertex_pointer == NULL) {
1651 int stride = _data_reader->get_format()->get_array(0)->get_stride();
1653 unsigned int start = 0;
1654 for (
size_t i = 0; i < ends.size(); i++) {
1655 _vertices_tristrip_pcollector.add_level(ends[i] - start);
1656 draw_primitive_up(D3DPT_TRIANGLESTRIP, ends[i] - start - 2,
1657 first_vertex + start,
1659 vertex_pointer, stride);
1661 start = ends[i] + 2;
1678 CPTA_int ends = reader->get_ends();
1679 _primitive_batches_trifan_pcollector.add_level(ends.size());
1681 if (reader->is_indexed()) {
1682 int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
1683 int max_vertex = reader->get_max_vertex();
1687 int index_stride = reader->get_index_stride();
1691 nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
1692 reader->get_maxs()->get_num_rows() == (int)ends.size(),
false);
1697 if (!apply_index_buffer(ibc, reader, force)) {
1701 unsigned int start = 0;
1702 for (
size_t i = 0; i < ends.size(); i++) {
1703 _vertices_trifan_pcollector.add_level(ends[i] - start);
1704 unsigned int min = mins.get_data1i();
1705 unsigned int max = maxs.get_data1i();
1706 _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLEFAN,
1709 start, ends[i] - start - 2 );
1715 int stride = _data_reader->get_format()->get_array(0)->get_stride();
1716 const unsigned char *index_pointer = reader->get_read_pointer(force);
1717 if (index_pointer == NULL) {
1720 D3DFORMAT index_type = get_index_type(reader->get_index_type());
1721 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1722 if (vertex_pointer == NULL) {
1726 unsigned int start = 0;
1727 for (
size_t i = 0; i < ends.size(); i++) {
1728 _vertices_trifan_pcollector.add_level(ends[i] - start);
1729 unsigned int min = mins.get_data1i();
1730 unsigned int max = maxs.get_data1i();
1731 draw_indexed_primitive_up
1734 ends[i] - start - 2,
1735 index_pointer + start * index_stride, index_type,
1736 vertex_pointer, stride);
1742 unsigned int first_vertex = reader->get_first_vertex();
1745 unsigned int start = 0;
1746 for (
size_t i = 0; i < ends.size(); i++) {
1747 _vertices_trifan_pcollector.add_level(ends[i] - start);
1748 _d3d_device->DrawPrimitive( D3DPT_TRIANGLEFAN,
1749 first_vertex + start,
1750 ends[i] - start - 2 );
1756 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1757 if (vertex_pointer == NULL) {
1760 int stride = _data_reader->get_format()->get_array(0)->get_stride();
1762 unsigned int start = 0;
1763 for (
size_t i = 0; i < ends.size(); i++) {
1764 _vertices_trifan_pcollector.add_level(ends[i] - start);
1765 draw_primitive_up(D3DPT_TRIANGLEFAN,
1766 ends[i] - start - 2,
1769 vertex_pointer, stride);
1786 _vertices_other_pcollector.add_level(reader->get_num_vertices());
1787 _primitive_batches_other_pcollector.add_level(1);
1789 if (reader->is_indexed()) {
1790 int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
1791 int max_vertex = reader->get_max_vertex();
1796 if (!apply_index_buffer(ibc, reader, force)) {
1800 _d3d_device->DrawIndexedPrimitive( D3DPT_LINELIST,
1802 min_vertex, max_vertex - min_vertex + 1,
1803 0, reader->get_num_primitives() );
1807 const unsigned char *index_pointer = reader->get_read_pointer(force);
1808 if (index_pointer == NULL) {
1811 D3DFORMAT index_type = get_index_type(reader->get_index_type());
1812 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1813 if (vertex_pointer == NULL) {
1817 draw_indexed_primitive_up
1819 min_vertex, max_vertex,
1820 reader->get_num_primitives(),
1821 index_pointer, index_type, vertex_pointer,
1822 _data_reader->get_format()->get_array(0)->get_stride());
1826 _d3d_device->DrawPrimitive( D3DPT_LINELIST,
1827 reader->get_first_vertex(),
1828 reader->get_num_primitives() );
1832 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1833 if (vertex_pointer == NULL) {
1836 draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(),
1837 reader->get_first_vertex(),
1838 reader->get_num_vertices(), vertex_pointer,
1839 _data_reader->get_format()->get_array(0)->get_stride());
1864 _vertices_other_pcollector.add_level(reader->get_num_vertices());
1865 _primitive_batches_other_pcollector.add_level(1);
1869 nassertr(!reader->is_indexed(),
false);
1872 _d3d_device->DrawPrimitive( D3DPT_POINTLIST,
1873 reader->get_first_vertex(),
1874 reader->get_num_primitives() );
1878 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1879 if (vertex_pointer == NULL) {
1882 draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(),
1883 reader->get_first_vertex(),
1884 reader->get_num_vertices(), vertex_pointer,
1885 _data_reader->get_format()->get_array(0)->get_stride());
1902 if (_vertex_blending_enabled) {
1903 set_render_state(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
1904 set_render_state(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
1905 _vertex_blending_enabled =
false;
1908 if (_data_reader->is_vertex_transformed()) {
1910 LMatrix4f mat = LCAST(
float, _projection_mat->get_mat());
1911 _d3d_device->SetTransform(D3DTS_PROJECTION,
1930 set_read_buffer(rb);
1951 <<
"Unable to re-create texture " << *dtc->
get_texture() << endl;
1958 return do_framebuffer_copy_to_ram(tex, view, z, dr, rb,
true);
1962 IDirect3DSurface9 *tex_level_0;
1965 dxgsg9_cat.error() <<
"GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
1970 D3DSURFACE_DESC texdesc;
1971 hr = tex_level_0->GetDesc(&texdesc);
1973 dxgsg9_cat.error() <<
"GetDesc failed in copy_texture" << D3DERRORSTRING(hr);
1974 SAFE_RELEASE(tex_level_0);
1980 SAFE_RELEASE(tex_level_0);
1984 <<
"Unable to re-create texture " << *dtc->
get_texture() << endl;
1989 dxgsg9_cat.error() <<
"GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
1992 hr = tex_level_0->GetDesc(&texdesc);
1994 dxgsg9_cat.error() <<
"GetDesc 2 failed in copy_texture" << D3DERRORSTRING(hr);
1995 SAFE_RELEASE(tex_level_0);
2003 <<
"Unable to copy to texture, texture is wrong size: " << *dtc->
get_texture() << endl;
2004 SAFE_RELEASE(tex_level_0);
2009 DWORD render_target_index;
2010 IDirect3DSurface9 *render_target;
2013 render_target_index = 0;
2015 hr = _d3d_device->GetRenderTarget(render_target_index, &render_target);
2018 <<
"GetRenderTarget failed in framebuffer_copy_to_texture" 2019 << D3DERRORSTRING(hr);
2020 SAFE_RELEASE(tex_level_0);
2027 src_rect.right = xo+w;
2029 src_rect.bottom = yo+h;
2035 D3DTEXTUREFILTERTYPE filter;
2037 filter = D3DTEXF_POINT;
2040 hr = _d3d_device->StretchRect(render_target, &src_rect,
2041 tex_level_0, &src_rect,
2045 <<
"StretchRect failed in framebuffer_copy_to_texture" 2046 << D3DERRORSTRING(hr);
2050 SAFE_RELEASE(render_target);
2051 SAFE_RELEASE(tex_level_0);
2055 dtc->
enqueue_lru(&_prepared_objects->_graphics_memory_lru);
2060 return do_framebuffer_copy_to_ram(tex, view, z, dr, rb,
true);
2080 return do_framebuffer_copy_to_ram(tex, view, z, dr, rb,
false);
2096 set_read_buffer(rb);
2099 nassertr(tex != NULL && dr != NULL,
false);
2108 case Texture::F_depth_stencil:
2113 format = Texture::F_rgb;
2114 component_type = Texture::T_unsigned_byte;
2117 Texture::TextureType texture_type;
2119 texture_type = Texture::TT_cube_map;
2121 texture_type = Texture::TT_2d_texture;
2130 component_type, format);
2135 rect.right = xo + w;
2136 rect.bottom = yo + h;
2137 bool copy_inverted =
false;
2139 IDirect3DSurface9 *temp_surface = NULL;
2145 if (_cur_read_pixel_buffer & RenderBuffer::T_back) {
2146 DWORD render_target_index;
2147 IDirect3DSurface9 *backbuffer = NULL;
2152 render_target_index = 0;
2153 hr = _d3d_device->GetRenderTarget(render_target_index, &backbuffer);
2156 dxgsg9_cat.error() <<
"GetRenderTarget failed" << D3DERRORSTRING(hr);
2164 D3DSURFACE_DESC surface_description;
2166 backbuffer -> GetDesc (&surface_description);
2168 pool = D3DPOOL_SYSTEMMEM;
2169 hr = _d3d_device->CreateOffscreenPlainSurface(
2170 surface_description.Width,
2171 surface_description.Height,
2172 surface_description.Format,
2178 <<
"CreateImageSurface failed in copy_pixel_buffer()" 2179 << D3DERRORSTRING(hr);
2180 backbuffer->Release();
2185 hr = _d3d_device -> GetRenderTargetData (backbuffer, temp_surface);
2187 dxgsg9_cat.error() <<
"GetRenderTargetData failed" << D3DERRORSTRING(hr);
2188 temp_surface->Release();
2189 backbuffer->Release();
2193 copy_inverted =
true;
2195 RELEASE(backbuffer, dxgsg9,
"backbuffer", RELEASE_ONCE);
2197 }
else if (_cur_read_pixel_buffer & RenderBuffer::T_front) {
2199 if (_screen->_presentation_params.Windowed) {
2206 minfo.cbSize =
sizeof(MONITORINFO);
2207 GetMonitorInfo(_screen->_monitor, &minfo);
2209 w = RECT_XSIZE(minfo.rcMonitor);
2210 h = RECT_YSIZE(minfo.rcMonitor);
2213 ClientToScreen(_screen->_window, (POINT*)&rect.left);
2214 ClientToScreen(_screen->_window, (POINT*)&rect.right);
2220 hr = _d3d_device->CreateOffscreenPlainSurface(w, h, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &temp_surface, NULL);
2223 <<
"CreateImageSurface failed in copy_pixel_buffer()" 2224 << D3DERRORSTRING(hr);
2231 hr = _d3d_device->GetFrontBufferData(swap_chain,temp_surface);
2233 if (hr == D3DERR_DEVICELOST) {
2235 <<
"copy_pixel_buffer failed: device lost\n";
2236 temp_surface->Release();
2240 copy_inverted =
true;
2244 <<
"copy_pixel_buffer: unhandled current_read_pixel_buffer type\n";
2245 temp_surface->Release();
2250 copy_inverted = !copy_inverted;
2253 copy_inverted, tex, view, z);
2255 RELEASE(temp_surface, dxgsg9,
"temp_surface", RELEASE_ONCE);
2261 void DXGraphicsStateGuardian9::reset_render_states (
void)
2264 int maximum_texture_stages;
2266 maximum_texture_stages = D3D_MAXTEXTURESTAGES;
2269 memset (_render_state_array, -1,
sizeof (_render_state_array));
2270 memset (_texture_stage_states_array, -1,
sizeof (_texture_stage_states_array));
2273 _render_state_array [D3DRS_FOGCOLOR] = 0;
2274 _render_state_array [D3DRS_AMBIENT] = 0;
2277 memset (_texture_render_states_array, 0,
sizeof (_texture_render_states_array));
2280 for (index = 0; index < MAXIMUM_TEXTURES; index++) {
2281 TextureRenderStates *texture_render_states;
2283 texture_render_states = &_texture_render_states_array [index];
2284 texture_render_states -> state_array [D3DSAMP_MAGFILTER] = D3DTEXF_POINT;
2285 texture_render_states -> state_array [D3DSAMP_MINFILTER] = D3DTEXF_POINT;
2286 texture_render_states -> state_array [D3DSAMP_MAXANISOTROPY] = 1;
2288 _num_active_texture_stages = 0;
2290 set_render_state(D3DRS_NORMALIZENORMALS,
false);
2310 _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot());
2311 _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot());
2312 _inv_state_mask.clear_bit(ClipPlaneAttrib::get_class_slot());
2313 _inv_state_mask.clear_bit(ColorAttrib::get_class_slot());
2314 _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot());
2315 _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot());
2316 _inv_state_mask.clear_bit(DepthOffsetAttrib::get_class_slot());
2317 _inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot());
2318 _inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
2319 _inv_state_mask.clear_bit(RenderModeAttrib::get_class_slot());
2320 _inv_state_mask.clear_bit(RescaleNormalAttrib::get_class_slot());
2321 _inv_state_mask.clear_bit(ShadeModelAttrib::get_class_slot());
2322 _inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
2323 _inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
2324 _inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot());
2325 _inv_state_mask.clear_bit(TextureAttrib::get_class_slot());
2326 _inv_state_mask.clear_bit(TexGenAttrib::get_class_slot());
2327 _inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
2328 _inv_state_mask.clear_bit(MaterialAttrib::get_class_slot());
2329 _inv_state_mask.clear_bit(LightAttrib::get_class_slot());
2330 _inv_state_mask.clear_bit(StencilAttrib::get_class_slot());
2331 _inv_state_mask.clear_bit(FogAttrib::get_class_slot());
2332 _inv_state_mask.clear_bit(ScissorAttrib::get_class_slot());
2337 _supported_geom_rendering =
2338 Geom::GR_point | Geom::GR_point_uniform_size |
2339 Geom::GR_point_perspective | Geom::GR_point_sprite |
2340 Geom::GR_indexed_other |
2341 Geom::GR_triangle_strip | Geom::GR_triangle_fan |
2342 Geom::GR_flat_first_vertex;
2344 _auto_rescale_normal =
false;
2355 nassertv(_screen->_d3d9 != NULL);
2357 if (_d3d_device == NULL) {
2362 _d3d_device->GetDeviceCaps(&d3d_caps);
2364 _vertex_shader_version_major = D3DSHADER_VERSION_MAJOR (d3d_caps.VertexShaderVersion);
2365 _vertex_shader_version_minor = D3DSHADER_VERSION_MINOR (d3d_caps.VertexShaderVersion);
2366 _pixel_shader_version_major = D3DSHADER_VERSION_MAJOR (d3d_caps.PixelShaderVersion);
2367 _pixel_shader_version_minor = D3DSHADER_VERSION_MINOR (d3d_caps.PixelShaderVersion);
2369 _vertex_shader_profile = (
char *) D3DXGetVertexShaderProfile (_d3d_device);
2370 _pixel_shader_profile = (
char *) D3DXGetPixelShaderProfile (_d3d_device);
2372 _vertex_shader_maximum_constants = d3d_caps.MaxVertexShaderConst;
2374 switch (_pixel_shader_version_major)
2377 _shader_model = SM_00;
2380 _shader_model = SM_11;
2384 _shader_model = SM_20;
2385 if (d3d_caps.PS20Caps.NumInstructionSlots >= 512) {
2386 _shader_model = SM_2X;
2390 _shader_model = SM_30;
2393 _shader_model = SM_40;
2397 _shader_model = SM_50;
2401 _auto_detect_shader_model = _shader_model;
2404 set_cg_device(_d3d_device);
2406 _cg_context = cgCreateContext();
2408 if (cgD3D9IsProfileSupported(CG_PROFILE_PS_2_0) &&
2409 cgD3D9IsProfileSupported(CG_PROFILE_VS_2_0)) {
2410 _supports_basic_shaders =
true;
2411 _shader_caps._active_vprofile = (int)cgD3D9GetLatestVertexProfile();
2412 _shader_caps._active_fprofile = (int)cgD3D9GetLatestPixelProfile();
2413 _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VS_3_0;
2414 _shader_caps._ultimate_fprofile = (int)CG_PROFILE_PS_3_0;
2423 if (dxgsg9_cat.is_debug()) {
2424 CGprofile vertex_profile;
2425 CGprofile pixel_profile;
2427 vertex_profile = cgD3D9GetLatestVertexProfile();
2428 pixel_profile = cgD3D9GetLatestPixelProfile();
2430 const char *vertex_profile_str =
2431 cgGetProfileString(vertex_profile);
2432 const char *pixel_profile_str =
2433 cgGetProfileString(pixel_profile);
2435 if (vertex_profile_str == NULL) {
2436 vertex_profile_str =
"(null)";
2438 if (pixel_profile_str == NULL) {
2439 pixel_profile_str =
"(null)";
2443 <<
"\nCg latest vertex profile = " << vertex_profile_str <<
" id = " << vertex_profile
2444 <<
"\nCg latest pixel profile = " << pixel_profile_str <<
" id = " << pixel_profile
2445 <<
"\nshader model = " << _shader_model
2450 _supports_stream_offset = (d3d_caps.DevCaps2 & D3DDEVCAPS2_STREAMOFFSET) != 0;
2451 _screen->_supports_dynamic_textures = ((d3d_caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) != 0);
2452 _screen->_supports_automatic_mipmap_generation = ((d3d_caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0);
2454 if (support_stencil) {
2455 int min_stencil = D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR;
2456 if ((d3d_caps.StencilCaps & min_stencil) == min_stencil) {
2457 if (dxgsg9_cat.is_debug()) {
2459 <<
"Checking for stencil; mode = " 2460 << D3DFormatStr(_screen->_presentation_params.AutoDepthStencilFormat)
2463 switch (_screen->_presentation_params.AutoDepthStencilFormat) {
2467 case D3DFMT_D24X4S4:
2468 _supports_stencil =
true;
2469 if (dxgsg9_cat.is_debug()) {
2471 <<
"Stencils supported.\n";
2476 if (dxgsg9_cat.is_debug()) {
2478 <<
"Stencils NOT supported.\n";
2484 _supports_stencil_wrap = (d3d_caps.StencilCaps & D3DSTENCILCAPS_INCR) && (d3d_caps.StencilCaps & D3DSTENCILCAPS_DECR);
2485 _supports_two_sided_stencil = ((d3d_caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) != 0);
2487 _max_color_targets = d3d_caps.NumSimultaneousRTs;
2489 _supports_depth_bias = ((d3d_caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) == (D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS));
2491 _supports_gamma_calibration = ((d3d_caps.Caps2 & D3DCAPS2_CANCALIBRATEGAMMA) != 0);
2494 hr = _d3d_device->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL);
2495 _supports_occlusion_query = !FAILED(hr);
2497 if (dxgsg9_cat.is_error()) {
2499 <<
"\nHwTransformAndLight = " << ((d3d_caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
2500 <<
"\nMaxTextureWidth = " << d3d_caps.MaxTextureWidth
2501 <<
"\nMaxTextureHeight = " << d3d_caps.MaxTextureHeight
2502 <<
"\nMaxVolumeExtent = " << d3d_caps.MaxVolumeExtent
2503 <<
"\nMaxTextureAspectRatio = " << d3d_caps.MaxTextureAspectRatio
2504 <<
"\nTexCoordCount = " << (d3d_caps.FVFCaps & D3DFVFCAPS_TEXCOORDCOUNTMASK)
2505 <<
"\nMaxTextureBlendStages = " << d3d_caps.MaxTextureBlendStages
2506 <<
"\nMaxSimultaneousTextures = " << d3d_caps.MaxSimultaneousTextures
2507 <<
"\nMaxActiveLights = " << d3d_caps.MaxActiveLights
2508 <<
"\nMaxUserClipPlanes = " << d3d_caps.MaxUserClipPlanes
2509 <<
"\nMaxVertexBlendMatrices = " << d3d_caps.MaxVertexBlendMatrices
2510 <<
"\nMaxVertexBlendMatrixIndex = " << d3d_caps.MaxVertexBlendMatrixIndex
2511 <<
"\nMaxPointSize = " << d3d_caps.MaxPointSize
2512 <<
"\nMaxPrimitiveCount = " << d3d_caps.MaxPrimitiveCount
2513 <<
"\nMaxVertexIndex = " << d3d_caps.MaxVertexIndex
2514 <<
"\nMaxStreams = " << d3d_caps.MaxStreams
2515 <<
"\nMaxStreamStride = " << d3d_caps.MaxStreamStride
2516 <<
"\nD3DTEXOPCAPS_MULTIPLYADD = " << ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_MULTIPLYADD) != 0)
2517 <<
"\nD3DTEXOPCAPS_LERP = " << ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_LERP) != 0)
2518 <<
"\nD3DPMISCCAPS_TSSARGTEMP = " << ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) != 0)
2519 <<
"\nD3DPRASTERCAPS_DEPTHBIAS = " << ((d3d_caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS) != 0)
2520 <<
"\nD3DPRASTERCAPS_SLOPESCALEDEPTHBIAS = " << ((d3d_caps.RasterCaps & D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS) != 0)
2521 <<
"\nVertexShaderVersion = " << _vertex_shader_version_major <<
"." << _vertex_shader_version_minor
2522 <<
"\nPixelShaderVersion = " << _pixel_shader_version_major <<
"." << _pixel_shader_version_minor
2523 <<
"\nMaxVertexShaderConst = " << _vertex_shader_maximum_constants
2524 <<
"\nsupports_stream_offset = " << _supports_stream_offset
2525 <<
"\nsupports_dynamic_textures = " << _screen->_supports_dynamic_textures
2526 <<
"\nsupports_automatic_mipmap_generation = " << _screen->_supports_automatic_mipmap_generation
2527 <<
"\nsupports_stencil_wrap = " << _supports_stencil_wrap
2528 <<
"\nsupports_two_sided_stencil = " << _supports_two_sided_stencil
2529 <<
"\nsupports_occlusion_query = " << _supports_occlusion_query
2530 <<
"\nsupports_gamma_calibration = " << _supports_gamma_calibration
2531 <<
"\nMaxAnisotropy = " << d3d_caps.MaxAnisotropy
2532 <<
"\nNumSimultaneousRTs = " << d3d_caps.NumSimultaneousRTs
2533 <<
"\nD3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING = " << ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) != 0)
2534 <<
"\nDirectX SDK version " DIRECTX_SDK_VERSION
2539 _screen->_supports_automatic_mipmap_generation =
false;
2541 this -> reset_render_states ( );
2543 _max_vertices_per_array = d3d_caps.MaxVertexIndex;
2544 _max_vertices_per_primitive = d3d_caps.MaxPrimitiveCount;
2546 _max_texture_stages = d3d_caps.MaxSimultaneousTextures;
2548 _max_texture_dimension = min(d3d_caps.MaxTextureWidth, d3d_caps.MaxTextureHeight);
2550 _supports_tex_non_pow2 = !(d3d_caps.TextureCaps & D3DPTEXTURECAPS_POW2);
2552 _supports_texture_combine = ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_LERP) != 0);
2553 _supports_texture_saved_result = ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) != 0);
2554 _supports_texture_constant_color = ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT) != 0);
2555 _supports_texture_dot3 =
true;
2557 if (_supports_texture_constant_color) {
2558 _constant_color_operand = D3DTA_CONSTANT;
2560 _constant_color_operand = D3DTA_TFACTOR;
2563 _screen->_managed_textures = _gsg_managed_textures;
2564 _screen->_managed_vertex_buffers = _gsg_managed_vertex_buffers;
2565 _screen->_managed_index_buffers = _gsg_managed_index_buffers;
2567 UINT available_texture_memory;
2569 available_texture_memory = _d3d_device->GetAvailableTextureMem ( );
2570 if (dxgsg9_cat.is_debug()) {
2571 dxgsg9_cat.debug() <<
"*** GetAvailableTextureMem = " << available_texture_memory <<
"\n";
2573 _available_texture_memory = available_texture_memory;
2576 D3DDEVICE_CREATION_PARAMETERS creation_parameters;
2578 _supports_render_texture =
false;
2579 _screen->_render_to_texture_d3d_format = D3DFMT_UNKNOWN;
2580 _screen->_framebuffer_d3d_format = D3DFMT_UNKNOWN;
2582 #define TOTAL_RENDER_TO_TEXTURE_FORMATS 3 2584 D3DFORMAT render_to_texture_formats [TOTAL_RENDER_TO_TEXTURE_FORMATS] =
2591 render_to_texture_formats [TOTAL_RENDER_TO_TEXTURE_FORMATS - 1] = _screen->_display_mode.Format;
2593 hr = _d3d_device->GetCreationParameters (&creation_parameters);
2594 if (SUCCEEDED (hr)) {
2595 _screen->_framebuffer_d3d_format = _screen->_display_mode.Format;
2598 for (index = 0; index < TOTAL_RENDER_TO_TEXTURE_FORMATS; index++) {
2599 hr = _screen->_d3d9->CheckDeviceFormat (
2600 creation_parameters.AdapterOrdinal,
2601 creation_parameters.DeviceType,
2602 _screen->_display_mode.Format,
2603 D3DUSAGE_RENDERTARGET,
2605 render_to_texture_formats [index]);
2606 if (SUCCEEDED (hr)) {
2607 _screen->_render_to_texture_d3d_format = render_to_texture_formats [index];
2608 _supports_render_texture =
true;
2610 if (_supports_render_texture) {
2615 if (dxgsg9_cat.is_debug()) {
2616 dxgsg9_cat.debug() <<
"Render to Texture Support = " << _supports_render_texture <<
"\n";
2622 _supports_3d_texture = ((d3d_caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) != 0);
2623 if (_supports_3d_texture) {
2624 _max_3d_texture_dimension = d3d_caps.MaxVolumeExtent;
2626 _supports_cube_map = ((d3d_caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) != 0);
2627 if (_supports_cube_map) {
2628 _max_cube_map_dimension = _max_texture_dimension;
2631 _max_lights = (int)d3d_caps.MaxActiveLights;
2632 _max_clip_planes = (
int)d3d_caps.MaxUserClipPlanes;
2633 _max_vertex_transforms = d3d_caps.MaxVertexBlendMatrices;
2634 _max_vertex_transform_indices = d3d_caps.MaxVertexBlendMatrixIndex;
2636 set_render_state(D3DRS_AMBIENT, 0x0);
2638 _clip_plane_bits = 0;
2639 set_render_state(D3DRS_CLIPPLANEENABLE , 0x0);
2641 set_render_state(D3DRS_CLIPPING,
true);
2643 set_render_state(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
2645 set_render_state(D3DRS_ZWRITEENABLE, TRUE);
2650 set_render_state(D3DRS_ZENABLE, D3DZB_FALSE);
2652 set_render_state(D3DRS_ALPHABLENDENABLE, FALSE);
2654 set_render_state(D3DRS_FOGENABLE, FALSE);
2656 _has_scene_graph_color =
false;
2658 _last_testcooplevel_result = D3D_OK;
2660 if (dxgsg9_cat.is_debug()) {
2661 dxgsg9_cat.debug() <<
"Supported texture formats:\n";
2664 for(
int i = 0; i < MAX_POSSIBLE_TEXFMTS; i++) {
2666 D3DFORMAT_FLAG fmtflag = D3DFORMAT_FLAG(1 << i);
2667 hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format,
2668 0x0, D3DRTYPE_TEXTURE, g_D3DFORMATmap[fmtflag]);
2669 if (SUCCEEDED(hr)) {
2670 if (dxgsg9_cat.is_debug()) {
2671 dxgsg9_cat.debug() <<
" " << D3DFormatStr(g_D3DFORMATmap[fmtflag]) <<
"\n";
2673 _screen->_supported_tex_formats_mask |= fmtflag;
2678 #define CHECK_FOR_DXTVERSION(num) \ 2679 if (_screen->_supported_tex_formats_mask & DXT##num##_FLAG) {\ 2680 if (dxgsg9_cat.is_debug()) {\ 2681 dxgsg9_cat.debug() << "Compressed texture format DXT" << #num << " supported\n";\ 2683 _supports_compressed_texture = true;\ 2684 _compressed_texture_formats.set_bit(Texture::CM_dxt##num);\ 2687 if (_screen->_intel_compressed_texture_bug) {
2689 <<
"Buggy Intel driver detected; disabling compressed textures.\n";
2690 _screen->_supported_tex_formats_mask &=
2691 ~(DXT1_FLAG | DXT2_FLAG | DXT3_FLAG | DXT4_FLAG | DXT5_FLAG);
2695 CHECK_FOR_DXTVERSION(1);
2696 CHECK_FOR_DXTVERSION(2);
2697 CHECK_FOR_DXTVERSION(3);
2698 CHECK_FOR_DXTVERSION(4);
2699 CHECK_FOR_DXTVERSION(5);
2702 #undef CHECK_FOR_DXTVERSION 2704 _screen->_supports_rgba16f_texture_format =
false;
2705 hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format, 0x0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F);
2707 _screen->_supports_rgba16f_texture_format =
true;
2709 _screen->_supports_rgba32_texture_format =
false;
2710 hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format, 0x0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F);
2712 _screen->_supports_rgba32_texture_format =
true;
2716 if (_screen->_d3dcaps.MaxTextureWidth == 0)
2717 _screen->_d3dcaps.MaxTextureWidth = 256;
2719 if (_screen->_d3dcaps.MaxTextureHeight == 0)
2720 _screen->_d3dcaps.MaxTextureHeight = 256;
2722 if (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) {
2727 _do_fog_type = PerPixelFog;
2731 nassertv((_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGVERTEX) != 0);
2736 if (dx_no_vertex_fog) {
2737 _do_fog_type = None;
2739 _do_fog_type = PerVertexFog;
2742 if (dx_use_rangebased_fog && (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGRANGE)) {
2743 set_render_state(D3DRS_RANGEFOGENABLE,
true);
2748 _screen->_can_direct_disable_color_writes = ((_screen->_d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0);
2751 set_render_state(D3DRS_LIGHTING,
false);
2754 bool dither_enabled = ((!dx_no_dithering) && IS_16BPP_DISPLAY_FORMAT(_screen->_presentation_params.BackBufferFormat)
2755 && (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_DITHER));
2756 set_render_state(D3DRS_DITHERENABLE, dither_enabled);
2758 set_render_state(D3DRS_CLIPPING,
true);
2761 set_render_state(D3DRS_STENCILENABLE, FALSE);
2762 if (_supports_two_sided_stencil) {
2763 set_render_state(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
2770 _current_fill_mode = RenderModeAttrib::M_filled;
2771 set_render_state(D3DRS_FILLMODE, D3DFILL_SOLID);
2776 set_texture_stage_state(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
2778 _cull_face_mode = CullFaceAttrib::M_cull_none;
2779 set_render_state(D3DRS_CULLMODE, D3DCULL_NONE);
2781 set_render_state(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
2782 set_render_state(D3DRS_ALPHAREF, 255);
2783 set_render_state(D3DRS_ALPHATESTENABLE, FALSE);
2787 set_render_state(D3DRS_BLENDOP, D3DBLENDOP_ADD);
2789 _current_shader = (
Shader *)NULL;
2791 _vertex_array_shader = (
Shader *)NULL;
2793 _texture_binding_shader = (
Shader *)NULL;
2794 _texture_binding_shader_context = (CLP(
ShaderContext) *)NULL;
2796 PRINT_REFCNT(dxgsg9, _d3d_device);
2808 void DXGraphicsStateGuardian9::
2809 apply_fog(
Fog *fog) {
2810 if (_do_fog_type == None)
2813 Fog::Mode panda_fogmode = fog->get_mode();
2814 D3DFOGMODE d3dfogmode = get_fog_mode_type(panda_fogmode);
2816 set_render_state((D3DRENDERSTATETYPE)_do_fog_type, d3dfogmode);
2819 set_render_state(D3DRS_FOGCOLOR,
2820 MY_D3DRGBA(fog_colr[0], fog_colr[1], fog_colr[2], 0.0f));
2825 switch (panda_fogmode) {
2828 PN_stdfloat onset, opaque;
2831 set_render_state(D3DRS_FOGSTART,
2832 *((LPDWORD) (&onset)));
2833 set_render_state(D3DRS_FOGEND,
2834 *((LPDWORD) (&opaque)));
2837 case Fog::M_exponential:
2838 case Fog::M_exponential_squared:
2842 set_render_state(D3DRS_FOGDENSITY,
2843 *((LPDWORD) (&fog_density)));
2858 void DXGraphicsStateGuardian9::
2859 do_issue_transform() {
2860 const TransformState *transform = _internal_transform;
2861 DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
2863 if (_current_shader_context) {
2865 _current_shader_context->issue_parameters(
this, Shader::SSD_transform);
2868 LMatrix4f mat = LCAST(
float, transform->get_mat());
2869 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)mat.
get_data();
2870 _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
2874 LMatrix4f mat = LCAST(
float, transform->get_mat());
2875 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)mat.
get_data();
2876 _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
2891 _transform_stale =
false;
2893 if (_auto_rescale_normal) {
2894 do_auto_rescale_normal();
2903 void DXGraphicsStateGuardian9::
2904 do_issue_alpha_test() {
2905 if (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) {
2906 set_render_state(D3DRS_ALPHATESTENABLE, FALSE);
2909 AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->
get_mode();
2910 if (mode == AlphaTestAttrib::M_none) {
2911 set_render_state(D3DRS_ALPHATESTENABLE, FALSE);
2914 set_render_state(D3DRS_ALPHAFUNC, (D3DCMPFUNC)mode);
2915 set_render_state(D3DRS_ALPHAREF, (UINT) (target_alpha_test->
get_reference_alpha()*255.0f));
2916 set_render_state(D3DRS_ALPHATESTENABLE, TRUE);
2926 void DXGraphicsStateGuardian9::
2931 if (_target_shader) {
2932 shader = (
Shader *)(_target_shader->get_shader());
2938 if (context == 0 || (context && context -> valid (
this) ==
false)) {
2939 if (_current_shader_context != 0) {
2940 _current_shader_context->unbind(
this);
2941 _current_shader = 0;
2942 _current_shader_context = 0;
2943 disable_standard_texture_bindings();
2948 if (context != _current_shader_context) {
2951 if (_current_shader_context != 0) {
2952 _current_shader_context->unbind(
this);
2953 _current_shader_context = 0;
2954 _current_shader = 0;
2955 disable_standard_texture_bindings();
2958 context->bind(
this);
2959 _current_shader = shader;
2960 _current_shader_context = context;
2964 context->issue_parameters(
this, Shader::SSD_shaderinputs);
2973 void DXGraphicsStateGuardian9::
2974 do_issue_render_mode() {
2976 RenderModeAttrib::Mode mode = target_render_mode->
get_mode();
2979 case RenderModeAttrib::M_unchanged:
2980 case RenderModeAttrib::M_filled:
2981 case RenderModeAttrib::M_filled_flat:
2982 set_render_state(D3DRS_FILLMODE, D3DFILL_SOLID);
2985 case RenderModeAttrib::M_wireframe:
2986 set_render_state(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
2989 case RenderModeAttrib::M_point:
2990 set_render_state(D3DRS_FILLMODE, D3DFILL_POINT);
2995 <<
"Unknown render mode " << (int)mode << endl;
2999 PN_stdfloat point_size = target_render_mode->
get_thickness();
3000 set_render_state(D3DRS_POINTSIZE, *((DWORD*)&point_size));
3003 set_render_state(D3DRS_POINTSCALEENABLE, TRUE);
3005 LVector3 height(0.0f, point_size, 1.0f);
3006 height = height * _projection_mat->get_mat();
3007 PN_stdfloat s = height[1] / point_size;
3009 PN_stdfloat zero = 0.0f;
3010 PN_stdfloat one_over_s2 = 1.0f / (s * s);
3011 set_render_state(D3DRS_POINTSCALE_A, *((DWORD*)&zero));
3012 set_render_state(D3DRS_POINTSCALE_B, *((DWORD*)&zero));
3013 set_render_state(D3DRS_POINTSCALE_C, *((DWORD*)&one_over_s2));
3016 set_render_state(D3DRS_POINTSCALEENABLE, FALSE);
3019 _current_fill_mode = mode;
3027 void DXGraphicsStateGuardian9::
3028 do_issue_rescale_normal() {
3030 RescaleNormalAttrib::Mode mode = target_rescale_normal->
get_mode();
3032 _auto_rescale_normal =
false;
3035 case RescaleNormalAttrib::M_none:
3036 set_render_state(D3DRS_NORMALIZENORMALS,
false);
3039 case RescaleNormalAttrib::M_rescale:
3040 case RescaleNormalAttrib::M_normalize:
3041 set_render_state(D3DRS_NORMALIZENORMALS,
true);
3044 case RescaleNormalAttrib::M_auto:
3045 _auto_rescale_normal =
true;
3046 do_auto_rescale_normal();
3051 <<
"Unknown rescale_normal mode " << (int)mode << endl;
3060 void DXGraphicsStateGuardian9::
3061 do_issue_depth_test() {
3063 DepthTestAttrib::PandaCompareFunc mode = target_depth_test->
get_mode();
3064 if (mode == DepthTestAttrib::M_none) {
3065 set_render_state(D3DRS_ZENABLE, D3DZB_FALSE);
3067 set_render_state(D3DRS_ZENABLE, D3DZB_TRUE);
3068 set_render_state(D3DRS_ZFUNC, (D3DCMPFUNC) mode);
3077 void DXGraphicsStateGuardian9::
3078 do_issue_depth_write() {
3080 DepthWriteAttrib::Mode mode = target_depth_write->
get_mode();
3081 if (mode == DepthWriteAttrib::M_on) {
3082 set_render_state(D3DRS_ZWRITEENABLE, TRUE);
3084 set_render_state(D3DRS_ZWRITEENABLE, FALSE);
3093 void DXGraphicsStateGuardian9::
3094 do_issue_cull_face() {
3098 switch (_cull_face_mode) {
3099 case CullFaceAttrib::M_cull_none:
3100 set_render_state(D3DRS_CULLMODE, D3DCULL_NONE);
3105 case CullFaceAttrib::M_cull_clockwise:
3106 set_render_state(D3DRS_CULLMODE, D3DCULL_CW);
3111 case CullFaceAttrib::M_cull_counter_clockwise:
3112 set_render_state(D3DRS_CULLMODE, D3DCULL_CCW);
3119 <<
"invalid cull face mode " << (int)_cull_face_mode << endl;
3129 void DXGraphicsStateGuardian9::
3131 const FogAttrib *target_fog = DCAST(
FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot()));
3132 if (!target_fog->
is_off()) {
3133 set_render_state(D3DRS_FOGENABLE, TRUE);
3135 nassertv(fog != (
Fog *)NULL);
3138 set_render_state(D3DRS_FOGENABLE, FALSE);
3147 void DXGraphicsStateGuardian9::
3148 do_issue_depth_offset() {
3150 int offset = target_depth_offset->
get_offset();
3152 if (_supports_depth_bias && !dx_broken_depth_bias) {
3153 set_render_state(D3DRS_DEPTHBIAS, offset);
3154 set_render_state(D3DRS_SLOPESCALEDEPTHBIAS, offset);
3160 static const PN_stdfloat bias_scale = dx_depth_bias_scale;
3161 D3DVIEWPORT9 vp = _current_viewport;
3162 vp.MinZ -= bias_scale * offset;
3163 vp.MaxZ -= bias_scale * offset;
3164 _d3d_device->SetViewport(&vp);
3173 void DXGraphicsStateGuardian9::
3174 do_issue_shade_model() {
3176 switch (target_shade_model->
get_mode()) {
3177 case ShadeModelAttrib::M_smooth:
3178 set_render_state(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
3181 case ShadeModelAttrib::M_flat:
3182 set_render_state(D3DRS_SHADEMODE, D3DSHADE_FLAT);
3206 const TransformState *transform) {
3208 if (gsg_cat.is_spam()) {
3209 gsg_cat.spam() <<
"Setting GSG state to " << (
void *)target <<
":\n";
3210 target->write(gsg_cat.spam(
false), 2);
3213 _state_pcollector.add_level(1);
3214 PStatTimer timer1(_draw_set_state_pcollector);
3216 if (transform != _internal_transform) {
3218 _state_pcollector.add_level(1);
3219 _internal_transform = transform;
3220 do_issue_transform();
3223 if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) {
3226 _target_rs = target;
3228 _target_shader = DCAST(
ShaderAttrib, _target_rs->get_attrib_def(ShaderAttrib::get_class_slot()));
3230 int alpha_test_slot = AlphaTestAttrib::get_class_slot();
3231 if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) ||
3232 !_state_mask.get_bit(alpha_test_slot)) {
3234 do_issue_alpha_test();
3235 _state_mask.set_bit(alpha_test_slot);
3238 int clip_plane_slot = ClipPlaneAttrib::get_class_slot();
3239 if (_target_rs->get_attrib(clip_plane_slot) != _state_rs->get_attrib(clip_plane_slot) ||
3240 !_state_mask.get_bit(clip_plane_slot)) {
3242 do_issue_clip_plane();
3243 _state_mask.set_bit(clip_plane_slot);
3246 int color_slot = ColorAttrib::get_class_slot();
3247 int color_scale_slot = ColorScaleAttrib::get_class_slot();
3248 if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) ||
3249 _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) ||
3250 !_state_mask.get_bit(color_slot) ||
3251 !_state_mask.get_bit(color_scale_slot)) {
3254 do_issue_color_scale();
3255 _state_mask.set_bit(color_slot);
3256 _state_mask.set_bit(color_scale_slot);
3257 if (_current_shader_context) {
3258 _current_shader_context->issue_parameters(
this, Shader::SSD_color);
3259 _current_shader_context->issue_parameters(
this, Shader::SSD_colorscale);
3263 int cull_face_slot = CullFaceAttrib::get_class_slot();
3264 if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) ||
3265 !_state_mask.get_bit(cull_face_slot)) {
3267 do_issue_cull_face();
3268 _state_mask.set_bit(cull_face_slot);
3271 int depth_offset_slot = DepthOffsetAttrib::get_class_slot();
3272 if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) ||
3273 !_state_mask.get_bit(depth_offset_slot)) {
3275 do_issue_depth_offset();
3276 _state_mask.set_bit(depth_offset_slot);
3279 int depth_test_slot = DepthTestAttrib::get_class_slot();
3280 if (_target_rs->get_attrib(depth_test_slot) != _state_rs->get_attrib(depth_test_slot) ||
3281 !_state_mask.get_bit(depth_test_slot)) {
3283 do_issue_depth_test();
3284 _state_mask.set_bit(depth_test_slot);
3287 int depth_write_slot = DepthWriteAttrib::get_class_slot();
3288 if (_target_rs->get_attrib(depth_write_slot) != _state_rs->get_attrib(depth_write_slot) ||
3289 !_state_mask.get_bit(depth_write_slot)) {
3291 do_issue_depth_write();
3292 _state_mask.set_bit(depth_write_slot);
3295 int render_mode_slot = RenderModeAttrib::get_class_slot();
3296 if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) ||
3297 !_state_mask.get_bit(render_mode_slot)) {
3299 do_issue_render_mode();
3300 _state_mask.set_bit(render_mode_slot);
3303 int rescale_normal_slot = RescaleNormalAttrib::get_class_slot();
3304 if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) ||
3305 !_state_mask.get_bit(rescale_normal_slot)) {
3307 do_issue_rescale_normal();
3308 _state_mask.set_bit(rescale_normal_slot);
3311 int shade_model_slot = ShadeModelAttrib::get_class_slot();
3312 if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) ||
3313 !_state_mask.get_bit(shade_model_slot)) {
3315 do_issue_shade_model();
3316 _state_mask.set_bit(shade_model_slot);
3319 int transparency_slot = TransparencyAttrib::get_class_slot();
3320 int color_write_slot = ColorWriteAttrib::get_class_slot();
3321 int color_blend_slot = ColorBlendAttrib::get_class_slot();
3322 if (_target_rs->get_attrib(transparency_slot) != _state_rs->get_attrib(transparency_slot) ||
3323 _target_rs->get_attrib(color_write_slot) != _state_rs->get_attrib(color_write_slot) ||
3324 _target_rs->get_attrib(color_blend_slot) != _state_rs->get_attrib(color_blend_slot) ||
3325 !_state_mask.get_bit(transparency_slot) ||
3326 !_state_mask.get_bit(color_write_slot) ||
3327 !_state_mask.get_bit(color_blend_slot) ||
3328 (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) !=
3329 _state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))) {
3331 do_issue_blending();
3332 _state_mask.set_bit(transparency_slot);
3333 _state_mask.set_bit(color_write_slot);
3334 _state_mask.set_bit(color_blend_slot);
3337 if (_target_shader != _state_shader) {
3340 _state_shader = _target_shader;
3341 _state_mask.clear_bit(TextureAttrib::get_class_slot());
3344 int texture_slot = TextureAttrib::get_class_slot();
3345 int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
3346 int tex_gen_slot = TexGenAttrib::get_class_slot();
3347 if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) ||
3348 _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
3349 _target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) ||
3350 !_state_mask.get_bit(texture_slot) ||
3351 !_state_mask.get_bit(tex_matrix_slot) ||
3352 !_state_mask.get_bit(tex_gen_slot)) {
3354 determine_target_texture();
3357 _state_texture = _target_texture;
3358 _state_mask.set_bit(texture_slot);
3359 _state_mask.set_bit(tex_matrix_slot);
3360 _state_mask.set_bit(tex_gen_slot);
3363 int material_slot = MaterialAttrib::get_class_slot();
3364 if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) ||
3365 !_state_mask.get_bit(material_slot)) {
3367 do_issue_material();
3368 _state_mask.set_bit(material_slot);
3369 if (_current_shader_context) {
3370 _current_shader_context->issue_parameters(
this, Shader::SSD_material);
3374 int light_slot = LightAttrib::get_class_slot();
3375 if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) ||
3376 !_state_mask.get_bit(light_slot)) {
3379 _state_mask.set_bit(light_slot);
3382 int stencil_slot = StencilAttrib::get_class_slot();
3383 if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) ||
3384 !_state_mask.get_bit(stencil_slot)) {
3387 _state_mask.set_bit(stencil_slot);
3390 int fog_slot = FogAttrib::get_class_slot();
3391 if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
3392 !_state_mask.get_bit(fog_slot)) {
3395 _state_mask.set_bit(fog_slot);
3396 if (_current_shader_context) {
3397 _current_shader_context->issue_parameters(
this, Shader::SSD_fog);
3401 int scissor_slot = ScissorAttrib::get_class_slot();
3402 if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) ||
3403 !_state_mask.get_bit(scissor_slot)) {
3406 _state_mask.set_bit(scissor_slot);
3409 _state_rs = _target_rs;
3425 CPT(TransformState) transform = light.
get_transform(_scene_setup->get_camera_path());
3426 const LMatrix4 &light_mat = transform->get_mat();
3430 D3DCOLORVALUE black;
3431 black.r = black.g = black.b = black.a = 0.0f;
3433 alight.Type = D3DLIGHT_POINT;
3434 alight.Diffuse = get_light_color(light_obj);
3435 alight.Ambient = black ;
3437 alight.Specular = *(D3DCOLORVALUE *)(color.
get_data());
3441 alight.Position = *(D3DVECTOR *)pos.
get_data();
3443 alight.Range = __D3DLIGHT_RANGE_MAX;
3444 alight.Falloff = 1.0f;
3447 alight.Attenuation0 = att[0];
3448 alight.Attenuation1 = att[1];
3449 alight.Attenuation2 = att[2];
3451 HRESULT hr = _d3d_device->SetLight(light_id, &alight);
3453 wdxdisplay9_cat.warning()
3454 <<
"Could not set light properties for " << light
3455 <<
" to id " << light_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3469 static PStatCollector _draw_set_state_light_bind_directional_pcollector(
"Draw:Set State:Light:Bind:Directional");
3472 pair<DirectionalLights::iterator, bool> lookup = _dlights.insert(DirectionalLights::value_type(light, D3DLIGHT9()));
3473 D3DLIGHT9 &fdata = (*lookup.first).second;
3474 if (lookup.second) {
3478 CPT(TransformState) transform = light.
get_transform(_scene_setup->get_camera_path());
3479 const LMatrix4 &light_mat = transform->get_mat();
3483 D3DCOLORVALUE black;
3484 black.r = black.g = black.b = black.a = 0.0f;
3486 ZeroMemory(&fdata,
sizeof(D3DLIGHT9));
3488 fdata.Type = D3DLIGHT_DIRECTIONAL;
3489 fdata.Ambient = black ;
3491 fdata.Specular = *(D3DCOLORVALUE *)(color.
get_data());
3493 fdata.Direction = *(D3DVECTOR *)dir.
get_data();
3495 fdata.Range = __D3DLIGHT_RANGE_MAX;
3496 fdata.Falloff = 1.0f;
3498 fdata.Attenuation0 = 1.0f;
3499 fdata.Attenuation1 = 0.0f;
3500 fdata.Attenuation2 = 0.0f;
3506 fdata.Diffuse = get_light_color(light_obj);
3508 HRESULT hr = _d3d_device->SetLight(light_id, &fdata);
3510 wdxdisplay9_cat.warning()
3511 <<
"Could not set light properties for " << light
3512 <<
" to id " << light_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3527 nassertv(lens != (
Lens *)NULL);
3532 CPT(TransformState) transform = light.
get_transform(_scene_setup->get_camera_path());
3533 const LMatrix4 &light_mat = transform->get_mat();
3538 D3DCOLORVALUE black;
3539 black.r = black.g = black.b = black.a = 0.0f;
3542 ZeroMemory(&alight,
sizeof(D3DLIGHT9));
3544 alight.Type = D3DLIGHT_SPOT;
3545 alight.Ambient = black ;
3546 alight.Diffuse = get_light_color(light_obj);
3548 alight.Specular = *(D3DCOLORVALUE *)(color.
get_data());
3550 alight.Position = *(D3DVECTOR *)pos.
get_data();
3552 alight.Direction = *(D3DVECTOR *)dir.get_data();
3554 alight.Range = __D3DLIGHT_RANGE_MAX;
3559 PN_stdfloat fov = lens->
get_hfov();
3560 alight.Falloff = light_obj->
get_exponent() * (fov * fov * fov) / 1620000.0f;
3562 alight.Theta = 0.0f;
3563 alight.Phi = deg_2_rad(fov);
3566 alight.Attenuation0 = att[0];
3567 alight.Attenuation1 = att[1];
3568 alight.Attenuation2 = att[2];
3570 HRESULT hr = _d3d_device->SetLight(light_id, &alight);
3572 wdxdisplay9_cat.warning()
3573 <<
"Could not set light properties for " << light
3574 <<
" to id " << light_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3586 switch (numeric_type) {
3588 case Geom::NT_uint8:
3589 case Geom::NT_uint16:
3590 return D3DFMT_INDEX16;
3592 case Geom::NT_uint32:
3593 return D3DFMT_INDEX32;
3597 <<
"Invalid index NumericType value (" << (int)numeric_type <<
")\n";
3598 return D3DFMT_INDEX16;
3606 void DXGraphicsStateGuardian9::
3607 do_issue_material() {
3611 if (target_material->
is_off()) {
3617 D3DMATERIAL9 cur_material;
3619 cur_material.Diffuse = *(D3DCOLORVALUE *)(color.
get_data());
3621 cur_material.Ambient = *(D3DCOLORVALUE *)(color.
get_data());
3623 cur_material.Specular = *(D3DCOLORVALUE *)(color.
get_data());
3625 cur_material.Emissive = *(D3DCOLORVALUE *)(color.
get_data());
3630 set_render_state(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
3633 if (_has_material_force_color) {
3634 color = LCAST(
float, _material_force_color);
3635 cur_material.Diffuse = *(D3DCOLORVALUE *)color.
get_data();
3636 set_render_state(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
3638 set_render_state(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
3643 set_render_state(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
3646 if (_has_material_force_color) {
3647 color = LCAST(
float, _material_force_color);
3648 cur_material.Ambient = *(D3DCOLORVALUE *)color.
get_data();
3649 set_render_state(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
3651 set_render_state(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1);
3656 set_render_state(D3DRS_SPECULARENABLE, TRUE);
3658 set_render_state(D3DRS_SPECULARENABLE, FALSE);
3662 set_render_state(D3DRS_LOCALVIEWER, TRUE);
3664 set_render_state(D3DRS_LOCALVIEWER, FALSE);
3667 _d3d_device->SetMaterial(&cur_material);
3675 void DXGraphicsStateGuardian9::
3676 do_issue_texture() {
3677 DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
3679 if (_texture_binding_shader_context==0) {
3680 if (_current_shader_context==0) {
3681 update_standard_texture_bindings();
3683 disable_standard_texture_bindings();
3684 _current_shader_context->update_shader_texture_bindings(NULL,
this);
3687 if (_current_shader_context==0) {
3688 _texture_binding_shader_context->disable_shader_texture_bindings(
this);
3689 update_standard_texture_bindings();
3691 _current_shader_context->
3692 update_shader_texture_bindings(_texture_binding_shader_context,
this);
3695 _texture_binding_shader = _current_shader;
3696 _texture_binding_shader_context = _current_shader_context;
3704 void DXGraphicsStateGuardian9::
3705 disable_standard_texture_bindings() {
3707 for (
int i = 0; i < _num_active_texture_stages; i++) {
3710 hr = _d3d_device -> SetTexture (i, NULL);
3715 <<
", NULL) failed " 3716 << D3DERRORSTRING(hr);
3718 set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
3721 _num_active_texture_stages = 0;
3729 void DXGraphicsStateGuardian9::
3730 update_standard_texture_bindings() {
3731 DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
3733 int num_stages = _target_texture->get_num_on_ff_stages();
3734 int num_old_stages = _max_texture_stages;
3736 num_old_stages = _state_texture->get_num_on_ff_stages();
3739 nassertv(num_stages <= _max_texture_stages &&
3740 _num_active_texture_stages <= _max_texture_stages);
3742 _texture_involves_color_scale =
false;
3749 for (si = 0; si < num_stages; si++) {
3750 TextureStage *stage = _target_texture->get_on_ff_stage(si);
3751 int texcoord_index = _target_texture->get_ff_tc_index(si);
3753 Texture *texture = _target_texture->get_on_texture(stage);
3754 nassertv(texture != (
Texture *)NULL);
3755 const SamplerState &sampler = _target_texture->get_on_sampler(stage);
3761 apply_texture(si, tc, sampler);
3762 set_texture_blend_mode(si, stage);
3764 int texcoord_dimensions = 2;
3766 CPT(TransformState) tex_mat = TransformState::make_identity();
3768 if (target_tex_matrix->has_stage(stage)) {
3769 tex_mat = target_tex_matrix->get_transform(stage);
3773 TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage);
3774 bool any_point_sprite =
false;
3777 case TexGenAttrib::M_off:
3778 case TexGenAttrib::M_unused2:
3779 set_texture_stage_state(si, D3DTSS_TEXCOORDINDEX, texcoord_index);
3782 case TexGenAttrib::M_eye_sphere_map:
3784 set_texture_stage_state(si, D3DTSS_TEXCOORDINDEX,
3785 texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
3789 static CPT(TransformState) sphere_map =
3790 TransformState::make_mat(
LMatrix4(0.33, 0.0f, 0.0f, 0.0f,
3791 0.0f, 0.33, 0.0f, 0.0f,
3792 0.0f, 0.0f, 1.0f, 0.0f,
3793 0.5f, 0.5f, 0.0f, 1.0f));
3794 tex_mat = tex_mat->compose(sphere_map);
3795 texcoord_dimensions = 3;
3799 case TexGenAttrib::M_world_cube_map:
3805 set_texture_stage_state(si, D3DTSS_TEXCOORDINDEX,
3806 texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
3807 texcoord_dimensions = 3;
3808 CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
3809 tex_mat = tex_mat->compose(camera_transform->set_pos(
LVecBase3::zero()));
3813 case TexGenAttrib::M_eye_cube_map:
3814 set_texture_stage_state(si, D3DTSS_TEXCOORDINDEX,
3815 texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
3816 tex_mat = tex_mat->compose(_inv_cs_transform);
3817 texcoord_dimensions = 3;
3820 case TexGenAttrib::M_world_normal:
3826 set_texture_stage_state(si, D3DTSS_TEXCOORDINDEX,
3827 texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
3828 texcoord_dimensions = 3;
3829 CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
3830 tex_mat = tex_mat->compose(camera_transform->set_pos(
LVecBase3::zero()));
3834 case TexGenAttrib::M_eye_normal:
3835 set_texture_stage_state(si, D3DTSS_TEXCOORDINDEX,
3836 texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
3837 texcoord_dimensions = 3;
3838 tex_mat = tex_mat->compose(_inv_cs_transform);
3841 case TexGenAttrib::M_world_position:
3846 set_texture_stage_state(si, D3DTSS_TEXCOORDINDEX,
3847 texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
3848 texcoord_dimensions = 3;
3849 CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
3850 tex_mat = tex_mat->compose(camera_transform);
3854 case TexGenAttrib::M_eye_position:
3855 set_texture_stage_state(si, D3DTSS_TEXCOORDINDEX,
3856 texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
3857 texcoord_dimensions = 3;
3858 tex_mat = tex_mat->compose(_inv_cs_transform);
3861 case TexGenAttrib::M_point_sprite:
3862 set_texture_stage_state(si, D3DTSS_TEXCOORDINDEX, texcoord_index);
3863 any_point_sprite =
true;
3866 case TexGenAttrib::M_constant:
3878 set_texture_stage_state(si, D3DTSS_TEXCOORDINDEX,
3879 texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
3880 texcoord_dimensions = 3;
3882 const LTexCoord3 &v = _target_tex_gen->get_constant_value(stage);
3883 CPT(TransformState) squash =
3886 tex_mat = tex_mat->compose(squash);
3891 set_render_state(D3DRS_POINTSPRITEENABLE, any_point_sprite);
3893 if (!tex_mat->is_identity()) {
3894 if ( texcoord_dimensions <= 2) {
3898 mf.set(m(0, 0), m(0, 1), m(0, 3), 0.0f,
3899 m(1, 0), m(1, 1), m(1, 3), 0.0f,
3900 m(3, 0), m(3, 1), m(3, 3), 0.0f,
3901 0.0f, 0.0f, 0.0f, 1.0f);
3902 _d3d_device->SetTransform(get_tex_mat_sym(si), (D3DMATRIX *)mf.
get_data());
3903 set_texture_stage_state(si, D3DTSS_TEXTURETRANSFORMFLAGS,
3906 LMatrix4f mf = LCAST(
float, tex_mat->get_mat());
3907 _d3d_device->SetTransform(get_tex_mat_sym(si), (D3DMATRIX *)mf.
get_data());
3908 DWORD transform_flags = texcoord_dimensions;
3912 transform_flags = D3DTTFF_COUNT4 | D3DTTFF_PROJECTED;
3914 set_texture_stage_state(si, D3DTSS_TEXTURETRANSFORMFLAGS,
3919 set_texture_stage_state(si, D3DTSS_TEXTURETRANSFORMFLAGS,
3924 _d3d_device->SetTransform(get_tex_mat_sym(si), &_d3d_ident_mat);
3929 for (si = num_stages; si < _num_active_texture_stages; si++) {
3930 set_texture_stage_state(si, D3DTSS_COLOROP, D3DTOP_DISABLE);
3931 _d3d_device->SetTexture(si, NULL);
3935 _num_active_texture_stages = num_stages;
3946 void DXGraphicsStateGuardian9::
3947 do_issue_blending() {
3953 unsigned int color_channels =
3954 target_color_write->
get_channels() & _color_write_mask;
3955 if (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write)) {
3956 color_channels &= ~(ColorWriteAttrib::C_alpha);
3958 if (color_channels == ColorWriteAttrib::C_off) {
3959 if (_screen->_can_direct_disable_color_writes) {
3960 set_render_state(D3DRS_ALPHABLENDENABLE, FALSE);
3961 set_render_state(D3DRS_COLORWRITEENABLE, (DWORD)0x0);
3963 set_render_state(D3DRS_ALPHABLENDENABLE, TRUE);
3964 set_render_state(D3DRS_SRCBLEND, D3DBLEND_ZERO);
3965 set_render_state(D3DRS_DESTBLEND, D3DBLEND_ONE);
3969 if (_screen->_can_direct_disable_color_writes) {
3970 set_render_state(D3DRS_COLORWRITEENABLE, color_channels);
3976 ColorBlendAttrib::Mode color_blend_mode = target_color_blend->
get_mode();
3979 TransparencyAttrib::Mode transparency_mode = target_transparency->
get_mode();
3982 if (color_blend_mode != ColorBlendAttrib::M_none) {
3983 set_render_state(D3DRS_ALPHABLENDENABLE, TRUE);
3985 switch (color_blend_mode) {
3986 case ColorBlendAttrib::M_add:
3987 set_render_state(D3DRS_BLENDOP, D3DBLENDOP_ADD);
3990 case ColorBlendAttrib::M_subtract:
3991 set_render_state(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
3994 case ColorBlendAttrib::M_inv_subtract:
3995 set_render_state(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT);
3998 case ColorBlendAttrib::M_min:
3999 set_render_state(D3DRS_BLENDOP, D3DBLENDOP_MIN);
4002 case ColorBlendAttrib::M_max:
4003 set_render_state(D3DRS_BLENDOP, D3DBLENDOP_MAX);
4007 set_render_state(D3DRS_SRCBLEND,
4008 get_blend_func(color_blend->get_operand_a()));
4009 set_render_state(D3DRS_DESTBLEND,
4010 get_blend_func(color_blend->get_operand_b()));
4015 switch (transparency_mode) {
4016 case TransparencyAttrib::M_none:
4017 case TransparencyAttrib::M_binary:
4020 case TransparencyAttrib::M_alpha:
4021 case TransparencyAttrib::M_multisample:
4022 case TransparencyAttrib::M_multisample_mask:
4023 case TransparencyAttrib::M_dual:
4024 set_render_state(D3DRS_ALPHABLENDENABLE, TRUE);
4025 set_render_state(D3DRS_BLENDOP, D3DBLENDOP_ADD);
4026 set_render_state(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
4027 set_render_state(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
4032 <<
"invalid transparency mode " << (int)transparency_mode << endl;
4037 set_render_state(D3DRS_ALPHABLENDENABLE, FALSE);
4048 void DXGraphicsStateGuardian9::
4049 reissue_transforms() {
4051 do_issue_transform();
4062 void DXGraphicsStateGuardian9::
4063 enable_lighting(
bool enable) {
4064 set_render_state(D3DRS_LIGHTING, (DWORD)enable);
4075 void DXGraphicsStateGuardian9::
4076 set_ambient_light(
const LColor &color) {
4078 c.set(c[0] * _light_color_scale[0],
4079 c[1] * _light_color_scale[1],
4080 c[2] * _light_color_scale[2],
4081 c[3] * _light_color_scale[3]);
4083 set_render_state(D3DRS_AMBIENT, LColor_to_D3DCOLOR(c));
4093 void DXGraphicsStateGuardian9::
4094 enable_light(
int light_id,
bool enable) {
4095 HRESULT hr = _d3d_device->LightEnable(light_id, enable);
4098 wdxdisplay9_cat.warning()
4099 <<
"Could not enable light " << light_id <<
": " 4100 << D3DERRORSTRING(hr) <<
"\n";
4112 void DXGraphicsStateGuardian9::
4113 enable_clip_plane(
int plane_id,
bool enable) {
4115 _clip_plane_bits |= ((DWORD)1 << plane_id);
4117 _clip_plane_bits &= ~((DWORD)1 << plane_id);
4119 set_render_state(D3DRS_CLIPPLANEENABLE, _clip_plane_bits);
4130 void DXGraphicsStateGuardian9::
4131 bind_clip_plane(
const NodePath &plane,
int plane_id) {
4135 CPT(TransformState) transform = plane.
get_transform(_scene_setup->get_camera_path());
4136 const LMatrix4 &plane_mat = transform->get_mat();
4139 DCAST_INTO_V(plane_node, plane.
node());
4140 LPlanef world_plane = LCAST(
float, plane_node->
get_plane() * rel_mat);
4142 HRESULT hr = _d3d_device->SetClipPlane(plane_id, world_plane.get_data());
4144 wdxdisplay9_cat.warning()
4145 <<
"Could not set clip plane for " << plane
4146 <<
" to id " << plane_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
4158 void DXGraphicsStateGuardian9::
4160 GraphicsStateGuardian::close_gsg();
4162 if (dxgsg9_cat.is_debug()) {
4164 <<
"Closing GSG, prepared_objects count = " 4165 << _prepared_objects->get_ref_count() <<
"\n";
4170 if (_prepared_objects->get_ref_count() == 1) {
4176 _prepared_objects->begin_frame(
this, current_thread);
4177 _prepared_objects->end_frame(current_thread);
4187 void DXGraphicsStateGuardian9::
4188 free_nondx_resources() {
4191 cgDestroyContext(_cg_context);
4203 void DXGraphicsStateGuardian9::
4206 _state_rs = RenderState::make_empty();
4207 _state_mask.clear();
4211 _dx_is_ready =
false;
4213 if (_d3d_device != NULL) {
4214 for(
int i = 0; i < D3D_MAXTEXTURESTAGES; i++) {
4216 _d3d_device->SetTexture(i, NULL);
4222 if (_d3d_device != NULL) {
4223 RELEASE(_d3d_device, dxgsg9,
"d3dDevice", RELEASE_DOWN_TO_ZERO);
4226 free_nondx_resources();
4239 void DXGraphicsStateGuardian9::
4241 dxgsg9_cat.fatal() <<
"DX set_draw_buffer unimplemented!!!";
4250 void DXGraphicsStateGuardian9::
4252 if (rb._buffer_type & RenderBuffer::T_front) {
4253 _cur_read_pixel_buffer = RenderBuffer::T_front;
4254 }
else if (rb._buffer_type & RenderBuffer::T_back) {
4255 _cur_read_pixel_buffer = RenderBuffer::T_back;
4256 }
else if (rb._buffer_type & RenderBuffer::T_aux_rgba_ALL) {
4257 _cur_read_pixel_buffer = RenderBuffer::T_back;
4259 dxgsg9_cat.error() <<
"Invalid or unimplemented Argument to set_read_buffer!\n";
4271 void DXGraphicsStateGuardian9::
4272 do_auto_rescale_normal() {
4273 if (_internal_transform->has_identity_scale()) {
4275 set_render_state(D3DRS_NORMALIZENORMALS,
false);
4278 set_render_state(D3DRS_NORMALIZENORMALS,
true);
4290 const D3DCOLORVALUE &DXGraphicsStateGuardian9::
4291 get_light_color(
Light *light)
const {
4294 cf.set(c[0] * _light_color_scale[0],
4295 c[1] * _light_color_scale[1],
4296 c[2] * _light_color_scale[2],
4297 c[3] * _light_color_scale[3]);
4298 return *(D3DCOLORVALUE *)cf.
get_data();
4307 D3DBLEND DXGraphicsStateGuardian9::
4308 get_blend_func(ColorBlendAttrib::Operand operand) {
4310 case ColorBlendAttrib::O_zero:
4311 return D3DBLEND_ZERO;
4313 case ColorBlendAttrib::O_one:
4314 return D3DBLEND_ONE;
4316 case ColorBlendAttrib::O_incoming_color:
4317 return D3DBLEND_SRCCOLOR;
4319 case ColorBlendAttrib::O_one_minus_incoming_color:
4320 return D3DBLEND_INVSRCCOLOR;
4322 case ColorBlendAttrib::O_fbuffer_color:
4323 return D3DBLEND_DESTCOLOR;
4325 case ColorBlendAttrib::O_one_minus_fbuffer_color:
4326 return D3DBLEND_INVDESTCOLOR;
4328 case ColorBlendAttrib::O_incoming_alpha:
4329 return D3DBLEND_SRCALPHA;
4331 case ColorBlendAttrib::O_one_minus_incoming_alpha:
4332 return D3DBLEND_INVSRCALPHA;
4334 case ColorBlendAttrib::O_fbuffer_alpha:
4335 return D3DBLEND_DESTALPHA;
4337 case ColorBlendAttrib::O_one_minus_fbuffer_alpha:
4338 return D3DBLEND_INVDESTALPHA;
4340 case ColorBlendAttrib::O_constant_color:
4342 return D3DBLEND_SRCCOLOR;
4344 case ColorBlendAttrib::O_one_minus_constant_color:
4346 return D3DBLEND_INVSRCCOLOR;
4348 case ColorBlendAttrib::O_constant_alpha:
4350 return D3DBLEND_SRCALPHA;
4352 case ColorBlendAttrib::O_one_minus_constant_alpha:
4354 return D3DBLEND_INVSRCALPHA;
4356 case ColorBlendAttrib::O_incoming_color_saturate:
4357 return D3DBLEND_SRCALPHASAT;
4361 <<
"Unknown color blend operand " << (int)operand << endl;
4362 return D3DBLEND_ZERO;
4370 void DXGraphicsStateGuardian9::
4371 report_texmgr_stats() {
4377 #ifdef TEXMGRSTATS_USES_GETAVAILVIDMEM 4378 DWORD dwTexTotal, dwTexFree, dwVidTotal, dwVidFree;
4380 if (_total_texmem_pcollector.is_active()) {
4383 ZeroMemory(&ddsCaps,
sizeof(ddsCaps));
4385 ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
4386 if (FAILED( hr = _d3d_device->GetAvailableVidMem(&ddsCaps, &dwVidTotal, &dwVidFree))) {
4387 dxgsg9_cat.fatal() <<
"report_texmgr GetAvailableVidMem for VIDMEM failed : result = " << D3DERRORSTRING(hr);
4388 throw_event(
"panda3d-render-error");
4392 ddsCaps.dwCaps = DDSCAPS_TEXTURE;
4393 if (FAILED( hr = _d3d_device->GetAvailableVidMem(&ddsCaps, &dwTexTotal, &dwTexFree))) {
4394 dxgsg9_cat.fatal() <<
"report_texmgr GetAvailableVidMem for TEXTURE failed : result = " << D3DERRORSTRING(hr);
4395 throw_event(
"panda3d-render-error");
4399 #endif // TEXMGRSTATS_USES_GETAVAILVIDMEM 4401 D3DDEVINFO_RESOURCEMANAGER all_resource_stats;
4402 ZeroMemory(&all_resource_stats,
sizeof(D3DDEVINFO_RESOURCEMANAGER));
4429 if (_texmgrmem_total_pcollector.is_active()) {
4431 _texmgrmem_total_pcollector.set_level(all_resource_stats.stats[D3DRTYPE_TEXTURE].TotalBytes);
4432 _texmgrmem_resident_pcollector.set_level(all_resource_stats.stats[D3DRTYPE_TEXTURE].WorkingSetBytes);
4434 #ifdef TEXMGRSTATS_USES_GETAVAILVIDMEM 4435 if (_total_texmem_pcollector.is_active()) {
4436 _total_texmem_pcollector.set_level(dwTexTotal);
4437 _used_texmem_pcollector.set_level(dwTexTotal - dwTexFree);
4439 #endif // TEXMGRSTATS_USES_GETAVAILVIDMEM 4448 void DXGraphicsStateGuardian9::
4450 nassertv(new_context != NULL);
4451 _screen = new_context;
4452 _d3d_device = _screen->_d3d_device;
4453 _swap_chain = _screen->_swap_chain;
4455 _screen->_dxgsg9 =
this;
4456 set_cg_device(_d3d_device);
4465 void DXGraphicsStateGuardian9::
4466 set_render_target() {
4467 if (_d3d_device == NULL) {
4471 LPDIRECT3DSURFACE9 back = NULL, stencil = NULL;
4479 _d3d_device->GetBackBuffer(swap_chain, 0, D3DBACKBUFFER_TYPE_MONO, &back);
4481 _swap_chain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &back);
4486 _d3d_device->GetDepthStencilSurface(&stencil);
4489 DWORD render_target_index;
4490 render_target_index = 0;
4491 _d3d_device->SetRenderTarget(render_target_index, back);
4506 void DXGraphicsStateGuardian9::
4507 set_texture_blend_mode(
int i,
const TextureStage *stage) {
4509 case TextureStage::M_modulate:
4510 case TextureStage::M_modulate_glow:
4511 case TextureStage::M_modulate_gloss:
4513 set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_MODULATE);
4514 set_texture_stage_state(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4515 set_texture_stage_state(i, D3DTSS_COLORARG2, D3DTA_CURRENT);
4516 set_texture_stage_state(i, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
4517 set_texture_stage_state(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
4518 set_texture_stage_state(i, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
4521 case TextureStage::M_decal:
4523 set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
4524 set_texture_stage_state(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4525 set_texture_stage_state(i, D3DTSS_COLORARG2, D3DTA_CURRENT);
4527 set_texture_stage_state(i, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
4528 set_texture_stage_state(i, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
4531 case TextureStage::M_replace:
4532 set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4533 set_texture_stage_state(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4535 set_texture_stage_state(i, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
4536 set_texture_stage_state(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
4539 case TextureStage::M_add:
4540 set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_ADD);
4541 set_texture_stage_state(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4542 set_texture_stage_state(i, D3DTSS_COLORARG2, D3DTA_CURRENT);
4544 set_texture_stage_state(i, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
4545 set_texture_stage_state(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
4546 set_texture_stage_state(i, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
4549 case TextureStage::M_blend:
4550 case TextureStage::M_blend_color_scale:
4552 set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_LERP);
4553 set_texture_stage_state(i, D3DTSS_COLORARG0, D3DTA_TEXTURE);
4554 set_texture_stage_state(i, D3DTSS_COLORARG2, D3DTA_CURRENT);
4555 set_texture_stage_state(i, D3DTSS_COLORARG1, _constant_color_operand);
4557 set_texture_stage_state(i, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
4558 set_texture_stage_state(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
4559 set_texture_stage_state(i, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
4563 case TextureStage::M_combine:
4566 set_texture_stage_state
4573 set_texture_stage_state
4574 (i, D3DTSS_COLORARG0,
4580 set_texture_stage_state
4581 (i, D3DTSS_COLORARG2,
4587 set_texture_stage_state
4588 (i, D3DTSS_COLORARG1,
4597 set_texture_stage_state
4604 set_texture_stage_state
4605 (i, D3DTSS_ALPHAARG0,
4611 set_texture_stage_state
4612 (i, D3DTSS_ALPHAARG2,
4618 set_texture_stage_state
4619 (i, D3DTSS_ALPHAARG1,
4631 <<
"Unknown texture mode " << (int)stage->
get_mode() << endl;
4636 set_texture_stage_state(i, D3DTSS_RESULTARG, D3DTA_TEMP);
4638 set_texture_stage_state(i, D3DTSS_RESULTARG, D3DTA_CURRENT);
4644 D3DCOLOR constant_color;
4647 color.set(color[0] * _current_color_scale[0],
4648 color[1] * _current_color_scale[1],
4649 color[2] * _current_color_scale[2],
4650 color[3] * _current_color_scale[3]);
4651 _texture_involves_color_scale =
true;
4652 constant_color = LColor_to_D3DCOLOR(color);
4654 constant_color = LColor_to_D3DCOLOR(stage->
get_color());
4656 if (_supports_texture_constant_color) {
4657 set_texture_stage_state(i, D3DTSS_CONSTANT, constant_color);
4662 set_render_state(D3DRS_TEXTUREFACTOR, constant_color);
4672 void DXGraphicsStateGuardian9::
4678 free_nondx_resources();
4679 PRINT_REFCNT(dxgsg9, _d3d_device);
4683 RELEASE(_d3d_device, dxgsg9,
"d3dDevice", RELEASE_DOWN_TO_ZERO);
4684 _screen->_d3d_device = NULL;
4700 HRESULT DXGraphicsStateGuardian9::
4701 reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
4705 nassertr(IS_VALID_PTR(presentation_params), E_FAIL);
4706 nassertr(IS_VALID_PTR(_screen->_d3d9), E_FAIL);
4707 nassertr(IS_VALID_PTR(_d3d_device), E_FAIL);
4711 _screen->_d3d9->GetAdapterDisplayMode(_screen->_card_id, &_screen->_display_mode);
4712 presentation_params->BackBufferFormat = _screen->_display_mode.Format;
4719 if (
true || !(_screen->_swap_chain)
4720 || (_presentation_reset.BackBufferWidth < presentation_params->BackBufferWidth)
4721 || (_presentation_reset.BackBufferHeight < presentation_params->BackBufferHeight)) {
4722 if (wdxdisplay9_cat.is_debug()) {
4723 wdxdisplay9_cat.debug()
4724 <<
"swap_chain = " << _screen->_swap_chain <<
" _presentation_reset = " 4725 << _presentation_reset.BackBufferWidth <<
"x" << _presentation_reset.BackBufferHeight
4726 <<
" presentation_params = " 4727 << presentation_params->BackBufferWidth <<
"x" << presentation_params->BackBufferHeight <<
"\n";
4730 get_engine()->reset_all_windows(
false);
4732 if (_screen->_swap_chain) {
4733 _presentation_reset.BackBufferWidth = max(_presentation_reset.BackBufferWidth, presentation_params->BackBufferWidth);
4734 _presentation_reset.BackBufferHeight = max(_presentation_reset.BackBufferHeight, presentation_params->BackBufferHeight);
4737 _presentation_reset.BackBufferWidth = presentation_params->BackBufferWidth;
4738 _presentation_reset.BackBufferHeight = presentation_params->BackBufferHeight;
4748 release_all_vertex_buffers();
4749 release_all_index_buffers();
4753 _prepared_objects->begin_frame(
this, current_thread);
4758 list <wdxGraphicsBuffer9 **>::iterator graphics_buffer_iterator;
4760 for (graphics_buffer_iterator = _graphics_buffer_list.begin( ); graphics_buffer_iterator != _graphics_buffer_list.end( ); graphics_buffer_iterator++)
4762 graphics_buffer = **graphics_buffer_iterator;
4763 if (graphics_buffer -> _color_backing_store)
4765 graphics_buffer -> _color_backing_store -> Release ( );
4766 graphics_buffer -> _color_backing_store = 0;
4768 if (graphics_buffer -> _depth_backing_store)
4770 graphics_buffer -> _depth_backing_store -> Release ( );
4771 graphics_buffer -> _depth_backing_store = 0;
4777 hr = _d3d_device->Reset(&_presentation_reset);
4778 if (FAILED(hr) && hr != D3DERR_DEVICELOST) {
4782 get_engine()->reset_all_windows(
true);
4787 if (presentation_params != &_screen->_presentation_params) {
4788 memcpy(&_screen->_presentation_params, presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
4795 if (_screen && _screen->_swap_chain) {
4796 _screen->_swap_chain->Release();
4797 wdxdisplay9_cat.debug()
4798 <<
"swap chain " << _screen->_swap_chain <<
" is released\n";
4799 _screen->_swap_chain = NULL;
4800 hr = _d3d_device->CreateAdditionalSwapChain(presentation_params, &_screen->_swap_chain);
4802 if (SUCCEEDED(hr)) {
4803 if (presentation_params != &_screen->_presentation_params) {
4804 memcpy(&_screen->_presentation_params, presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
4818 bool DXGraphicsStateGuardian9::
4819 check_cooperative_level() {
4820 bool bDoReactivateWindow =
false;
4821 if (_d3d_device == NULL) {
4825 HRESULT hr = _d3d_device->TestCooperativeLevel();
4827 if (SUCCEEDED(hr)) {
4828 nassertr(SUCCEEDED(_last_testcooplevel_result),
false);
4833 case D3DERR_DEVICENOTRESET:
4834 _dx_is_ready =
false;
4839 hr = reset_d3d_device(&_screen->_presentation_params);
4844 <<
"check_cooperative_level Reset() failed, hr = " << D3DERRORSTRING(hr);
4847 hr = _d3d_device->TestCooperativeLevel();
4851 <<
"TestCooperativeLevel following Reset() failed, hr = " << D3DERRORSTRING(hr);
4855 _dx_is_ready = TRUE;
4858 case D3DERR_DEVICELOST:
4862 if (SUCCEEDED(_last_testcooplevel_result)) {
4864 _dx_is_ready =
false;
4865 if (dxgsg9_cat.is_debug()) {
4866 dxgsg9_cat.debug() <<
"D3D Device was Lost, waiting...\n";
4872 _last_testcooplevel_result = hr;
4873 return SUCCEEDED(hr);
4881 void DXGraphicsStateGuardian9::
4883 if (_d3d_device == NULL) {
4893 hr = _swap_chain->Present((CONST RECT*)NULL, (CONST RECT*)NULL, (HWND)NULL, NULL, flags);
4895 hr = _d3d_device->Present((CONST RECT*)NULL, (CONST RECT*)NULL, (HWND)NULL, NULL);
4899 if (hr == D3DERR_DEVICELOST) {
4900 check_cooperative_level();
4903 <<
"show_frame() - Present() failed" << D3DERRORSTRING(hr);
4904 throw_event(
"panda3d-render-error");
4914 bool DXGraphicsStateGuardian9::
4922 hr = new_context->_d3d_device->CreateAdditionalSwapChain(&new_context->_presentation_params, &new_context->_swap_chain);
4924 wdxdisplay9_cat.debug() <<
"Swapchain creation failed :"<<D3DERRORSTRING(hr)<<
"\n";
4935 bool DXGraphicsStateGuardian9::
4938 if (new_context->_swap_chain) {
4939 hr = new_context->_swap_chain->Release();
4941 wdxdisplay9_cat.debug() <<
"Swapchain release failed:" << D3DERRORSTRING(hr) <<
"\n";
4953 void DXGraphicsStateGuardian9::
4955 memcpy(&_presentation_reset, &_screen->_presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
4963 D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian9::
4964 get_d3d_min_type(SamplerState::FilterType filter_type) {
4965 switch (filter_type) {
4966 case SamplerState::FT_nearest:
4967 return D3DTEXF_POINT;
4969 case SamplerState::FT_linear:
4970 return D3DTEXF_LINEAR;
4972 case SamplerState::FT_nearest_mipmap_nearest:
4973 return D3DTEXF_POINT;
4975 case SamplerState::FT_linear_mipmap_nearest:
4976 return D3DTEXF_LINEAR;
4978 case SamplerState::FT_nearest_mipmap_linear:
4979 return D3DTEXF_POINT;
4981 case SamplerState::FT_linear_mipmap_linear:
4982 return D3DTEXF_LINEAR;
4984 case SamplerState::FT_shadow:
4985 case SamplerState::FT_default:
4986 return D3DTEXF_LINEAR;
4990 <<
"Invalid FilterType value (" << (int)filter_type <<
")\n";
4991 return D3DTEXF_POINT;
4999 D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian9::
5000 get_d3d_mip_type(SamplerState::FilterType filter_type) {
5001 switch (filter_type) {
5002 case SamplerState::FT_nearest:
5003 return D3DTEXF_NONE;
5005 case SamplerState::FT_linear:
5006 return D3DTEXF_NONE;
5008 case SamplerState::FT_nearest_mipmap_nearest:
5009 return D3DTEXF_POINT;
5011 case SamplerState::FT_linear_mipmap_nearest:
5012 return D3DTEXF_POINT;
5014 case SamplerState::FT_nearest_mipmap_linear:
5015 return D3DTEXF_LINEAR;
5017 case SamplerState::FT_linear_mipmap_linear:
5018 return D3DTEXF_LINEAR;
5020 case SamplerState::FT_shadow:
5021 case SamplerState::FT_default:
5022 return D3DTEXF_NONE;
5026 <<
"Invalid FilterType value (" << (int)filter_type <<
")\n";
5027 return D3DTEXF_NONE;
5036 D3DTEXTUREOP DXGraphicsStateGuardian9::
5037 get_texture_operation(TextureStage::CombineMode mode,
int scale) {
5039 case TextureStage::CM_undefined:
5040 case TextureStage::CM_replace:
5041 return D3DTOP_SELECTARG1;
5043 case TextureStage::CM_modulate:
5045 return D3DTOP_MODULATE;
5046 }
else if (scale < 4) {
5047 return D3DTOP_MODULATE2X;
5049 return D3DTOP_MODULATE4X;
5052 case TextureStage::CM_add:
5055 case TextureStage::CM_add_signed:
5057 return D3DTOP_ADDSIGNED;
5059 return D3DTOP_ADDSIGNED2X;
5062 case TextureStage::CM_interpolate:
5065 case TextureStage::CM_subtract:
5066 return D3DTOP_SUBTRACT;
5068 case TextureStage::CM_dot3_rgb:
5069 case TextureStage::CM_dot3_rgba:
5070 return D3DTOP_DOTPRODUCT3;
5074 <<
"Invalid TextureStage::CombineMode value (" << (int)mode <<
")\n";
5075 return D3DTOP_DISABLE;
5085 DWORD DXGraphicsStateGuardian9::
5086 get_texture_argument(TextureStage::CombineSource source,
5087 TextureStage::CombineOperand operand)
const {
5089 case TextureStage::CS_undefined:
5090 case TextureStage::CS_texture:
5091 return D3DTA_TEXTURE | get_texture_argument_modifier(operand);
5093 case TextureStage::CS_constant:
5094 case TextureStage::CS_constant_color_scale:
5095 return _constant_color_operand | get_texture_argument_modifier(operand);
5097 case TextureStage::CS_primary_color:
5098 return D3DTA_DIFFUSE | get_texture_argument_modifier(operand);
5100 case TextureStage::CS_previous:
5101 return D3DTA_CURRENT | get_texture_argument_modifier(operand);
5103 case TextureStage::CS_last_saved_result:
5104 return D3DTA_TEMP | get_texture_argument_modifier(operand);
5107 <<
"Invalid TextureStage::CombineSource value (" << (int)source <<
")\n";
5108 return D3DTA_CURRENT;
5118 DWORD DXGraphicsStateGuardian9::
5119 get_texture_argument_modifier(TextureStage::CombineOperand operand) {
5121 case TextureStage::CO_src_color:
5124 case TextureStage::CO_one_minus_src_color:
5125 return D3DTA_COMPLEMENT;
5127 case TextureStage::CO_src_alpha:
5128 return D3DTA_ALPHAREPLICATE;
5130 case TextureStage::CO_one_minus_src_alpha:
5131 return D3DTA_ALPHAREPLICATE | D3DTA_COMPLEMENT;
5133 case TextureStage::CO_undefined:
5137 <<
"Invalid TextureStage::CombineOperand value (" << (int)operand <<
")\n";
5149 void DXGraphicsStateGuardian9::
5150 draw_primitive_up(D3DPRIMITIVETYPE primitive_type,
5151 unsigned int primitive_count,
5152 unsigned int first_vertex,
5153 unsigned int num_vertices,
5154 const unsigned char *buffer,
size_t stride) {
5162 const unsigned char *buffer_start = buffer + stride * first_vertex;
5163 const unsigned char *buffer_end = buffer_start + stride * num_vertices;
5165 if (buffer_end - buffer_start > 0x10000) {
5168 _d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
5169 buffer_start, stride);
5171 }
else if ((((
long)buffer_end ^ (
long)buffer_start) & ~0xffff) == 0) {
5173 _d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
5174 buffer_start, stride);
5180 unsigned char *safe_buffer_start = get_safe_buffer_start();
5181 memcpy(safe_buffer_start, buffer_start, buffer_end - buffer_start);
5182 _d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
5183 safe_buffer_start, stride);
5199 void DXGraphicsStateGuardian9::
5200 draw_indexed_primitive_up(D3DPRIMITIVETYPE primitive_type,
5201 unsigned int min_index,
unsigned int max_index,
5202 unsigned int num_primitives,
5203 const unsigned char *index_data,
5204 D3DFORMAT index_type,
5205 const unsigned char *buffer,
size_t stride) {
5208 const unsigned char *buffer_start = buffer + stride * min_index;
5209 const unsigned char *buffer_end = buffer + stride * (max_index + 1);
5211 if (buffer_end - buffer_start > 0x10000) {
5214 _d3d_device->DrawIndexedPrimitiveUP
5215 (primitive_type, min_index, max_index - min_index + 1, num_primitives,
5216 index_data, index_type, buffer, stride);
5218 }
else if ((((
long)buffer_end ^ (
long)buffer_start) & ~0xffff) == 0) {
5220 _d3d_device->DrawIndexedPrimitiveUP
5221 (primitive_type, min_index, max_index - min_index + 1, num_primitives,
5222 index_data, index_type, buffer, stride);
5228 unsigned char *safe_buffer_start = get_safe_buffer_start();
5229 memcpy(safe_buffer_start, buffer_start, buffer_end - buffer_start);
5230 _d3d_device->DrawIndexedPrimitiveUP
5231 (primitive_type, min_index, max_index - min_index + 1, num_primitives,
5232 index_data, index_type, safe_buffer_start - stride * min_index, stride);
5260 case D3DERR_OUTOFVIDEOMEMORY:
5264 size_t current_size = _prepared_objects->_graphics_memory_lru.get_total_size();
5265 size_t target_size = max(current_size - allocation_size * attempts, (
size_t) 0);
5266 _prepared_objects->_graphics_memory_lru.evict_to(target_size);
5268 <<
"Evicted " << current_size - _prepared_objects->_graphics_memory_lru.get_total_size() <<
" bytes of texture memory to make room for more.\n";
5269 if (_prepared_objects->_graphics_memory_lru.get_total_size() < current_size) {
5286 static int dx_stencil_comparison_function_array[] = {
5293 D3DCMP_GREATEREQUAL,
5297 static int dx_stencil_operation_array[] = {
5300 D3DSTENCILOP_REPLACE,
5303 D3DSTENCILOP_INVERT,
5305 D3DSTENCILOP_INCRSAT,
5306 D3DSTENCILOP_DECRSAT,
5314 void DXGraphicsStateGuardian9::
5315 do_issue_stencil() {
5316 if (!_supports_stencil) {
5325 dxgsg9_cat.debug() <<
"STENCIL STATE CHANGE\n";
5326 dxgsg9_cat.debug() <<
"\n" 5327 <<
"SRS_front_comparison_function " << stencil->
get_render_state(StencilAttrib::SRS_front_comparison_function) <<
"\n" 5328 <<
"SRS_front_stencil_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_front_stencil_fail_operation) <<
"\n" 5329 <<
"SRS_front_stencil_pass_z_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation) <<
"\n" 5330 <<
"SRS_front_stencil_pass_z_pass_operation " << stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation) <<
"\n" 5331 <<
"SRS_reference " << stencil->
get_render_state(StencilAttrib::SRS_reference) <<
"\n" 5332 <<
"SRS_read_mask " << stencil->
get_render_state(StencilAttrib::SRS_read_mask) <<
"\n" 5333 <<
"SRS_write_mask " << stencil->
get_render_state(StencilAttrib::SRS_write_mask) <<
"\n" 5334 <<
"SRS_back_comparison_function " << stencil->
get_render_state(StencilAttrib::SRS_back_comparison_function) <<
"\n" 5335 <<
"SRS_back_stencil_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_back_stencil_fail_operation) <<
"\n" 5336 <<
"SRS_back_stencil_pass_z_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation) <<
"\n" 5337 <<
"SRS_back_stencil_pass_z_pass_operation " << stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) <<
"\n";
5342 unsigned int front_compare;
5343 front_compare = stencil->
get_render_state(StencilAttrib::SRS_front_comparison_function);
5345 if (front_compare != RenderAttrib::M_none) {
5346 set_render_state(D3DRS_STENCILENABLE, TRUE);
5347 set_render_state(D3DRS_STENCILFUNC, dx_stencil_comparison_function_array[front_compare]);
5348 set_render_state(D3DRS_STENCILFAIL, dx_stencil_operation_array[
5349 stencil->
get_render_state(StencilAttrib::SRS_front_stencil_fail_operation)]);
5350 set_render_state(D3DRS_STENCILZFAIL, dx_stencil_operation_array[
5351 stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation)]);
5352 set_render_state(D3DRS_STENCILPASS, dx_stencil_operation_array[
5353 stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation)]);
5356 set_render_state(D3DRS_STENCILENABLE, FALSE);
5359 if (_supports_two_sided_stencil) {
5360 unsigned int back_compare;
5361 back_compare = stencil->
get_render_state(StencilAttrib::SRS_back_comparison_function);
5363 if (back_compare != RenderAttrib::M_none) {
5364 set_render_state(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
5365 set_render_state(D3DRS_CCW_STENCILFUNC, dx_stencil_comparison_function_array[back_compare]);
5366 set_render_state(D3DRS_CCW_STENCILFAIL, dx_stencil_operation_array[
5367 stencil->
get_render_state(StencilAttrib::SRS_back_stencil_fail_operation)]);
5368 set_render_state(D3DRS_CCW_STENCILZFAIL, dx_stencil_operation_array[
5369 stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation)]);
5370 set_render_state(D3DRS_CCW_STENCILPASS, dx_stencil_operation_array[
5371 stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation)]);
5374 set_render_state(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
5379 set_render_state(D3DRS_STENCILREF, stencil->
get_render_state(StencilAttrib::SRS_reference));
5380 set_render_state(D3DRS_STENCILMASK, stencil->
get_render_state(StencilAttrib::SRS_read_mask));
5381 set_render_state(D3DRS_STENCILWRITEMASK, stencil->
get_render_state(StencilAttrib::SRS_write_mask));
5385 _d3d_device->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 0.0f, stencil->
get_render_state(StencilAttrib::SRS_clear_value));
5391 dxgsg9_cat.debug() <<
"STENCIL STATE CHANGE TO OFF\n";
5394 set_render_state(D3DRS_STENCILENABLE, FALSE);
5395 if (_supports_two_sided_stencil) {
5396 set_render_state(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
5406 void DXGraphicsStateGuardian9::
5407 do_issue_scissor() {
5412 r.left = _current_viewport.X + _current_viewport.Width * frame[0];
5413 r.top = _current_viewport.Y + _current_viewport.Height * (1.0f - frame[3]);
5414 r.right = _current_viewport.X + _current_viewport.Width * frame[1];
5415 r.bottom = _current_viewport.Y + _current_viewport.Height * (1.0f - frame[2]);
5416 _d3d_device->SetScissorRect(&r);
5417 set_render_state(D3DRS_SCISSORTESTENABLE, TRUE);
5428 DWORD multisampletype, DWORD multisamplequality) {
5431 int r=0, g=0, b=0, a=0;
5433 case D3DFMT_R8G8B8: r=8; g=8; b=8; a=0;
break;
5434 case D3DFMT_A8R8G8B8: r=8; g=8; b=8; a=8;
break;
5435 case D3DFMT_X8R8G8B8: r=8; g=8; b=8; a=0;
break;
5436 case D3DFMT_R5G6B5: r=5; g=6; b=5; a=0;
break;
5437 case D3DFMT_X1R5G5B5: r=5; g=5; b=5; a=0;
break;
5438 case D3DFMT_A1R5G5B5: r=5; g=5; b=5; a=1;
break;
5439 case D3DFMT_A4R4G4B4: r=4; g=4; b=4; a=4;
break;
5440 case D3DFMT_R3G3B2: r=3; g=3; b=2; a=0;
break;
5441 case D3DFMT_A8R3G3B2: r=3; g=3; b=2; a=8;
break;
5442 case D3DFMT_X4R4G4B4: r=4; g=4; b=4; a=0;
break;
5443 case D3DFMT_A2B10G10R10: r=10;g=10;b=10;a=2;
break;
5444 case D3DFMT_A8P8: index=8; a=8;
break;
5445 case D3DFMT_P8: index=8; a=0;
break;
5449 props.set_rgb_color(0);
5450 props.set_indexed_color(1);
5452 }
else if (r + g + b > 0) {
5453 props.set_rgb_color(1);
5454 props.set_indexed_color(0);
5457 props.set_alpha_bits(a);
5462 case D3DFMT_D32: depth=32; stencil=0;
break;
5463 case D3DFMT_D15S1: depth=15; stencil=1;
break;
5464 case D3DFMT_D24S8: depth=24; stencil=8;
break;
5465 case D3DFMT_D16: depth=16; stencil=0;
break;
5466 case D3DFMT_D24X8: depth=24; stencil=0;
break;
5467 case D3DFMT_D24X4S4: depth=24; stencil=4;
break;
5470 props.set_depth_bits(depth);
5471 props.set_stencil_bits(stencil);
5472 if (multisampletype == D3DMULTISAMPLE_NONMASKABLE) {
5473 props.set_multisamples(2);
5475 props.set_multisamples(multisampletype);
5481 #define GAMMA_1 (255.0 * 256.0) 5483 static bool _gamma_table_initialized =
false;
5484 static unsigned short _orignial_gamma_table [256 * 3];
5486 void _create_gamma_table (PN_stdfloat gamma,
unsigned short *original_red_table,
unsigned short *original_green_table,
unsigned short *original_blue_table,
unsigned short *red_table,
unsigned short *green_table,
unsigned short *blue_table) {
5488 double gamma_correction;
5494 gamma_correction = 1.0 / (double) gamma;
5496 for (i = 0; i < 256; i++) {
5501 if (original_red_table) {
5502 r = (double) original_red_table [i] / GAMMA_1;
5503 g = (double) original_green_table [i] / GAMMA_1;
5504 b = (double) original_blue_table [i] / GAMMA_1;
5507 r = ((double) i / 255.0);
5512 r = pow (r, gamma_correction);
5513 g = pow (g, gamma_correction);
5514 b = pow (b, gamma_correction);
5531 green_table [i] = g;
5546 if (_gamma_table_initialized ==
false) {
5547 HDC hdc = GetDC(NULL);
5550 if (GetDeviceGammaRamp (hdc, (LPVOID) _orignial_gamma_table)) {
5551 _gamma_table_initialized =
true;
5555 ReleaseDC (NULL, hdc);
5571 HDC hdc = GetDC(NULL);
5575 unsigned short ramp [256 * 3];
5577 if (restore && _gamma_table_initialized) {
5578 _create_gamma_table (gamma, &_orignial_gamma_table [0], &_orignial_gamma_table [256], &_orignial_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
5581 _create_gamma_table (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]);
5584 if (SetDeviceGammaRamp (hdc, ramp)) {
5588 ReleaseDC (NULL, hdc);
5604 set = static_set_gamma(
false, gamma);
5619 static_set_gamma(
true, 1.0f);
5629 set_cg_device(NULL);
5630 static_set_gamma(
true, 1.0f);
5644 CGprofile profile = cgGetProfile(name.c_str());
5646 if (profile == CG_PROFILE_UNKNOWN) {
5647 dxgsg9_cat.error() << name <<
", unknown Cg-profile\n";
5650 return cgD3D9IsProfileSupported(cgGetProfile(name.c_str())) != 0;
5664 if (_cg_device != cg_device) {
5665 cgD3D9SetDevice(cg_device);
5666 _cg_device = cg_device;
5677 int secondary_count;
5685 int total_key_elements;
5695 key_element -> key = key;
5696 key_element -> count = 1;
5697 key_element -> secondary_count = 0;
5698 key_element -> next = 0;
5700 key_list -> total_key_elements++;
5707 return key_list -> key_element;
5712 return key_element -> next;
5715 void delete_key_list (
KEY_LIST *key_list)
5722 key_element = first_key_element (key_list);
5725 key_element_next = next_key_element (key_element);
5727 key_element = key_element_next;
5739 memset (key_list, 0,
sizeof (
KEY_LIST));
5751 last_key_element = 0;
5752 current_key_element = key_list -> key_element;
5753 if (current_key_element == 0)
5755 key_element = new_key_element (key, key_list);
5756 key_list -> key_element = key_element;
5760 while (current_key_element)
5762 if (key < current_key_element -> key)
5764 key_element = new_key_element (key, key_list);
5765 key_element -> next = current_key_element;
5767 if (last_key_element == 0)
5769 key_list -> key_element = key_element;
5773 last_key_element -> next = key_element;
5779 if (key > current_key_element -> key)
5781 if (current_key_element -> next == 0)
5783 key_element = new_key_element (key, key_list);
5784 current_key_element -> next = key_element;
5794 current_key_element -> count++;
5799 last_key_element = current_key_element;
5800 current_key_element = current_key_element -> next;
CombineSource get_combine_alpha_source2() const
Get source2 of combine_alpha_mode.
void get_linear_range(PN_stdfloat &onset, PN_stdfloat &opaque)
Retrieves the current onset and offset ranges.
virtual bool is_linear() const
Returns true if the lens represents a linear projection (e.g.
IDirect3DTexture9 * get_d3d_2d_texture() const
Returns the Direct3D object that represents the texture, in the case of a 1-d or 2-d texture...
A light shining from infinitely far away in a particular direction, like sunlight.
static bool is_srgb(Format format)
Returns true if the indicated format is in the sRGB color space, false otherwise. ...
Fog * get_fog() const
If the FogAttrib is not an 'off' FogAttrib, returns the fog that is associated.
Format get_format() const
Returns the format of the texture, which represents both the semantic meaning of the texels and...
Texture * get_texture() const
Returns the pointer to the associated Texture object.
int get_offset() const
Returns the depth offset represented by this attrib.
The abstract interface to all kinds of lights.
virtual void end_frame(Thread *current_thread)
Called after each frame is rendered, to allow the GSG a chance to do any internal cleanup after rende...
Encapsulates the data from a DisplayRegion, pre-fetched for one stage of the pipeline.
This is the base class for all three-component vectors and points.
void release_shader(ShaderContext *sc)
Releases the resources allocated by prepare_shader.
const float * get_data() const
Returns the address of the first of the four data elements in the vector.
int get_z_size() const
Returns the depth of the texture image in texels.
Mode get_mode() const
Returns the colorBlend mode.
Mode get_mode() const
Returns the render mode.
bool get_local() const
Returns the local viewer flag.
bool do_framebuffer_copy_to_ram(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb, bool inverted)
This is the implementation of framebuffer_copy_to_ram(); it adds one additional parameter, which should be true if the framebuffer is to be inverted during the copy (as in the same way it copies to texture memory).
This is a base class for GraphicsWindow (actually, GraphicsOutput) and DisplayRegion, both of which are conceptually rectangular regions into which drawing commands may be issued.
Enables or disables writing to the depth buffer.
Material * get_material() const
If the MaterialAttrib is not an 'off' MaterialAttrib, returns the material that is associated...
Mode get_mode() const
Returns the shade mode.
virtual void clear(DrawableRegion *clearable)
Clears all of the indicated buffers to their assigned colors.
static LMatrix4f scale_mat(const LVecBase3f &scale)
Returns a matrix that applies the indicated scale in each of the three axes.
LColor get_color() const
return the color for this stage
A base class for any number of different kinds of lenses, linear and otherwise.
CombineOperand get_combine_alpha_operand0() const
Get operand0 of combine_alpha_mode.
int get_rgb_scale() const
See set_rgb_scale().
TextureType get_texture_type() const
Returns the overall interpretation of the texture.
static bool static_set_gamma(bool restore, PN_stdfloat gamma)
Static function for setting gamma which is needed for atexit.
Enables or disables writing to the color buffer.
virtual bool extract_texture_data(Texture *tex)
This method should only be called by the GraphicsEngine.
bool might_have_ram_image() const
Returns true if the texture's image contents are currently available in main RAM, or there is reason ...
void get_region_pixels_i(int &xo, int &yo, int &w, int &h) const
Similar to get_region_pixels(), but returns the upper left corner, and the pixel numbers are numbered...
Indicates which, if any, material should be applied to geometry.
This object describes how the vertex animation, if any, represented in a GeomVertexData is encoded...
bool has_ambient() const
Returns true if the ambient color has been explicitly set for this material, false otherwise...
Enables or disables writing to the depth buffer.
virtual void prepare_display_region(DisplayRegionPipelineReader *dr)
Makes the specified DisplayRegion current.
LPoint3 get_nodal_point() const
Returns the center point of the lens: the point from which the lens is viewing.
virtual void end_draw_primitives()
Called after a sequence of draw_primitive() functions are called, this should do whatever cleanup is ...
PN_stdfloat get_shininess() const
Returns the shininess exponent of the material.
This controls the enabling of transparency.
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected triangles.
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
This is a special class object that holds all the information returned by a particular GSG to indicat...
PN_stdfloat get_clear_depth() const
Returns the current clear depth value.
unsigned int get_channels() const
Returns the mask of color channels that are enabled by this attrib.
Mode get_mode() const
Returns the transparency mode.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
void setup_texture(TextureType texture_type, int x_size, int y_size, int z_size, ComponentType component_type, Format format)
Sets the texture to the indicated type and dimensions, presumably in preparation for calling read() o...
PandaCompareFunc get_mode() const
Returns the alpha write mode.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, const GeomVertexDataPipelineReader *data_reader, bool force)
Called before a sequence of draw_primitive() functions are called, this should prepare the vertex dat...
Specifies whether flat shading (per-polygon) or smooth shading (per-vertex) is in effect...
void apply_texture(int i, TextureContext *tc, const SamplerState &sampler)
Makes the texture the currently available texture for rendering on the ith stage. ...
int get_num_transforms() const
This is only meaningful for animation_type AT_hardware.
This is a special class object that holds all the information returned by a particular GSG to indicat...
bool create_texture(DXScreenData &scrn)
Use panda texture's pixelbuffer to create a texture for the specified device.
static D3DFORMAT get_index_type(Geom::NumericType numeric_type)
Maps from the Geom's internal numeric type symbols to DirectX's.
bool get_indexed_transforms() const
This is only meaningful for animation_type AT_hardware.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
int get_alpha_scale() const
See set_alpha_scale().
Caches a GeomPrimitive in the DirectX device as an index buffer.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
bool was_simple_image_modified() const
Returns true if the texture's "simple" image has been modified since the last time mark_simple_loaded...
Mode get_mode() const
Return the mode of this stage.
PN_stdfloat get_hfov() const
Returns the horizontal component of fov only.
int get_num_combine_alpha_operands() const
Returns the number of meaningful operands that may be retrieved via get_combine_alpha_sourceN() and g...
bool get_perspective() const
Returns the perspective flag.
virtual void set_state_and_transform(const RenderState *state, const TransformState *transform)
Simultaneously resets the render state and the transform state.
CombineOperand get_combine_rgb_operand1() const
Get operand1 of combine_rgb_mode.
static const LVecBase3f & zero()
Returns a zero-length vector.
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
Encapsulates the data from a Geom, pre-fetched for one stage of the pipeline.
static const LMatrix4f & convert_mat(CoordinateSystem from, CoordinateSystem to)
Returns a matrix that transforms from the indicated coordinate system to the indicated coordinate sys...
bool has_ram_image() const
Returns true if the Texture has its image contents available in main RAM, false if it exists only in ...
ComponentType get_component_type() const
Returns the numeric interpretation of each component of the texture.
PN_stdfloat get_exponent() const FINAL
Returns the exponent that controls the amount of light falloff from the center of the spotlight...
bool has_mipmaps() const
Returns true if the texture was created with mipmaps, false otherwise.
virtual void end_scene()
Called between begin_frame() and end_frame() to mark the end of drawing commands for a "scene" (usual...
ShaderLanguage get_language() const
Returns the shader language in which this shader was written.
static bool get_gamma_table(void)
Static function for getting the original gamma.
virtual bool framebuffer_copy_to_texture(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)
Copy the pixels within the indicated display region from the framebuffer into texture memory...
Mode get_mode() const
Returns the depth write mode.
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
CombineSource get_combine_rgb_source1() const
Get source1 of combine_rgb_mode.
static void atexit_function(void)
This function is passed to the atexit function.
The ShaderContext is meant to contain the compiled version of a shader string.
const LColor & get_specular_color() const FINAL
Returns the color of specular highlights generated by the light.
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
void enqueue_lru(AdaptiveLru *lru)
Adds the page to the LRU for the first time, or marks it recently-accessed if it has already been add...
Lens * get_lens(int index=0) const
Returns a pointer to the particular Lens associated with this LensNode, or NULL if there is not yet a...
Indicates which faces should be culled based on their vertex ordering.
FilterType get_effective_minfilter() const
Returns the filter mode of the texture for minification, with special treatment for FT_default...
const LColor & get_diffuse() const
Returns the diffuse color setting, if it has been set.
Applies a Fog to the geometry at and below this node.
void set_size_padded(int x=1, int y=1, int z=1)
Changes the size of the texture, padding if necessary, and setting the pad region as well...
const LColor & get_ambient() const
Returns the ambient color setting, if it has been set.
A lightweight class that represents a single element that may be timed and/or counted via stats...
int get_effective_anisotropic_degree() const
Returns the degree of anisotropic filtering that should be applied to the texture.
PN_stdfloat get_thickness() const
Returns the line width or point thickness.
CombineSource get_combine_alpha_source0() const
Get source0 of combine_alpha_mode.
bool was_modified(const GeomPrimitivePipelineReader *reader) const
Returns true if the data has been modified since the last time mark_loaded() was called.
An offscreen render buffer.
bool check_dx_allocation(HRESULT result, int allocation_size, int attempts)
This function is called after the creation of textures, vertex buffers, and index buffers to check if...
A StencilAttrib is a collection of all stencil render states.
const LVecBase4 & get_frame() const
Returns the left, right, bottom, top coordinates of the scissor frame.
bool extract_texture_data(DXScreenData &scrn)
This method will be called in the draw thread to download the texture memory's image into its ram_ima...
CombineSource get_combine_rgb_source2() const
Get source2 of combine_rgb_mode.
void restore_gamma()
Restore original gamma.
IDirect3DBaseTexture9 * get_d3d_texture() const
Returns the Direct3D object that represents the texture, whatever kind of texture it is...
This is a 4-by-4 transform matrix.
static void set_cg_device(LPDIRECT3DDEVICE9 cg_device)
Sets the global Cg device pointer.
const LPlane & get_plane() const
Returns the plane represented by the PlaneNode.
virtual void reset()
Resets all internal state as if the gsg were newly created.
virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of line strips.
const LPoint3 & get_point() const
Returns the point in space at which the light is located.
Specifies how atmospheric fog effects are applied to geometry.
const LColor & get_border_color() const
Returns the solid color of the texture's border.
bool get_clear_color_active() const
Returns the current setting of the flag that indicates whether the color buffer should be cleared eve...
CombineOperand get_combine_rgb_operand0() const
Get operand0 of combine_rgb_mode.
An object to create GraphicsOutputs that share a particular 3-D API.
bool get_clear_depth_active() const
Returns the current setting of the flag that indicates whether the depth buffer should be cleared eve...
bool has_simple_ram_image() const
Returns true if the Texture has a "simple" image available in main RAM.
ShaderContext * prepare_shader(Shader *se)
Compile a vertex/fragment shader body.
const LColor & get_specular_color() const FINAL
Returns the color of specular highlights generated by the light.
virtual void begin_occlusion_query()
Begins a new occlusion query.
This specialization on GeomMunger finesses vertices for DirectX rendering.
const LColor & get_clear_color() const
Returns the current clear color value.
AnimationType get_animation_type() const
Returns the type of animation represented by this spec.
A light originating from a single point in space, and shining in a particular direction, with a cone-shaped falloff.
int get_num_combine_rgb_operands() const
Returns the number of meaningful operands that may be retrieved via get_combine_rgb_sourceN() and get...
void get_region_pixels_i(int &xo, int &yo, int &w, int &h) const
Similar to get_region_pixels(), but returns the upper left corner, and the pixel numbers are numbered...
bool apply_index_buffer(IndexBufferContext *ibc, const GeomPrimitivePipelineReader *reader, bool force)
Updates the index buffer with the current data, and makes it the current index buffer for rendering...
bool has_specular() const
Returns true if the specular color has been explicitly set for this material, false otherwise...
bool get_clear_stencil_active() const
Returns the current setting of the flag that indicates whether the color buffer should be cleared eve...
bool set_gamma(PN_stdfloat gamma)
Non static version of setting gamma.
void set_render_to_texture(bool render_to_texture)
Sets a flag on the texture that indicates whether the texture is intended to be used as a direct-rend...
CombineMode get_combine_alpha_mode() const
Get combine_alpha_mode.
int get_tex_view_offset() const
Returns the current setting of the tex_view_offset.
virtual void end_frame(Thread *current_thread)
Called after each frame is rendered, to allow the GSG a chance to do any internal cleanup after rende...
virtual void end_draw_primitives()
Called after a sequence of draw_primitive() functions are called, this should do whatever cleanup is ...
const LColor & get_specular_color() const FINAL
Returns the color of specular highlights generated by the light.
Enables or disables writing of pixel to framebuffer based on its alpha value relative to a reference ...
CombineOperand get_combine_alpha_operand1() const
Get operand1 of combine_alpha_mode.
virtual bool update_texture(TextureContext *tc, bool force)
Ensures that the current Texture data is refreshed onto the GSG.
Defines the way an object appears in the presence of lighting.
const GeomVertexArrayFormat * get_array_format() const
Returns the format object that describes this array.
bool upload_data(const GeomPrimitivePipelineReader *reader, bool force)
Copies the latest data from the client store to DirectX.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
const float * get_data() const
Returns the address of the first of the nine data elements in the matrix.
PN_stdfloat get_exp_density() const
Returns the density of the fog for exponential calculations.
const LVecBase3 & get_attenuation() const FINAL
Returns the terms of the attenuation equation for the light.
Represents a set of settings that indicate how a texture is sampled.
void mark_loaded(const GeomPrimitivePipelineReader *reader)
Should be called after the IndexBufferContext has been loaded into graphics memory, this updates the internal flags for changed_size() and modified().
virtual TextureContext * prepare_texture(Texture *tex, int view)
Creates a new retained-mode representation of the given texture, and returns a newly-allocated Textur...
TextureContext * prepare_now(int view, PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg)
Creates a context for the texture on the particular GSG, if it does not already exist.
virtual void bind_light(PointLight *light_obj, const NodePath &light, int light_id)
Called the first time a particular light has been bound to a given id within a frame, this should set up the associated hardware light with the light's properties.
PN_stdfloat get_reference_alpha() const
Returns the alpha reference value.
This is the base class for all three-component vectors and points.
const unsigned char * get_read_pointer(bool force) const
Returns a readable pointer to the beginning of the actual data stream, or NULL if the data is not cur...
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, const GeomVertexDataPipelineReader *data_reader, bool force)
Called before a sequence of draw_primitive() functions are called, this should prepare the vertex dat...
Applies a transform matrix to UV's before they are rendered.
CompressionMode get_ram_image_compression() const
Returns the compression mode in which the ram image is already stored pre-compressed.
unsigned int get_clear_stencil() const
Returns the current clear stencil value.
const LMatrix4 & get_projection_mat(StereoChannel channel=SC_mono) const
Returns the complete transformation matrix from a 3-d point in space to a point on the film...
const LVector3 & get_direction() const
Returns the direction in which the light is aimed.
virtual bool prepare_lens()
Makes the current lens (whichever lens was most recently specified with set_scene()) active...
int get_num_rows() const
Returns the number of rows stored in the array, based on the number of bytes and the stride...
This specifies how colors are blended into the frame buffer, for special effects. ...
CombineMode get_combine_rgb_mode() const
Get the combine_rgb_mode.
PandaNode * node() const
Returns the referenced node of the path.
CombineSource get_combine_rgb_source0() const
Get source0 of combine_rgb_mode.
void set_rgba_bits(int r, int g, int b, int a)
Convenience method for setting the red, green, blue and alpha bits in one go.
PandaCompareFunc get_mode() const
Returns the depth write mode.
virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected line segments.
A thread; that is, a lightweight process.
void update_data_size_bytes(size_t new_data_size_bytes)
Should be called (usually by a derived class) when the on-card size of this object has changed...
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
virtual void prepare_display_region(DisplayRegionPipelineReader *dr)
Prepare a display region for rendering (set up scissor region and viewport)
This is a special kind of attribute that instructs the graphics driver to apply an offset or bias to ...
int get_y_size() const
Returns the height of the texture image in texels.
virtual bool begin_frame(Thread *current_thread)
Called before each frame is rendered, to allow the GSG a chance to do any internal cleanup before beg...
bool involves_color_scale() const
Returns true if the TextureStage is affected by the setting of the current ColorScaleAttrib, false otherwise.
void mark_loaded()
Should be called after the texture has been loaded into graphics memory, this updates the internal fl...
This is a special class object that holds all the information returned by a particular GSG to indicat...
Encapsulates all the communication with a particular instance of a given rendering backend...
Specifies how polygons are to be drawn.
unsigned int get_render_state(StencilRenderState render_state_identifier) const
Returns render state.
void set_active(bool flag)
Changes the active flag associated with this object.
bool is_off() const
Returns true if the MaterialAttrib is an 'off' MaterialAttrib, indicating that it should disable the ...
const LColor & get_color() const
Returns the color of the fog.
LVecBase4f get_col(int col) const
Retrieves the indicated column of the matrix as a 4-component vector.
virtual void end_scene()
Called between begin_frame() and end_frame() to mark the end of drawing commands for a "scene" (usual...
int get_num_views() const
Returns the number of "views" in the texture.
FrameBufferProperties calc_fb_properties(DWORD cformat, DWORD dformat, DWORD multisampletype, DWORD multisamplequality)
Convert DirectX framebuffer format ids into a FrameBufferProperties structure.
Specifies how polygons are to be drawn.
A rectangular subregion within a window for rendering into.
CombineOperand get_combine_rgb_operand2() const
Get operand2 of combine_rgb_mode.
virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle fans.
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
const LVecBase3 & get_attenuation() const FINAL
Returns the terms of the attenuation equation for the light.
CombineSource get_combine_alpha_source1() const
Get source1 of combine_alpha_mode.
CombineOperand get_combine_alpha_operand2() const
Get operand2 of combine_alpha_mode.
void set_color_bits(int n)
Sets the number of requested color bits as a single number that represents the sum of the individual ...
This restricts rendering to within a rectangular region of the scene, without otherwise affecting the...
bool uses_color() const
Returns true if the TextureStage makes use of whatever color is specified in set_color(), false otherwise.
virtual void release_texture(TextureContext *tc)
Frees the GL resources previously allocated for the texture.
const LColor & get_color() const
Returns the basic color of the light.
Mode get_effective_mode() const
Returns the effective culling mode.
Returned from a GSG in response to begin_occlusion_query() .
This class is the main interface to controlling the render process.
const LColor & get_emission() const
Returns the emission color setting, if it has been set.
WrapMode get_wrap_w() const
Returns the wrap mode of the texture in the W direction.
virtual bool get_supports_cg_profile(const string &name) const
Returns true if this particular GSG supports the specified Cg Shader Profile.
virtual void reset()
Resets all internal state as if the gsg were newly created.
void mark_unloaded()
Should be called after the texture has been forced out of texture memory.
virtual bool begin_scene()
Called between begin_frame() and end_frame() to mark the beginning of drawing commands for a "scene" ...
Mode get_mode() const
Returns the render mode.
virtual bool begin_frame(Thread *current_thread)
Called before each frame is rendered, to allow the GSG a chance to do any internal cleanup before beg...
void create_ibuffer(DXScreenData &scrn, const GeomPrimitivePipelineReader *reader)
Creates a new index buffer (but does not upload data to it).
virtual IndexBufferContext * prepare_index_buffer(GeomPrimitive *data)
Creates a new retained-mode representation of the given data, and returns a newly-allocated IndexBuff...
TypeHandle is the identifier used to differentiate C++ class types.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
bool has_diffuse() const
Returns true if the diffuse color has been explicitly set for this material, false otherwise...
virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle strips.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
bool is_off() const
Returns true if the FogAttrib is an 'off' FogAttrib, indicating that it should disable fog...
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
bool changed_size(const GeomPrimitivePipelineReader *reader) const
Returns true if the data has changed size since the last time mark_loaded() was called.
PN_stdfloat get_lod_bias() const
Returns the bias that will be added to the texture level of detail when sampling this texture...
Defines the properties of a named stage of the multitexture pipeline.
const float * get_data() const
Returns the address of the first of the three data elements in the vector.
bool upload_texture(DXTextureContext9 *dtc, bool force)
Creates a texture surface on the graphics card and fills it with its pixel data.
ShaderContext * prepare_now(PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg)
Creates a context for the shader on the particular GSG, if it does not already exist.
WrapMode get_wrap_v() const
Returns the wrap mode of the texture in the V direction.
A RenderBuffer is an arbitrary subset of the various layers (depth buffer, color buffer, etc.) of a drawing region.
bool was_modified() const
Returns true if the texture properties or image have been modified since the last time mark_loaded() ...
virtual bool framebuffer_copy_to_ram(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)
Copy the pixels within the indicated display region from the framebuffer into system memory...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
virtual bool draw_points(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected points.
const LVector3 & get_view_vector() const
Returns the axis along which the lens is facing.
WrapMode get_wrap_u() const
Returns the wrap mode of the texture in the U direction.
const LColor & get_specular() const
Returns the specular color setting, if it has been set.
A light originating from a single point in space, and shining in all directions.
void delete_texture()
Release the surface used to store the texture.
A node that contains a plane.
int get_data_size_bytes() const
Returns the number of bytes stored in the array.
Similar to PointerToArray, except that its contents may not be modified.
int get_x_size() const
Returns the width of the texture image in texels.
This is the data for one array of a GeomVertexData structure.
virtual bool begin_scene()
Called between begin_frame() and end_frame() to mark the beginning of drawing commands for a "scene" ...
FilterType get_effective_magfilter() const
Returns the filter mode of the texture for magnification, with special treatment for FT_default...
static HRESULT d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface9 *d3d_surface, bool inverted, Texture *result, int view, int z)
copies source_rect in pD3DSurf to upper left of texture
virtual void release_index_buffer(IndexBufferContext *ibc)
Frees the GL resources previously allocated for the data.
bool has_uncompressed_ram_image() const
Returns true if the Texture has its image contents available in main RAM and is uncompressed, false otherwise.
bool get_saved_result() const
Returns the current setting of the saved_result flag.