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)
84 TypeHandle DXGraphicsStateGuardian9::_type_handle;
86 D3DMATRIX DXGraphicsStateGuardian9::_d3d_ident_mat;
88 unsigned char *DXGraphicsStateGuardian9::_temp_buffer =
nullptr;
89 unsigned char *DXGraphicsStateGuardian9::_safe_buffer_start =
nullptr;
92 LPDIRECT3DDEVICE9 DXGraphicsStateGuardian9::_cg_device =
nullptr;
95 #define __D3DLIGHT_RANGE_MAX ((PN_stdfloat)sqrt(FLT_MAX))
97 #define MY_D3DRGBA(r, g, b, a) ((D3DCOLOR) D3DCOLOR_COLORVALUE(r, g, b, a))
102 DXGraphicsStateGuardian9::
106 if (dxgsg9_cat.is_debug()) {
108 <<
"DXGraphicsStateGuardian9 " <<
this <<
" constructing\n";
116 _d3d_device =
nullptr;
118 _dx_is_ready =
false;
119 _vertex_blending_enabled =
false;
120 _overlay_windows_supported =
false;
121 _tex_stats_retrieval_impossible =
false;
122 _supports_render_texture =
false;
124 _active_ibuffer =
nullptr;
128 ZeroMemory(&_d3d_ident_mat,
sizeof(D3DMATRIX));
129 _d3d_ident_mat._11 = _d3d_ident_mat._22 = _d3d_ident_mat._33 = _d3d_ident_mat._44 = 1.0f;
131 _cur_read_pixel_buffer = RenderBuffer::T_front;
135 _copy_texture_inverted =
true;
137 _gsg_managed_textures = dx_management | dx_texture_management;
138 _gsg_managed_vertex_buffers = dx_management;
139 _gsg_managed_index_buffers = dx_management;
142 _num_bound_streams = 0;
143 _white_vbuffer =
nullptr;
145 _vertex_shader_version_major = 0;
146 _vertex_shader_version_minor = 0;
147 _pixel_shader_version_major = 0;
148 _pixel_shader_version_minor = 0;
150 _vertex_shader_profile = 0;
151 _pixel_shader_profile = 0;
153 _vertex_shader_maximum_constants = 0;
155 _supports_stream_offset =
false;
162 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,
nullptr);
179 free_nondx_resources();
197 << *dtc->
get_texture() <<
" is stored in an unsupported compressed format.\n";
251 if (aniso_degree >= 1) {
255 int supports_anisotropic_mag_filter;
256 D3DTEXTUREFILTERTYPE new_mag_filter;
258 supports_anisotropic_mag_filter = (_screen -> _d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) != 0;
259 if (aniso_degree <= 1 || supports_anisotropic_mag_filter == 0) {
260 new_mag_filter = ((ft != SamplerState::FT_nearest) ? D3DTEXF_LINEAR : D3DTEXF_POINT);
262 new_mag_filter = D3DTEXF_ANISOTROPIC;
269 <<
"ERROR: set_sampler_state (D3DSAMP_MAGFILTER, "
270 << new_mag_filter <<
") failed for sampler: " << sampler << endl;
281 new_mip_filter = D3DTEXF_NONE;
286 new_mip_filter = D3DTEXF_NONE;
289 if (aniso_degree >= 2) {
290 new_min_filter = D3DTEXF_ANISOTROPIC;
324 <<
"Unable to re-create texture " << *tex << endl;
328 dtc->
enqueue_lru(&_prepared_objects->_graphics_memory_lru);
342 << *tex <<
" is stored in an unsupported compressed format.\n";
350 if (_effective_incomplete_render && !force) {
354 !_loader.is_null()) {
357 async_reload_texture(dtc);
361 return dtc->create_simple_texture(*_screen);
393 for (
int view = 0; view < num_views; ++view) {
395 nassertr(tc !=
nullptr,
false);
414 case Shader::SL_GLSL:
416 <<
"Tried to load GLSL shader, but GLSL shaders not supported by Direct3D 9.\n";
421 if (_supports_basic_shaders) {
425 <<
"Tried to load Cg shader, but basic shaders not supported.\n";
430 <<
"Tried to load Cg shader, but Cg support not compiled in.\n";
436 <<
"Tried to load shader with unsupported shader language!\n";
468 if (_screen->_managed_vertex_buffers) {
469 pool = D3DPOOL_MANAGED;
470 usage = D3DUSAGE_WRITEONLY;
472 pool = D3DPOOL_DEFAULT;
473 usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC;
476 int num_bytes = data->get_data_size_bytes();
484 hr = _screen->_d3d_device->CreateVertexBuffer(num_bytes, usage, dvbc->_fvf, pool, &dvbc->_vbuffer,
nullptr);
491 if (dxgsg9_cat.is_debug() && DXdebug_buffers9) {
493 <<
"creating vertex buffer " << dvbc->_vbuffer <<
": "
494 << data->get_num_rows() <<
" vertices "
495 << *data->get_array_format() <<
"\n";
503 <<
"CreateVertexBuffer failed" << D3DERRORSTRING(hr);
505 dvbc->_vbuffer =
nullptr;
522 int num_bytes = reader->get_data_size_bytes();
524 if (dxgsg9_cat.is_debug() && DXdebug_buffers9) {
526 <<
"copying " << num_bytes
527 <<
" bytes into vertex buffer " << dvbc->_vbuffer <<
"\n";
531 if ( num_bytes != 0 ) {
533 if (client_pointer ==
nullptr) {
540 if (dvbc->_vbuffer !=
nullptr) {
541 dvbc->_vbuffer->Release();
542 dvbc->_vbuffer =
nullptr;
547 if (_screen->_managed_vertex_buffers) {
548 pool = D3DPOOL_MANAGED;
549 usage = D3DUSAGE_WRITEONLY;
551 pool = D3DPOOL_DEFAULT;
552 usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC;
560 hr = _screen->_d3d_device->CreateVertexBuffer(num_bytes, usage, dvbc->_fvf, pool, &dvbc->_vbuffer,
nullptr);
565 dvbc->_vbuffer =
nullptr;
567 <<
"CreateVertexBuffer failed" << D3DERRORSTRING(hr);
572 PStatTimer timer(_load_vertex_buffer_pcollector, reader->get_current_thread());
576 if (_screen->_managed_vertex_buffers) {
577 hr = dvbc->_vbuffer->Lock(0, num_bytes, (
void **) &local_pointer, 0);
579 hr = dvbc->_vbuffer->Lock(0, num_bytes, (
void **) &local_pointer, D3DLOCK_DISCARD);
583 <<
"VertexBuffer::Lock failed" << D3DERRORSTRING(hr);
587 memcpy(local_pointer, client_pointer, num_bytes);
589 dvbc->_vbuffer->Unlock();
591 _data_transferred_pcollector.add_level(num_bytes);
596 dvbc->
enqueue_lru(&_prepared_objects->_graphics_memory_lru);
612 if (dxgsg9_cat.is_debug() && DXdebug_buffers9) {
614 <<
"deleting vertex buffer " << dvbc->_vbuffer <<
"\n";
618 if (dvbc->_vbuffer !=
nullptr) {
619 dvbc->_vbuffer->Release();
620 dvbc->_vbuffer =
nullptr;
646 nassertr(vbc !=
nullptr,
false);
679 if (dibc->_ibuffer ==
nullptr) {
683 if (dibc->_ibuffer !=
nullptr) {
689 _d3d_device->SetIndices(dibc->_ibuffer);
690 _active_ibuffer = dibc;
694 _d3d_device->SetIndices(
nullptr);
695 _active_ibuffer =
nullptr;
710 _active_ibuffer =
nullptr;
713 if (_active_ibuffer != dibc) {
714 _d3d_device->SetIndices(dibc->_ibuffer);
715 _active_ibuffer = dibc;
719 dibc->
enqueue_lru(&_prepared_objects->_graphics_memory_lru);
748 nassertv(_supports_occlusion_query);
749 nassertv(_current_occlusion_query ==
nullptr);
751 IDirect3DQuery9 *query;
752 HRESULT hr = _d3d_device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &query);
755 <<
"Occlusion query failed.\n";
761 if (dxgsg9_cat.is_debug()) {
763 <<
"beginning occlusion query " << query <<
"\n";
766 query->Issue(D3DISSUE_BEGIN);
767 _current_occlusion_query = queryobj;
777 end_occlusion_query() {
778 if (_current_occlusion_query ==
nullptr) {
786 if (dxgsg9_cat.is_debug()) {
788 <<
"ending occlusion query " << query <<
"\n";
791 _current_occlusion_query =
nullptr;
792 query->Issue(D3DISSUE_END);
804 return GeomMunger::register_munger(munger, current_thread);
813 DWORD main_flags = 0;
830 main_flags |= D3DCLEAR_TARGET;
834 _screen->_presentation_params.EnableAutoDepthStencil) {
835 aux_flags |= D3DCLEAR_ZBUFFER;
840 if (_screen->_presentation_params.EnableAutoDepthStencil &&
841 IS_STENCIL_FORMAT(_screen->_presentation_params.AutoDepthStencilFormat)) {
842 aux_flags |= D3DCLEAR_STENCIL;
846 if ((main_flags | aux_flags) != 0) {
847 HRESULT hr = _d3d_device->Clear(0,
nullptr, main_flags | aux_flags, color_clear_value,
848 depth_clear_value, stencil_clear_value);
849 if (FAILED(hr) && main_flags == D3DCLEAR_TARGET && aux_flags != 0) {
852 hr = _d3d_device->Clear(0,
nullptr, D3DCLEAR_TARGET, color_clear_value,
853 depth_clear_value, stencil_clear_value);
858 aux_flags |= D3DCLEAR_ZBUFFER;
859 HRESULT hr2 = _d3d_device->Clear(0,
nullptr, D3DCLEAR_ZBUFFER, color_clear_value,
860 depth_clear_value, stencil_clear_value);
863 <<
"Unable to clear depth buffer; removing.\n";
869 aux_flags |= D3DCLEAR_STENCIL;
870 HRESULT hr2 = _d3d_device->Clear(0,
nullptr, D3DCLEAR_STENCIL, color_clear_value,
871 stencil_clear_value, stencil_clear_value);
874 <<
"Unable to clear stencil buffer; removing.\n";
877 _supports_stencil =
false;
885 <<
"clear_buffer failed: Clear returned " << D3DERRORSTRING(hr);
895 nassertv(dr !=
nullptr);
902 D3DVIEWPORT9 vp = { (DWORD)l, (DWORD)u, (DWORD)w, (DWORD)h, 0.0f, 1.0f };
903 _current_viewport = vp;
904 HRESULT hr = _d3d_device->SetViewport(&_current_viewport);
907 <<
"_screen->_swap_chain = " << _screen->_swap_chain <<
" _swap_chain = " << _swap_chain <<
"\n";
909 <<
"SetViewport(" << l <<
", " << u <<
", " << w <<
", " << h
910 <<
") failed" << D3DERRORSTRING(hr);
913 _d3d_device->GetViewport(&vp_old);
915 <<
"GetViewport(" << vp_old.X <<
", " << vp_old.Y <<
", " << vp_old.Width <<
", "
916 << vp_old.Height <<
") returned: Trying to set that vp---->\n";
917 hr = _d3d_device->SetViewport(&vp_old);
921 dxgsg9_cat.error() <<
"Failed again\n";
922 throw_event(
"panda3d-render-error");
927 if (_screen->_can_direct_disable_color_writes) {
941 calc_projection_mat(
const Lens *lens) {
942 if (lens ==
nullptr) {
953 static const LMatrix4 rescale_mat
960 LMatrix4::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()) *
964 if (_scene_setup->get_inverted()) {
967 result *= LMatrix4::scale_mat(1.0f, -1.0f, 1.0f);
970 return TransformState::make_mat(result);
983 LMatrix4f mat = LCAST(
float, _projection_mat->get_mat());
985 _d3d_device->SetTransform(D3DTS_PROJECTION,
986 (D3DMATRIX*)mat.get_data());
987 return SUCCEEDED(hr);
1003 if (_d3d_device ==
nullptr) {
1005 <<
this <<
"::begin_frame(): no device.\n";
1009 HRESULT hr = _d3d_device->BeginScene();
1012 if (hr == D3DERR_DEVICELOST) {
1013 if (dxgsg9_cat.is_debug()) {
1015 <<
"BeginScene returns D3DERR_DEVICELOST" << endl;
1018 check_cooperative_level();
1022 <<
"BeginScene failed, unhandled error hr == "
1023 << D3DERRORSTRING(hr) << endl;
1024 throw_event(
"panda3d-render-error");
1029 if (_current_properties->get_srgb_color()) {
1089 if (_vertex_array_shader_context != 0) {
1091 _vertex_array_shader =
nullptr;
1092 _vertex_array_shader_context =
nullptr;
1094 if (_texture_binding_shader_context != 0) {
1096 _texture_binding_shader =
nullptr;
1097 _texture_binding_shader_context =
nullptr;
1099 if (_current_shader_context != 0) {
1100 _current_shader_context->
unbind(
this);
1101 _current_shader =
nullptr;
1102 _current_shader_context =
nullptr;
1136 HRESULT hr = _d3d_device->EndScene();
1139 if (hr == D3DERR_DEVICELOST) {
1140 if (dxgsg9_cat.is_debug()) {
1142 <<
"EndScene returns DeviceLost\n";
1144 check_cooperative_level();
1148 <<
"EndScene failed, unhandled error hr == " << D3DERRORSTRING(hr);
1149 throw_event(
"panda3d-render-error");
1154 #if defined(DO_PSTATS)
1155 if (_texmgrmem_total_pcollector.is_active()) {
1156 #define TICKS_PER_GETTEXINFO (2.5*1000)
1157 static DWORD last_tick_count = 0;
1158 DWORD cur_tick_count = GetTickCount();
1160 if (cur_tick_count - last_tick_count > TICKS_PER_GETTEXINFO) {
1161 last_tick_count = cur_tick_count;
1162 report_texmgr_stats();
1185 nassertr(_data_reader !=
nullptr,
false);
1220 const TransformTable *table = data_reader->get_transform_table();
1221 if (table !=
nullptr) {
1224 table->
get_transform(i)->mult_matrix(mat, _internal_transform->get_mat());
1225 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)mat.get_data();
1226 _d3d_device->SetTransform(D3DTS_WORLDMATRIX(i), d3d_mat);
1231 _transform_stale =
true;
1233 _vertex_blending_enabled =
true;
1237 if (_vertex_blending_enabled) {
1240 _vertex_blending_enabled =
false;
1243 if (_transform_stale && !_data_reader->is_vertex_transformed()) {
1244 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)_internal_transform->get_mat().get_data();
1245 _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
1246 _transform_stale =
false;
1250 if (_data_reader->is_vertex_transformed()) {
1258 _d3d_device->SetTransform(D3DTS_WORLD, &_d3d_ident_mat);
1259 static const LMatrix4f rescale_mat
1264 _transform_stale =
true;
1266 _d3d_device->SetTransform(D3DTS_PROJECTION, (
const D3DMATRIX *)rescale_mat.get_data());
1269 if (_current_shader_context == 0 ) {
1271 if (_vertex_array_shader_context != 0) {
1274 if (!update_standard_vertex_arrays(force)) {
1279 if (_vertex_array_shader_context == 0) {
1280 disable_standard_vertex_arrays();
1285 if (!_current_shader_context->
1286 update_shader_vertex_arrays(_vertex_array_shader_context,
this, force)) {
1292 _vertex_array_shader = _current_shader;
1293 _vertex_array_shader_context = _current_shader_context;
1304 bool DXGraphicsStateGuardian9::
1305 update_standard_vertex_arrays(
bool force) {
1310 int number_of_arrays = _data_reader->get_num_arrays();
1311 for (
int array_index = 0; array_index < number_of_arrays; ++array_index ) {
1313 if ( array_reader ==
nullptr ) {
1314 dxgsg9_cat.error() <<
"Unable to get reader for array " << array_index <<
"\n";
1321 dxgsg9_cat.error() <<
"Unable to setup vertex buffer for array " << array_index <<
"\n";
1327 hr = _d3d_device->SetStreamSource( array_index, dvbc->_vbuffer, 0, array_format->
get_stride() );
1329 dxgsg9_cat.error() <<
"SetStreamSource failed" << D3DERRORSTRING(hr);
1337 hr = _d3d_device->SetFVF( fvf );
1339 dxgsg9_cat.error() <<
"SetFVF failed" << D3DERRORSTRING(hr);
1352 void DXGraphicsStateGuardian9::
1353 disable_standard_vertex_arrays() {
1354 for (
int array_index = 0; array_index < _num_bound_streams; ++array_index )
1356 _d3d_device->SetStreamSource( array_index,
nullptr, 0, 0 );
1358 _num_bound_streams = 0;
1368 _vertices_tri_pcollector.add_level(reader->get_num_vertices());
1369 _primitive_batches_tri_pcollector.add_level(1);
1371 if (reader->is_indexed()) {
1372 int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
1373 int max_vertex = reader->get_max_vertex();
1377 nassertr(ibc !=
nullptr,
false);
1382 _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,
1384 min_vertex, max_vertex - min_vertex + 1,
1385 0, reader->get_num_primitives() );
1389 const unsigned char *index_pointer = reader->get_read_pointer(force);
1390 if (index_pointer ==
nullptr) {
1394 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1395 if (vertex_pointer ==
nullptr) {
1399 draw_indexed_primitive_up( D3DPT_TRIANGLELIST,
1400 min_vertex, max_vertex,
1401 reader->get_num_primitives(),
1402 index_pointer, index_type, vertex_pointer,
1403 _data_reader->get_format()->get_array(0)->get_stride() );
1407 _d3d_device->DrawPrimitive( D3DPT_TRIANGLELIST,
1408 reader->get_first_vertex(),
1409 reader->get_num_primitives() );
1413 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1414 if (vertex_pointer ==
nullptr) {
1418 draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(),
1419 reader->get_first_vertex(),
1420 reader->get_num_vertices(), vertex_pointer,
1421 _data_reader->get_format()->get_array(0)->get_stride());
1435 if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) {
1438 _vertices_tristrip_pcollector.add_level(reader->get_num_vertices());
1439 _primitive_batches_tristrip_pcollector.add_level(1);
1441 if (reader->is_indexed()) {
1442 int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
1443 int max_vertex = reader->get_max_vertex();
1447 nassertr(ibc !=
nullptr,
false);
1452 _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP,
1454 min_vertex, max_vertex - min_vertex + 1,
1455 0, reader->get_num_vertices() - 2 );
1459 const unsigned char *index_pointer = reader->get_read_pointer(force);
1460 if (index_pointer ==
nullptr) {
1464 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1465 if (vertex_pointer ==
nullptr) {
1469 draw_indexed_primitive_up
1470 (D3DPT_TRIANGLESTRIP,
1471 min_vertex, max_vertex,
1472 reader->get_num_vertices() - 2,
1473 index_pointer, index_type, vertex_pointer,
1474 _data_reader->get_format()->get_array(0)->get_stride());
1478 _d3d_device->DrawPrimitive( D3DPT_TRIANGLESTRIP,
1479 reader->get_first_vertex(),
1480 reader->get_num_vertices() - 2 );
1484 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1485 if (vertex_pointer ==
nullptr) {
1488 draw_primitive_up(D3DPT_TRIANGLESTRIP,
1489 reader->get_num_vertices() - 2,
1490 reader->get_first_vertex(),
1491 reader->get_num_vertices(), vertex_pointer,
1492 _data_reader->get_format()->get_array(0)->get_stride());
1499 CPTA_int ends = reader->get_ends();
1500 _primitive_batches_tristrip_pcollector.add_level(ends.size());
1502 if (reader->is_indexed()) {
1503 CPTA_int ends = reader->get_ends();
1504 int index_stride = reader->get_index_stride();
1505 _primitive_batches_tristrip_pcollector.add_level(ends.size());
1509 nassertr(reader->get_mins()->get_num_rows() == (
int)ends.size() &&
1510 reader->get_maxs()->get_num_rows() == (
int)ends.size(),
false);
1514 nassertr(ibc !=
nullptr,
false);
1519 unsigned int start = 0;
1520 for (
size_t i = 0; i < ends.size(); i++) {
1521 _vertices_tristrip_pcollector.add_level(ends[i] - start);
1524 _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP,
1527 start, ends[i] - start - 2 );
1528 start = ends[i] + 2;
1533 int stride = _data_reader->get_format()->get_array(0)->get_stride();
1534 const unsigned char *index_pointer = reader->get_read_pointer(force);
1535 if (index_pointer ==
nullptr) {
1539 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1540 if (vertex_pointer ==
nullptr) {
1544 unsigned int start = 0;
1545 for (
size_t i = 0; i < ends.size(); i++) {
1546 _vertices_tristrip_pcollector.add_level(ends[i] - start);
1549 draw_indexed_primitive_up
1550 (D3DPT_TRIANGLESTRIP,
1552 ends[i] - start - 2,
1553 index_pointer + start * index_stride, index_type,
1554 vertex_pointer, stride);
1556 start = ends[i] + 2;
1560 unsigned int first_vertex = reader->get_first_vertex();
1563 unsigned int start = 0;
1564 for (
size_t i = 0; i < ends.size(); i++) {
1565 _vertices_tristrip_pcollector.add_level(ends[i] - start);
1566 _d3d_device->DrawPrimitive( D3DPT_TRIANGLESTRIP,
1567 first_vertex + start,
1568 ends[i] - start - 2 );
1569 start = ends[i] + 2;
1574 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1575 if (vertex_pointer ==
nullptr) {
1578 int stride = _data_reader->get_format()->get_array(0)->get_stride();
1580 unsigned int start = 0;
1581 for (
size_t i = 0; i < ends.size(); i++) {
1582 _vertices_tristrip_pcollector.add_level(ends[i] - start);
1583 draw_primitive_up(D3DPT_TRIANGLESTRIP, ends[i] - start - 2,
1584 first_vertex + start,
1586 vertex_pointer, stride);
1588 start = ends[i] + 2;
1603 CPTA_int ends = reader->get_ends();
1604 _primitive_batches_trifan_pcollector.add_level(ends.size());
1606 if (reader->is_indexed()) {
1607 int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
1608 int max_vertex = reader->get_max_vertex();
1612 int index_stride = reader->get_index_stride();
1616 nassertr(reader->get_mins()->get_num_rows() == (
int)ends.size() &&
1617 reader->get_maxs()->get_num_rows() == (
int)ends.size(),
false);
1621 nassertr(ibc !=
nullptr,
false);
1626 unsigned int start = 0;
1627 for (
size_t i = 0; i < ends.size(); i++) {
1628 _vertices_trifan_pcollector.add_level(ends[i] - start);
1631 _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLEFAN,
1634 start, ends[i] - start - 2 );
1640 int stride = _data_reader->get_format()->get_array(0)->get_stride();
1641 const unsigned char *index_pointer = reader->get_read_pointer(force);
1642 if (index_pointer ==
nullptr) {
1646 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1647 if (vertex_pointer ==
nullptr) {
1651 unsigned int start = 0;
1652 for (
size_t i = 0; i < ends.size(); i++) {
1653 _vertices_trifan_pcollector.add_level(ends[i] - start);
1656 draw_indexed_primitive_up
1659 ends[i] - start - 2,
1660 index_pointer + start * index_stride, index_type,
1661 vertex_pointer, stride);
1667 unsigned int first_vertex = reader->get_first_vertex();
1670 unsigned int start = 0;
1671 for (
size_t i = 0; i < ends.size(); i++) {
1672 _vertices_trifan_pcollector.add_level(ends[i] - start);
1673 _d3d_device->DrawPrimitive( D3DPT_TRIANGLEFAN,
1674 first_vertex + start,
1675 ends[i] - start - 2 );
1681 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1682 if (vertex_pointer ==
nullptr) {
1685 int stride = _data_reader->get_format()->get_array(0)->get_stride();
1687 unsigned int start = 0;
1688 for (
size_t i = 0; i < ends.size(); i++) {
1689 _vertices_trifan_pcollector.add_level(ends[i] - start);
1690 draw_primitive_up(D3DPT_TRIANGLEFAN,
1691 ends[i] - start - 2,
1694 vertex_pointer, stride);
1709 _vertices_other_pcollector.add_level(reader->get_num_vertices());
1710 _primitive_batches_other_pcollector.add_level(1);
1712 if (reader->is_indexed()) {
1713 int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
1714 int max_vertex = reader->get_max_vertex();
1718 nassertr(ibc !=
nullptr,
false);
1723 _d3d_device->DrawIndexedPrimitive( D3DPT_LINELIST,
1725 min_vertex, max_vertex - min_vertex + 1,
1726 0, reader->get_num_primitives() );
1730 const unsigned char *index_pointer = reader->get_read_pointer(force);
1731 if (index_pointer ==
nullptr) {
1735 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1736 if (vertex_pointer ==
nullptr) {
1740 draw_indexed_primitive_up
1742 min_vertex, max_vertex,
1743 reader->get_num_primitives(),
1744 index_pointer, index_type, vertex_pointer,
1745 _data_reader->get_format()->get_array(0)->get_stride());
1749 _d3d_device->DrawPrimitive( D3DPT_LINELIST,
1750 reader->get_first_vertex(),
1751 reader->get_num_primitives() );
1755 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1756 if (vertex_pointer ==
nullptr) {
1759 draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(),
1760 reader->get_first_vertex(),
1761 reader->get_num_vertices(), vertex_pointer,
1762 _data_reader->get_format()->get_array(0)->get_stride());
1783 _vertices_other_pcollector.add_level(reader->get_num_vertices());
1784 _primitive_batches_other_pcollector.add_level(1);
1788 nassertr(!reader->is_indexed(),
false);
1791 _d3d_device->DrawPrimitive( D3DPT_POINTLIST,
1792 reader->get_first_vertex(),
1793 reader->get_num_primitives() );
1797 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1798 if (vertex_pointer ==
nullptr) {
1801 draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(),
1802 reader->get_first_vertex(),
1803 reader->get_num_vertices(), vertex_pointer,
1804 _data_reader->get_format()->get_array(0)->get_stride());
1817 if (_vertex_blending_enabled) {
1820 _vertex_blending_enabled =
false;
1823 if (_data_reader->is_vertex_transformed()) {
1825 LMatrix4f mat = LCAST(
float, _projection_mat->get_mat());
1826 _d3d_device->SetTransform(D3DTS_PROJECTION,
1827 (D3DMATRIX*)mat.get_data());
1842 set_read_buffer(rb);
1856 if (tc ==
nullptr) {
1863 <<
"Unable to re-create texture " << *dtc->
get_texture() << endl;
1874 IDirect3DSurface9 *tex_level_0;
1877 dxgsg9_cat.error() <<
"GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
1882 D3DSURFACE_DESC texdesc;
1883 hr = tex_level_0->GetDesc(&texdesc);
1885 dxgsg9_cat.error() <<
"GetDesc failed in copy_texture" << D3DERRORSTRING(hr);
1886 SAFE_RELEASE(tex_level_0);
1893 SAFE_RELEASE(tex_level_0);
1897 <<
"Unable to re-create texture " << *dtc->
get_texture() << endl;
1902 dxgsg9_cat.error() <<
"GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
1905 hr = tex_level_0->GetDesc(&texdesc);
1907 dxgsg9_cat.error() <<
"GetDesc 2 failed in copy_texture" << D3DERRORSTRING(hr);
1908 SAFE_RELEASE(tex_level_0);
1917 <<
"Unable to copy to texture, texture is wrong size: " << *dtc->
get_texture() << endl;
1918 SAFE_RELEASE(tex_level_0);
1923 DWORD render_target_index;
1924 IDirect3DSurface9 *render_target;
1927 render_target_index = 0;
1929 hr = _d3d_device->GetRenderTarget(render_target_index, &render_target);
1932 <<
"GetRenderTarget failed in framebuffer_copy_to_texture"
1933 << D3DERRORSTRING(hr);
1934 SAFE_RELEASE(tex_level_0);
1941 src_rect.right = xo+w;
1943 src_rect.bottom = yo+h;
1949 D3DTEXTUREFILTERTYPE filter;
1951 filter = D3DTEXF_POINT;
1954 hr = _d3d_device->StretchRect(render_target, &src_rect,
1955 tex_level_0, &src_rect,
1959 <<
"StretchRect failed in framebuffer_copy_to_texture"
1960 << D3DERRORSTRING(hr);
1964 SAFE_RELEASE(render_target);
1965 SAFE_RELEASE(tex_level_0);
1969 dtc->
enqueue_lru(&_prepared_objects->_graphics_memory_lru);
2003 set_read_buffer(rb);
2006 nassertr(tex !=
nullptr && dr !=
nullptr,
false);
2015 case Texture::F_depth_stencil:
2020 format = Texture::F_rgb;
2021 component_type = Texture::T_unsigned_byte;
2024 Texture::TextureType texture_type;
2026 texture_type = Texture::TT_cube_map;
2028 texture_type = Texture::TT_2d_texture;
2037 component_type, format);
2042 rect.right = xo + w;
2043 rect.bottom = yo + h;
2044 bool copy_inverted =
false;
2046 IDirect3DSurface9 *temp_surface =
nullptr;
2052 if (_cur_read_pixel_buffer & RenderBuffer::T_back) {
2053 DWORD render_target_index;
2054 IDirect3DSurface9 *backbuffer =
nullptr;
2058 render_target_index = 0;
2059 hr = _d3d_device->GetRenderTarget(render_target_index, &backbuffer);
2062 dxgsg9_cat.error() <<
"GetRenderTarget failed" << D3DERRORSTRING(hr);
2069 D3DSURFACE_DESC surface_description;
2071 backbuffer -> GetDesc (&surface_description);
2073 pool = D3DPOOL_SYSTEMMEM;
2074 hr = _d3d_device->CreateOffscreenPlainSurface(
2075 surface_description.Width,
2076 surface_description.Height,
2077 surface_description.Format,
2083 <<
"CreateImageSurface failed in copy_pixel_buffer()"
2084 << D3DERRORSTRING(hr);
2085 backbuffer->Release();
2090 hr = _d3d_device -> GetRenderTargetData (backbuffer, temp_surface);
2092 dxgsg9_cat.error() <<
"GetRenderTargetData failed" << D3DERRORSTRING(hr);
2093 temp_surface->Release();
2094 backbuffer->Release();
2098 copy_inverted =
true;
2100 RELEASE(backbuffer, dxgsg9,
"backbuffer", RELEASE_ONCE);
2102 }
else if (_cur_read_pixel_buffer & RenderBuffer::T_front) {
2104 if (_screen->_presentation_params.Windowed) {
2111 minfo.cbSize =
sizeof(MONITORINFO);
2112 GetMonitorInfo(_screen->_monitor, &minfo);
2114 w = RECT_XSIZE(minfo.rcMonitor);
2115 h = RECT_YSIZE(minfo.rcMonitor);
2118 ClientToScreen(_screen->_window, (POINT*)&rect.left);
2119 ClientToScreen(_screen->_window, (POINT*)&rect.right);
2124 hr = _d3d_device->CreateOffscreenPlainSurface(w, h, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &temp_surface,
nullptr);
2127 <<
"CreateImageSurface failed in copy_pixel_buffer()"
2128 << D3DERRORSTRING(hr);
2135 hr = _d3d_device->GetFrontBufferData(swap_chain,temp_surface);
2137 if (hr == D3DERR_DEVICELOST) {
2139 <<
"copy_pixel_buffer failed: device lost\n";
2140 temp_surface->Release();
2144 copy_inverted =
true;
2148 <<
"copy_pixel_buffer: unhandled current_read_pixel_buffer type\n";
2149 temp_surface->Release();
2154 copy_inverted = !copy_inverted;
2157 copy_inverted, tex, view, z);
2159 RELEASE(temp_surface, dxgsg9,
"temp_surface", RELEASE_ONCE);
2165 void DXGraphicsStateGuardian9::reset_render_states (
void)
2168 int maximum_texture_stages;
2170 maximum_texture_stages = D3D_MAXTEXTURESTAGES;
2173 memset (_render_state_array, -1,
sizeof (_render_state_array));
2174 memset (_texture_stage_states_array, -1,
sizeof (_texture_stage_states_array));
2178 _render_state_array [D3DRS_FOGCOLOR] = 0;
2179 _render_state_array [D3DRS_AMBIENT] = 0;
2183 memset (_texture_render_states_array, 0,
sizeof (_texture_render_states_array));
2187 for (index = 0; index < MAXIMUM_TEXTURES; index++) {
2188 TextureRenderStates *texture_render_states;
2190 texture_render_states = &_texture_render_states_array [index];
2191 texture_render_states -> state_array [D3DSAMP_MAGFILTER] = D3DTEXF_POINT;
2192 texture_render_states -> state_array [D3DSAMP_MINFILTER] = D3DTEXF_POINT;
2193 texture_render_states -> state_array [D3DSAMP_MAXANISOTROPY] = 1;
2195 _num_active_texture_stages = 0;
2214 _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot());
2215 _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot());
2216 _inv_state_mask.clear_bit(ClipPlaneAttrib::get_class_slot());
2217 _inv_state_mask.clear_bit(ColorAttrib::get_class_slot());
2218 _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot());
2219 _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot());
2220 _inv_state_mask.clear_bit(DepthOffsetAttrib::get_class_slot());
2221 _inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot());
2222 _inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
2223 _inv_state_mask.clear_bit(RenderModeAttrib::get_class_slot());
2224 _inv_state_mask.clear_bit(RescaleNormalAttrib::get_class_slot());
2225 _inv_state_mask.clear_bit(ShadeModelAttrib::get_class_slot());
2226 _inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
2227 _inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
2228 _inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot());
2229 _inv_state_mask.clear_bit(TextureAttrib::get_class_slot());
2230 _inv_state_mask.clear_bit(TexGenAttrib::get_class_slot());
2231 _inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
2232 _inv_state_mask.clear_bit(MaterialAttrib::get_class_slot());
2233 _inv_state_mask.clear_bit(LightAttrib::get_class_slot());
2234 _inv_state_mask.clear_bit(StencilAttrib::get_class_slot());
2235 _inv_state_mask.clear_bit(FogAttrib::get_class_slot());
2236 _inv_state_mask.clear_bit(ScissorAttrib::get_class_slot());
2241 _supported_geom_rendering =
2242 Geom::GR_point | Geom::GR_point_uniform_size |
2243 Geom::GR_point_perspective | Geom::GR_point_sprite |
2244 Geom::GR_indexed_other |
2245 Geom::GR_triangle_strip | Geom::GR_triangle_fan |
2246 Geom::GR_flat_first_vertex |
2247 Geom::GR_render_mode_wireframe | Geom::GR_render_mode_point;
2258 nassertv(_screen->_d3d9 !=
nullptr);
2260 if (_d3d_device ==
nullptr) {
2265 _d3d_device->GetDeviceCaps(&d3d_caps);
2267 _vertex_shader_version_major = D3DSHADER_VERSION_MAJOR (d3d_caps.VertexShaderVersion);
2268 _vertex_shader_version_minor = D3DSHADER_VERSION_MINOR (d3d_caps.VertexShaderVersion);
2269 _pixel_shader_version_major = D3DSHADER_VERSION_MAJOR (d3d_caps.PixelShaderVersion);
2270 _pixel_shader_version_minor = D3DSHADER_VERSION_MINOR (d3d_caps.PixelShaderVersion);
2272 _supports_hlsl = (_pixel_shader_version_major != 0);
2274 _vertex_shader_profile = (
char *) D3DXGetVertexShaderProfile (_d3d_device);
2275 _pixel_shader_profile = (
char *) D3DXGetPixelShaderProfile (_d3d_device);
2277 _vertex_shader_maximum_constants = d3d_caps.MaxVertexShaderConst;
2279 switch (_pixel_shader_version_major)
2282 _shader_model = SM_00;
2285 _shader_model = SM_11;
2289 _shader_model = SM_20;
2290 if (d3d_caps.PS20Caps.NumInstructionSlots >= 512) {
2291 _shader_model = SM_2X;
2295 _shader_model = SM_30;
2298 _shader_model = SM_40;
2302 _shader_model = SM_50;
2306 _auto_detect_shader_model = _shader_model;
2311 _cg_context = cgCreateContext();
2313 if (cgD3D9IsProfileSupported(CG_PROFILE_PS_2_0) &&
2314 cgD3D9IsProfileSupported(CG_PROFILE_VS_2_0)) {
2315 _supports_basic_shaders =
true;
2316 _shader_caps._active_vprofile = (int)cgD3D9GetLatestVertexProfile();
2317 _shader_caps._active_fprofile = (int)cgD3D9GetLatestPixelProfile();
2318 _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VS_3_0;
2319 _shader_caps._ultimate_fprofile = (int)CG_PROFILE_PS_3_0;
2328 if (dxgsg9_cat.is_debug()) {
2329 CGprofile vertex_profile;
2330 CGprofile pixel_profile;
2332 vertex_profile = cgD3D9GetLatestVertexProfile();
2333 pixel_profile = cgD3D9GetLatestPixelProfile();
2335 const char *vertex_profile_str =
2336 cgGetProfileString(vertex_profile);
2337 const char *pixel_profile_str =
2338 cgGetProfileString(pixel_profile);
2340 if (vertex_profile_str ==
nullptr) {
2341 vertex_profile_str =
"(null)";
2343 if (pixel_profile_str ==
nullptr) {
2344 pixel_profile_str =
"(null)";
2348 <<
"\nCg latest vertex profile = " << vertex_profile_str <<
" id = " << vertex_profile
2349 <<
"\nCg latest pixel profile = " << pixel_profile_str <<
" id = " << pixel_profile
2350 <<
"\nshader model = " << _shader_model
2355 _supports_stream_offset = (d3d_caps.DevCaps2 & D3DDEVCAPS2_STREAMOFFSET) != 0;
2356 _screen->_supports_dynamic_textures = ((d3d_caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) != 0);
2357 _screen->_supports_automatic_mipmap_generation = ((d3d_caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0);
2359 if (support_stencil) {
2360 int min_stencil = D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR;
2361 if ((d3d_caps.StencilCaps & min_stencil) == min_stencil) {
2362 if (dxgsg9_cat.is_debug()) {
2364 <<
"Checking for stencil; mode = "
2365 << D3DFormatStr(_screen->_presentation_params.AutoDepthStencilFormat)
2368 switch (_screen->_presentation_params.AutoDepthStencilFormat) {
2372 case D3DFMT_D24X4S4:
2373 _supports_stencil =
true;
2374 if (dxgsg9_cat.is_debug()) {
2376 <<
"Stencils supported.\n";
2381 if (dxgsg9_cat.is_debug()) {
2383 <<
"Stencils NOT supported.\n";
2389 _supports_stencil_wrap = (d3d_caps.StencilCaps & D3DSTENCILCAPS_INCR) && (d3d_caps.StencilCaps & D3DSTENCILCAPS_DECR);
2390 _supports_two_sided_stencil = ((d3d_caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) != 0);
2392 _max_color_targets = d3d_caps.NumSimultaneousRTs;
2394 _supports_depth_bias = ((d3d_caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) == (D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS));
2396 _supports_gamma_calibration = ((d3d_caps.Caps2 & D3DCAPS2_CANCALIBRATEGAMMA) != 0);
2399 hr = _d3d_device->CreateQuery(D3DQUERYTYPE_OCCLUSION,
nullptr);
2400 _supports_occlusion_query = !FAILED(hr);
2402 if (dxgsg9_cat.is_error()) {
2404 <<
"\nHwTransformAndLight = " << ((d3d_caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
2405 <<
"\nMaxTextureWidth = " << d3d_caps.MaxTextureWidth
2406 <<
"\nMaxTextureHeight = " << d3d_caps.MaxTextureHeight
2407 <<
"\nMaxVolumeExtent = " << d3d_caps.MaxVolumeExtent
2408 <<
"\nMaxTextureAspectRatio = " << d3d_caps.MaxTextureAspectRatio
2409 <<
"\nTexCoordCount = " << (d3d_caps.FVFCaps & D3DFVFCAPS_TEXCOORDCOUNTMASK)
2410 <<
"\nMaxTextureBlendStages = " << d3d_caps.MaxTextureBlendStages
2411 <<
"\nMaxSimultaneousTextures = " << d3d_caps.MaxSimultaneousTextures
2412 <<
"\nMaxActiveLights = " << d3d_caps.MaxActiveLights
2413 <<
"\nMaxUserClipPlanes = " << d3d_caps.MaxUserClipPlanes
2414 <<
"\nMaxVertexBlendMatrices = " << d3d_caps.MaxVertexBlendMatrices
2415 <<
"\nMaxVertexBlendMatrixIndex = " << d3d_caps.MaxVertexBlendMatrixIndex
2416 <<
"\nMaxPointSize = " << d3d_caps.MaxPointSize
2417 <<
"\nMaxPrimitiveCount = " << d3d_caps.MaxPrimitiveCount
2418 <<
"\nMaxVertexIndex = " << d3d_caps.MaxVertexIndex
2419 <<
"\nMaxStreams = " << d3d_caps.MaxStreams
2420 <<
"\nMaxStreamStride = " << d3d_caps.MaxStreamStride
2421 <<
"\nD3DTEXOPCAPS_MULTIPLYADD = " << ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_MULTIPLYADD) != 0)
2422 <<
"\nD3DTEXOPCAPS_LERP = " << ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_LERP) != 0)
2423 <<
"\nD3DPMISCCAPS_TSSARGTEMP = " << ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) != 0)
2424 <<
"\nD3DPRASTERCAPS_DEPTHBIAS = " << ((d3d_caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS) != 0)
2425 <<
"\nD3DPRASTERCAPS_SLOPESCALEDEPTHBIAS = " << ((d3d_caps.RasterCaps & D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS) != 0)
2426 <<
"\nVertexShaderVersion = " << _vertex_shader_version_major <<
"." << _vertex_shader_version_minor
2427 <<
"\nPixelShaderVersion = " << _pixel_shader_version_major <<
"." << _pixel_shader_version_minor
2428 <<
"\nMaxVertexShaderConst = " << _vertex_shader_maximum_constants
2429 <<
"\nsupports_stream_offset = " << _supports_stream_offset
2430 <<
"\nsupports_dynamic_textures = " << _screen->_supports_dynamic_textures
2431 <<
"\nsupports_automatic_mipmap_generation = " << _screen->_supports_automatic_mipmap_generation
2432 <<
"\nsupports_stencil_wrap = " << _supports_stencil_wrap
2433 <<
"\nsupports_two_sided_stencil = " << _supports_two_sided_stencil
2434 <<
"\nsupports_occlusion_query = " << _supports_occlusion_query
2435 <<
"\nsupports_gamma_calibration = " << _supports_gamma_calibration
2436 <<
"\nMaxAnisotropy = " << d3d_caps.MaxAnisotropy
2437 <<
"\nNumSimultaneousRTs = " << d3d_caps.NumSimultaneousRTs
2438 <<
"\nD3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING = " << ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) != 0)
2439 <<
"\nDirectX SDK version " DIRECTX_SDK_VERSION
2444 _screen->_supports_automatic_mipmap_generation =
false;
2446 reset_render_states();
2448 _max_vertices_per_array = d3d_caps.MaxVertexIndex;
2449 _max_vertices_per_primitive = d3d_caps.MaxPrimitiveCount;
2451 _max_texture_stages = d3d_caps.MaxSimultaneousTextures;
2453 _max_texture_dimension = min(d3d_caps.MaxTextureWidth, d3d_caps.MaxTextureHeight);
2455 _supports_tex_non_pow2 = !(d3d_caps.TextureCaps & D3DPTEXTURECAPS_POW2);
2457 _supports_texture_combine = ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_LERP) != 0);
2458 _supports_texture_saved_result = ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) != 0);
2459 _supports_texture_constant_color = ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT) != 0);
2460 _supports_texture_dot3 =
true;
2462 if (_supports_texture_constant_color) {
2463 _constant_color_operand = D3DTA_CONSTANT;
2465 _constant_color_operand = D3DTA_TFACTOR;
2468 _screen->_managed_textures = _gsg_managed_textures;
2469 _screen->_managed_vertex_buffers = _gsg_managed_vertex_buffers;
2470 _screen->_managed_index_buffers = _gsg_managed_index_buffers;
2472 UINT available_texture_memory;
2474 available_texture_memory = _d3d_device->GetAvailableTextureMem ( );
2475 if (dxgsg9_cat.is_debug()) {
2476 dxgsg9_cat.debug() <<
"*** GetAvailableTextureMem = " << available_texture_memory <<
"\n";
2478 _available_texture_memory = available_texture_memory;
2481 D3DDEVICE_CREATION_PARAMETERS creation_parameters;
2483 _supports_render_texture =
false;
2484 _screen->_render_to_texture_d3d_format = D3DFMT_UNKNOWN;
2485 _screen->_framebuffer_d3d_format = D3DFMT_UNKNOWN;
2487 #define TOTAL_RENDER_TO_TEXTURE_FORMATS 3
2489 D3DFORMAT render_to_texture_formats [TOTAL_RENDER_TO_TEXTURE_FORMATS] =
2496 render_to_texture_formats [TOTAL_RENDER_TO_TEXTURE_FORMATS - 1] = _screen->_display_mode.Format;
2498 hr = _d3d_device->GetCreationParameters (&creation_parameters);
2499 if (SUCCEEDED (hr)) {
2500 _screen->_framebuffer_d3d_format = _screen->_display_mode.Format;
2503 for (index = 0; index < TOTAL_RENDER_TO_TEXTURE_FORMATS; index++) {
2504 hr = _screen->_d3d9->CheckDeviceFormat (
2505 creation_parameters.AdapterOrdinal,
2506 creation_parameters.DeviceType,
2507 _screen->_display_mode.Format,
2508 D3DUSAGE_RENDERTARGET,
2510 render_to_texture_formats [index]);
2511 if (SUCCEEDED (hr)) {
2512 _screen->_render_to_texture_d3d_format = render_to_texture_formats [index];
2513 _supports_render_texture =
true;
2515 if (_supports_render_texture) {
2520 if (dxgsg9_cat.is_debug()) {
2521 dxgsg9_cat.debug() <<
"Render to Texture Support = " << _supports_render_texture <<
"\n";
2527 _supports_3d_texture = ((d3d_caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) != 0);
2528 if (_supports_3d_texture) {
2529 _max_3d_texture_dimension = d3d_caps.MaxVolumeExtent;
2531 _supports_cube_map = ((d3d_caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) != 0);
2532 if (_supports_cube_map) {
2533 _max_cube_map_dimension = _max_texture_dimension;
2536 _max_lights = (int)d3d_caps.MaxActiveLights;
2537 _max_clip_planes = (
int)d3d_caps.MaxUserClipPlanes;
2538 _max_vertex_transforms = d3d_caps.MaxVertexBlendMatrices;
2539 _max_vertex_transform_indices = d3d_caps.MaxVertexBlendMatrixIndex;
2543 _clip_plane_bits = 0;
2561 _has_scene_graph_color =
false;
2563 _last_testcooplevel_result = D3D_OK;
2565 if (dxgsg9_cat.is_debug()) {
2566 dxgsg9_cat.debug() <<
"Supported texture formats:\n";
2569 for(
int i = 0; i < MAX_POSSIBLE_TEXFMTS; i++) {
2571 D3DFORMAT_FLAG fmtflag = D3DFORMAT_FLAG(1 << i);
2572 hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format,
2573 0x0, D3DRTYPE_TEXTURE, g_D3DFORMATmap[fmtflag]);
2574 if (SUCCEEDED(hr)) {
2575 if (dxgsg9_cat.is_debug()) {
2576 dxgsg9_cat.debug() <<
" " << D3DFormatStr(g_D3DFORMATmap[fmtflag]) <<
"\n";
2578 _screen->_supported_tex_formats_mask |= fmtflag;
2582 _supports_depth_stencil = ((_screen->_supported_tex_formats_mask & D24S8_FLAG) != 0);
2583 _supports_depth_texture = _supports_depth_stencil ||
2584 (_screen->_supported_tex_formats_mask & D16_FLAG) != 0 ||
2585 (_screen->_supported_tex_formats_mask & D32_FLAG) != 0 ||
2586 (_screen->_supported_tex_formats_mask & D24X8_FLAG) != 0;
2592 _supports_shadow_filter = _supports_depth_texture;
2595 #define CHECK_COMPRESSED_FMT(mode, fmt) \
2596 if (_screen->_supported_tex_formats_mask & fmt##_FLAG) {\
2597 if (dxgsg9_cat.is_debug()) {\
2598 dxgsg9_cat.debug() << "Compressed texture format " << #fmt << " supported\n";\
2600 _supports_compressed_texture = true;\
2601 _compressed_texture_formats.set_bit(Texture::mode);\
2604 if (_screen->_intel_compressed_texture_bug) {
2606 <<
"Buggy Intel driver detected; disabling compressed textures.\n";
2607 _screen->_supported_tex_formats_mask &=
2608 ~(DXT1_FLAG | DXT2_FLAG | DXT3_FLAG | DXT4_FLAG | DXT5_FLAG);
2612 CHECK_COMPRESSED_FMT(CM_dxt1, DXT1);
2613 CHECK_COMPRESSED_FMT(CM_dxt2, DXT2);
2614 CHECK_COMPRESSED_FMT(CM_dxt3, DXT3);
2615 CHECK_COMPRESSED_FMT(CM_dxt4, DXT4);
2616 CHECK_COMPRESSED_FMT(CM_dxt5, DXT5);
2617 CHECK_COMPRESSED_FMT(CM_rgtc, ATI1);
2618 CHECK_COMPRESSED_FMT(CM_rgtc, ATI2);
2621 #undef CHECK_COMPRESSED_FMT
2623 _screen->_supports_rgba16f_texture_format =
false;
2624 hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format, 0x0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F);
2626 _screen->_supports_rgba16f_texture_format =
true;
2628 _screen->_supports_rgba32_texture_format =
false;
2629 hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format, 0x0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F);
2631 _screen->_supports_rgba32_texture_format =
true;
2635 if (_screen->_d3dcaps.MaxTextureWidth == 0)
2636 _screen->_d3dcaps.MaxTextureWidth = 256;
2638 if (_screen->_d3dcaps.MaxTextureHeight == 0)
2639 _screen->_d3dcaps.MaxTextureHeight = 256;
2641 if (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) {
2645 _do_fog_type = PerPixelFog;
2649 nassertv((_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGVERTEX) != 0);
2654 if (dx_no_vertex_fog) {
2655 _do_fog_type = None;
2657 _do_fog_type = PerVertexFog;
2660 if (dx_use_rangebased_fog && (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGRANGE)) {
2666 _screen->_can_direct_disable_color_writes = ((_screen->_d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0);
2672 bool dither_enabled = ((!dx_no_dithering) && IS_16BPP_DISPLAY_FORMAT(_screen->_presentation_params.BackBufferFormat)
2673 && (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_DITHER));
2680 if (_supports_two_sided_stencil) {
2688 _current_fill_mode = RenderModeAttrib::M_filled;
2695 _cull_face_mode = CullFaceAttrib::M_cull_none;
2708 _current_shader =
nullptr;
2709 _current_shader_context =
nullptr;
2710 _vertex_array_shader =
nullptr;
2711 _vertex_array_shader_context =
nullptr;
2712 _texture_binding_shader =
nullptr;
2713 _texture_binding_shader_context =
nullptr;
2715 PRINT_REFCNT(dxgsg9, _d3d_device);
2725 void DXGraphicsStateGuardian9::
2726 apply_fog(
Fog *fog) {
2727 if (_do_fog_type == None)
2730 Fog::Mode panda_fogmode = fog->get_mode();
2731 D3DFOGMODE d3dfogmode = get_fog_mode_type(panda_fogmode);
2735 const LColor &fog_colr = fog->
get_color();
2737 MY_D3DRGBA(fog_colr[0], fog_colr[1], fog_colr[2], 0.0f));
2743 switch (panda_fogmode) {
2746 PN_stdfloat onset, opaque;
2750 *((LPDWORD) (&onset)));
2752 *((LPDWORD) (&opaque)));
2755 case Fog::M_exponential:
2756 case Fog::M_exponential_squared:
2761 *((LPDWORD) (&fog_density)));
2774 void DXGraphicsStateGuardian9::
2775 do_issue_transform() {
2777 DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
2779 if (_current_shader_context) {
2785 LMatrix4f mat = LCAST(
float, transform->
get_mat());
2786 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)mat.get_data();
2787 _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
2791 LMatrix4f mat = LCAST(
float, transform->
get_mat());
2792 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)mat.get_data();
2793 _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
2808 _transform_stale =
false;
2814 void DXGraphicsStateGuardian9::
2815 do_issue_alpha_test() {
2816 if (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) {
2820 AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->
get_mode();
2821 if (mode == AlphaTestAttrib::M_none) {
2835 void DXGraphicsStateGuardian9::
2840 if (_target_shader) {
2841 shader = (
Shader *)(_target_shader->get_shader());
2847 if (context == 0 || (context && context -> valid (
this) ==
false)) {
2848 if (_current_shader_context != 0) {
2849 _current_shader_context->
unbind(
this);
2850 _current_shader = 0;
2851 _current_shader_context = 0;
2852 disable_standard_texture_bindings();
2857 if (context != _current_shader_context) {
2860 if (_current_shader_context != 0) {
2861 _current_shader_context->
unbind(
this);
2862 _current_shader_context = 0;
2863 _current_shader = 0;
2864 disable_standard_texture_bindings();
2867 context->
bind(
this);
2868 _current_shader = shader;
2869 _current_shader_context = context;
2880 void DXGraphicsStateGuardian9::
2881 do_issue_render_mode() {
2883 _target_rs->get_attrib_def(target_render_mode);
2884 RenderModeAttrib::Mode mode = target_render_mode->
get_mode();
2887 case RenderModeAttrib::M_unchanged:
2888 case RenderModeAttrib::M_filled:
2889 case RenderModeAttrib::M_filled_flat:
2893 case RenderModeAttrib::M_wireframe:
2897 case RenderModeAttrib::M_point:
2903 <<
"Unknown render mode " << (int)mode << endl;
2907 PN_stdfloat point_size = target_render_mode->
get_thickness();
2913 LVector3 height(0.0f, point_size, 1.0f);
2914 height = height * _projection_mat->get_mat();
2915 PN_stdfloat s = height[1] / point_size;
2917 PN_stdfloat zero = 0.0f;
2918 PN_stdfloat one_over_s2 = 1.0f / (s * s);
2927 _current_fill_mode = mode;
2933 void DXGraphicsStateGuardian9::
2934 do_issue_rescale_normal() {
2935 RescaleNormalAttrib::Mode mode = RescaleNormalAttrib::M_none;
2938 if (_target_rs->get_attrib(target_rescale_normal)) {
2939 mode = target_rescale_normal->
get_mode();
2943 case RescaleNormalAttrib::M_none:
2947 case RescaleNormalAttrib::M_rescale:
2948 case RescaleNormalAttrib::M_normalize:
2954 <<
"Unknown rescale_normal mode " << (int)mode << endl;
2961 void DXGraphicsStateGuardian9::
2962 do_issue_depth_test() {
2964 DepthTestAttrib::PandaCompareFunc mode = target_depth_test->
get_mode();
2965 if (mode == DepthTestAttrib::M_none) {
2976 void DXGraphicsStateGuardian9::
2977 do_issue_depth_write() {
2979 DepthWriteAttrib::Mode mode = target_depth_write->
get_mode();
2980 if (mode == DepthWriteAttrib::M_on) {
2990 void DXGraphicsStateGuardian9::
2991 do_issue_cull_face() {
2995 switch (_cull_face_mode) {
2996 case CullFaceAttrib::M_cull_none:
3002 case CullFaceAttrib::M_cull_clockwise:
3008 case CullFaceAttrib::M_cull_counter_clockwise:
3016 <<
"invalid cull face mode " << (int)_cull_face_mode << endl;
3024 void DXGraphicsStateGuardian9::
3026 const FogAttrib *target_fog = DCAST(
FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot()));
3027 if (!target_fog->
is_off()) {
3030 nassertv(fog !=
nullptr);
3040 void DXGraphicsStateGuardian9::
3041 do_issue_depth_offset() {
3043 int offset = target_depth_offset->
get_offset();
3045 if (_supports_depth_bias && !dx_broken_depth_bias) {
3052 static const PN_stdfloat bias_scale = dx_depth_bias_scale;
3053 D3DVIEWPORT9 vp = _current_viewport;
3054 vp.MinZ -= bias_scale * offset;
3055 vp.MaxZ -= bias_scale * offset;
3056 _d3d_device->SetViewport(&vp);
3063 void DXGraphicsStateGuardian9::
3064 do_issue_shade_model() {
3066 switch (target_shade_model->
get_mode()) {
3067 case ShadeModelAttrib::M_smooth:
3071 case ShadeModelAttrib::M_flat:
3093 if (gsg_cat.is_spam()) {
3094 gsg_cat.spam() <<
"Setting GSG state to " << (
void *)target <<
":\n";
3095 target->write(gsg_cat.spam(
false), 2);
3098 _state_pcollector.add_level(1);
3099 PStatTimer timer1(_draw_set_state_pcollector);
3101 if (transform != _internal_transform) {
3103 _state_pcollector.add_level(1);
3104 _internal_transform = transform;
3105 do_issue_transform();
3108 if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) {
3111 _target_rs = target;
3113 determine_target_shader();
3115 int alpha_test_slot = AlphaTestAttrib::get_class_slot();
3116 if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) ||
3117 !_state_mask.get_bit(alpha_test_slot)) {
3119 do_issue_alpha_test();
3120 _state_mask.set_bit(alpha_test_slot);
3123 int clip_plane_slot = ClipPlaneAttrib::get_class_slot();
3124 if (_target_rs->get_attrib(clip_plane_slot) != _state_rs->get_attrib(clip_plane_slot) ||
3125 !_state_mask.get_bit(clip_plane_slot)) {
3127 do_issue_clip_plane();
3128 _state_mask.set_bit(clip_plane_slot);
3131 int color_slot = ColorAttrib::get_class_slot();
3132 int color_scale_slot = ColorScaleAttrib::get_class_slot();
3133 if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) ||
3134 _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) ||
3135 !_state_mask.get_bit(color_slot) ||
3136 !_state_mask.get_bit(color_scale_slot)) {
3139 do_issue_color_scale();
3140 _state_mask.set_bit(color_slot);
3141 _state_mask.set_bit(color_scale_slot);
3142 if (_current_shader_context) {
3148 int cull_face_slot = CullFaceAttrib::get_class_slot();
3149 if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) ||
3150 !_state_mask.get_bit(cull_face_slot)) {
3152 do_issue_cull_face();
3153 _state_mask.set_bit(cull_face_slot);
3156 int depth_offset_slot = DepthOffsetAttrib::get_class_slot();
3157 if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) ||
3158 !_state_mask.get_bit(depth_offset_slot)) {
3160 do_issue_depth_offset();
3161 _state_mask.set_bit(depth_offset_slot);
3164 int depth_test_slot = DepthTestAttrib::get_class_slot();
3165 if (_target_rs->get_attrib(depth_test_slot) != _state_rs->get_attrib(depth_test_slot) ||
3166 !_state_mask.get_bit(depth_test_slot)) {
3168 do_issue_depth_test();
3169 _state_mask.set_bit(depth_test_slot);
3172 int depth_write_slot = DepthWriteAttrib::get_class_slot();
3173 if (_target_rs->get_attrib(depth_write_slot) != _state_rs->get_attrib(depth_write_slot) ||
3174 !_state_mask.get_bit(depth_write_slot)) {
3176 do_issue_depth_write();
3177 _state_mask.set_bit(depth_write_slot);
3180 int render_mode_slot = RenderModeAttrib::get_class_slot();
3181 if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) ||
3182 !_state_mask.get_bit(render_mode_slot)) {
3184 do_issue_render_mode();
3185 _state_mask.set_bit(render_mode_slot);
3188 int rescale_normal_slot = RescaleNormalAttrib::get_class_slot();
3189 if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) ||
3190 !_state_mask.get_bit(rescale_normal_slot)) {
3192 do_issue_rescale_normal();
3193 _state_mask.set_bit(rescale_normal_slot);
3196 int shade_model_slot = ShadeModelAttrib::get_class_slot();
3197 if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) ||
3198 !_state_mask.get_bit(shade_model_slot)) {
3200 do_issue_shade_model();
3201 _state_mask.set_bit(shade_model_slot);
3204 int transparency_slot = TransparencyAttrib::get_class_slot();
3205 int color_write_slot = ColorWriteAttrib::get_class_slot();
3206 int color_blend_slot = ColorBlendAttrib::get_class_slot();
3207 if (_target_rs->get_attrib(transparency_slot) != _state_rs->get_attrib(transparency_slot) ||
3208 _target_rs->get_attrib(color_write_slot) != _state_rs->get_attrib(color_write_slot) ||
3209 _target_rs->get_attrib(color_blend_slot) != _state_rs->get_attrib(color_blend_slot) ||
3210 !_state_mask.get_bit(transparency_slot) ||
3211 !_state_mask.get_bit(color_write_slot) ||
3212 !_state_mask.get_bit(color_blend_slot) ||
3213 (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) !=
3214 _state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))) {
3216 do_issue_blending();
3217 _state_mask.set_bit(transparency_slot);
3218 _state_mask.set_bit(color_write_slot);
3219 _state_mask.set_bit(color_blend_slot);
3222 if (_target_shader != _state_shader) {
3225 _state_shader = _target_shader;
3226 _state_mask.clear_bit(TextureAttrib::get_class_slot());
3229 int texture_slot = TextureAttrib::get_class_slot();
3230 int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
3231 int tex_gen_slot = TexGenAttrib::get_class_slot();
3232 if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) ||
3233 _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
3234 _target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) ||
3235 !_state_mask.get_bit(texture_slot) ||
3236 !_state_mask.get_bit(tex_matrix_slot) ||
3237 !_state_mask.get_bit(tex_gen_slot)) {
3239 determine_target_texture();
3242 _state_texture = _target_texture;
3243 _state_mask.set_bit(texture_slot);
3244 _state_mask.set_bit(tex_matrix_slot);
3245 _state_mask.set_bit(tex_gen_slot);
3248 int material_slot = MaterialAttrib::get_class_slot();
3249 if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) ||
3250 !_state_mask.get_bit(material_slot)) {
3252 do_issue_material();
3253 _state_mask.set_bit(material_slot);
3254 if (_current_shader_context) {
3259 int light_slot = LightAttrib::get_class_slot();
3260 if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) ||
3261 !_state_mask.get_bit(light_slot)) {
3264 _state_mask.set_bit(light_slot);
3267 int stencil_slot = StencilAttrib::get_class_slot();
3268 if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) ||
3269 !_state_mask.get_bit(stencil_slot)) {
3272 _state_mask.set_bit(stencil_slot);
3275 int fog_slot = FogAttrib::get_class_slot();
3276 if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
3277 !_state_mask.get_bit(fog_slot)) {
3280 _state_mask.set_bit(fog_slot);
3281 if (_current_shader_context) {
3286 int scissor_slot = ScissorAttrib::get_class_slot();
3287 if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) ||
3288 !_state_mask.get_bit(scissor_slot)) {
3291 _state_mask.set_bit(scissor_slot);
3294 _state_rs = _target_rs;
3308 const LMatrix4 &light_mat = transform->
get_mat();
3309 LMatrix4 rel_mat = light_mat * LMatrix4::convert_mat(CS_yup_left, CS_default);
3310 LPoint3f pos = LCAST(
float, light_obj->
get_point() * rel_mat);
3312 D3DCOLORVALUE black;
3313 black.r = black.g = black.b = black.a = 0.0f;
3315 alight.Type = D3DLIGHT_POINT;
3316 alight.Diffuse = get_light_color(light_obj);
3317 alight.Ambient = black ;
3319 alight.Specular = *(D3DCOLORVALUE *)(color.get_data());
3323 alight.Position = *(D3DVECTOR *)pos.get_data();
3325 alight.Range = __D3DLIGHT_RANGE_MAX;
3326 alight.Falloff = 1.0f;
3329 alight.Attenuation0 = att[0];
3330 alight.Attenuation1 = att[1];
3331 alight.Attenuation2 = att[2];
3333 HRESULT hr = _d3d_device->SetLight(light_id, &alight);
3335 wdxdisplay9_cat.warning()
3336 <<
"Could not set light properties for " << light
3337 <<
" to id " << light_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3348 static PStatCollector _draw_set_state_light_bind_directional_pcollector(
"Draw:Set State:Light:Bind:Directional");
3351 std::pair<DirectionalLights::iterator, bool> lookup = _dlights.insert(DirectionalLights::value_type(light, D3DLIGHT9()));
3352 D3DLIGHT9 &fdata = (*lookup.first).second;
3353 if (lookup.second) {
3358 const LMatrix4 &light_mat = transform->
get_mat();
3359 LMatrix4 rel_mat = light_mat * LMatrix4::convert_mat(CS_yup_left, CS_default);
3360 LVector3f dir = LCAST(
float, light_obj->
get_direction() * rel_mat);
3362 D3DCOLORVALUE black;
3363 black.r = black.g = black.b = black.a = 0.0f;
3365 ZeroMemory(&fdata,
sizeof(D3DLIGHT9));
3367 fdata.Type = D3DLIGHT_DIRECTIONAL;
3368 fdata.Ambient = black ;
3370 fdata.Specular = *(D3DCOLORVALUE *)(color.get_data());
3372 fdata.Direction = *(D3DVECTOR *)dir.get_data();
3374 fdata.Range = __D3DLIGHT_RANGE_MAX;
3375 fdata.Falloff = 1.0f;
3377 fdata.Attenuation0 = 1.0f;
3378 fdata.Attenuation1 = 0.0f;
3379 fdata.Attenuation2 = 0.0f;
3385 fdata.Diffuse = get_light_color(light_obj);
3387 HRESULT hr = _d3d_device->SetLight(light_id, &fdata);
3389 wdxdisplay9_cat.warning()
3390 <<
"Could not set light properties for " << light
3391 <<
" to id " << light_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3403 nassertv(lens !=
nullptr);
3409 const LMatrix4 &light_mat = transform->
get_mat();
3410 LMatrix4 rel_mat = light_mat * LMatrix4::convert_mat(CS_yup_left, CS_default);
3414 D3DCOLORVALUE black;
3415 black.r = black.g = black.b = black.a = 0.0f;
3418 ZeroMemory(&alight,
sizeof(D3DLIGHT9));
3420 alight.Type = D3DLIGHT_SPOT;
3421 alight.Ambient = black ;
3422 alight.Diffuse = get_light_color(light_obj);
3424 alight.Specular = *(D3DCOLORVALUE *)(color.get_data());
3426 alight.Position = *(D3DVECTOR *)pos.get_data();
3428 alight.Direction = *(D3DVECTOR *)dir.get_data();
3430 alight.Range = __D3DLIGHT_RANGE_MAX;
3434 PN_stdfloat fov = lens->
get_hfov();
3435 alight.Falloff = light_obj->
get_exponent() * (fov * fov * fov) / 1620000.0f;
3437 alight.Theta = 0.0f;
3438 alight.Phi = deg_2_rad(fov);
3441 alight.Attenuation0 = att[0];
3442 alight.Attenuation1 = att[1];
3443 alight.Attenuation2 = att[2];
3445 HRESULT hr = _d3d_device->SetLight(light_id, &alight);
3447 wdxdisplay9_cat.warning()
3448 <<
"Could not set light properties for " << light
3449 <<
" to id " << light_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3458 switch (numeric_type) {
3460 case Geom::NT_uint8:
3461 case Geom::NT_uint16:
3462 return D3DFMT_INDEX16;
3464 case Geom::NT_uint32:
3465 return D3DFMT_INDEX32;
3469 <<
"Invalid index NumericType value (" << (int)numeric_type <<
")\n";
3470 return D3DFMT_INDEX16;
3476 void DXGraphicsStateGuardian9::
3477 do_issue_material() {
3481 if (target_material->
is_off()) {
3487 D3DMATERIAL9 cur_material;
3488 LColorf color = LCAST(
float, material->
get_diffuse());
3489 cur_material.Diffuse = *(D3DCOLORVALUE *)(color.get_data());
3491 cur_material.Ambient = *(D3DCOLORVALUE *)(color.get_data());
3493 cur_material.Specular = *(D3DCOLORVALUE *)(color.get_data());
3495 cur_material.Emissive = *(D3DCOLORVALUE *)(color.get_data());
3503 if (_has_material_force_color) {
3504 color = LCAST(
float, _material_force_color);
3505 cur_material.Diffuse = *(D3DCOLORVALUE *)color.get_data();
3516 if (_has_material_force_color) {
3517 color = LCAST(
float, _material_force_color);
3518 cur_material.Ambient = *(D3DCOLORVALUE *)color.get_data();
3537 _d3d_device->SetMaterial(&cur_material);
3543 void DXGraphicsStateGuardian9::
3544 do_issue_texture() {
3545 DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
3547 if (_texture_binding_shader_context==0) {
3548 if (_current_shader_context==0) {
3549 update_standard_texture_bindings();
3551 disable_standard_texture_bindings();
3555 if (_current_shader_context==0) {
3557 update_standard_texture_bindings();
3559 _current_shader_context->
3560 update_shader_texture_bindings(_texture_binding_shader_context,
this);
3563 _texture_binding_shader = _current_shader;
3564 _texture_binding_shader_context = _current_shader_context;
3570 void DXGraphicsStateGuardian9::
3571 disable_standard_texture_bindings() {
3573 for (
int i = 0; i < _num_active_texture_stages; i++) {
3576 hr = _d3d_device -> SetTexture (i,
nullptr);
3581 <<
", NULL) failed "
3582 << D3DERRORSTRING(hr);
3587 _num_active_texture_stages = 0;
3593 void DXGraphicsStateGuardian9::
3594 update_standard_texture_bindings() {
3595 DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
3597 int num_stages = _target_texture->get_num_on_ff_stages();
3598 int num_old_stages = _max_texture_stages;
3599 if (_state_texture !=
nullptr) {
3600 num_old_stages = _state_texture->get_num_on_ff_stages();
3603 nassertv(num_stages <= _max_texture_stages &&
3604 _num_active_texture_stages <= _max_texture_stages);
3606 _texture_involves_color_scale =
false;
3613 for (si = 0; si < num_stages; si++) {
3614 TextureStage *stage = _target_texture->get_on_ff_stage(si);
3615 int texcoord_index = _target_texture->get_ff_tc_index(si);
3617 Texture *texture = _target_texture->get_on_texture(stage);
3618 nassertv(texture !=
nullptr);
3619 const SamplerState &sampler = _target_texture->get_on_sampler(stage);
3626 set_texture_blend_mode(si, stage);
3628 int texcoord_dimensions = 2;
3632 if (target_tex_matrix->has_stage(stage)) {
3633 tex_mat = target_tex_matrix->get_transform(stage);
3637 TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage);
3638 bool any_point_sprite =
false;
3641 case TexGenAttrib::M_off:
3642 case TexGenAttrib::M_unused2:
3646 case TexGenAttrib::M_eye_sphere_map:
3649 texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
3654 TransformState::make_mat(LMatrix4(0.33, 0.0f, 0.0f, 0.0f,
3655 0.0f, 0.33, 0.0f, 0.0f,
3656 0.0f, 0.0f, 1.0f, 0.0f,
3657 0.5f, 0.5f, 0.0f, 1.0f));
3658 tex_mat = tex_mat->compose(sphere_map);
3659 texcoord_dimensions = 3;
3663 case TexGenAttrib::M_world_cube_map:
3670 texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
3671 texcoord_dimensions = 3;
3672 CPT(
TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
3673 tex_mat = tex_mat->compose(camera_transform->set_pos(LVecBase3::zero()));
3677 case TexGenAttrib::M_eye_cube_map:
3679 texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
3680 tex_mat = tex_mat->compose(_inv_cs_transform);
3681 texcoord_dimensions = 3;
3684 case TexGenAttrib::M_world_normal:
3690 texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
3691 texcoord_dimensions = 3;
3692 CPT(
TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
3693 tex_mat = tex_mat->compose(camera_transform->set_pos(LVecBase3::zero()));
3697 case TexGenAttrib::M_eye_normal:
3699 texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
3700 texcoord_dimensions = 3;
3701 tex_mat = tex_mat->compose(_inv_cs_transform);
3704 case TexGenAttrib::M_world_position:
3709 texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
3710 texcoord_dimensions = 3;
3711 CPT(
TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
3712 tex_mat = tex_mat->compose(camera_transform);
3716 case TexGenAttrib::M_eye_position:
3718 texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
3719 texcoord_dimensions = 3;
3720 tex_mat = tex_mat->compose(_inv_cs_transform);
3723 case TexGenAttrib::M_point_sprite:
3725 any_point_sprite =
true;
3728 case TexGenAttrib::M_constant:
3741 texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
3742 texcoord_dimensions = 3;
3744 const LTexCoord3 &v = _target_tex_gen->get_constant_value(stage);
3746 TransformState::make_pos_hpr_scale(v, LVecBase3::zero(),
3748 tex_mat = tex_mat->compose(squash);
3755 if (!tex_mat->is_identity()) {
3756 if ( texcoord_dimensions <= 2) {
3758 LMatrix4 m = tex_mat->get_mat();
3760 mf.set(m(0, 0), m(0, 1), m(0, 3), 0.0f,
3761 m(1, 0), m(1, 1), m(1, 3), 0.0f,
3762 m(3, 0), m(3, 1), m(3, 3), 0.0f,
3763 0.0f, 0.0f, 0.0f, 1.0f);
3764 _d3d_device->SetTransform(get_tex_mat_sym(si), (D3DMATRIX *)mf.get_data());
3768 LMatrix4f mf = LCAST(
float, tex_mat->get_mat());
3769 _d3d_device->SetTransform(get_tex_mat_sym(si), (D3DMATRIX *)mf.get_data());
3770 DWORD transform_flags = texcoord_dimensions;
3771 if (mf.get_col(3) != LVecBase4f(0.0f, 0.0f, 0.0f, 1.0f)) {
3774 transform_flags = D3DTTFF_COUNT4 | D3DTTFF_PROJECTED;
3786 _d3d_device->SetTransform(get_tex_mat_sym(si), &_d3d_ident_mat);
3791 for (si = num_stages; si < _num_active_texture_stages; si++) {
3793 _d3d_device->SetTexture(si,
nullptr);
3797 _num_active_texture_stages = num_stages;
3805 void DXGraphicsStateGuardian9::
3806 do_issue_blending() {
3811 unsigned int color_channels =
3812 target_color_write->
get_channels() & _color_write_mask;
3813 if (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write)) {
3814 color_channels &= ~(ColorWriteAttrib::C_alpha);
3816 if (color_channels == ColorWriteAttrib::C_off) {
3817 if (_screen->_can_direct_disable_color_writes) {
3827 if (_screen->_can_direct_disable_color_writes) {
3833 _target_rs->get_attrib_def(color_blend);
3834 ColorBlendAttrib::Mode color_blend_mode = color_blend->
get_mode();
3837 _target_rs->get_attrib_def(target_transparency);
3838 TransparencyAttrib::Mode transparency_mode = target_transparency->
get_mode();
3841 if (color_blend_mode != ColorBlendAttrib::M_none) {
3854 switch (transparency_mode) {
3855 case TransparencyAttrib::M_none:
3856 case TransparencyAttrib::M_binary:
3859 case TransparencyAttrib::M_alpha:
3860 case TransparencyAttrib::M_multisample:
3861 case TransparencyAttrib::M_multisample_mask:
3862 case TransparencyAttrib::M_dual:
3864 if (old_alpha_blend) {
3877 case TransparencyAttrib::M_premultiplied_alpha:
3887 <<
"invalid transparency mode " << (int)transparency_mode << endl;
3900 void DXGraphicsStateGuardian9::
3901 reissue_transforms() {
3903 do_issue_transform();
3911 void DXGraphicsStateGuardian9::
3912 enable_lighting(
bool enable) {
3921 void DXGraphicsStateGuardian9::
3922 set_ambient_light(
const LColor &color) {
3924 c.set(c[0] * _light_color_scale[0],
3925 c[1] * _light_color_scale[1],
3926 c[2] * _light_color_scale[2],
3927 c[3] * _light_color_scale[3]);
3937 void DXGraphicsStateGuardian9::
3938 enable_light(
int light_id,
bool enable) {
3939 HRESULT hr = _d3d_device->LightEnable(light_id, enable);
3942 wdxdisplay9_cat.warning()
3943 <<
"Could not enable light " << light_id <<
": "
3944 << D3DERRORSTRING(hr) <<
"\n";
3953 void DXGraphicsStateGuardian9::
3954 enable_clip_plane(
int plane_id,
bool enable) {
3956 _clip_plane_bits |= ((DWORD)1 << plane_id);
3958 _clip_plane_bits &= ~((DWORD)1 << plane_id);
3968 void DXGraphicsStateGuardian9::
3969 bind_clip_plane(
const NodePath &plane,
int plane_id) {
3974 const LMatrix4 &plane_mat = transform->
get_mat();
3975 LMatrix4 rel_mat = plane_mat * LMatrix4::convert_mat(CS_yup_left, CS_default);
3977 DCAST_INTO_V(plane_node, plane.
node());
3978 LPlanef world_plane = LCAST(
float, plane_node->
get_plane() * rel_mat);
3980 HRESULT hr = _d3d_device->SetClipPlane(plane_id, world_plane.get_data());
3982 wdxdisplay9_cat.warning()
3983 <<
"Could not set clip plane for " << plane
3984 <<
" to id " << plane_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3993 void DXGraphicsStateGuardian9::
3995 GraphicsStateGuardian::close_gsg();
3997 if (_prepared_objects.is_null()) {
4001 if (dxgsg9_cat.is_debug()) {
4003 <<
"Closing GSG, prepared_objects count = "
4004 << _prepared_objects->get_ref_count() <<
"\n";
4009 if (_prepared_objects->get_ref_count() == 1) {
4014 _prepared_objects->begin_frame(
this, current_thread);
4015 _prepared_objects->end_frame(current_thread);
4022 void DXGraphicsStateGuardian9::
4023 free_nondx_resources() {
4026 cgDestroyContext(_cg_context);
4036 void DXGraphicsStateGuardian9::
4039 _state_rs = RenderState::make_empty();
4040 _state_mask.clear();
4044 _dx_is_ready =
false;
4046 if (_d3d_device !=
nullptr) {
4047 for(
int i = 0; i < D3D_MAXTEXTURESTAGES; i++) {
4049 _d3d_device->SetTexture(i,
nullptr);
4055 if (_d3d_device !=
nullptr) {
4056 RELEASE(_d3d_device, dxgsg9,
"d3dDevice", RELEASE_DOWN_TO_ZERO);
4059 free_nondx_resources();
4069 void DXGraphicsStateGuardian9::
4071 dxgsg9_cat.fatal() <<
"DX set_draw_buffer unimplemented!!!";
4078 void DXGraphicsStateGuardian9::
4080 if (rb._buffer_type & RenderBuffer::T_front) {
4081 _cur_read_pixel_buffer = RenderBuffer::T_front;
4082 }
else if (rb._buffer_type & RenderBuffer::T_back) {
4083 _cur_read_pixel_buffer = RenderBuffer::T_back;
4084 }
else if (rb._buffer_type & RenderBuffer::T_aux_rgba_ALL) {
4085 _cur_read_pixel_buffer = RenderBuffer::T_back;
4087 dxgsg9_cat.error() <<
"Invalid or unimplemented Argument to set_read_buffer!\n";
4097 const D3DCOLORVALUE &DXGraphicsStateGuardian9::
4098 get_light_color(
Light *light)
const {
4101 cf.set(c[0] * _light_color_scale[0],
4102 c[1] * _light_color_scale[1],
4103 c[2] * _light_color_scale[2],
4104 c[3] * _light_color_scale[3]);
4105 return *(D3DCOLORVALUE *)cf.get_data();
4111 D3DBLENDOP DXGraphicsStateGuardian9::
4112 get_blend_mode(ColorBlendAttrib::Mode mode) {
4114 case ColorBlendAttrib::M_add:
4115 return D3DBLENDOP_ADD;
4117 case ColorBlendAttrib::M_subtract:
4118 return D3DBLENDOP_SUBTRACT;
4120 case ColorBlendAttrib::M_inv_subtract:
4121 return D3DBLENDOP_REVSUBTRACT;
4123 case ColorBlendAttrib::M_min:
4124 return D3DBLENDOP_MIN;
4126 case ColorBlendAttrib::M_max:
4127 return D3DBLENDOP_MAX;
4131 <<
"Unknown color blend mode " << (int)mode << endl;
4132 return D3DBLENDOP_ADD;
4138 D3DBLEND DXGraphicsStateGuardian9::
4139 get_blend_func(ColorBlendAttrib::Operand operand) {
4141 case ColorBlendAttrib::O_zero:
4142 return D3DBLEND_ZERO;
4144 case ColorBlendAttrib::O_one:
4145 return D3DBLEND_ONE;
4147 case ColorBlendAttrib::O_incoming_color:
4148 return D3DBLEND_SRCCOLOR;
4150 case ColorBlendAttrib::O_one_minus_incoming_color:
4151 return D3DBLEND_INVSRCCOLOR;
4153 case ColorBlendAttrib::O_fbuffer_color:
4154 return D3DBLEND_DESTCOLOR;
4156 case ColorBlendAttrib::O_one_minus_fbuffer_color:
4157 return D3DBLEND_INVDESTCOLOR;
4159 case ColorBlendAttrib::O_incoming_alpha:
4160 return D3DBLEND_SRCALPHA;
4162 case ColorBlendAttrib::O_one_minus_incoming_alpha:
4163 return D3DBLEND_INVSRCALPHA;
4165 case ColorBlendAttrib::O_fbuffer_alpha:
4166 return D3DBLEND_DESTALPHA;
4168 case ColorBlendAttrib::O_one_minus_fbuffer_alpha:
4169 return D3DBLEND_INVDESTALPHA;
4171 case ColorBlendAttrib::O_constant_color:
4173 return D3DBLEND_SRCCOLOR;
4175 case ColorBlendAttrib::O_one_minus_constant_color:
4177 return D3DBLEND_INVSRCCOLOR;
4179 case ColorBlendAttrib::O_constant_alpha:
4181 return D3DBLEND_SRCALPHA;
4183 case ColorBlendAttrib::O_one_minus_constant_alpha:
4185 return D3DBLEND_INVSRCALPHA;
4187 case ColorBlendAttrib::O_incoming_color_saturate:
4188 return D3DBLEND_SRCALPHASAT;
4190 case ColorBlendAttrib::O_incoming1_color:
4191 return (D3DBLEND)16;
4193 case ColorBlendAttrib::O_one_minus_incoming1_color:
4194 return (D3DBLEND)17;
4196 case ColorBlendAttrib::O_incoming1_alpha:
4198 return (D3DBLEND)18;
4200 case ColorBlendAttrib::O_one_minus_incoming1_alpha:
4202 return (D3DBLEND)19;
4206 <<
"Unknown color blend operand " << (int)operand << endl;
4207 return D3DBLEND_ZERO;
4213 void DXGraphicsStateGuardian9::
4214 report_texmgr_stats() {
4220 #ifdef TEXMGRSTATS_USES_GETAVAILVIDMEM
4221 DWORD dwTexTotal, dwTexFree, dwVidTotal, dwVidFree;
4223 if (_total_texmem_pcollector.is_active()) {
4226 ZeroMemory(&ddsCaps,
sizeof(ddsCaps));
4228 ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
4229 if (FAILED( hr = _d3d_device->GetAvailableVidMem(&ddsCaps, &dwVidTotal, &dwVidFree))) {
4230 dxgsg9_cat.fatal() <<
"report_texmgr GetAvailableVidMem for VIDMEM failed : result = " << D3DERRORSTRING(hr);
4231 throw_event(
"panda3d-render-error");
4235 ddsCaps.dwCaps = DDSCAPS_TEXTURE;
4236 if (FAILED( hr = _d3d_device->GetAvailableVidMem(&ddsCaps, &dwTexTotal, &dwTexFree))) {
4237 dxgsg9_cat.fatal() <<
"report_texmgr GetAvailableVidMem for TEXTURE failed : result = " << D3DERRORSTRING(hr);
4238 throw_event(
"panda3d-render-error");
4244 D3DDEVINFO_RESOURCEMANAGER all_resource_stats;
4245 ZeroMemory(&all_resource_stats,
sizeof(D3DDEVINFO_RESOURCEMANAGER));
4272 if (_texmgrmem_total_pcollector.is_active()) {
4274 _texmgrmem_total_pcollector.set_level(all_resource_stats.stats[D3DRTYPE_TEXTURE].TotalBytes);
4275 _texmgrmem_resident_pcollector.set_level(all_resource_stats.stats[D3DRTYPE_TEXTURE].WorkingSetBytes);
4277 #ifdef TEXMGRSTATS_USES_GETAVAILVIDMEM
4278 if (_total_texmem_pcollector.is_active()) {
4279 _total_texmem_pcollector.set_level(dwTexTotal);
4280 _used_texmem_pcollector.set_level(dwTexTotal - dwTexFree);
4289 void DXGraphicsStateGuardian9::
4291 nassertv(new_context !=
nullptr);
4292 _screen = new_context;
4293 _d3d_device = _screen->_d3d_device;
4294 _swap_chain = _screen->_swap_chain;
4296 _screen->_dxgsg9 =
this;
4303 void DXGraphicsStateGuardian9::
4304 set_render_target() {
4305 if (_d3d_device ==
nullptr) {
4309 LPDIRECT3DSURFACE9 back =
nullptr, stencil =
nullptr;
4317 _d3d_device->GetBackBuffer(swap_chain, 0, D3DBACKBUFFER_TYPE_MONO, &back);
4319 _swap_chain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &back);
4324 _d3d_device->GetDepthStencilSurface(&stencil);
4327 DWORD render_target_index;
4328 render_target_index = 0;
4329 _d3d_device->SetRenderTarget(render_target_index, back);
4342 void DXGraphicsStateGuardian9::
4343 set_texture_blend_mode(
int i,
const TextureStage *stage) {
4345 case TextureStage::M_modulate:
4346 case TextureStage::M_modulate_glow:
4347 case TextureStage::M_modulate_gloss:
4357 case TextureStage::M_decal:
4367 case TextureStage::M_replace:
4375 case TextureStage::M_add:
4385 case TextureStage::M_blend:
4386 case TextureStage::M_blend_color_scale:
4399 case TextureStage::M_combine:
4410 (i, D3DTSS_COLORARG0,
4417 (i, D3DTSS_COLORARG2,
4424 (i, D3DTSS_COLORARG1,
4441 (i, D3DTSS_ALPHAARG0,
4448 (i, D3DTSS_ALPHAARG2,
4455 (i, D3DTSS_ALPHAARG1,
4467 <<
"Unknown texture mode " << (int)stage->
get_mode() << endl;
4480 D3DCOLOR constant_color;
4483 color.set(color[0] * _current_color_scale[0],
4484 color[1] * _current_color_scale[1],
4485 color[2] * _current_color_scale[2],
4486 color[3] * _current_color_scale[3]);
4487 _texture_involves_color_scale =
true;
4492 if (_supports_texture_constant_color) {
4506 void DXGraphicsStateGuardian9::
4512 free_nondx_resources();
4513 PRINT_REFCNT(dxgsg9, _d3d_device);
4517 RELEASE(_d3d_device, dxgsg9,
"d3dDevice", RELEASE_DOWN_TO_ZERO);
4518 _screen->_d3d_device =
nullptr;
4530 HRESULT DXGraphicsStateGuardian9::
4531 reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
4535 nassertr(IS_VALID_PTR(presentation_params), E_FAIL);
4536 nassertr(IS_VALID_PTR(_screen->_d3d9), E_FAIL);
4537 nassertr(IS_VALID_PTR(_d3d_device), E_FAIL);
4541 _screen->_d3d9->GetAdapterDisplayMode(_screen->_card_id, &_screen->_display_mode);
4542 presentation_params->BackBufferFormat = _screen->_display_mode.Format;
4549 if (
true || !(_screen->_swap_chain)
4550 || (_presentation_reset.BackBufferWidth < presentation_params->BackBufferWidth)
4551 || (_presentation_reset.BackBufferHeight < presentation_params->BackBufferHeight)) {
4552 if (wdxdisplay9_cat.is_debug()) {
4553 wdxdisplay9_cat.debug()
4554 <<
"swap_chain = " << _screen->_swap_chain <<
" _presentation_reset = "
4555 << _presentation_reset.BackBufferWidth <<
"x" << _presentation_reset.BackBufferHeight
4556 <<
" presentation_params = "
4557 << presentation_params->BackBufferWidth <<
"x" << presentation_params->BackBufferHeight <<
"\n";
4562 if (_screen->_swap_chain) {
4563 _presentation_reset.BackBufferWidth = max(_presentation_reset.BackBufferWidth, presentation_params->BackBufferWidth);
4564 _presentation_reset.BackBufferHeight = max(_presentation_reset.BackBufferHeight, presentation_params->BackBufferHeight);
4567 _presentation_reset.BackBufferWidth = presentation_params->BackBufferWidth;
4568 _presentation_reset.BackBufferHeight = presentation_params->BackBufferHeight;
4580 if (_white_vbuffer !=
nullptr) {
4581 _white_vbuffer->Release();
4582 _white_vbuffer =
nullptr;
4587 _prepared_objects->begin_frame(
this, current_thread);
4592 std::list <wdxGraphicsBuffer9 **>::iterator graphics_buffer_iterator;
4594 for (graphics_buffer_iterator = _graphics_buffer_list.begin( ); graphics_buffer_iterator != _graphics_buffer_list.end( ); graphics_buffer_iterator++)
4596 graphics_buffer = **graphics_buffer_iterator;
4597 if (graphics_buffer -> _color_backing_store)
4599 graphics_buffer -> _color_backing_store -> Release ( );
4600 graphics_buffer -> _color_backing_store = 0;
4602 if (graphics_buffer -> _depth_backing_store)
4604 graphics_buffer -> _depth_backing_store -> Release ( );
4605 graphics_buffer -> _depth_backing_store = 0;
4611 hr = _d3d_device->Reset(&_presentation_reset);
4612 if (FAILED(hr) && hr != D3DERR_DEVICELOST) {
4621 if (presentation_params != &_screen->_presentation_params) {
4622 memcpy(&_screen->_presentation_params, presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
4629 if (_screen && _screen->_swap_chain) {
4630 _screen->_swap_chain->Release();
4631 wdxdisplay9_cat.debug()
4632 <<
"swap chain " << _screen->_swap_chain <<
" is released\n";
4633 _screen->_swap_chain =
nullptr;
4634 hr = _d3d_device->CreateAdditionalSwapChain(presentation_params, &_screen->_swap_chain);
4636 if (SUCCEEDED(hr)) {
4637 if (presentation_params != &_screen->_presentation_params) {
4638 memcpy(&_screen->_presentation_params, presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
4650 bool DXGraphicsStateGuardian9::
4651 check_cooperative_level() {
4652 bool bDoReactivateWindow =
false;
4653 if (_d3d_device ==
nullptr) {
4657 HRESULT hr = _d3d_device->TestCooperativeLevel();
4659 if (SUCCEEDED(hr)) {
4660 nassertr(SUCCEEDED(_last_testcooplevel_result),
false);
4665 case D3DERR_DEVICENOTRESET:
4666 _dx_is_ready =
false;
4671 hr = reset_d3d_device(&_screen->_presentation_params);
4676 <<
"check_cooperative_level Reset() failed, hr = " << D3DERRORSTRING(hr);
4679 hr = _d3d_device->TestCooperativeLevel();
4683 <<
"TestCooperativeLevel following Reset() failed, hr = " << D3DERRORSTRING(hr);
4687 _dx_is_ready = TRUE;
4690 case D3DERR_DEVICELOST:
4694 if (SUCCEEDED(_last_testcooplevel_result)) {
4696 _dx_is_ready =
false;
4697 if (dxgsg9_cat.is_debug()) {
4698 dxgsg9_cat.debug() <<
"D3D Device was Lost, waiting...\n";
4704 _last_testcooplevel_result = hr;
4705 return SUCCEEDED(hr);
4711 void DXGraphicsStateGuardian9::
4713 if (_d3d_device ==
nullptr) {
4723 hr = _swap_chain->Present(
nullptr,
nullptr, (HWND)
nullptr,
nullptr, flags);
4725 hr = _d3d_device->Present(
nullptr,
nullptr, (HWND)
nullptr,
nullptr);
4729 if (hr == D3DERR_DEVICELOST) {
4730 check_cooperative_level();
4733 <<
"show_frame() - Present() failed" << D3DERRORSTRING(hr);
4734 throw_event(
"panda3d-render-error");
4742 bool DXGraphicsStateGuardian9::
4750 hr = new_context->_d3d_device->CreateAdditionalSwapChain(&new_context->_presentation_params, &new_context->_swap_chain);
4752 wdxdisplay9_cat.debug() <<
"Swapchain creation failed :"<<D3DERRORSTRING(hr)<<
"\n";
4761 bool DXGraphicsStateGuardian9::
4764 if (new_context->_swap_chain) {
4765 hr = new_context->_swap_chain->Release();
4767 wdxdisplay9_cat.debug() <<
"Swapchain release failed:" << D3DERRORSTRING(hr) <<
"\n";
4770 if (new_context->_swap_chain == _swap_chain) {
4771 _swap_chain =
nullptr;
4780 void DXGraphicsStateGuardian9::
4782 memcpy(&_presentation_reset, &_screen->_presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
4788 D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian9::
4789 get_d3d_min_type(SamplerState::FilterType filter_type) {
4790 switch (filter_type) {
4791 case SamplerState::FT_nearest:
4792 return D3DTEXF_POINT;
4794 case SamplerState::FT_linear:
4795 return D3DTEXF_LINEAR;
4797 case SamplerState::FT_nearest_mipmap_nearest:
4798 return D3DTEXF_POINT;
4800 case SamplerState::FT_linear_mipmap_nearest:
4801 return D3DTEXF_LINEAR;
4803 case SamplerState::FT_nearest_mipmap_linear:
4804 return D3DTEXF_POINT;
4806 case SamplerState::FT_linear_mipmap_linear:
4807 return D3DTEXF_LINEAR;
4809 case SamplerState::FT_shadow:
4810 case SamplerState::FT_default:
4811 return D3DTEXF_LINEAR;
4815 <<
"Invalid FilterType value (" << (int)filter_type <<
")\n";
4816 return D3DTEXF_POINT;
4822 D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian9::
4823 get_d3d_mip_type(SamplerState::FilterType filter_type) {
4824 switch (filter_type) {
4825 case SamplerState::FT_nearest:
4826 return D3DTEXF_NONE;
4828 case SamplerState::FT_linear:
4829 return D3DTEXF_NONE;
4831 case SamplerState::FT_nearest_mipmap_nearest:
4832 return D3DTEXF_POINT;
4834 case SamplerState::FT_linear_mipmap_nearest:
4835 return D3DTEXF_POINT;
4837 case SamplerState::FT_nearest_mipmap_linear:
4838 return D3DTEXF_LINEAR;
4840 case SamplerState::FT_linear_mipmap_linear:
4841 return D3DTEXF_LINEAR;
4843 case SamplerState::FT_shadow:
4844 case SamplerState::FT_default:
4845 return D3DTEXF_NONE;
4849 <<
"Invalid FilterType value (" << (int)filter_type <<
")\n";
4850 return D3DTEXF_NONE;
4857 D3DTEXTUREOP DXGraphicsStateGuardian9::
4858 get_texture_operation(TextureStage::CombineMode mode,
int scale) {
4860 case TextureStage::CM_undefined:
4861 case TextureStage::CM_replace:
4862 return D3DTOP_SELECTARG1;
4864 case TextureStage::CM_modulate:
4866 return D3DTOP_MODULATE;
4867 }
else if (scale < 4) {
4868 return D3DTOP_MODULATE2X;
4870 return D3DTOP_MODULATE4X;
4873 case TextureStage::CM_add:
4876 case TextureStage::CM_add_signed:
4878 return D3DTOP_ADDSIGNED;
4880 return D3DTOP_ADDSIGNED2X;
4883 case TextureStage::CM_interpolate:
4886 case TextureStage::CM_subtract:
4887 return D3DTOP_SUBTRACT;
4889 case TextureStage::CM_dot3_rgb:
4890 case TextureStage::CM_dot3_rgba:
4891 return D3DTOP_DOTPRODUCT3;
4895 <<
"Invalid TextureStage::CombineMode value (" << (int)mode <<
")\n";
4896 return D3DTOP_DISABLE;
4904 DWORD DXGraphicsStateGuardian9::
4905 get_texture_argument(TextureStage::CombineSource source,
4906 TextureStage::CombineOperand operand)
const {
4908 case TextureStage::CS_undefined:
4909 case TextureStage::CS_texture:
4910 return D3DTA_TEXTURE | get_texture_argument_modifier(operand);
4912 case TextureStage::CS_constant:
4913 case TextureStage::CS_constant_color_scale:
4914 return _constant_color_operand | get_texture_argument_modifier(operand);
4916 case TextureStage::CS_primary_color:
4917 return D3DTA_DIFFUSE | get_texture_argument_modifier(operand);
4919 case TextureStage::CS_previous:
4920 return D3DTA_CURRENT | get_texture_argument_modifier(operand);
4922 case TextureStage::CS_last_saved_result:
4923 return D3DTA_TEMP | get_texture_argument_modifier(operand);
4926 <<
"Invalid TextureStage::CombineSource value (" << (int)source <<
")\n";
4927 return D3DTA_CURRENT;
4934 DWORD DXGraphicsStateGuardian9::
4935 get_texture_argument_modifier(TextureStage::CombineOperand operand) {
4937 case TextureStage::CO_src_color:
4940 case TextureStage::CO_one_minus_src_color:
4941 return D3DTA_COMPLEMENT;
4943 case TextureStage::CO_src_alpha:
4944 return D3DTA_ALPHAREPLICATE;
4946 case TextureStage::CO_one_minus_src_alpha:
4947 return D3DTA_ALPHAREPLICATE | D3DTA_COMPLEMENT;
4949 case TextureStage::CO_undefined:
4953 <<
"Invalid TextureStage::CombineOperand value (" << (int)operand <<
")\n";
4962 void DXGraphicsStateGuardian9::
4963 draw_primitive_up(D3DPRIMITIVETYPE primitive_type,
4964 unsigned int primitive_count,
4965 unsigned int first_vertex,
4966 unsigned int num_vertices,
4967 const unsigned char *buffer,
size_t stride) {
4974 const unsigned char *buffer_start = buffer + stride * first_vertex;
4975 const unsigned char *buffer_end = buffer_start + stride * num_vertices;
4977 if (buffer_end - buffer_start > 0x10000) {
4980 _d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
4981 buffer_start, stride);
4983 }
else if ((((uintptr_t)buffer_end ^ (uintptr_t)buffer_start) & ~0xffff) == 0) {
4985 _d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
4986 buffer_start, stride);
4991 unsigned char *safe_buffer_start = get_safe_buffer_start();
4992 memcpy(safe_buffer_start, buffer_start, buffer_end - buffer_start);
4993 _d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
4994 safe_buffer_start, stride);
5006 void DXGraphicsStateGuardian9::
5007 draw_indexed_primitive_up(D3DPRIMITIVETYPE primitive_type,
5008 unsigned int min_index,
unsigned int max_index,
5009 unsigned int num_primitives,
5010 const unsigned char *index_data,
5011 D3DFORMAT index_type,
5012 const unsigned char *buffer,
size_t stride) {
5015 const unsigned char *buffer_start = buffer + stride * min_index;
5016 const unsigned char *buffer_end = buffer + stride * (max_index + 1);
5018 if (buffer_end - buffer_start > 0x10000) {
5021 _d3d_device->DrawIndexedPrimitiveUP
5022 (primitive_type, min_index, max_index - min_index + 1, num_primitives,
5023 index_data, index_type, buffer, stride);
5025 }
else if ((((uintptr_t)buffer_end ^ (uintptr_t)buffer_start) & ~0xffff) == 0) {
5027 _d3d_device->DrawIndexedPrimitiveUP
5028 (primitive_type, min_index, max_index - min_index + 1, num_primitives,
5029 index_data, index_type, buffer, stride);
5034 unsigned char *safe_buffer_start = get_safe_buffer_start();
5035 memcpy(safe_buffer_start, buffer_start, buffer_end - buffer_start);
5036 _d3d_device->DrawIndexedPrimitiveUP
5037 (primitive_type, min_index, max_index - min_index + 1, num_primitives,
5038 index_data, index_type, safe_buffer_start - stride * min_index, stride);
5061 case D3DERR_OUTOFVIDEOMEMORY:
5065 size_t current_size = _prepared_objects->_graphics_memory_lru.get_total_size();
5066 size_t target_size = max(current_size - allocation_size * attempts, (
size_t) 0);
5067 _prepared_objects->_graphics_memory_lru.evict_to(target_size);
5069 <<
"Evicted " << current_size - _prepared_objects->_graphics_memory_lru.get_total_size() <<
" bytes of texture memory to make room for more.\n";
5070 if (_prepared_objects->_graphics_memory_lru.get_total_size() < current_size) {
5085 static int dx_stencil_comparison_function_array[] = {
5092 D3DCMP_GREATEREQUAL,
5096 static int dx_stencil_operation_array[] = {
5099 D3DSTENCILOP_REPLACE,
5102 D3DSTENCILOP_INVERT,
5104 D3DSTENCILOP_INCRSAT,
5105 D3DSTENCILOP_DECRSAT,
5111 void DXGraphicsStateGuardian9::
5112 do_issue_stencil() {
5113 if (!_supports_stencil) {
5119 if (stencil !=
nullptr) {
5122 dxgsg9_cat.debug() <<
"STENCIL STATE CHANGE\n";
5123 dxgsg9_cat.debug() <<
"\n"
5124 <<
"SRS_front_comparison_function " << stencil->
get_render_state(StencilAttrib::SRS_front_comparison_function) <<
"\n"
5125 <<
"SRS_front_stencil_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_front_stencil_fail_operation) <<
"\n"
5126 <<
"SRS_front_stencil_pass_z_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation) <<
"\n"
5127 <<
"SRS_front_stencil_pass_z_pass_operation " << stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation) <<
"\n"
5128 <<
"SRS_reference " << stencil->
get_render_state(StencilAttrib::SRS_reference) <<
"\n"
5129 <<
"SRS_read_mask " << stencil->
get_render_state(StencilAttrib::SRS_read_mask) <<
"\n"
5130 <<
"SRS_write_mask " << stencil->
get_render_state(StencilAttrib::SRS_write_mask) <<
"\n"
5131 <<
"SRS_back_comparison_function " << stencil->
get_render_state(StencilAttrib::SRS_back_comparison_function) <<
"\n"
5132 <<
"SRS_back_stencil_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_back_stencil_fail_operation) <<
"\n"
5133 <<
"SRS_back_stencil_pass_z_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation) <<
"\n"
5134 <<
"SRS_back_stencil_pass_z_pass_operation " << stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) <<
"\n";
5139 unsigned int front_compare;
5140 front_compare = stencil->
get_render_state(StencilAttrib::SRS_front_comparison_function);
5142 if (front_compare != RenderAttrib::M_none) {
5144 set_render_state(D3DRS_STENCILFUNC, dx_stencil_comparison_function_array[front_compare]);
5146 stencil->
get_render_state(StencilAttrib::SRS_front_stencil_fail_operation)]);
5148 stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation)]);
5150 stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation)]);
5156 if (_supports_two_sided_stencil) {
5157 unsigned int back_compare;
5158 back_compare = stencil->
get_render_state(StencilAttrib::SRS_back_comparison_function);
5160 if (back_compare != RenderAttrib::M_none) {
5162 set_render_state(D3DRS_CCW_STENCILFUNC, dx_stencil_comparison_function_array[back_compare]);
5164 stencil->
get_render_state(StencilAttrib::SRS_back_stencil_fail_operation)]);
5166 stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation)]);
5168 stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation)]);
5182 _d3d_device->Clear(0,
nullptr, D3DCLEAR_STENCIL, 0, 0.0f, stencil->
get_render_state(StencilAttrib::SRS_clear_value));
5188 dxgsg9_cat.debug() <<
"STENCIL STATE CHANGE TO OFF\n";
5192 if (_supports_two_sided_stencil) {
5201 void DXGraphicsStateGuardian9::
5202 do_issue_scissor() {
5204 const LVecBase4 &frame = target_scissor->
get_frame();
5207 r.left = _current_viewport.X + _current_viewport.Width * frame[0];
5208 r.top = _current_viewport.Y + _current_viewport.Height * (1.0f - frame[3]);
5209 r.right = _current_viewport.X + _current_viewport.Width * frame[1];
5210 r.bottom = _current_viewport.Y + _current_viewport.Height * (1.0f - frame[2]);
5211 _d3d_device->SetScissorRect(&r);
5221 DWORD multisampletype, DWORD multisamplequality) {
5224 int r=0, g=0, b=0, a=0;
5226 case D3DFMT_R8G8B8: r=8; g=8; b=8; a=0;
break;
5227 case D3DFMT_A8R8G8B8: r=8; g=8; b=8; a=8;
break;
5228 case D3DFMT_X8R8G8B8: r=8; g=8; b=8; a=0;
break;
5229 case D3DFMT_R5G6B5: r=5; g=6; b=5; a=0;
break;
5230 case D3DFMT_X1R5G5B5: r=5; g=5; b=5; a=0;
break;
5231 case D3DFMT_A1R5G5B5: r=5; g=5; b=5; a=1;
break;
5232 case D3DFMT_A4R4G4B4: r=4; g=4; b=4; a=4;
break;
5233 case D3DFMT_R3G3B2: r=3; g=3; b=2; a=0;
break;
5234 case D3DFMT_A8R3G3B2: r=3; g=3; b=2; a=8;
break;
5235 case D3DFMT_X4R4G4B4: r=4; g=4; b=4; a=0;
break;
5236 case D3DFMT_A2B10G10R10: r=10;g=10;b=10;a=2;
break;
5237 case D3DFMT_A8P8: index=8; a=8;
break;
5238 case D3DFMT_P8: index=8; a=0;
break;
5242 props.set_rgb_color(0);
5243 props.set_indexed_color(1);
5245 }
else if (r + g + b > 0) {
5246 props.set_rgb_color(1);
5247 props.set_indexed_color(0);
5250 props.set_alpha_bits(a);
5255 case D3DFMT_D32: depth=32; stencil=0;
break;
5256 case D3DFMT_D15S1: depth=15; stencil=1;
break;
5257 case D3DFMT_D24S8: depth=24; stencil=8;
break;
5258 case D3DFMT_D16: depth=16; stencil=0;
break;
5259 case D3DFMT_D24X8: depth=24; stencil=0;
break;
5260 case D3DFMT_D24X4S4: depth=24; stencil=4;
break;
5263 props.set_depth_bits(depth);
5264 props.set_stencil_bits(stencil);
5265 if (multisampletype == D3DMULTISAMPLE_NONMASKABLE) {
5266 props.set_multisamples(2);
5268 props.set_multisamples(multisampletype);
5274 #define GAMMA_1 (255.0 * 256.0)
5276 static bool _gamma_table_initialized =
false;
5277 static bool _gamma_changed =
false;
5278 static unsigned short _original_gamma_table [256 * 3];
5280 void _create_gamma_table_dx9 (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) {
5282 double gamma_correction;
5288 gamma_correction = 1.0 / (double) gamma;
5290 for (i = 0; i < 256; i++) {
5295 if (original_red_table) {
5296 r = (double) original_red_table [i] / GAMMA_1;
5297 g = (double) original_green_table [i] / GAMMA_1;
5298 b = (double) original_blue_table [i] / GAMMA_1;
5301 r = ((double) i / 255.0);
5306 r = pow (r, gamma_correction);
5307 g = pow (g, gamma_correction);
5308 b = pow (b, gamma_correction);
5325 green_table [i] = g;
5338 if (_gamma_table_initialized ==
false) {
5339 HDC hdc = GetDC(
nullptr);
5342 if (GetDeviceGammaRamp (hdc, (LPVOID) _original_gamma_table)) {
5343 _gamma_table_initialized =
true;
5347 ReleaseDC (
nullptr, hdc);
5360 HDC hdc = GetDC(
nullptr);
5364 unsigned short ramp [256 * 3];
5366 if (restore && _gamma_table_initialized) {
5367 _create_gamma_table_dx9 (gamma, &_original_gamma_table [0], &_original_gamma_table [256], &_original_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
5370 _create_gamma_table_dx9 (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]);
5373 if (SetDeviceGammaRamp (hdc, ramp)) {
5375 _gamma_changed = !restore;
5378 ReleaseDC (
nullptr, hdc);
5413 if (_gamma_changed) {
5427 CGprofile profile = cgGetProfile(name.c_str());
5429 if (profile == CG_PROFILE_UNKNOWN) {
5430 dxgsg9_cat.error() << name <<
", unknown Cg-profile\n";
5433 return cgD3D9IsProfileSupported(cgGetProfile(name.c_str())) != 0;
5444 if (_cg_device != cg_device) {
5445 cgD3D9SetDevice(cg_device);
5446 _cg_device = cg_device;
5456 if (_white_vbuffer !=
nullptr) {
5457 return _white_vbuffer;
5460 LPDIRECT3DVERTEXBUFFER9 vbuffer;
5462 hr = _screen->_d3d_device->CreateVertexBuffer(
sizeof(D3DCOLOR), D3DUSAGE_WRITEONLY, D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &vbuffer,
nullptr);
5466 <<
"CreateVertexBuffer failed" << D3DERRORSTRING(hr);
5470 D3DCOLOR *local_pointer;
5471 hr = vbuffer->Lock(0,
sizeof(D3DCOLOR), (
void **) &local_pointer, D3DLOCK_DISCARD);
5474 <<
"VertexBuffer::Lock failed" << D3DERRORSTRING(hr);
5478 *local_pointer = D3DCOLOR_ARGB(255, 255, 255, 255);
5481 _white_vbuffer = vbuffer;
5485 typedef std::string KEY;
5487 typedef struct _KEY_ELEMENT
5491 int secondary_count;
5493 struct _KEY_ELEMENT *next;
5497 typedef struct _KEY_LIST
5499 int total_key_elements;
5500 KEY_ELEMENT *key_element;
5504 KEY_ELEMENT *new_key_element (KEY key, KEY_LIST *key_list)
5506 KEY_ELEMENT *key_element;
5508 key_element =
new KEY_ELEMENT;
5509 key_element -> key = key;
5510 key_element -> count = 1;
5511 key_element -> secondary_count = 0;
5512 key_element -> next = 0;
5514 key_list -> total_key_elements++;
5519 KEY_ELEMENT *first_key_element (KEY_LIST *key_list)
5521 return key_list -> key_element;
5524 KEY_ELEMENT *next_key_element (KEY_ELEMENT *key_element)
5526 return key_element -> next;
5529 void delete_key_list (KEY_LIST *key_list)
5533 KEY_ELEMENT *key_element;
5534 KEY_ELEMENT *key_element_next;
5536 key_element = first_key_element (key_list);
5539 key_element_next = next_key_element (key_element);
5541 key_element = key_element_next;
5548 KEY_LIST *new_key_list (
void)
5552 key_list =
new KEY_LIST;
5553 memset (key_list, 0,
sizeof (KEY_LIST));
5558 KEY_ELEMENT *add_to_key_list (KEY key, KEY_LIST *key_list)
5560 KEY_ELEMENT *key_element;
5561 KEY_ELEMENT *last_key_element;
5562 KEY_ELEMENT *current_key_element;
5565 last_key_element = 0;
5566 current_key_element = key_list -> key_element;
5567 if (current_key_element == 0)
5569 key_element = new_key_element (key, key_list);
5570 key_list -> key_element = key_element;
5574 while (current_key_element)
5576 if (key < current_key_element -> key)
5578 key_element = new_key_element (key, key_list);
5579 key_element -> next = current_key_element;
5581 if (last_key_element == 0)
5583 key_list -> key_element = key_element;
5587 last_key_element -> next = key_element;
5593 if (key > current_key_element -> key)
5595 if (current_key_element -> next == 0)
5597 key_element = new_key_element (key, key_list);
5598 current_key_element -> next = key_element;
5608 current_key_element -> count++;
5613 last_key_element = current_key_element;
5614 current_key_element = current_key_element -> next;
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
Enables or disables writing of pixel to framebuffer based on its alpha value relative to a reference ...
get_reference_alpha
Returns the alpha reference value.
get_mode
Returns the alpha write mode.
void set_active(bool flag)
Changes the active flag associated with this object.
This specifies how colors are blended into the frame buffer, for special effects.
get_operand_a
Returns the RGB multiplier for the first component.
get_alpha_operand_b
Returns the alpha multiplier for the second component.
get_alpha_mode
Returns the blending mode for the alpha channel.
get_operand_b
Returns the RGB multiplier for the second component.
get_mode
Returns the blending mode for the RGB channels.
get_alpha_operand_a
Returns the alpha multiplier for the first component.
Enables or disables writing to the color buffer.
get_channels
Returns the mask of color channels that are enabled by this attrib.
Similar to PointerToArray, except that its contents may not be modified.
Indicates which faces should be culled based on their vertex ordering.
get_effective_mode
Returns the effective culling mode.
This specialization on GeomMunger finesses vertices for DirectX rendering.
virtual void end_draw_primitives()
Called after a sequence of draw_primitive() functions are called, this should do whatever cleanup is ...
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...
virtual void release_texture(TextureContext *tc)
Frees the GL resources previously allocated for the texture.
bool setup_array_data(DXVertexBufferContext9 *&vbc, const GeomVertexArrayDataHandle *data, bool force)
Internal function to bind a buffer object for the indicated data array, if appropriate,...
virtual VertexBufferContext * prepare_vertex_buffer(GeomVertexArrayData *data)
Creates a new retained-mode representation of the given data, and returns a newly-allocated VertexBuf...
virtual bool prepare_lens()
Makes the current lens (whichever lens was most recently specified with set_scene()) active,...
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomVertexDataPipelineReader *data_reader, bool force)
Called before a sequence of draw_primitive() functions are called, this should prepare the vertex dat...
virtual bool get_supports_cg_profile(const std::string &name) const
Returns true if this particular GSG supports the specified Cg Shader Profile.
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,...
static void atexit_function(void)
This function is passed to the atexit function.
virtual bool draw_points(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected points.
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,...
virtual void reset()
Resets all internal state as if the gsg were newly created.
static bool static_set_gamma(bool restore, PN_stdfloat gamma)
Static function for setting gamma which is needed for atexit.
static DWORD LColor_to_D3DCOLOR(const LColor &cLColor)
Converts Panda's floating-point LColor structure to DirectX's D3DCOLOR packed structure.
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.
void release_shader(ShaderContext *sc)
Releases the resources allocated by prepare_shader.
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected triangles.
virtual bool update_texture(TextureContext *tc, bool force)
Ensures that the current Texture data is refreshed onto the GSG.
void apply_texture(int i, TextureContext *tc, const SamplerState &sampler)
Makes the texture the currently available texture for rendering on the ith stage.
static bool get_gamma_table(void)
Static function for getting the original gamma.
virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of line strips.
virtual bool begin_scene()
Called between begin_frame() and end_frame() to mark the beginning of drawing commands for a "scene" ...
HRESULT set_render_state(D3DRENDERSTATETYPE state, DWORD value)
This function creates a common layer between DX and Panda for SetRenderState.
virtual void clear(DrawableRegion *clearable)
Clears all of the indicated buffers to their assigned colors.
bool apply_vertex_buffer(VertexBufferContext *vbc, const GeomVertexArrayDataHandle *reader, bool force)
Updates the vertex buffer with the current data, and makes it the current vertex buffer for rendering...
LPDIRECT3DVERTEXBUFFER9 get_white_vbuffer()
Returns a vertex buffer containing only a full-white color.
void restore_gamma()
Restore original gamma.
virtual void release_index_buffer(IndexBufferContext *ibc)
Frees the GL resources previously allocated for the data.
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...
virtual bool extract_texture_data(Texture *tex)
This method should only be called by the GraphicsEngine.
FrameBufferProperties calc_fb_properties(DWORD cformat, DWORD dformat, DWORD multisampletype, DWORD multisamplequality)
Convert DirectX framebuffer format ids into a FrameBufferProperties structure.
virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle strips.
virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected line segments.
virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle fans.
virtual void set_state_and_transform(const RenderState *state, const TransformState *transform)
Simultaneously resets the render state and the transform state.
virtual TextureContext * prepare_texture(Texture *tex, int view)
Creates a new retained-mode representation of the given texture, and returns a newly-allocated Textur...
virtual void prepare_display_region(DisplayRegionPipelineReader *dr)
Prepare a display region for rendering (set up scissor region and viewport)
virtual IndexBufferContext * prepare_index_buffer(GeomPrimitive *data)
Creates a new retained-mode representation of the given data, and returns a newly-allocated IndexBuff...
virtual void begin_occlusion_query()
Begins a new occlusion query.
virtual void end_scene()
Called between begin_frame() and end_frame() to mark the end of drawing commands for a "scene" (usual...
static void set_cg_device(LPDIRECT3DDEVICE9 cg_device)
Sets the global Cg device pointer.
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.
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...
HRESULT set_sampler_state(DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value)
This function creates a common layer between DX and Panda.
ShaderContext * prepare_shader(Shader *se)
Compile a vertex/fragment shader body.
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,...
virtual void release_vertex_buffer(VertexBufferContext *vbc)
Frees the GL resources previously allocated for the data.
bool upload_texture(DXTextureContext9 *dtc, bool force)
Creates a texture surface on the graphics card and fills it with its pixel data.
static D3DFORMAT get_index_type(Geom::NumericType numeric_type)
Maps from the Geom's internal numeric type symbols to DirectX's.
HRESULT set_texture_stage_state(DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value)
This function creates a common layer between DX and Panda.
Caches a GeomPrimitive in the DirectX device as an index buffer.
bool upload_data(const GeomPrimitivePipelineReader *reader, bool force)
Copies the latest data from the client store to DirectX.
void create_ibuffer(DXScreenData &scrn, const GeomPrimitivePipelineReader *reader)
Creates a new index buffer (but does not upload data to it).
bool update_shader_vertex_arrays(DXShaderContext9 *prev, GSG *gsg, bool force)
Disables all vertex arrays used by the previous shader, then enables all the vertex arrays needed by ...
void disable_shader_vertex_arrays(GSG *gsg)
Disable all the vertex arrays used by this shader.
void unbind(GSG *gsg)
This function disables a currently-bound shader.
void disable_shader_texture_bindings(GSG *gsg)
Disable all the texture bindings used by this shader.
bool bind(GSG *gsg)
This function is to be called to enable a new shader.
void update_shader_texture_bindings(DXShaderContext9 *prev, GSG *gsg)
Disables all texture bindings used by the previous shader, then enables all the texture bindings need...
void issue_parameters(GSG *gsg, int altered)
This function gets called whenever the RenderState or TransformState has changed, but the Shader itse...
bool create_texture(DXScreenData &scrn)
Use panda texture's pixelbuffer to create a texture for the specified device.
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.
IDirect3DBaseTexture9 * get_d3d_texture() const
Returns the Direct3D object that represents the texture, whatever kind of texture it is.
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...
void delete_texture()
Release the surface used to store the texture.
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
bool has_mipmaps() const
Returns true if the texture was created with mipmaps, false otherwise.
Caches a GeomVertexArrayData in the DirectX device as a vertex buffer.
This is a special kind of attribute that instructs the graphics driver to apply an offset or bias to ...
get_offset
Returns the depth offset represented by this attrib.
Enables or disables writing to the depth buffer.
get_mode
Returns the depth write mode.
Enables or disables writing to the depth buffer.
get_mode
Returns the depth write mode.
A light shining from infinitely far away in a particular direction, like sunlight.
get_direction
Returns the direction in which the light is aimed.
get_specular_color
Returns the color of specular highlights generated by the light.
Encapsulates the data from a DisplayRegion, pre-fetched for one stage of the pipeline.
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...
A rectangular subregion within a window for rendering into.
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...
This is a base class for GraphicsWindow (actually, GraphicsOutput) and DisplayRegion,...
get_clear_color
Returns the current clear color value.
get_clear_stencil
Returns the current clear stencil value.
bool get_clear_depth_active() const
Returns the current setting of the flag that indicates whether the depth buffer should be cleared eve...
get_clear_depth
Returns the current clear depth value.
bool get_clear_stencil_active() const
Returns the current setting of the flag that indicates whether the color buffer should be cleared eve...
bool get_clear_color_active() const
Returns the current setting of the flag that indicates whether the color buffer should be cleared eve...
Applies a Fog to the geometry at and below this node.
get_fog
If the FogAttrib is not an 'off' FogAttrib, returns the fog that is associated.
bool is_off() const
Returns true if the FogAttrib is an 'off' FogAttrib, indicating that it should disable fog.
Specifies how atmospheric fog effects are applied to geometry.
get_color
Returns the color of the fog.
get_exp_density
Returns the density of the fog for exponential calculations.
void get_linear_range(PN_stdfloat &onset, PN_stdfloat &opaque)
Retrieves the current onset and offset ranges.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
set_color_bits
Sets the number of requested color bits as a single number that represents the sum of the individual ...
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.
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
Encapsulates the data from a Geom, pre-fetched for one stage of the pipeline.
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
This object describes how the vertex animation, if any, represented in a GeomVertexData is encoded.
get_animation_type
Returns the type of animation represented by this spec.
get_indexed_transforms
This is only meaningful for animation_type AT_hardware.
get_num_transforms
This is only meaningful for animation_type AT_hardware.
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
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...
This is the data for one array of a GeomVertexData structure.
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
int get_data1i()
Returns the data associated with the read row, expressed as a 1-component value, and advances the rea...
This class is the main interface to controlling the render process.
void reset_all_windows(bool swapchain)
Resets the framebuffer of the current window.
An object to create GraphicsOutputs that share a particular 3-D API.
static void add_gsg(GraphicsStateGuardianBase *gsg)
Called by a GSG after it has been initialized, to add a new GSG to the available list.
Encapsulates all the communication with a particular instance of a given rendering backend.
void release_all()
Releases all prepared objects.
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomVertexDataPipelineReader *data_reader, bool force)
Called before a sequence of draw_primitive() functions are called, this should prepare the vertex dat...
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
virtual bool get_supports_compressed_texture_format(int compression_mode) const
Returns true if this GSG can accept textures pre-compressed in the indicated format.
virtual void prepare_display_region(DisplayRegionPipelineReader *dr)
Makes the specified DisplayRegion current.
get_prepared_objects
Returns the set of texture and geom objects that have been prepared with this GSG (and possibly other...
void mark_new()
Marks the GSG as "new", so that the next call to reset_if_new() will be effective.
virtual void do_issue_light()
This implementation of do_issue_light() assumes we have a limited number of hardware lights available...
void do_issue_color()
This method is defined in the base class because it is likely that this functionality will be used fo...
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_scene()
Called between begin_frame() and end_frame() to mark the end of drawing commands for a "scene" (usual...
virtual void reset()
Resets all internal state as if the gsg were newly created.
int release_all_vertex_buffers()
Frees the resources for all vertex buffers associated with this GSG.
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...
virtual void end_draw_primitives()
Called after a sequence of draw_primitive() functions are called, this should do whatever cleanup is ...
int release_all_index_buffers()
Frees the resources for all index buffers associated with this GSG.
virtual bool begin_scene()
Called between begin_frame() and end_frame() to mark the beginning of drawing commands for a "scene" ...
This is a special class object that holds all the information returned by a particular GSG to indicat...
bool changed_size(const GeomPrimitivePipelineReader *reader) const
Returns true if the data has changed size since the last time mark_loaded() was called.
void mark_loaded(const GeomPrimitivePipelineReader *reader)
Should be called after the IndexBufferContext has been loaded into graphics memory,...
bool was_modified(const GeomPrimitivePipelineReader *reader) const
Returns true if the data has been modified since the last time mark_loaded() was called.
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...
A base class for any number of different kinds of lenses, linear and otherwise.
virtual bool is_linear() const
Returns true if the lens represents a linear projection (e.g.
PN_stdfloat get_hfov() const
Returns the horizontal component of fov only.
get_nodal_point
Returns the center point of the lens: the point from which the lens is viewing.
const LVector3 & get_view_vector() const
Returns the axis along which the lens is facing.
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,...
The abstract interface to all kinds of lights.
get_color
Returns the basic color of the light.
Indicates which, if any, material should be applied to geometry.
bool is_off() const
Returns true if the MaterialAttrib is an 'off' MaterialAttrib, indicating that it should disable the ...
get_material
If the MaterialAttrib is not an 'off' MaterialAttrib, returns the material that is associated.
Defines the way an object appears in the presence of lighting.
get_ambient
Returns the ambient color setting, if it has been set.
has_specular
Returns true if the specular color has been explicitly set for this material, false otherwise.
get_emission
Returns the emission color setting, if it has been set.
has_diffuse
Returns true if the diffuse color has been explicitly set for this material, false otherwise.
has_base_color
Returns true if the base color has been explicitly set for this material, false otherwise.
get_specular
Returns the specular color setting, if it has been set.
has_ambient
Returns true if the ambient color has been explicitly set for this material, false otherwise.
get_shininess
Returns the shininess exponent of the material.
get_diffuse
Returns the diffuse color setting, if it has been set.
get_local
Returns the local viewer flag.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
PandaNode * node() const
Returns the referenced node of the path.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Returned from a GSG in response to begin_occlusion_query() .
A lightweight class that represents a single element that may be timed and/or counted via stats.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
A node that contains a plane.
const LPlane & get_plane() const
Returns the plane represented by the PlaneNode.
A light originating from a single point in space, and shining in all directions.
get_specular_color
Returns the color of specular highlights generated by the light.
get_point
Returns the point in space at which the light is located.
get_attenuation
Returns the terms of the attenuation equation for the light.
A RenderBuffer is an arbitrary subset of the various layers (depth buffer, color buffer,...
Specifies how polygons are to be drawn.
get_perspective
Returns the perspective flag.
get_thickness
Returns the line width or point thickness.
get_mode
Returns the render mode.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Specifies how polygons are to be drawn.
get_mode
Returns the render mode.
Represents a set of settings that indicate how a texture is sampled.
get_wrap_v
Returns the wrap mode of the texture in the V direction.
get_wrap_w
Returns the wrap mode of the texture in the W direction.
get_effective_magfilter
Returns the filter mode of the texture for magnification, with special treatment for FT_default.
get_lod_bias
Returns the bias that will be added to the texture level of detail when sampling this texture.
get_effective_minfilter
Returns the filter mode of the texture for minification, with special treatment for FT_default.
get_effective_anisotropic_degree
Returns the degree of anisotropic filtering that should be applied to the texture.
get_wrap_u
Returns the wrap mode of the texture in the U direction.
get_border_color
Returns the solid color of the texture's border.
This restricts rendering to within a rectangular region of the scene, without otherwise affecting the...
get_frame
Returns the left, right, bottom, top coordinates of the scissor frame.
Specifies whether flat shading (per-polygon) or smooth shading (per-vertex) is in effect.
get_mode
Returns the shade mode.
The ShaderContext is meant to contain the compiled version of a shader string.
ShaderContext * prepare_now(PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg)
Creates a context for the shader on the particular GSG, if it does not already exist.
ShaderLanguage get_language() const
Returns the shader language in which this shader was written.
A light originating from a single point in space, and shining in a particular direction,...
get_specular_color
Returns the color of specular highlights generated by the light.
get_exponent
Returns the exponent that controls the amount of light falloff from the center of the spotlight.
get_attenuation
Returns the terms of the attenuation equation for the light.
A StencilAttrib is a collection of all stencil render states.
unsigned int get_render_state(StencilRenderState render_state_identifier) const
Returns render state.
Applies a transform matrix to UV's before they are rendered.
This is a special class object that holds all the information returned by a particular GSG to indicat...
bool was_simple_image_modified() const
Returns true if the texture's "simple" image has been modified since the last time mark_simple_loaded...
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.
Texture * get_texture() const
Returns the pointer to the associated Texture object.
bool was_modified() const
Returns true if the texture properties or image have been modified since the last time mark_loaded() ...
void mark_unloaded()
Should be called after the texture has been forced out of texture memory.
void mark_loaded()
Should be called after the texture has been loaded into graphics memory, this updates the internal fl...
Defines the properties of a named stage of the multitexture pipeline.
CombineMode get_combine_alpha_mode() const
Get combine_alpha_mode.
get_saved_result
Returns the current setting of the saved_result flag.
CombineOperand get_combine_rgb_operand2() const
Get operand2 of combine_rgb_mode.
CombineSource get_combine_alpha_source1() const
Get source1 of combine_alpha_mode.
CombineMode get_combine_rgb_mode() const
Get the combine_rgb_mode.
CombineSource get_combine_rgb_source1() const
Get source1 of combine_rgb_mode.
bool involves_color_scale() const
Returns true if the TextureStage is affected by the setting of the current ColorScaleAttrib,...
CombineOperand get_combine_alpha_operand0() const
Get operand0 of combine_alpha_mode.
CombineOperand get_combine_rgb_operand1() const
Get operand1 of combine_rgb_mode.
CombineSource get_combine_alpha_source0() const
Get source0 of combine_alpha_mode.
get_rgb_scale
See set_rgb_scale().
get_alpha_scale
See set_alpha_scale().
int get_num_combine_rgb_operands() const
Returns the number of meaningful operands that may be retrieved via get_combine_rgb_sourceN() and get...
CombineOperand get_combine_alpha_operand1() const
Get operand1 of combine_alpha_mode.
get_color
return the color for this stage
get_tex_view_offset
Returns the current setting of the tex_view_offset.
CombineSource get_combine_rgb_source0() const
Get source0 of combine_rgb_mode.
CombineSource get_combine_rgb_source2() const
Get source2 of combine_rgb_mode.
get_mode
Return the mode of this stage.
bool uses_color() const
Returns true if the TextureStage makes use of whatever color is specified in set_color(),...
int get_num_combine_alpha_operands() const
Returns the number of meaningful operands that may be retrieved via get_combine_alpha_sourceN() and g...
CombineOperand get_combine_rgb_operand0() const
Get operand0 of combine_rgb_mode.
CombineSource get_combine_alpha_source2() const
Get source2 of combine_alpha_mode.
CombineOperand get_combine_alpha_operand2() const
Get operand2 of combine_alpha_mode.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
get_format
Returns the format of the texture, which represents both the semantic meaning of the texels and,...
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.
get_num_views
Returns the number of "views" in the texture.
bool has_ram_image() const
Returns true if the Texture has its image contents available in main RAM, false if it exists only in ...
get_texture_type
Returns the overall interpretation of the texture.
static bool is_srgb(Format format)
Returns true if the indicated format is in the sRGB color space, false otherwise.
get_ram_image_compression
Returns the compression mode in which the ram image is already stored pre- compressed.
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...
set_render_to_texture
Sets a flag on the texture that indicates whether the texture is intended to be used as a direct-rend...
get_y_size
Returns the height of the texture image in texels.
get_z_size
Returns the depth of the texture image in texels.
bool might_have_ram_image() const
Returns true if the texture's image contents are currently available in main RAM, or there is reason ...
has_simple_ram_image
Returns true if the Texture has a "simple" image available in main RAM.
get_x_size
Returns the width of the texture image in texels.
bool has_uncompressed_ram_image() const
Returns true if the Texture has its image contents available in main RAM and is uncompressed,...
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.
get_component_type
Returns the numeric interpretation of each component of the texture.
A thread; that is, a lightweight process.
get_current_thread
Returns a pointer to the currently-executing Thread object.
This controls the enabling of transparency.
get_mode
Returns the transparency mode.
TypeHandle is the identifier used to differentiate C++ class types.
This is a special class object that holds all the information returned by a particular GSG to indicat...
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.
bool was_modified(const GeomVertexArrayDataHandle *reader) const
Returns true if the data has been modified since the last time mark_loaded() was called.
bool changed_size(const GeomVertexArrayDataHandle *reader) const
Returns true if the data has changed size since the last time mark_loaded() was called.
void mark_loaded(const GeomVertexArrayDataHandle *reader)
Should be called after the VertexBufferContext has been loaded into graphics memory,...
An offscreen render buffer.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PT(OcclusionQueryContext) DXGraphicsStateGuardian9
Ends a previous call to begin_occlusion_query().
CPT(TransformState) DXGraphicsStateGuardian9
Given a lens, calculates the appropriate projection matrix for use with this gsg.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.