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)
84TypeHandle DXGraphicsStateGuardian9::_type_handle;
86D3DMATRIX DXGraphicsStateGuardian9::_d3d_ident_mat;
88unsigned char *DXGraphicsStateGuardian9::_temp_buffer =
nullptr;
89unsigned char *DXGraphicsStateGuardian9::_safe_buffer_start =
nullptr;
92LPDIRECT3DDEVICE9 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))
102DXGraphicsStateGuardian9::
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);
168DXGraphicsStateGuardian9::
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;
777end_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) {
941calc_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;
1304bool DXGraphicsStateGuardian9::
1305update_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);
1352void DXGraphicsStateGuardian9::
1353disable_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);
2075 if (surface_description.MultiSampleType != D3DMULTISAMPLE_NONE) {
2076 IDirect3DSurface9 *resolved;
2077 hr = _d3d_device->CreateRenderTarget(surface_description.Width,
2078 surface_description.Height,
2079 surface_description.Format,
2080 D3DMULTISAMPLE_NONE, 0, FALSE,
2081 &resolved,
nullptr);
2084 <<
"CreateRenderTarget failed" << D3DERRORSTRING(hr) <<
"\n";
2085 backbuffer->Release();
2089 _d3d_device->StretchRect(backbuffer,
nullptr, resolved,
nullptr, D3DTEXF_NONE);
2092 <<
"StretchRect failed" << D3DERRORSTRING(hr) <<
"\n";
2093 backbuffer->Release();
2094 resolved->Release();
2098 backbuffer->Release();
2099 backbuffer = resolved;
2102 pool = D3DPOOL_SYSTEMMEM;
2103 hr = _d3d_device->CreateOffscreenPlainSurface(
2104 surface_description.Width,
2105 surface_description.Height,
2106 surface_description.Format,
2112 <<
"CreateImageSurface failed in copy_pixel_buffer()"
2113 << D3DERRORSTRING(hr);
2114 backbuffer->Release();
2119 hr = _d3d_device -> GetRenderTargetData (backbuffer, temp_surface);
2121 dxgsg9_cat.error() <<
"GetRenderTargetData failed" << D3DERRORSTRING(hr);
2122 temp_surface->Release();
2123 backbuffer->Release();
2127 copy_inverted =
true;
2129 RELEASE(backbuffer, dxgsg9,
"backbuffer", RELEASE_ONCE);
2131 }
else if (_cur_read_pixel_buffer & RenderBuffer::T_front) {
2133 if (_screen->_presentation_params.Windowed) {
2140 minfo.cbSize =
sizeof(MONITORINFO);
2141 GetMonitorInfo(_screen->_monitor, &minfo);
2143 w = RECT_XSIZE(minfo.rcMonitor);
2144 h = RECT_YSIZE(minfo.rcMonitor);
2147 ClientToScreen(_screen->_window, (POINT*)&rect.left);
2148 ClientToScreen(_screen->_window, (POINT*)&rect.right);
2153 hr = _d3d_device->CreateOffscreenPlainSurface(w, h, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &temp_surface,
nullptr);
2156 <<
"CreateImageSurface failed in copy_pixel_buffer()"
2157 << D3DERRORSTRING(hr);
2164 hr = _d3d_device->GetFrontBufferData(swap_chain,temp_surface);
2166 if (hr == D3DERR_DEVICELOST) {
2168 <<
"copy_pixel_buffer failed: device lost\n";
2169 temp_surface->Release();
2173 copy_inverted =
true;
2177 <<
"copy_pixel_buffer: unhandled current_read_pixel_buffer type\n";
2178 temp_surface->Release();
2183 copy_inverted = !copy_inverted;
2186 copy_inverted, tex, view, z);
2188 RELEASE(temp_surface, dxgsg9,
"temp_surface", RELEASE_ONCE);
2194void DXGraphicsStateGuardian9::reset_render_states (
void)
2197 int maximum_texture_stages;
2199 maximum_texture_stages = D3D_MAXTEXTURESTAGES;
2202 memset (_render_state_array, -1,
sizeof (_render_state_array));
2203 memset (_texture_stage_states_array, -1,
sizeof (_texture_stage_states_array));
2207 _render_state_array [D3DRS_FOGCOLOR] = 0;
2208 _render_state_array [D3DRS_AMBIENT] = 0;
2212 memset (_texture_render_states_array, 0,
sizeof (_texture_render_states_array));
2216 for (index = 0; index < MAXIMUM_TEXTURES; index++) {
2217 TextureRenderStates *texture_render_states;
2219 texture_render_states = &_texture_render_states_array [index];
2220 texture_render_states -> state_array [D3DSAMP_MAGFILTER] = D3DTEXF_POINT;
2221 texture_render_states -> state_array [D3DSAMP_MINFILTER] = D3DTEXF_POINT;
2222 texture_render_states -> state_array [D3DSAMP_MAXANISOTROPY] = 1;
2224 _num_active_texture_stages = 0;
2243 _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot());
2244 _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot());
2245 _inv_state_mask.clear_bit(ClipPlaneAttrib::get_class_slot());
2246 _inv_state_mask.clear_bit(ColorAttrib::get_class_slot());
2247 _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot());
2248 _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot());
2249 _inv_state_mask.clear_bit(DepthOffsetAttrib::get_class_slot());
2250 _inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot());
2251 _inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
2252 _inv_state_mask.clear_bit(RenderModeAttrib::get_class_slot());
2253 _inv_state_mask.clear_bit(RescaleNormalAttrib::get_class_slot());
2254 _inv_state_mask.clear_bit(ShadeModelAttrib::get_class_slot());
2255 _inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
2256 _inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
2257 _inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot());
2258 _inv_state_mask.clear_bit(TextureAttrib::get_class_slot());
2259 _inv_state_mask.clear_bit(TexGenAttrib::get_class_slot());
2260 _inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
2261 _inv_state_mask.clear_bit(MaterialAttrib::get_class_slot());
2262 _inv_state_mask.clear_bit(LightAttrib::get_class_slot());
2263 _inv_state_mask.clear_bit(StencilAttrib::get_class_slot());
2264 _inv_state_mask.clear_bit(FogAttrib::get_class_slot());
2265 _inv_state_mask.clear_bit(ScissorAttrib::get_class_slot());
2270 _supported_geom_rendering =
2271 Geom::GR_point | Geom::GR_point_uniform_size |
2272 Geom::GR_point_perspective | Geom::GR_point_sprite |
2273 Geom::GR_indexed_other |
2274 Geom::GR_triangle_strip | Geom::GR_triangle_fan |
2275 Geom::GR_flat_first_vertex |
2276 Geom::GR_render_mode_wireframe | Geom::GR_render_mode_point;
2287 nassertv(_screen->_d3d9 !=
nullptr);
2289 if (_d3d_device ==
nullptr) {
2294 _d3d_device->GetDeviceCaps(&d3d_caps);
2296 _vertex_shader_version_major = D3DSHADER_VERSION_MAJOR (d3d_caps.VertexShaderVersion);
2297 _vertex_shader_version_minor = D3DSHADER_VERSION_MINOR (d3d_caps.VertexShaderVersion);
2298 _pixel_shader_version_major = D3DSHADER_VERSION_MAJOR (d3d_caps.PixelShaderVersion);
2299 _pixel_shader_version_minor = D3DSHADER_VERSION_MINOR (d3d_caps.PixelShaderVersion);
2301 _supports_hlsl = (_pixel_shader_version_major != 0);
2303 _vertex_shader_profile = (
char *) D3DXGetVertexShaderProfile (_d3d_device);
2304 _pixel_shader_profile = (
char *) D3DXGetPixelShaderProfile (_d3d_device);
2306 _vertex_shader_maximum_constants = d3d_caps.MaxVertexShaderConst;
2308 switch (_pixel_shader_version_major)
2311 _shader_model = SM_00;
2314 _shader_model = SM_11;
2318 _shader_model = SM_20;
2319 if (d3d_caps.PS20Caps.NumInstructionSlots >= 512) {
2320 _shader_model = SM_2X;
2324 _shader_model = SM_30;
2327 _shader_model = SM_40;
2331 _shader_model = SM_50;
2335 _auto_detect_shader_model = _shader_model;
2340 _cg_context = cgCreateContext();
2342 if (cgD3D9IsProfileSupported(CG_PROFILE_PS_2_0) &&
2343 cgD3D9IsProfileSupported(CG_PROFILE_VS_2_0)) {
2344 _supports_basic_shaders =
true;
2345 _shader_caps._active_vprofile = (int)cgD3D9GetLatestVertexProfile();
2346 _shader_caps._active_fprofile = (int)cgD3D9GetLatestPixelProfile();
2347 _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VS_3_0;
2348 _shader_caps._ultimate_fprofile = (int)CG_PROFILE_PS_3_0;
2357 if (dxgsg9_cat.is_debug()) {
2358 CGprofile vertex_profile;
2359 CGprofile pixel_profile;
2361 vertex_profile = cgD3D9GetLatestVertexProfile();
2362 pixel_profile = cgD3D9GetLatestPixelProfile();
2364 const char *vertex_profile_str =
2365 cgGetProfileString(vertex_profile);
2366 const char *pixel_profile_str =
2367 cgGetProfileString(pixel_profile);
2369 if (vertex_profile_str ==
nullptr) {
2370 vertex_profile_str =
"(null)";
2372 if (pixel_profile_str ==
nullptr) {
2373 pixel_profile_str =
"(null)";
2377 <<
"\nCg latest vertex profile = " << vertex_profile_str <<
" id = " << vertex_profile
2378 <<
"\nCg latest pixel profile = " << pixel_profile_str <<
" id = " << pixel_profile
2379 <<
"\nshader model = " << _shader_model
2384 _supports_stream_offset = (d3d_caps.DevCaps2 & D3DDEVCAPS2_STREAMOFFSET) != 0;
2385 _screen->_supports_dynamic_textures = ((d3d_caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) != 0);
2386 _screen->_supports_automatic_mipmap_generation = ((d3d_caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0);
2388 if (support_stencil) {
2389 int min_stencil = D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR;
2390 if ((d3d_caps.StencilCaps & min_stencil) == min_stencil) {
2391 if (dxgsg9_cat.is_debug()) {
2393 <<
"Checking for stencil; mode = "
2394 << D3DFormatStr(_screen->_presentation_params.AutoDepthStencilFormat)
2397 switch (_screen->_presentation_params.AutoDepthStencilFormat) {
2401 case D3DFMT_D24X4S4:
2402 _supports_stencil =
true;
2403 if (dxgsg9_cat.is_debug()) {
2405 <<
"Stencils supported.\n";
2410 if (dxgsg9_cat.is_debug()) {
2412 <<
"Stencils NOT supported.\n";
2418 _supports_stencil_wrap = (d3d_caps.StencilCaps & D3DSTENCILCAPS_INCR) && (d3d_caps.StencilCaps & D3DSTENCILCAPS_DECR);
2419 _supports_two_sided_stencil = ((d3d_caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) != 0);
2421 _max_color_targets = d3d_caps.NumSimultaneousRTs;
2423 _supports_depth_bias = ((d3d_caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) == (D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS));
2425 _supports_gamma_calibration = ((d3d_caps.Caps2 & D3DCAPS2_CANCALIBRATEGAMMA) != 0);
2428 hr = _d3d_device->CreateQuery(D3DQUERYTYPE_OCCLUSION,
nullptr);
2429 _supports_occlusion_query = !FAILED(hr);
2431 if (dxgsg9_cat.is_error()) {
2433 <<
"\nHwTransformAndLight = " << ((d3d_caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
2434 <<
"\nMaxTextureWidth = " << d3d_caps.MaxTextureWidth
2435 <<
"\nMaxTextureHeight = " << d3d_caps.MaxTextureHeight
2436 <<
"\nMaxVolumeExtent = " << d3d_caps.MaxVolumeExtent
2437 <<
"\nMaxTextureAspectRatio = " << d3d_caps.MaxTextureAspectRatio
2438 <<
"\nTexCoordCount = " << (d3d_caps.FVFCaps & D3DFVFCAPS_TEXCOORDCOUNTMASK)
2439 <<
"\nMaxTextureBlendStages = " << d3d_caps.MaxTextureBlendStages
2440 <<
"\nMaxSimultaneousTextures = " << d3d_caps.MaxSimultaneousTextures
2441 <<
"\nMaxActiveLights = " << d3d_caps.MaxActiveLights
2442 <<
"\nMaxUserClipPlanes = " << d3d_caps.MaxUserClipPlanes
2443 <<
"\nMaxVertexBlendMatrices = " << d3d_caps.MaxVertexBlendMatrices
2444 <<
"\nMaxVertexBlendMatrixIndex = " << d3d_caps.MaxVertexBlendMatrixIndex
2445 <<
"\nMaxPointSize = " << d3d_caps.MaxPointSize
2446 <<
"\nMaxPrimitiveCount = " << d3d_caps.MaxPrimitiveCount
2447 <<
"\nMaxVertexIndex = " << d3d_caps.MaxVertexIndex
2448 <<
"\nMaxStreams = " << d3d_caps.MaxStreams
2449 <<
"\nMaxStreamStride = " << d3d_caps.MaxStreamStride
2450 <<
"\nD3DTEXOPCAPS_MULTIPLYADD = " << ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_MULTIPLYADD) != 0)
2451 <<
"\nD3DTEXOPCAPS_LERP = " << ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_LERP) != 0)
2452 <<
"\nD3DPMISCCAPS_TSSARGTEMP = " << ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) != 0)
2453 <<
"\nD3DPRASTERCAPS_DEPTHBIAS = " << ((d3d_caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS) != 0)
2454 <<
"\nD3DPRASTERCAPS_SLOPESCALEDEPTHBIAS = " << ((d3d_caps.RasterCaps & D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS) != 0)
2455 <<
"\nVertexShaderVersion = " << _vertex_shader_version_major <<
"." << _vertex_shader_version_minor
2456 <<
"\nPixelShaderVersion = " << _pixel_shader_version_major <<
"." << _pixel_shader_version_minor
2457 <<
"\nMaxVertexShaderConst = " << _vertex_shader_maximum_constants
2458 <<
"\nsupports_stream_offset = " << _supports_stream_offset
2459 <<
"\nsupports_dynamic_textures = " << _screen->_supports_dynamic_textures
2460 <<
"\nsupports_automatic_mipmap_generation = " << _screen->_supports_automatic_mipmap_generation
2461 <<
"\nsupports_stencil_wrap = " << _supports_stencil_wrap
2462 <<
"\nsupports_two_sided_stencil = " << _supports_two_sided_stencil
2463 <<
"\nsupports_occlusion_query = " << _supports_occlusion_query
2464 <<
"\nsupports_gamma_calibration = " << _supports_gamma_calibration
2465 <<
"\nMaxAnisotropy = " << d3d_caps.MaxAnisotropy
2466 <<
"\nNumSimultaneousRTs = " << d3d_caps.NumSimultaneousRTs
2467 <<
"\nD3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING = " << ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) != 0)
2468 <<
"\nDirectX SDK version " DIRECTX_SDK_VERSION
2473 _screen->_supports_automatic_mipmap_generation =
false;
2475 reset_render_states();
2477 _max_vertices_per_array = d3d_caps.MaxVertexIndex;
2478 _max_vertices_per_primitive = d3d_caps.MaxPrimitiveCount;
2480 _max_texture_stages = d3d_caps.MaxSimultaneousTextures;
2482 _max_texture_dimension = min(d3d_caps.MaxTextureWidth, d3d_caps.MaxTextureHeight);
2484 _supports_tex_non_pow2 = !(d3d_caps.TextureCaps & D3DPTEXTURECAPS_POW2);
2486 _supports_texture_combine = ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_LERP) != 0);
2487 _supports_texture_saved_result = ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) != 0);
2488 _supports_texture_constant_color = ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT) != 0);
2489 _supports_texture_dot3 =
true;
2491 if (_supports_texture_constant_color) {
2492 _constant_color_operand = D3DTA_CONSTANT;
2494 _constant_color_operand = D3DTA_TFACTOR;
2497 _screen->_managed_textures = _gsg_managed_textures;
2498 _screen->_managed_vertex_buffers = _gsg_managed_vertex_buffers;
2499 _screen->_managed_index_buffers = _gsg_managed_index_buffers;
2501 UINT available_texture_memory;
2503 available_texture_memory = _d3d_device->GetAvailableTextureMem ( );
2504 if (dxgsg9_cat.is_debug()) {
2505 dxgsg9_cat.debug() <<
"*** GetAvailableTextureMem = " << available_texture_memory <<
"\n";
2507 _available_texture_memory = available_texture_memory;
2510 D3DDEVICE_CREATION_PARAMETERS creation_parameters;
2512 _supports_render_texture =
false;
2513 _screen->_render_to_texture_d3d_format = D3DFMT_UNKNOWN;
2514 _screen->_framebuffer_d3d_format = D3DFMT_UNKNOWN;
2516 #define TOTAL_RENDER_TO_TEXTURE_FORMATS 3
2518 D3DFORMAT render_to_texture_formats [TOTAL_RENDER_TO_TEXTURE_FORMATS] =
2525 render_to_texture_formats [TOTAL_RENDER_TO_TEXTURE_FORMATS - 1] = _screen->_display_mode.Format;
2527 hr = _d3d_device->GetCreationParameters (&creation_parameters);
2528 if (SUCCEEDED (hr)) {
2529 _screen->_framebuffer_d3d_format = _screen->_display_mode.Format;
2532 for (index = 0; index < TOTAL_RENDER_TO_TEXTURE_FORMATS; index++) {
2533 hr = _screen->_d3d9->CheckDeviceFormat (
2534 creation_parameters.AdapterOrdinal,
2535 creation_parameters.DeviceType,
2536 _screen->_display_mode.Format,
2537 D3DUSAGE_RENDERTARGET,
2539 render_to_texture_formats [index]);
2540 if (SUCCEEDED (hr)) {
2541 _screen->_render_to_texture_d3d_format = render_to_texture_formats [index];
2542 _supports_render_texture =
true;
2544 if (_supports_render_texture) {
2549 if (dxgsg9_cat.is_debug()) {
2550 dxgsg9_cat.debug() <<
"Render to Texture Support = " << _supports_render_texture <<
"\n";
2556 _supports_3d_texture = ((d3d_caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) != 0);
2557 if (_supports_3d_texture) {
2558 _max_3d_texture_dimension = d3d_caps.MaxVolumeExtent;
2560 _supports_cube_map = ((d3d_caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) != 0);
2561 if (_supports_cube_map) {
2562 _max_cube_map_dimension = _max_texture_dimension;
2565 _max_lights = (int)d3d_caps.MaxActiveLights;
2566 _max_clip_planes = (int)d3d_caps.MaxUserClipPlanes;
2567 _max_vertex_transforms = d3d_caps.MaxVertexBlendMatrices;
2568 _max_vertex_transform_indices = d3d_caps.MaxVertexBlendMatrixIndex;
2572 _clip_plane_bits = 0;
2590 _has_scene_graph_color =
false;
2592 _last_testcooplevel_result = D3D_OK;
2594 if (dxgsg9_cat.is_debug()) {
2595 dxgsg9_cat.debug() <<
"Supported texture formats:\n";
2598 for(
int i = 0; i < MAX_POSSIBLE_TEXFMTS; i++) {
2600 D3DFORMAT_FLAG fmtflag = D3DFORMAT_FLAG(1 << i);
2601 hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format,
2602 0x0, D3DRTYPE_TEXTURE, g_D3DFORMATmap[fmtflag]);
2603 if (SUCCEEDED(hr)) {
2604 if (dxgsg9_cat.is_debug()) {
2605 dxgsg9_cat.debug() <<
" " << D3DFormatStr(g_D3DFORMATmap[fmtflag]) <<
"\n";
2607 _screen->_supported_tex_formats_mask |= fmtflag;
2611 _supports_depth_stencil = ((_screen->_supported_tex_formats_mask & D24S8_FLAG) != 0);
2612 _supports_depth_texture = _supports_depth_stencil ||
2613 (_screen->_supported_tex_formats_mask & D16_FLAG) != 0 ||
2614 (_screen->_supported_tex_formats_mask & D32_FLAG) != 0 ||
2615 (_screen->_supported_tex_formats_mask & D24X8_FLAG) != 0;
2621 _supports_shadow_filter = _supports_depth_texture;
2624 #define CHECK_COMPRESSED_FMT(mode, fmt) \
2625 if (_screen->_supported_tex_formats_mask & fmt##_FLAG) {\
2626 if (dxgsg9_cat.is_debug()) {\
2627 dxgsg9_cat.debug() << "Compressed texture format " << #fmt << " supported\n";\
2629 _supports_compressed_texture = true;\
2630 _compressed_texture_formats.set_bit(Texture::mode);\
2633 if (_screen->_intel_compressed_texture_bug) {
2635 <<
"Buggy Intel driver detected; disabling compressed textures.\n";
2636 _screen->_supported_tex_formats_mask &=
2637 ~(DXT1_FLAG | DXT2_FLAG | DXT3_FLAG | DXT4_FLAG | DXT5_FLAG);
2641 CHECK_COMPRESSED_FMT(CM_dxt1, DXT1);
2642 CHECK_COMPRESSED_FMT(CM_dxt2, DXT2);
2643 CHECK_COMPRESSED_FMT(CM_dxt3, DXT3);
2644 CHECK_COMPRESSED_FMT(CM_dxt4, DXT4);
2645 CHECK_COMPRESSED_FMT(CM_dxt5, DXT5);
2646 CHECK_COMPRESSED_FMT(CM_rgtc, ATI1);
2647 CHECK_COMPRESSED_FMT(CM_rgtc, ATI2);
2650 #undef CHECK_COMPRESSED_FMT
2652 _screen->_supports_rgba16f_texture_format =
false;
2653 hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format, 0x0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F);
2655 _screen->_supports_rgba16f_texture_format =
true;
2657 _screen->_supports_rgba32_texture_format =
false;
2658 hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format, 0x0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F);
2660 _screen->_supports_rgba32_texture_format =
true;
2664 if (_screen->_d3dcaps.MaxTextureWidth == 0)
2665 _screen->_d3dcaps.MaxTextureWidth = 256;
2667 if (_screen->_d3dcaps.MaxTextureHeight == 0)
2668 _screen->_d3dcaps.MaxTextureHeight = 256;
2670 if (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) {
2674 _do_fog_type = PerPixelFog;
2678 nassertv((_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGVERTEX) != 0);
2683 if (dx_no_vertex_fog) {
2684 _do_fog_type = None;
2686 _do_fog_type = PerVertexFog;
2689 if (dx_use_rangebased_fog && (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGRANGE)) {
2695 _screen->_can_direct_disable_color_writes = ((_screen->_d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0);
2701 bool dither_enabled = ((!dx_no_dithering) && IS_16BPP_DISPLAY_FORMAT(_screen->_presentation_params.BackBufferFormat)
2702 && (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_DITHER));
2709 if (_supports_two_sided_stencil) {
2717 _current_fill_mode = RenderModeAttrib::M_filled;
2724 _cull_face_mode = CullFaceAttrib::M_cull_none;
2737 _current_shader =
nullptr;
2738 _current_shader_context =
nullptr;
2739 _vertex_array_shader =
nullptr;
2740 _vertex_array_shader_context =
nullptr;
2741 _texture_binding_shader =
nullptr;
2742 _texture_binding_shader_context =
nullptr;
2744 PRINT_REFCNT(dxgsg9, _d3d_device);
2754void DXGraphicsStateGuardian9::
2755apply_fog(
Fog *fog) {
2756 if (_do_fog_type == None)
2759 Fog::Mode panda_fogmode = fog->get_mode();
2760 D3DFOGMODE d3dfogmode = get_fog_mode_type(panda_fogmode);
2764 const LColor &fog_colr = fog->
get_color();
2766 MY_D3DRGBA(fog_colr[0], fog_colr[1], fog_colr[2], 0.0f));
2772 switch (panda_fogmode) {
2775 PN_stdfloat onset, opaque;
2779 *((LPDWORD) (&onset)));
2781 *((LPDWORD) (&opaque)));
2784 case Fog::M_exponential:
2785 case Fog::M_exponential_squared:
2790 *((LPDWORD) (&fog_density)));
2803void DXGraphicsStateGuardian9::
2804do_issue_transform() {
2806 DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
2808 if (_current_shader_context) {
2814 LMatrix4f mat = LCAST(
float, transform->
get_mat());
2815 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)mat.get_data();
2816 _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
2820 LMatrix4f mat = LCAST(
float, transform->
get_mat());
2821 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)mat.get_data();
2822 _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
2837 _transform_stale =
false;
2843void DXGraphicsStateGuardian9::
2844do_issue_alpha_test() {
2845 if (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) {
2849 AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->
get_mode();
2850 if (mode == AlphaTestAttrib::M_none) {
2864void DXGraphicsStateGuardian9::
2869 if (_target_shader) {
2870 shader = (
Shader *)(_target_shader->get_shader());
2876 if (context == 0 || (context && context -> valid (
this) ==
false)) {
2877 if (_current_shader_context != 0) {
2878 _current_shader_context->
unbind(
this);
2879 _current_shader = 0;
2880 _current_shader_context = 0;
2881 disable_standard_texture_bindings();
2886 if (context != _current_shader_context) {
2889 if (_current_shader_context != 0) {
2890 _current_shader_context->
unbind(
this);
2891 _current_shader_context = 0;
2892 _current_shader = 0;
2893 disable_standard_texture_bindings();
2896 context->
bind(
this);
2897 _current_shader = shader;
2898 _current_shader_context = context;
2909void DXGraphicsStateGuardian9::
2910do_issue_render_mode() {
2912 _target_rs->get_attrib_def(target_render_mode);
2913 RenderModeAttrib::Mode mode = target_render_mode->
get_mode();
2916 case RenderModeAttrib::M_unchanged:
2917 case RenderModeAttrib::M_filled:
2918 case RenderModeAttrib::M_filled_flat:
2922 case RenderModeAttrib::M_wireframe:
2926 case RenderModeAttrib::M_point:
2932 <<
"Unknown render mode " << (int)mode << endl;
2936 PN_stdfloat point_size = target_render_mode->
get_thickness();
2942 LVector3 height(0.0f, point_size, 1.0f);
2943 height = height * _projection_mat->get_mat();
2944 PN_stdfloat s = height[1] / point_size;
2946 PN_stdfloat zero = 0.0f;
2947 PN_stdfloat one_over_s2 = 1.0f / (s * s);
2956 _current_fill_mode = mode;
2962void DXGraphicsStateGuardian9::
2963do_issue_rescale_normal() {
2964 RescaleNormalAttrib::Mode mode = RescaleNormalAttrib::M_none;
2967 if (_target_rs->get_attrib(target_rescale_normal)) {
2968 mode = target_rescale_normal->
get_mode();
2972 case RescaleNormalAttrib::M_none:
2976 case RescaleNormalAttrib::M_rescale:
2977 case RescaleNormalAttrib::M_normalize:
2983 <<
"Unknown rescale_normal mode " << (int)mode << endl;
2990void DXGraphicsStateGuardian9::
2991do_issue_depth_test() {
2993 DepthTestAttrib::PandaCompareFunc mode = target_depth_test->
get_mode();
2994 if (mode == DepthTestAttrib::M_none) {
3005void DXGraphicsStateGuardian9::
3006do_issue_depth_write() {
3008 DepthWriteAttrib::Mode mode = target_depth_write->
get_mode();
3009 if (mode == DepthWriteAttrib::M_on) {
3019void DXGraphicsStateGuardian9::
3020do_issue_cull_face() {
3024 switch (_cull_face_mode) {
3025 case CullFaceAttrib::M_cull_none:
3031 case CullFaceAttrib::M_cull_clockwise:
3037 case CullFaceAttrib::M_cull_counter_clockwise:
3045 <<
"invalid cull face mode " << (int)_cull_face_mode << endl;
3053void DXGraphicsStateGuardian9::
3055 const FogAttrib *target_fog = DCAST(
FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot()));
3056 if (!target_fog->
is_off()) {
3059 nassertv(fog !=
nullptr);
3069void DXGraphicsStateGuardian9::
3070do_issue_depth_offset() {
3072 int offset = target_depth_offset->
get_offset();
3074 if (_supports_depth_bias && !dx_broken_depth_bias) {
3081 static const PN_stdfloat bias_scale = dx_depth_bias_scale;
3082 D3DVIEWPORT9 vp = _current_viewport;
3083 vp.MinZ -= bias_scale * offset;
3084 vp.MaxZ -= bias_scale * offset;
3085 _d3d_device->SetViewport(&vp);
3092void DXGraphicsStateGuardian9::
3093do_issue_shade_model() {
3095 switch (target_shade_model->
get_mode()) {
3096 case ShadeModelAttrib::M_smooth:
3100 case ShadeModelAttrib::M_flat:
3122 if (gsg_cat.is_spam()) {
3123 gsg_cat.spam() <<
"Setting GSG state to " << (
void *)target <<
":\n";
3124 target->write(gsg_cat.spam(
false), 2);
3127 _state_pcollector.add_level(1);
3128 PStatTimer timer1(_draw_set_state_pcollector);
3130 if (transform != _internal_transform) {
3132 _state_pcollector.add_level(1);
3133 _internal_transform = transform;
3134 do_issue_transform();
3137 if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) {
3140 _target_rs = target;
3142 int shader_deps = 0;
3143 determine_target_shader();
3145 int alpha_test_slot = AlphaTestAttrib::get_class_slot();
3146 if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) ||
3147 !_state_mask.get_bit(alpha_test_slot)) {
3149 do_issue_alpha_test();
3150 _state_mask.set_bit(alpha_test_slot);
3153 int clip_plane_slot = ClipPlaneAttrib::get_class_slot();
3154 if (_target_rs->get_attrib(clip_plane_slot) != _state_rs->get_attrib(clip_plane_slot) ||
3155 !_state_mask.get_bit(clip_plane_slot)) {
3157 do_issue_clip_plane();
3158 _state_mask.set_bit(clip_plane_slot);
3161 int color_slot = ColorAttrib::get_class_slot();
3162 int color_scale_slot = ColorScaleAttrib::get_class_slot();
3163 if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) ||
3164 _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) ||
3165 !_state_mask.get_bit(color_slot) ||
3166 !_state_mask.get_bit(color_scale_slot)) {
3169 do_issue_color_scale();
3170 _state_mask.set_bit(color_slot);
3171 _state_mask.set_bit(color_scale_slot);
3172 shader_deps |= Shader::SSD_color | Shader::SSD_colorscale;
3175 int cull_face_slot = CullFaceAttrib::get_class_slot();
3176 if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) ||
3177 !_state_mask.get_bit(cull_face_slot)) {
3179 do_issue_cull_face();
3180 _state_mask.set_bit(cull_face_slot);
3183 int depth_offset_slot = DepthOffsetAttrib::get_class_slot();
3184 if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) ||
3185 !_state_mask.get_bit(depth_offset_slot)) {
3187 do_issue_depth_offset();
3188 _state_mask.set_bit(depth_offset_slot);
3191 int depth_test_slot = DepthTestAttrib::get_class_slot();
3192 if (_target_rs->get_attrib(depth_test_slot) != _state_rs->get_attrib(depth_test_slot) ||
3193 !_state_mask.get_bit(depth_test_slot)) {
3195 do_issue_depth_test();
3196 _state_mask.set_bit(depth_test_slot);
3199 int depth_write_slot = DepthWriteAttrib::get_class_slot();
3200 if (_target_rs->get_attrib(depth_write_slot) != _state_rs->get_attrib(depth_write_slot) ||
3201 !_state_mask.get_bit(depth_write_slot)) {
3203 do_issue_depth_write();
3204 _state_mask.set_bit(depth_write_slot);
3207 int render_mode_slot = RenderModeAttrib::get_class_slot();
3208 if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) ||
3209 !_state_mask.get_bit(render_mode_slot)) {
3211 do_issue_render_mode();
3212 _state_mask.set_bit(render_mode_slot);
3213 shader_deps |= Shader::SSD_render_mode;
3216 int rescale_normal_slot = RescaleNormalAttrib::get_class_slot();
3217 if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) ||
3218 !_state_mask.get_bit(rescale_normal_slot)) {
3220 do_issue_rescale_normal();
3221 _state_mask.set_bit(rescale_normal_slot);
3224 int shade_model_slot = ShadeModelAttrib::get_class_slot();
3225 if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) ||
3226 !_state_mask.get_bit(shade_model_slot)) {
3228 do_issue_shade_model();
3229 _state_mask.set_bit(shade_model_slot);
3232 int transparency_slot = TransparencyAttrib::get_class_slot();
3233 int color_write_slot = ColorWriteAttrib::get_class_slot();
3234 int color_blend_slot = ColorBlendAttrib::get_class_slot();
3235 if (_target_rs->get_attrib(transparency_slot) != _state_rs->get_attrib(transparency_slot) ||
3236 _target_rs->get_attrib(color_write_slot) != _state_rs->get_attrib(color_write_slot) ||
3237 _target_rs->get_attrib(color_blend_slot) != _state_rs->get_attrib(color_blend_slot) ||
3238 !_state_mask.get_bit(transparency_slot) ||
3239 !_state_mask.get_bit(color_write_slot) ||
3240 !_state_mask.get_bit(color_blend_slot) ||
3241 (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) !=
3242 _state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))) {
3244 do_issue_blending();
3245 _state_mask.set_bit(transparency_slot);
3246 _state_mask.set_bit(color_write_slot);
3247 _state_mask.set_bit(color_blend_slot);
3250 if (_target_shader != _state_shader) {
3253 _state_shader = _target_shader;
3254 _state_mask.clear_bit(TextureAttrib::get_class_slot());
3257 int texture_slot = TextureAttrib::get_class_slot();
3258 int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
3259 int tex_gen_slot = TexGenAttrib::get_class_slot();
3260 if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) ||
3261 _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
3262 _target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) ||
3263 !_state_mask.get_bit(texture_slot) ||
3264 !_state_mask.get_bit(tex_matrix_slot) ||
3265 !_state_mask.get_bit(tex_gen_slot)) {
3267 determine_target_texture();
3270 _state_texture = _target_texture;
3271 _state_mask.set_bit(texture_slot);
3272 _state_mask.set_bit(tex_matrix_slot);
3273 _state_mask.set_bit(tex_gen_slot);
3274 shader_deps |= Shader::SSD_tex_matrix | Shader::SSD_tex_gen;
3277 int material_slot = MaterialAttrib::get_class_slot();
3278 if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) ||
3279 !_state_mask.get_bit(material_slot)) {
3281 do_issue_material();
3282 _state_mask.set_bit(material_slot);
3283 shader_deps |= Shader::SSD_material;
3286 int light_slot = LightAttrib::get_class_slot();
3287 if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) ||
3288 !_state_mask.get_bit(light_slot)) {
3291 _state_mask.set_bit(light_slot);
3294 int stencil_slot = StencilAttrib::get_class_slot();
3295 if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) ||
3296 !_state_mask.get_bit(stencil_slot)) {
3299 _state_mask.set_bit(stencil_slot);
3302 int fog_slot = FogAttrib::get_class_slot();
3303 if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
3304 !_state_mask.get_bit(fog_slot)) {
3307 _state_mask.set_bit(fog_slot);
3308 shader_deps |= Shader::SSD_fog;
3311 int scissor_slot = ScissorAttrib::get_class_slot();
3312 if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) ||
3313 !_state_mask.get_bit(scissor_slot)) {
3316 _state_mask.set_bit(scissor_slot);
3319 if (_current_shader_context !=
nullptr && shader_deps != 0) {
3323 _state_rs = _target_rs;
3337 const LMatrix4 &light_mat = transform->
get_mat();
3338 LMatrix4 rel_mat = light_mat * LMatrix4::convert_mat(CS_yup_left, CS_default);
3339 LPoint3f pos = LCAST(
float, light_obj->
get_point() * rel_mat);
3341 D3DCOLORVALUE black;
3342 black.r = black.g = black.b = black.a = 0.0f;
3344 alight.Type = D3DLIGHT_POINT;
3345 alight.Diffuse = get_light_color(light_obj);
3346 alight.Ambient = black ;
3348 alight.Specular = *(D3DCOLORVALUE *)(color.get_data());
3352 alight.Position = *(D3DVECTOR *)pos.get_data();
3354 alight.Range = __D3DLIGHT_RANGE_MAX;
3355 alight.Falloff = 1.0f;
3358 alight.Attenuation0 = att[0];
3359 alight.Attenuation1 = att[1];
3360 alight.Attenuation2 = att[2];
3362 HRESULT hr = _d3d_device->SetLight(light_id, &alight);
3364 wdxdisplay9_cat.warning()
3365 <<
"Could not set light properties for " << light
3366 <<
" to id " << light_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3377 static PStatCollector _draw_set_state_light_bind_directional_pcollector(
"Draw:Set State:Light:Bind:Directional");
3380 std::pair<DirectionalLights::iterator, bool> lookup = _dlights.insert(DirectionalLights::value_type(light, D3DLIGHT9()));
3381 D3DLIGHT9 &fdata = (*lookup.first).second;
3382 if (lookup.second) {
3387 const LMatrix4 &light_mat = transform->
get_mat();
3388 LMatrix4 rel_mat = light_mat * LMatrix4::convert_mat(CS_yup_left, CS_default);
3389 LVector3f dir = LCAST(
float, light_obj->
get_direction() * rel_mat);
3391 D3DCOLORVALUE black;
3392 black.r = black.g = black.b = black.a = 0.0f;
3394 ZeroMemory(&fdata,
sizeof(D3DLIGHT9));
3396 fdata.Type = D3DLIGHT_DIRECTIONAL;
3397 fdata.Ambient = black ;
3399 fdata.Specular = *(D3DCOLORVALUE *)(color.get_data());
3401 fdata.Direction = *(D3DVECTOR *)dir.get_data();
3403 fdata.Range = __D3DLIGHT_RANGE_MAX;
3404 fdata.Falloff = 1.0f;
3406 fdata.Attenuation0 = 1.0f;
3407 fdata.Attenuation1 = 0.0f;
3408 fdata.Attenuation2 = 0.0f;
3414 fdata.Diffuse = get_light_color(light_obj);
3416 HRESULT hr = _d3d_device->SetLight(light_id, &fdata);
3418 wdxdisplay9_cat.warning()
3419 <<
"Could not set light properties for " << light
3420 <<
" to id " << light_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3432 nassertv(lens !=
nullptr);
3438 const LMatrix4 &light_mat = transform->
get_mat();
3439 LMatrix4 rel_mat = light_mat * LMatrix4::convert_mat(CS_yup_left, CS_default);
3443 D3DCOLORVALUE black;
3444 black.r = black.g = black.b = black.a = 0.0f;
3447 ZeroMemory(&alight,
sizeof(D3DLIGHT9));
3449 alight.Type = D3DLIGHT_SPOT;
3450 alight.Ambient = black ;
3451 alight.Diffuse = get_light_color(light_obj);
3453 alight.Specular = *(D3DCOLORVALUE *)(color.get_data());
3455 alight.Position = *(D3DVECTOR *)pos.get_data();
3457 alight.Direction = *(D3DVECTOR *)dir.get_data();
3459 alight.Range = __D3DLIGHT_RANGE_MAX;
3463 PN_stdfloat fov = lens->
get_hfov();
3464 alight.Falloff = light_obj->
get_exponent() * (fov * fov * fov) / 1620000.0f;
3466 alight.Theta = 0.0f;
3467 alight.Phi = deg_2_rad(fov);
3470 alight.Attenuation0 = att[0];
3471 alight.Attenuation1 = att[1];
3472 alight.Attenuation2 = att[2];
3474 HRESULT hr = _d3d_device->SetLight(light_id, &alight);
3476 wdxdisplay9_cat.warning()
3477 <<
"Could not set light properties for " << light
3478 <<
" to id " << light_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3487 switch (numeric_type) {
3489 case Geom::NT_uint8:
3490 case Geom::NT_uint16:
3491 return D3DFMT_INDEX16;
3493 case Geom::NT_uint32:
3494 return D3DFMT_INDEX32;
3498 <<
"Invalid index NumericType value (" << (int)numeric_type <<
")\n";
3499 return D3DFMT_INDEX16;
3505void DXGraphicsStateGuardian9::
3506do_issue_material() {
3510 if (target_material->
is_off()) {
3516 D3DMATERIAL9 cur_material;
3517 LColorf color = LCAST(
float, material->
get_diffuse());
3518 cur_material.Diffuse = *(D3DCOLORVALUE *)(color.get_data());
3520 cur_material.Ambient = *(D3DCOLORVALUE *)(color.get_data());
3522 cur_material.Specular = *(D3DCOLORVALUE *)(color.get_data());
3524 cur_material.Emissive = *(D3DCOLORVALUE *)(color.get_data());
3532 if (_has_material_force_color) {
3533 color = LCAST(
float, _material_force_color);
3534 cur_material.Diffuse = *(D3DCOLORVALUE *)color.get_data();
3545 if (_has_material_force_color) {
3546 color = LCAST(
float, _material_force_color);
3547 cur_material.Ambient = *(D3DCOLORVALUE *)color.get_data();
3566 _d3d_device->SetMaterial(&cur_material);
3572void DXGraphicsStateGuardian9::
3574 DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
3576 if (_texture_binding_shader_context==0) {
3577 if (_current_shader_context==0) {
3578 update_standard_texture_bindings();
3580 disable_standard_texture_bindings();
3584 if (_current_shader_context==0) {
3586 update_standard_texture_bindings();
3588 _current_shader_context->
3589 update_shader_texture_bindings(_texture_binding_shader_context,
this);
3592 _texture_binding_shader = _current_shader;
3593 _texture_binding_shader_context = _current_shader_context;
3599void DXGraphicsStateGuardian9::
3600disable_standard_texture_bindings() {
3602 for (
int i = 0; i < _num_active_texture_stages; i++) {
3605 hr = _d3d_device -> SetTexture (i,
nullptr);
3610 <<
", NULL) failed "
3611 << D3DERRORSTRING(hr);
3616 _num_active_texture_stages = 0;
3622void DXGraphicsStateGuardian9::
3623update_standard_texture_bindings() {
3624 DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
3626 int num_stages = _target_texture->get_num_on_ff_stages();
3627 int num_old_stages = _max_texture_stages;
3628 if (_state_texture !=
nullptr) {
3629 num_old_stages = _state_texture->get_num_on_ff_stages();
3632 nassertv(num_stages <= _max_texture_stages &&
3633 _num_active_texture_stages <= _max_texture_stages);
3635 _texture_involves_color_scale =
false;
3642 for (si = 0; si < num_stages; si++) {
3643 TextureStage *stage = _target_texture->get_on_ff_stage(si);
3644 int texcoord_index = _target_texture->get_ff_tc_index(si);
3646 Texture *texture = _target_texture->get_on_texture(stage);
3647 nassertv(texture !=
nullptr);
3648 const SamplerState &sampler = _target_texture->get_on_sampler(stage);
3655 set_texture_blend_mode(si, stage);
3657 int texcoord_dimensions = 2;
3661 if (target_tex_matrix->has_stage(stage)) {
3662 tex_mat = target_tex_matrix->get_transform(stage);
3666 TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage);
3667 bool any_point_sprite =
false;
3670 case TexGenAttrib::M_off:
3671 case TexGenAttrib::M_unused2:
3675 case TexGenAttrib::M_eye_sphere_map:
3678 texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
3683 TransformState::make_mat(LMatrix4(0.33, 0.0f, 0.0f, 0.0f,
3684 0.0f, 0.33, 0.0f, 0.0f,
3685 0.0f, 0.0f, 1.0f, 0.0f,
3686 0.5f, 0.5f, 0.0f, 1.0f));
3687 tex_mat = tex_mat->compose(sphere_map);
3688 texcoord_dimensions = 3;
3692 case TexGenAttrib::M_world_cube_map:
3699 texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
3700 texcoord_dimensions = 3;
3701 CPT(
TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
3702 tex_mat = tex_mat->compose(camera_transform->set_pos(LVecBase3::zero()));
3706 case TexGenAttrib::M_eye_cube_map:
3708 texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
3709 tex_mat = tex_mat->compose(_inv_cs_transform);
3710 texcoord_dimensions = 3;
3713 case TexGenAttrib::M_world_normal:
3719 texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
3720 texcoord_dimensions = 3;
3721 CPT(
TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
3722 tex_mat = tex_mat->compose(camera_transform->set_pos(LVecBase3::zero()));
3726 case TexGenAttrib::M_eye_normal:
3728 texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
3729 texcoord_dimensions = 3;
3730 tex_mat = tex_mat->compose(_inv_cs_transform);
3733 case TexGenAttrib::M_world_position:
3738 texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
3739 texcoord_dimensions = 3;
3740 CPT(
TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
3741 tex_mat = tex_mat->compose(camera_transform);
3745 case TexGenAttrib::M_eye_position:
3747 texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
3748 texcoord_dimensions = 3;
3749 tex_mat = tex_mat->compose(_inv_cs_transform);
3752 case TexGenAttrib::M_point_sprite:
3754 any_point_sprite =
true;
3757 case TexGenAttrib::M_constant:
3770 texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
3771 texcoord_dimensions = 3;
3773 const LTexCoord3 &v = _target_tex_gen->get_constant_value(stage);
3775 TransformState::make_pos_hpr_scale(v, LVecBase3::zero(),
3777 tex_mat = tex_mat->compose(squash);
3784 if (!tex_mat->is_identity()) {
3785 if ( texcoord_dimensions <= 2) {
3787 LMatrix4 m = tex_mat->get_mat();
3789 mf.set(m(0, 0), m(0, 1), m(0, 3), 0.0f,
3790 m(1, 0), m(1, 1), m(1, 3), 0.0f,
3791 m(3, 0), m(3, 1), m(3, 3), 0.0f,
3792 0.0f, 0.0f, 0.0f, 1.0f);
3793 _d3d_device->SetTransform(get_tex_mat_sym(si), (D3DMATRIX *)mf.get_data());
3797 LMatrix4f mf = LCAST(
float, tex_mat->get_mat());
3798 _d3d_device->SetTransform(get_tex_mat_sym(si), (D3DMATRIX *)mf.get_data());
3799 DWORD transform_flags = texcoord_dimensions;
3800 if (mf.get_col(3) != LVecBase4f(0.0f, 0.0f, 0.0f, 1.0f)) {
3803 transform_flags = D3DTTFF_COUNT4 | D3DTTFF_PROJECTED;
3815 _d3d_device->SetTransform(get_tex_mat_sym(si), &_d3d_ident_mat);
3820 for (si = num_stages; si < _num_active_texture_stages; si++) {
3822 _d3d_device->SetTexture(si,
nullptr);
3826 _num_active_texture_stages = num_stages;
3834void DXGraphicsStateGuardian9::
3835do_issue_blending() {
3840 unsigned int color_channels =
3841 target_color_write->
get_channels() & _color_write_mask;
3842 if (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write)) {
3843 color_channels &= ~(ColorWriteAttrib::C_alpha);
3845 if (color_channels == ColorWriteAttrib::C_off) {
3846 if (_screen->_can_direct_disable_color_writes) {
3856 if (_screen->_can_direct_disable_color_writes) {
3862 _target_rs->get_attrib_def(color_blend);
3863 ColorBlendAttrib::Mode color_blend_mode = color_blend->
get_mode();
3866 _target_rs->get_attrib_def(target_transparency);
3867 TransparencyAttrib::Mode transparency_mode = target_transparency->
get_mode();
3870 if (color_blend_mode != ColorBlendAttrib::M_none) {
3883 switch (transparency_mode) {
3884 case TransparencyAttrib::M_none:
3885 case TransparencyAttrib::M_binary:
3888 case TransparencyAttrib::M_alpha:
3889 case TransparencyAttrib::M_multisample:
3890 case TransparencyAttrib::M_multisample_mask:
3891 case TransparencyAttrib::M_dual:
3893 if (old_alpha_blend) {
3906 case TransparencyAttrib::M_premultiplied_alpha:
3916 <<
"invalid transparency mode " << (int)transparency_mode << endl;
3929void DXGraphicsStateGuardian9::
3930reissue_transforms() {
3932 do_issue_transform();
3940void DXGraphicsStateGuardian9::
3941enable_lighting(
bool enable) {
3950void DXGraphicsStateGuardian9::
3951set_ambient_light(
const LColor &color) {
3953 c.set(c[0] * _light_color_scale[0],
3954 c[1] * _light_color_scale[1],
3955 c[2] * _light_color_scale[2],
3956 c[3] * _light_color_scale[3]);
3966void DXGraphicsStateGuardian9::
3967enable_light(
int light_id,
bool enable) {
3968 HRESULT hr = _d3d_device->LightEnable(light_id, enable);
3971 wdxdisplay9_cat.warning()
3972 <<
"Could not enable light " << light_id <<
": "
3973 << D3DERRORSTRING(hr) <<
"\n";
3982void DXGraphicsStateGuardian9::
3983enable_clip_plane(
int plane_id,
bool enable) {
3985 _clip_plane_bits |= ((DWORD)1 << plane_id);
3987 _clip_plane_bits &= ~((DWORD)1 << plane_id);
3997void DXGraphicsStateGuardian9::
3998bind_clip_plane(
const NodePath &plane,
int plane_id) {
4003 const LMatrix4 &plane_mat = transform->
get_mat();
4004 LMatrix4 rel_mat = plane_mat * LMatrix4::convert_mat(CS_yup_left, CS_default);
4006 DCAST_INTO_V(plane_node, plane.
node());
4007 LPlanef world_plane = LCAST(
float, plane_node->
get_plane() * rel_mat);
4009 HRESULT hr = _d3d_device->SetClipPlane(plane_id, world_plane.get_data());
4011 wdxdisplay9_cat.warning()
4012 <<
"Could not set clip plane for " << plane
4013 <<
" to id " << plane_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
4022void DXGraphicsStateGuardian9::
4024 GraphicsStateGuardian::close_gsg();
4026 if (_prepared_objects.is_null()) {
4030 if (dxgsg9_cat.is_debug()) {
4032 <<
"Closing GSG, prepared_objects count = "
4033 << _prepared_objects->get_ref_count() <<
"\n";
4038 if (_prepared_objects->get_ref_count() == 1) {
4043 _prepared_objects->begin_frame(
this, current_thread);
4044 _prepared_objects->end_frame(current_thread);
4051void DXGraphicsStateGuardian9::
4052free_nondx_resources() {
4055 cgDestroyContext(_cg_context);
4065void DXGraphicsStateGuardian9::
4068 _state_rs = RenderState::make_empty();
4069 _state_mask.clear();
4073 _dx_is_ready =
false;
4075 if (_d3d_device !=
nullptr) {
4076 for(
int i = 0; i < D3D_MAXTEXTURESTAGES; i++) {
4078 _d3d_device->SetTexture(i,
nullptr);
4084 if (_d3d_device !=
nullptr) {
4085 RELEASE(_d3d_device, dxgsg9,
"d3dDevice", RELEASE_DOWN_TO_ZERO);
4088 free_nondx_resources();
4098void DXGraphicsStateGuardian9::
4100 dxgsg9_cat.fatal() <<
"DX set_draw_buffer unimplemented!!!";
4107void DXGraphicsStateGuardian9::
4109 if (rb._buffer_type & RenderBuffer::T_front) {
4110 _cur_read_pixel_buffer = RenderBuffer::T_front;
4111 }
else if (rb._buffer_type & RenderBuffer::T_back) {
4112 _cur_read_pixel_buffer = RenderBuffer::T_back;
4113 }
else if (rb._buffer_type & RenderBuffer::T_aux_rgba_ALL) {
4114 _cur_read_pixel_buffer = RenderBuffer::T_back;
4116 dxgsg9_cat.error() <<
"Invalid or unimplemented Argument to set_read_buffer!\n";
4126const D3DCOLORVALUE &DXGraphicsStateGuardian9::
4127get_light_color(
Light *light)
const {
4130 cf.set(c[0] * _light_color_scale[0],
4131 c[1] * _light_color_scale[1],
4132 c[2] * _light_color_scale[2],
4133 c[3] * _light_color_scale[3]);
4134 return *(D3DCOLORVALUE *)cf.get_data();
4140D3DBLENDOP DXGraphicsStateGuardian9::
4141get_blend_mode(ColorBlendAttrib::Mode mode) {
4143 case ColorBlendAttrib::M_add:
4144 return D3DBLENDOP_ADD;
4146 case ColorBlendAttrib::M_subtract:
4147 return D3DBLENDOP_SUBTRACT;
4149 case ColorBlendAttrib::M_inv_subtract:
4150 return D3DBLENDOP_REVSUBTRACT;
4152 case ColorBlendAttrib::M_min:
4153 return D3DBLENDOP_MIN;
4155 case ColorBlendAttrib::M_max:
4156 return D3DBLENDOP_MAX;
4160 <<
"Unknown color blend mode " << (int)mode << endl;
4161 return D3DBLENDOP_ADD;
4167D3DBLEND DXGraphicsStateGuardian9::
4168get_blend_func(ColorBlendAttrib::Operand operand) {
4170 case ColorBlendAttrib::O_zero:
4171 return D3DBLEND_ZERO;
4173 case ColorBlendAttrib::O_one:
4174 return D3DBLEND_ONE;
4176 case ColorBlendAttrib::O_incoming_color:
4177 return D3DBLEND_SRCCOLOR;
4179 case ColorBlendAttrib::O_one_minus_incoming_color:
4180 return D3DBLEND_INVSRCCOLOR;
4182 case ColorBlendAttrib::O_fbuffer_color:
4183 return D3DBLEND_DESTCOLOR;
4185 case ColorBlendAttrib::O_one_minus_fbuffer_color:
4186 return D3DBLEND_INVDESTCOLOR;
4188 case ColorBlendAttrib::O_incoming_alpha:
4189 return D3DBLEND_SRCALPHA;
4191 case ColorBlendAttrib::O_one_minus_incoming_alpha:
4192 return D3DBLEND_INVSRCALPHA;
4194 case ColorBlendAttrib::O_fbuffer_alpha:
4195 return D3DBLEND_DESTALPHA;
4197 case ColorBlendAttrib::O_one_minus_fbuffer_alpha:
4198 return D3DBLEND_INVDESTALPHA;
4200 case ColorBlendAttrib::O_constant_color:
4202 return D3DBLEND_SRCCOLOR;
4204 case ColorBlendAttrib::O_one_minus_constant_color:
4206 return D3DBLEND_INVSRCCOLOR;
4208 case ColorBlendAttrib::O_constant_alpha:
4210 return D3DBLEND_SRCALPHA;
4212 case ColorBlendAttrib::O_one_minus_constant_alpha:
4214 return D3DBLEND_INVSRCALPHA;
4216 case ColorBlendAttrib::O_incoming_color_saturate:
4217 return D3DBLEND_SRCALPHASAT;
4219 case ColorBlendAttrib::O_incoming1_color:
4220 return (D3DBLEND)16;
4222 case ColorBlendAttrib::O_one_minus_incoming1_color:
4223 return (D3DBLEND)17;
4225 case ColorBlendAttrib::O_incoming1_alpha:
4227 return (D3DBLEND)18;
4229 case ColorBlendAttrib::O_one_minus_incoming1_alpha:
4231 return (D3DBLEND)19;
4235 <<
"Unknown color blend operand " << (int)operand << endl;
4236 return D3DBLEND_ZERO;
4242void DXGraphicsStateGuardian9::
4243report_texmgr_stats() {
4249#ifdef TEXMGRSTATS_USES_GETAVAILVIDMEM
4250 DWORD dwTexTotal, dwTexFree, dwVidTotal, dwVidFree;
4252 if (_total_texmem_pcollector.is_active()) {
4255 ZeroMemory(&ddsCaps,
sizeof(ddsCaps));
4257 ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
4258 if (FAILED( hr = _d3d_device->GetAvailableVidMem(&ddsCaps, &dwVidTotal, &dwVidFree))) {
4259 dxgsg9_cat.fatal() <<
"report_texmgr GetAvailableVidMem for VIDMEM failed : result = " << D3DERRORSTRING(hr);
4260 throw_event(
"panda3d-render-error");
4264 ddsCaps.dwCaps = DDSCAPS_TEXTURE;
4265 if (FAILED( hr = _d3d_device->GetAvailableVidMem(&ddsCaps, &dwTexTotal, &dwTexFree))) {
4266 dxgsg9_cat.fatal() <<
"report_texmgr GetAvailableVidMem for TEXTURE failed : result = " << D3DERRORSTRING(hr);
4267 throw_event(
"panda3d-render-error");
4273 D3DDEVINFO_RESOURCEMANAGER all_resource_stats;
4274 ZeroMemory(&all_resource_stats,
sizeof(D3DDEVINFO_RESOURCEMANAGER));
4301 if (_texmgrmem_total_pcollector.is_active()) {
4303 _texmgrmem_total_pcollector.set_level(all_resource_stats.stats[D3DRTYPE_TEXTURE].TotalBytes);
4304 _texmgrmem_resident_pcollector.set_level(all_resource_stats.stats[D3DRTYPE_TEXTURE].WorkingSetBytes);
4306#ifdef TEXMGRSTATS_USES_GETAVAILVIDMEM
4307 if (_total_texmem_pcollector.is_active()) {
4308 _total_texmem_pcollector.set_level(dwTexTotal);
4309 _used_texmem_pcollector.set_level(dwTexTotal - dwTexFree);
4318void DXGraphicsStateGuardian9::
4320 nassertv(new_context !=
nullptr);
4321 _screen = new_context;
4322 _d3d_device = _screen->_d3d_device;
4323 _swap_chain = _screen->_swap_chain;
4325 _screen->_dxgsg9 =
this;
4332void DXGraphicsStateGuardian9::
4333set_render_target() {
4334 if (_d3d_device ==
nullptr) {
4338 LPDIRECT3DSURFACE9 back =
nullptr, stencil =
nullptr;
4346 _d3d_device->GetBackBuffer(swap_chain, 0, D3DBACKBUFFER_TYPE_MONO, &back);
4348 _swap_chain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &back);
4353 _d3d_device->GetDepthStencilSurface(&stencil);
4356 DWORD render_target_index;
4357 render_target_index = 0;
4358 _d3d_device->SetRenderTarget(render_target_index, back);
4371void DXGraphicsStateGuardian9::
4372set_texture_blend_mode(
int i,
const TextureStage *stage) {
4374 case TextureStage::M_modulate:
4375 case TextureStage::M_modulate_glow:
4376 case TextureStage::M_modulate_gloss:
4386 case TextureStage::M_decal:
4396 case TextureStage::M_replace:
4404 case TextureStage::M_add:
4414 case TextureStage::M_blend:
4415 case TextureStage::M_blend_color_scale:
4428 case TextureStage::M_combine:
4439 (i, D3DTSS_COLORARG0,
4446 (i, D3DTSS_COLORARG2,
4453 (i, D3DTSS_COLORARG1,
4470 (i, D3DTSS_ALPHAARG0,
4477 (i, D3DTSS_ALPHAARG2,
4484 (i, D3DTSS_ALPHAARG1,
4496 <<
"Unknown texture mode " << (int)stage->
get_mode() << endl;
4509 D3DCOLOR constant_color;
4512 color.set(color[0] * _current_color_scale[0],
4513 color[1] * _current_color_scale[1],
4514 color[2] * _current_color_scale[2],
4515 color[3] * _current_color_scale[3]);
4516 _texture_involves_color_scale =
true;
4521 if (_supports_texture_constant_color) {
4535void DXGraphicsStateGuardian9::
4541 free_nondx_resources();
4542 PRINT_REFCNT(dxgsg9, _d3d_device);
4546 RELEASE(_d3d_device, dxgsg9,
"d3dDevice", RELEASE_DOWN_TO_ZERO);
4547 _screen->_d3d_device =
nullptr;
4559HRESULT DXGraphicsStateGuardian9::
4560reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
4564 nassertr(IS_VALID_PTR(presentation_params), E_FAIL);
4565 nassertr(IS_VALID_PTR(_screen->_d3d9), E_FAIL);
4566 nassertr(IS_VALID_PTR(_d3d_device), E_FAIL);
4570 _screen->_d3d9->GetAdapterDisplayMode(_screen->_card_id, &_screen->_display_mode);
4571 presentation_params->BackBufferFormat = _screen->_display_mode.Format;
4578 if (
true || !(_screen->_swap_chain)
4579 || (_presentation_reset.BackBufferWidth < presentation_params->BackBufferWidth)
4580 || (_presentation_reset.BackBufferHeight < presentation_params->BackBufferHeight)) {
4581 if (wdxdisplay9_cat.is_debug()) {
4582 wdxdisplay9_cat.debug()
4583 <<
"swap_chain = " << _screen->_swap_chain <<
" _presentation_reset = "
4584 << _presentation_reset.BackBufferWidth <<
"x" << _presentation_reset.BackBufferHeight
4585 <<
" presentation_params = "
4586 << presentation_params->BackBufferWidth <<
"x" << presentation_params->BackBufferHeight <<
"\n";
4591 if (_screen->_swap_chain) {
4592 _presentation_reset.BackBufferWidth = max(_presentation_reset.BackBufferWidth, presentation_params->BackBufferWidth);
4593 _presentation_reset.BackBufferHeight = max(_presentation_reset.BackBufferHeight, presentation_params->BackBufferHeight);
4596 _presentation_reset.BackBufferWidth = presentation_params->BackBufferWidth;
4597 _presentation_reset.BackBufferHeight = presentation_params->BackBufferHeight;
4609 if (_white_vbuffer !=
nullptr) {
4610 _white_vbuffer->Release();
4611 _white_vbuffer =
nullptr;
4616 _prepared_objects->begin_frame(
this, current_thread);
4621 std::list <wdxGraphicsBuffer9 **>::iterator graphics_buffer_iterator;
4623 for (graphics_buffer_iterator = _graphics_buffer_list.begin( ); graphics_buffer_iterator != _graphics_buffer_list.end( ); graphics_buffer_iterator++)
4625 graphics_buffer = **graphics_buffer_iterator;
4626 if (graphics_buffer -> _color_backing_store)
4628 graphics_buffer -> _color_backing_store -> Release ( );
4629 graphics_buffer -> _color_backing_store = 0;
4631 if (graphics_buffer -> _depth_backing_store)
4633 graphics_buffer -> _depth_backing_store -> Release ( );
4634 graphics_buffer -> _depth_backing_store = 0;
4640 hr = _d3d_device->Reset(&_presentation_reset);
4641 if (FAILED(hr) && hr != D3DERR_DEVICELOST) {
4650 if (presentation_params != &_screen->_presentation_params) {
4651 memcpy(&_screen->_presentation_params, presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
4658 if (_screen && _screen->_swap_chain) {
4659 _screen->_swap_chain->Release();
4660 wdxdisplay9_cat.debug()
4661 <<
"swap chain " << _screen->_swap_chain <<
" is released\n";
4662 _screen->_swap_chain =
nullptr;
4663 hr = _d3d_device->CreateAdditionalSwapChain(presentation_params, &_screen->_swap_chain);
4665 if (SUCCEEDED(hr)) {
4666 if (presentation_params != &_screen->_presentation_params) {
4667 memcpy(&_screen->_presentation_params, presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
4679bool DXGraphicsStateGuardian9::
4680check_cooperative_level() {
4681 bool bDoReactivateWindow =
false;
4682 if (_d3d_device ==
nullptr) {
4686 HRESULT hr = _d3d_device->TestCooperativeLevel();
4688 if (SUCCEEDED(hr)) {
4689 nassertr(SUCCEEDED(_last_testcooplevel_result),
false);
4694 case D3DERR_DEVICENOTRESET:
4695 _dx_is_ready =
false;
4700 hr = reset_d3d_device(&_screen->_presentation_params);
4705 <<
"check_cooperative_level Reset() failed, hr = " << D3DERRORSTRING(hr);
4708 hr = _d3d_device->TestCooperativeLevel();
4712 <<
"TestCooperativeLevel following Reset() failed, hr = " << D3DERRORSTRING(hr);
4716 _dx_is_ready = TRUE;
4719 case D3DERR_DEVICELOST:
4723 if (SUCCEEDED(_last_testcooplevel_result)) {
4725 _dx_is_ready =
false;
4726 if (dxgsg9_cat.is_debug()) {
4727 dxgsg9_cat.debug() <<
"D3D Device was Lost, waiting...\n";
4733 _last_testcooplevel_result = hr;
4734 return SUCCEEDED(hr);
4740void DXGraphicsStateGuardian9::
4742 if (_d3d_device ==
nullptr) {
4752 hr = _swap_chain->Present(
nullptr,
nullptr, (HWND)
nullptr,
nullptr, flags);
4754 hr = _d3d_device->Present(
nullptr,
nullptr, (HWND)
nullptr,
nullptr);
4758 if (hr == D3DERR_DEVICELOST) {
4759 check_cooperative_level();
4762 <<
"show_frame() - Present() failed" << D3DERRORSTRING(hr);
4763 throw_event(
"panda3d-render-error");
4771bool DXGraphicsStateGuardian9::
4779 hr = new_context->_d3d_device->CreateAdditionalSwapChain(&new_context->_presentation_params, &new_context->_swap_chain);
4781 wdxdisplay9_cat.debug() <<
"Swapchain creation failed :"<<D3DERRORSTRING(hr)<<
"\n";
4790bool DXGraphicsStateGuardian9::
4793 if (new_context->_swap_chain) {
4794 hr = new_context->_swap_chain->Release();
4796 wdxdisplay9_cat.debug() <<
"Swapchain release failed:" << D3DERRORSTRING(hr) <<
"\n";
4799 if (new_context->_swap_chain == _swap_chain) {
4800 _swap_chain =
nullptr;
4809void DXGraphicsStateGuardian9::
4811 memcpy(&_presentation_reset, &_screen->_presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
4817D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian9::
4818get_d3d_min_type(SamplerState::FilterType filter_type) {
4819 switch (filter_type) {
4820 case SamplerState::FT_nearest:
4821 return D3DTEXF_POINT;
4823 case SamplerState::FT_linear:
4824 return D3DTEXF_LINEAR;
4826 case SamplerState::FT_nearest_mipmap_nearest:
4827 return D3DTEXF_POINT;
4829 case SamplerState::FT_linear_mipmap_nearest:
4830 return D3DTEXF_LINEAR;
4832 case SamplerState::FT_nearest_mipmap_linear:
4833 return D3DTEXF_POINT;
4835 case SamplerState::FT_linear_mipmap_linear:
4836 return D3DTEXF_LINEAR;
4838 case SamplerState::FT_shadow:
4839 case SamplerState::FT_default:
4840 return D3DTEXF_LINEAR;
4844 <<
"Invalid FilterType value (" << (int)filter_type <<
")\n";
4845 return D3DTEXF_POINT;
4851D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian9::
4852get_d3d_mip_type(SamplerState::FilterType filter_type) {
4853 switch (filter_type) {
4854 case SamplerState::FT_nearest:
4855 return D3DTEXF_NONE;
4857 case SamplerState::FT_linear:
4858 return D3DTEXF_NONE;
4860 case SamplerState::FT_nearest_mipmap_nearest:
4861 return D3DTEXF_POINT;
4863 case SamplerState::FT_linear_mipmap_nearest:
4864 return D3DTEXF_POINT;
4866 case SamplerState::FT_nearest_mipmap_linear:
4867 return D3DTEXF_LINEAR;
4869 case SamplerState::FT_linear_mipmap_linear:
4870 return D3DTEXF_LINEAR;
4872 case SamplerState::FT_shadow:
4873 case SamplerState::FT_default:
4874 return D3DTEXF_NONE;
4878 <<
"Invalid FilterType value (" << (int)filter_type <<
")\n";
4879 return D3DTEXF_NONE;
4886D3DTEXTUREOP DXGraphicsStateGuardian9::
4887get_texture_operation(TextureStage::CombineMode mode,
int scale) {
4889 case TextureStage::CM_undefined:
4890 case TextureStage::CM_replace:
4891 return D3DTOP_SELECTARG1;
4893 case TextureStage::CM_modulate:
4895 return D3DTOP_MODULATE;
4896 }
else if (scale < 4) {
4897 return D3DTOP_MODULATE2X;
4899 return D3DTOP_MODULATE4X;
4902 case TextureStage::CM_add:
4905 case TextureStage::CM_add_signed:
4907 return D3DTOP_ADDSIGNED;
4909 return D3DTOP_ADDSIGNED2X;
4912 case TextureStage::CM_interpolate:
4915 case TextureStage::CM_subtract:
4916 return D3DTOP_SUBTRACT;
4918 case TextureStage::CM_dot3_rgb:
4919 case TextureStage::CM_dot3_rgba:
4920 return D3DTOP_DOTPRODUCT3;
4924 <<
"Invalid TextureStage::CombineMode value (" << (int)mode <<
")\n";
4925 return D3DTOP_DISABLE;
4933DWORD DXGraphicsStateGuardian9::
4934get_texture_argument(TextureStage::CombineSource source,
4935 TextureStage::CombineOperand operand)
const {
4937 case TextureStage::CS_undefined:
4938 case TextureStage::CS_texture:
4939 return D3DTA_TEXTURE | get_texture_argument_modifier(operand);
4941 case TextureStage::CS_constant:
4942 case TextureStage::CS_constant_color_scale:
4943 return _constant_color_operand | get_texture_argument_modifier(operand);
4945 case TextureStage::CS_primary_color:
4946 return D3DTA_DIFFUSE | get_texture_argument_modifier(operand);
4948 case TextureStage::CS_previous:
4949 return D3DTA_CURRENT | get_texture_argument_modifier(operand);
4951 case TextureStage::CS_last_saved_result:
4952 return D3DTA_TEMP | get_texture_argument_modifier(operand);
4955 <<
"Invalid TextureStage::CombineSource value (" << (int)source <<
")\n";
4956 return D3DTA_CURRENT;
4963DWORD DXGraphicsStateGuardian9::
4964get_texture_argument_modifier(TextureStage::CombineOperand operand) {
4966 case TextureStage::CO_src_color:
4969 case TextureStage::CO_one_minus_src_color:
4970 return D3DTA_COMPLEMENT;
4972 case TextureStage::CO_src_alpha:
4973 return D3DTA_ALPHAREPLICATE;
4975 case TextureStage::CO_one_minus_src_alpha:
4976 return D3DTA_ALPHAREPLICATE | D3DTA_COMPLEMENT;
4978 case TextureStage::CO_undefined:
4982 <<
"Invalid TextureStage::CombineOperand value (" << (int)operand <<
")\n";
4991void DXGraphicsStateGuardian9::
4992draw_primitive_up(D3DPRIMITIVETYPE primitive_type,
4993 unsigned int primitive_count,
4994 unsigned int first_vertex,
4995 unsigned int num_vertices,
4996 const unsigned char *buffer,
size_t stride) {
5003 const unsigned char *buffer_start = buffer + stride * first_vertex;
5004 const unsigned char *buffer_end = buffer_start + stride * num_vertices;
5006 if (buffer_end - buffer_start > 0x10000) {
5009 _d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
5010 buffer_start, stride);
5012 }
else if ((((uintptr_t)buffer_end ^ (uintptr_t)buffer_start) & ~0xffff) == 0) {
5014 _d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
5015 buffer_start, stride);
5020 unsigned char *safe_buffer_start = get_safe_buffer_start();
5021 memcpy(safe_buffer_start, buffer_start, buffer_end - buffer_start);
5022 _d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
5023 safe_buffer_start, stride);
5035void DXGraphicsStateGuardian9::
5036draw_indexed_primitive_up(D3DPRIMITIVETYPE primitive_type,
5037 unsigned int min_index,
unsigned int max_index,
5038 unsigned int num_primitives,
5039 const unsigned char *index_data,
5040 D3DFORMAT index_type,
5041 const unsigned char *buffer,
size_t stride) {
5044 const unsigned char *buffer_start = buffer + stride * min_index;
5045 const unsigned char *buffer_end = buffer + stride * (max_index + 1);
5047 if (buffer_end - buffer_start > 0x10000) {
5050 _d3d_device->DrawIndexedPrimitiveUP
5051 (primitive_type, min_index, max_index - min_index + 1, num_primitives,
5052 index_data, index_type, buffer, stride);
5054 }
else if ((((uintptr_t)buffer_end ^ (uintptr_t)buffer_start) & ~0xffff) == 0) {
5056 _d3d_device->DrawIndexedPrimitiveUP
5057 (primitive_type, min_index, max_index - min_index + 1, num_primitives,
5058 index_data, index_type, buffer, stride);
5063 unsigned char *safe_buffer_start = get_safe_buffer_start();
5064 memcpy(safe_buffer_start, buffer_start, buffer_end - buffer_start);
5065 _d3d_device->DrawIndexedPrimitiveUP
5066 (primitive_type, min_index, max_index - min_index + 1, num_primitives,
5067 index_data, index_type, safe_buffer_start - stride * min_index, stride);
5090 case D3DERR_OUTOFVIDEOMEMORY:
5094 size_t current_size = _prepared_objects->_graphics_memory_lru.get_total_size();
5095 size_t target_size = max(current_size - allocation_size * attempts, (
size_t) 0);
5096 _prepared_objects->_graphics_memory_lru.evict_to(target_size);
5098 <<
"Evicted " << current_size - _prepared_objects->_graphics_memory_lru.get_total_size() <<
" bytes of texture memory to make room for more.\n";
5099 if (_prepared_objects->_graphics_memory_lru.get_total_size() < current_size) {
5114static int dx_stencil_comparison_function_array[] = {
5121 D3DCMP_GREATEREQUAL,
5125static int dx_stencil_operation_array[] = {
5128 D3DSTENCILOP_REPLACE,
5131 D3DSTENCILOP_INVERT,
5133 D3DSTENCILOP_INCRSAT,
5134 D3DSTENCILOP_DECRSAT,
5140void DXGraphicsStateGuardian9::
5142 if (!_supports_stencil) {
5148 if (stencil !=
nullptr) {
5151 dxgsg9_cat.debug() <<
"STENCIL STATE CHANGE\n";
5152 dxgsg9_cat.debug() <<
"\n"
5153 <<
"SRS_front_comparison_function " << stencil->
get_render_state(StencilAttrib::SRS_front_comparison_function) <<
"\n"
5154 <<
"SRS_front_stencil_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_front_stencil_fail_operation) <<
"\n"
5155 <<
"SRS_front_stencil_pass_z_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation) <<
"\n"
5156 <<
"SRS_front_stencil_pass_z_pass_operation " << stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation) <<
"\n"
5157 <<
"SRS_reference " << stencil->
get_render_state(StencilAttrib::SRS_reference) <<
"\n"
5158 <<
"SRS_read_mask " << stencil->
get_render_state(StencilAttrib::SRS_read_mask) <<
"\n"
5159 <<
"SRS_write_mask " << stencil->
get_render_state(StencilAttrib::SRS_write_mask) <<
"\n"
5160 <<
"SRS_back_comparison_function " << stencil->
get_render_state(StencilAttrib::SRS_back_comparison_function) <<
"\n"
5161 <<
"SRS_back_stencil_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_back_stencil_fail_operation) <<
"\n"
5162 <<
"SRS_back_stencil_pass_z_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation) <<
"\n"
5163 <<
"SRS_back_stencil_pass_z_pass_operation " << stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) <<
"\n";
5168 unsigned int front_compare;
5169 front_compare = stencil->
get_render_state(StencilAttrib::SRS_front_comparison_function);
5171 if (front_compare != RenderAttrib::M_none) {
5173 set_render_state(D3DRS_STENCILFUNC, dx_stencil_comparison_function_array[front_compare]);
5175 stencil->
get_render_state(StencilAttrib::SRS_front_stencil_fail_operation)]);
5177 stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation)]);
5179 stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation)]);
5185 if (_supports_two_sided_stencil) {
5186 unsigned int back_compare;
5187 back_compare = stencil->
get_render_state(StencilAttrib::SRS_back_comparison_function);
5189 if (back_compare != RenderAttrib::M_none) {
5191 set_render_state(D3DRS_CCW_STENCILFUNC, dx_stencil_comparison_function_array[back_compare]);
5193 stencil->
get_render_state(StencilAttrib::SRS_back_stencil_fail_operation)]);
5195 stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation)]);
5197 stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation)]);
5211 _d3d_device->Clear(0,
nullptr, D3DCLEAR_STENCIL, 0, 0.0f, stencil->
get_render_state(StencilAttrib::SRS_clear_value));
5217 dxgsg9_cat.debug() <<
"STENCIL STATE CHANGE TO OFF\n";
5221 if (_supports_two_sided_stencil) {
5230void DXGraphicsStateGuardian9::
5233 const LVecBase4 &frame = target_scissor->
get_frame();
5236 r.left = _current_viewport.X + _current_viewport.Width * frame[0];
5237 r.top = _current_viewport.Y + _current_viewport.Height * (1.0f - frame[3]);
5238 r.right = _current_viewport.X + _current_viewport.Width * frame[1];
5239 r.bottom = _current_viewport.Y + _current_viewport.Height * (1.0f - frame[2]);
5240 _d3d_device->SetScissorRect(&r);
5250 DWORD multisampletype, DWORD multisamplequality) {
5253 int r=0, g=0, b=0, a=0;
5255 case D3DFMT_R8G8B8: r=8; g=8; b=8; a=0;
break;
5256 case D3DFMT_A8R8G8B8: r=8; g=8; b=8; a=8;
break;
5257 case D3DFMT_X8R8G8B8: r=8; g=8; b=8; a=0;
break;
5258 case D3DFMT_R5G6B5: r=5; g=6; b=5; a=0;
break;
5259 case D3DFMT_X1R5G5B5: r=5; g=5; b=5; a=0;
break;
5260 case D3DFMT_A1R5G5B5: r=5; g=5; b=5; a=1;
break;
5261 case D3DFMT_A4R4G4B4: r=4; g=4; b=4; a=4;
break;
5262 case D3DFMT_R3G3B2: r=3; g=3; b=2; a=0;
break;
5263 case D3DFMT_A8R3G3B2: r=3; g=3; b=2; a=8;
break;
5264 case D3DFMT_X4R4G4B4: r=4; g=4; b=4; a=0;
break;
5265 case D3DFMT_A2B10G10R10: r=10;g=10;b=10;a=2;
break;
5266 case D3DFMT_A8P8: index=8; a=8;
break;
5267 case D3DFMT_P8: index=8; a=0;
break;
5271 props.set_rgb_color(0);
5272 props.set_indexed_color(1);
5274 }
else if (r + g + b > 0) {
5275 props.set_rgb_color(1);
5276 props.set_indexed_color(0);
5279 props.set_alpha_bits(a);
5284 case D3DFMT_D32: depth=32; stencil=0;
break;
5285 case D3DFMT_D15S1: depth=15; stencil=1;
break;
5286 case D3DFMT_D24S8: depth=24; stencil=8;
break;
5287 case D3DFMT_D16: depth=16; stencil=0;
break;
5288 case D3DFMT_D24X8: depth=24; stencil=0;
break;
5289 case D3DFMT_D24X4S4: depth=24; stencil=4;
break;
5292 props.set_depth_bits(depth);
5293 props.set_stencil_bits(stencil);
5294 if (multisampletype == D3DMULTISAMPLE_NONMASKABLE) {
5295 props.set_multisamples(2);
5297 props.set_multisamples(multisampletype);
5303#define GAMMA_1 (255.0 * 256.0)
5305static bool _gamma_table_initialized =
false;
5306static bool _gamma_changed =
false;
5307static unsigned short _original_gamma_table [256 * 3];
5309void _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) {
5311 double gamma_correction;
5317 gamma_correction = 1.0 / (double) gamma;
5319 for (i = 0; i < 256; i++) {
5324 if (original_red_table) {
5325 r = (double) original_red_table [i] / GAMMA_1;
5326 g = (double) original_green_table [i] / GAMMA_1;
5327 b = (double) original_blue_table [i] / GAMMA_1;
5330 r = ((double) i / 255.0);
5335 r = pow (r, gamma_correction);
5336 g = pow (g, gamma_correction);
5337 b = pow (b, gamma_correction);
5354 green_table [i] = g;
5367 if (_gamma_table_initialized ==
false) {
5368 HDC hdc = GetDC(
nullptr);
5371 if (GetDeviceGammaRamp (hdc, (LPVOID) _original_gamma_table)) {
5372 _gamma_table_initialized =
true;
5376 ReleaseDC (
nullptr, hdc);
5389 HDC hdc = GetDC(
nullptr);
5393 unsigned short ramp [256 * 3];
5395 if (restore && _gamma_table_initialized) {
5396 _create_gamma_table_dx9 (gamma, &_original_gamma_table [0], &_original_gamma_table [256], &_original_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
5399 _create_gamma_table_dx9 (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]);
5402 if (SetDeviceGammaRamp (hdc, ramp)) {
5404 _gamma_changed = !restore;
5407 ReleaseDC (
nullptr, hdc);
5442 if (_gamma_changed) {
5456 CGprofile profile = cgGetProfile(name.c_str());
5458 if (profile == CG_PROFILE_UNKNOWN) {
5459 dxgsg9_cat.error() << name <<
", unknown Cg-profile\n";
5462 return cgD3D9IsProfileSupported(cgGetProfile(name.c_str())) != 0;
5473 if (_cg_device != cg_device) {
5474 cgD3D9SetDevice(cg_device);
5475 _cg_device = cg_device;
5485 if (_white_vbuffer !=
nullptr) {
5486 return _white_vbuffer;
5489 LPDIRECT3DVERTEXBUFFER9 vbuffer;
5491 hr = _screen->_d3d_device->CreateVertexBuffer(
sizeof(D3DCOLOR), D3DUSAGE_WRITEONLY, D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &vbuffer,
nullptr);
5495 <<
"CreateVertexBuffer failed" << D3DERRORSTRING(hr);
5499 D3DCOLOR *local_pointer;
5500 hr = vbuffer->Lock(0,
sizeof(D3DCOLOR), (
void **) &local_pointer, D3DLOCK_DISCARD);
5503 <<
"VertexBuffer::Lock failed" << D3DERRORSTRING(hr);
5507 *local_pointer = D3DCOLOR_ARGB(255, 255, 255, 255);
5510 _white_vbuffer = vbuffer;
5514typedef std::string KEY;
5516typedef struct _KEY_ELEMENT
5520 int secondary_count;
5522 struct _KEY_ELEMENT *next;
5526typedef struct _KEY_LIST
5528 int total_key_elements;
5529 KEY_ELEMENT *key_element;
5533KEY_ELEMENT *new_key_element (KEY key, KEY_LIST *key_list)
5535 KEY_ELEMENT *key_element;
5537 key_element =
new KEY_ELEMENT;
5538 key_element -> key = key;
5539 key_element -> count = 1;
5540 key_element -> secondary_count = 0;
5541 key_element -> next = 0;
5543 key_list -> total_key_elements++;
5548KEY_ELEMENT *first_key_element (KEY_LIST *key_list)
5550 return key_list -> key_element;
5553KEY_ELEMENT *next_key_element (KEY_ELEMENT *key_element)
5555 return key_element -> next;
5558void delete_key_list (KEY_LIST *key_list)
5562 KEY_ELEMENT *key_element;
5563 KEY_ELEMENT *key_element_next;
5565 key_element = first_key_element (key_list);
5568 key_element_next = next_key_element (key_element);
5570 key_element = key_element_next;
5577KEY_LIST *new_key_list (
void)
5581 key_list =
new KEY_LIST;
5582 memset (key_list, 0,
sizeof (KEY_LIST));
5587KEY_ELEMENT *add_to_key_list (KEY key, KEY_LIST *key_list)
5589 KEY_ELEMENT *key_element;
5590 KEY_ELEMENT *last_key_element;
5591 KEY_ELEMENT *current_key_element;
5594 last_key_element = 0;
5595 current_key_element = key_list -> key_element;
5596 if (current_key_element == 0)
5598 key_element = new_key_element (key, key_list);
5599 key_list -> key_element = key_element;
5603 while (current_key_element)
5605 if (key < current_key_element -> key)
5607 key_element = new_key_element (key, key_list);
5608 key_element -> next = current_key_element;
5610 if (last_key_element == 0)
5612 key_list -> key_element = key_element;
5616 last_key_element -> next = key_element;
5622 if (key > current_key_element -> key)
5624 if (current_key_element -> next == 0)
5626 key_element = new_key_element (key, key_list);
5627 current_key_element -> next = key_element;
5637 current_key_element -> count++;
5642 last_key_element = current_key_element;
5643 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.
get_plane
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.
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.