16 #include "dxGraphicsStateGuardian9.h"
17 #include "config_dxgsg9.h"
18 #include "displayRegion.h"
19 #include "renderBuffer.h"
21 #include "graphicsWindow.h"
22 #include "graphicsEngine.h"
24 #include "ambientLight.h"
25 #include "directionalLight.h"
26 #include "pointLight.h"
27 #include "spotlight.h"
28 #include "textureAttrib.h"
29 #include "texGenAttrib.h"
30 #include "shadeModelAttrib.h"
31 #include "cullFaceAttrib.h"
32 #include "transparencyAttrib.h"
33 #include "alphaTestAttrib.h"
34 #include "depthTestAttrib.h"
35 #include "depthWriteAttrib.h"
36 #include "colorWriteAttrib.h"
37 #include "texMatrixAttrib.h"
38 #include "materialAttrib.h"
39 #include "renderModeAttrib.h"
40 #include "rescaleNormalAttrib.h"
41 #include "fogAttrib.h"
42 #include "depthOffsetAttrib.h"
43 #include "lightAttrib.h"
44 #include "stencilAttrib.h"
45 #include "scissorAttrib.h"
46 #include "clipPlaneAttrib.h"
48 #include "throw_event.h"
49 #include "geomVertexFormat.h"
50 #include "geomVertexData.h"
51 #include "geomTriangles.h"
52 #include "geomTristrips.h"
53 #include "geomTrifans.h"
54 #include "geomLines.h"
55 #include "geomLinestrips.h"
56 #include "geomPoints.h"
57 #include "geomVertexReader.h"
58 #include "dxGeomMunger9.h"
59 #include "config_gobj.h"
60 #include "dxVertexBufferContext9.h"
61 #include "dxIndexBufferContext9.h"
62 #include "dxOcclusionQueryContext9.h"
63 #include "pStatTimer.h"
64 #include "pStatCollector.h"
65 #include "wdxGraphicsBuffer9.h"
66 #include "config_pgraph.h"
67 #include "shaderGenerator.h"
69 #include "Cg/cgD3D9.h"
76 #define tostring(x) #x
77 #define SDK_VERSION(major,minor) tostring(major) << "." << tostring(minor)
78 #define DIRECTX_SDK_VERSION SDK_VERSION (_DXSDK_PRODUCT_MAJOR, _DXSDK_PRODUCT_MINOR) << "." << SDK_VERSION (_DXSDK_BUILD_MAJOR, _DXSDK_BUILD_MINOR)
80 TypeHandle DXGraphicsStateGuardian9::_type_handle;
82 D3DMATRIX DXGraphicsStateGuardian9::_d3d_ident_mat;
84 unsigned char *DXGraphicsStateGuardian9::_temp_buffer = NULL;
85 unsigned char *DXGraphicsStateGuardian9::_safe_buffer_start = NULL;
88 LPDIRECT3DDEVICE9 DXGraphicsStateGuardian9::_cg_device = NULL;
91 #define __D3DLIGHT_RANGE_MAX ((PN_stdfloat)sqrt(FLT_MAX)) //for some reason this is missing in dx9 hdrs
93 #define MY_D3DRGBA(r, g, b, a) ((D3DCOLOR) D3DCOLOR_COLORVALUE(r, g, b, a))
100 DXGraphicsStateGuardian9::
104 if (dxgsg9_cat.is_debug()) {
106 <<
"DXGraphicsStateGuardian9 " <<
this <<
" constructing\n";
116 _dx_is_ready =
false;
117 _vertex_blending_enabled =
false;
118 _overlay_windows_supported =
false;
119 _tex_stats_retrieval_impossible =
false;
120 _supports_render_texture =
false;
122 _active_ibuffer = NULL;
127 ZeroMemory(&_d3d_ident_mat,
sizeof(D3DMATRIX));
128 _d3d_ident_mat._11 = _d3d_ident_mat._22 = _d3d_ident_mat._33 = _d3d_ident_mat._44 = 1.0f;
130 _cur_read_pixel_buffer = RenderBuffer::T_front;
134 _copy_texture_inverted =
true;
136 _gsg_managed_textures = dx_management | dx_texture_management;
137 _gsg_managed_vertex_buffers = dx_management;
138 _gsg_managed_index_buffers = dx_management;
141 _num_bound_streams = 0;
143 _vertex_shader_version_major = 0;
144 _vertex_shader_version_minor = 0;
145 _pixel_shader_version_major = 0;
146 _pixel_shader_version_minor = 0;
148 _vertex_shader_profile = 0;
149 _pixel_shader_profile = 0;
151 _vertex_shader_maximum_constants = 0;
153 _supports_stream_offset =
false;
160 atexit (atexit_function);
168 DXGraphicsStateGuardian9::
169 ~DXGraphicsStateGuardian9() {
170 if (dxgsg9_cat.is_debug()) {
172 <<
"DXGraphicsStateGuardian9 " <<
this <<
" destructing\n";
175 if (IS_VALID_PTR(_d3d_device)) {
176 _d3d_device->SetTexture(0, NULL);
179 free_nondx_resources();
201 << *dtc->
get_texture() <<
" is stored in an unsupported compressed format.\n";
257 if (aniso_degree >= 1) {
261 int supports_anisotropic_mag_filter;
262 D3DTEXTUREFILTERTYPE new_mag_filter;
264 supports_anisotropic_mag_filter = (_screen -> _d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) != 0;
265 if (aniso_degree <= 1 || supports_anisotropic_mag_filter == 0) {
266 new_mag_filter = ((ft != SamplerState::FT_nearest) ? D3DTEXF_LINEAR : D3DTEXF_POINT);
268 new_mag_filter = D3DTEXF_ANISOTROPIC;
275 <<
"ERROR: set_sampler_state (D3DSAMP_MAGFILTER, "
276 << new_mag_filter <<
") failed for sampler: " << sampler << endl;
287 new_mip_filter = D3DTEXF_NONE;
292 new_mip_filter = D3DTEXF_NONE;
295 if (aniso_degree >= 2) {
296 new_min_filter = D3DTEXF_ANISOTROPIC;
336 <<
"Unable to re-create texture " << *tex << endl;
340 dtc->
enqueue_lru(&_prepared_objects->_graphics_memory_lru);
356 << *tex <<
" is stored in an unsupported compressed format.\n";
364 if (_effective_incomplete_render && !force) {
368 !_loader.is_null()) {
371 async_reload_texture(dtc);
375 return dtc->create_simple_texture(*_screen);
414 for (
int view = 0; view < num_views; ++view) {
471 if (_screen->_managed_vertex_buffers) {
472 pool = D3DPOOL_MANAGED;
473 usage = D3DUSAGE_WRITEONLY;
475 pool = D3DPOOL_DEFAULT;
476 usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC;
479 int num_bytes = data->get_data_size_bytes();
487 hr = _screen->_d3d_device->CreateVertexBuffer(num_bytes, usage, dvbc->_fvf, pool, &dvbc->_vbuffer, NULL);
490 while (check_dx_allocation(hr, num_bytes, attempts));
494 if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) {
496 <<
"creating vertex buffer " << dvbc->_vbuffer <<
": "
497 << data->get_num_rows() <<
" vertices "
498 << *data->get_array_format() <<
"\n";
505 <<
"CreateVertexBuffer failed" << D3DERRORSTRING(hr);
507 dvbc->_vbuffer = NULL;
525 if (dvbc->was_modified(reader)) {
526 int num_bytes = reader->get_data_size_bytes();
528 if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) {
530 <<
"copying " << num_bytes
531 <<
" bytes into vertex buffer " << dvbc->_vbuffer <<
"\n";
535 if ( num_bytes != 0 ) {
536 const unsigned char *client_pointer = reader->get_read_pointer(force);
537 if (client_pointer == NULL) {
541 PStatTimer timer(_load_vertex_buffer_pcollector, reader->get_current_thread());
544 if (dvbc->changed_size(reader)) {
547 dvbc->create_vbuffer(*_screen, reader);
553 if (_screen->_managed_vertex_buffers) {
554 hr = dvbc->_vbuffer->Lock(0, num_bytes, (
void **) &local_pointer, 0);
556 hr = dvbc->_vbuffer->Lock(0, num_bytes, (
void **) &local_pointer, D3DLOCK_DISCARD);
560 <<
"VertexBuffer::Lock failed" << D3DERRORSTRING(hr);
564 memcpy(local_pointer, client_pointer, num_bytes);
566 dvbc->_vbuffer->Unlock();
568 _data_transferred_pcollector.add_level(num_bytes);
571 dvbc->mark_loaded(reader);
573 dvbc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
592 if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) {
594 <<
"deleting vertex buffer " << dvbc->_vbuffer <<
"\n";
598 dvbc->_vbuffer->Release();
599 dvbc->_vbuffer = NULL;
630 if (!apply_vertex_buffer(vbc, array_reader, force)) {
668 if (dibc->_ibuffer == NULL) {
672 if (dibc->_ibuffer != NULL) {
678 _d3d_device->SetIndices(dibc->_ibuffer);
679 _active_ibuffer = dibc;
683 _d3d_device->SetIndices(NULL);
684 _active_ibuffer = NULL;
700 _active_ibuffer = NULL;
703 if (_active_ibuffer != dibc) {
704 _d3d_device->SetIndices(dibc->_ibuffer);
705 _active_ibuffer = dibc;
709 dibc->
enqueue_lru(&_prepared_objects->_graphics_memory_lru);
746 nassertv(_supports_occlusion_query);
749 IDirect3DQuery9 *query;
750 HRESULT hr = _d3d_device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &query);
753 <<
"Occlusion query failed.\n";
759 if (dxgsg9_cat.is_debug()) {
761 <<
"beginning occlusion query " << query <<
"\n";
764 query->Issue(D3DISSUE_BEGIN);
765 _current_occlusion_query = queryobj;
778 end_occlusion_query() {
787 if (dxgsg9_cat.is_debug()) {
789 <<
"ending occlusion query " << query <<
"\n";
792 _current_occlusion_query = NULL;
793 query->Issue(D3DISSUE_END);
807 return
GeomMunger::register_munger(munger, current_thread);
819 DWORD main_flags = 0;
822 if ((!clearable->get_clear_color_active())&&
823 (!clearable->get_clear_depth_active())&&
824 (!clearable->get_clear_stencil_active())) {
828 set_state_and_transform(RenderState::make_empty(), _internal_transform);
830 D3DCOLOR color_clear_value = LColor_to_D3DCOLOR(clearable->get_clear_color());
831 PN_stdfloat depth_clear_value = clearable->get_clear_depth();
832 DWORD stencil_clear_value = (DWORD)(clearable->get_clear_stencil());
835 if (clearable->get_clear_color_active()) {
836 main_flags |= D3DCLEAR_TARGET;
839 if (clearable->get_clear_depth_active()) {
840 aux_flags |= D3DCLEAR_ZBUFFER;
841 nassertv(_screen->_presentation_params.EnableAutoDepthStencil);
844 if (clearable->get_clear_stencil_active()) {
846 if (_screen->_presentation_params.EnableAutoDepthStencil &&
847 IS_STENCIL_FORMAT(_screen->_presentation_params.AutoDepthStencilFormat)) {
848 aux_flags |= D3DCLEAR_STENCIL;
852 if ((main_flags | aux_flags) != 0) {
853 HRESULT hr = _d3d_device->Clear(0, NULL, main_flags | aux_flags, color_clear_value,
854 depth_clear_value, stencil_clear_value);
855 if (FAILED(hr) && main_flags == D3DCLEAR_TARGET && aux_flags != 0) {
858 hr = _d3d_device->Clear(0, NULL, D3DCLEAR_TARGET, color_clear_value,
859 depth_clear_value, stencil_clear_value);
863 if (clearable->get_clear_depth_active()) {
864 aux_flags |= D3DCLEAR_ZBUFFER;
865 HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, color_clear_value,
866 depth_clear_value, stencil_clear_value);
869 <<
"Unable to clear depth buffer; removing.\n";
874 if (clearable->get_clear_stencil_active()) {
875 aux_flags |= D3DCLEAR_STENCIL;
876 HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_STENCIL, color_clear_value,
877 stencil_clear_value, stencil_clear_value);
880 <<
"Unable to clear stencil buffer; removing.\n";
883 _supports_stencil =
false;
891 <<
"clear_buffer failed: Clear returned " << D3DERRORSTRING(hr);
911 D3DVIEWPORT9 vp = { l, u, w, h, 0.0f, 1.0f };
912 _current_viewport = vp;
913 HRESULT hr = _d3d_device->SetViewport(&_current_viewport);
916 <<
"_screen->_swap_chain = " << _screen->_swap_chain <<
" _swap_chain = " << _swap_chain <<
"\n";
918 <<
"SetViewport(" << l <<
", " << u <<
", " << w <<
", " << h
919 <<
") failed" << D3DERRORSTRING(hr);
922 _d3d_device->GetViewport(&vp_old);
924 <<
"GetViewport(" << vp_old.X <<
", " << vp_old.Y <<
", " << vp_old.Width <<
", "
925 << vp_old.Height <<
") returned: Trying to set that vp---->\n";
926 hr = _d3d_device->SetViewport(&vp_old);
930 dxgsg9_cat.error() <<
"Failed again\n";
931 throw_event(
"panda3d-render-error");
936 if (_screen->_can_direct_disable_color_writes) {
953 calc_projection_mat(const
Lens *lens) {
954 if (lens == (
Lens *)NULL) {
958 if (!lens->is_linear()) {
973 lens->get_projection_mat(_current_stereo_channel) *
976 if (_scene_setup->get_inverted()) {
982 return TransformState::make_mat(result);
999 LMatrix4f mat = LCAST(
float, _projection_mat->get_mat());
1001 _d3d_device->SetTransform(D3DTS_PROJECTION,
1003 return SUCCEEDED(hr);
1024 if (_d3d_device == NULL) {
1026 <<
this <<
"::begin_frame(): no device.\n";
1030 HRESULT hr = _d3d_device->BeginScene();
1033 if (hr == D3DERR_DEVICELOST) {
1034 if (dxgsg9_cat.is_debug()) {
1036 <<
"BeginScene returns D3DERR_DEVICELOST" << endl;
1039 check_cooperative_level();
1043 <<
"BeginScene failed, unhandled error hr == "
1044 << D3DERRORSTRING(hr) << endl;
1045 throw_event(
"panda3d-render-error");
1050 if (_current_properties->get_srgb_color()) {
1118 if (_vertex_array_shader_context != 0) {
1120 _vertex_array_shader = (
Shader *)NULL;
1123 if (_texture_binding_shader_context != 0) {
1125 _texture_binding_shader = (
Shader *)NULL;
1126 _texture_binding_shader_context = (CLP(
ShaderContext) *)NULL;
1128 if (_current_shader_context != 0) {
1129 _current_shader_context->
unbind(
this);
1130 _current_shader = (
Shader *)NULL;
1168 HRESULT hr = _d3d_device->EndScene();
1171 if (hr == D3DERR_DEVICELOST) {
1172 if (dxgsg9_cat.is_debug()) {
1174 <<
"EndScene returns DeviceLost\n";
1176 check_cooperative_level();
1180 <<
"EndScene failed, unhandled error hr == " << D3DERRORSTRING(hr);
1181 throw_event(
"panda3d-render-error");
1186 #if defined(DO_PSTATS)
1187 if (_texmgrmem_total_pcollector.is_active()) {
1188 #define TICKS_PER_GETTEXINFO (2.5*1000) // 2.5 second interval
1189 static DWORD last_tick_count = 0;
1190 DWORD cur_tick_count = GetTickCount();
1192 if (cur_tick_count - last_tick_count > TICKS_PER_GETTEXINFO) {
1193 last_tick_count = cur_tick_count;
1194 report_texmgr_stats();
1219 data_reader, force)) {
1224 const GeomVertexFormat *format = _data_reader->get_format();
1227 data_reader->get_format()->get_animation();
1258 const TransformTable *table = data_reader->get_transform_table();
1263 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)mat.
get_data();
1264 _d3d_device->SetTransform(D3DTS_WORLDMATRIX(i), d3d_mat);
1269 _transform_stale =
true;
1271 _vertex_blending_enabled =
true;
1275 if (_vertex_blending_enabled) {
1278 _vertex_blending_enabled =
false;
1281 if (_transform_stale && !_data_reader->is_vertex_transformed()) {
1282 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)_internal_transform->get_mat().get_data();
1283 _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
1284 _transform_stale =
false;
1288 if (_data_reader->is_vertex_transformed()) {
1297 _d3d_device->SetTransform(D3DTS_WORLD, &_d3d_ident_mat);
1303 _transform_stale =
true;
1305 _d3d_device->SetTransform(D3DTS_PROJECTION, (
const D3DMATRIX *)rescale_mat.
get_data());
1308 if (_current_shader_context == 0 ) {
1310 if (_vertex_array_shader_context != 0) {
1313 if (!update_standard_vertex_arrays(force)) {
1318 if (_vertex_array_shader_context == 0) {
1319 disable_standard_vertex_arrays();
1324 if (!_current_shader_context->
1325 update_shader_vertex_arrays(_vertex_array_shader_context,
this, force)) {
1331 _vertex_array_shader = _current_shader;
1332 _vertex_array_shader_context = _current_shader_context;
1347 update_standard_vertex_arrays(bool force) {
1352 int number_of_arrays = _data_reader->get_num_arrays();
1353 for (
int array_index = 0; array_index < number_of_arrays; ++array_index ) {
1355 if ( array_reader == NULL ) {
1356 dxgsg9_cat.error() <<
"Unable to get reader for array " << array_index <<
"\n";
1362 if (!setup_array_data(dvbc, array_reader, force)) {
1363 dxgsg9_cat.error() <<
"Unable to setup vertex buffer for array " << array_index <<
"\n";
1368 const GeomVertexArrayFormat* array_format = array_reader->get_array_format();
1369 hr = _d3d_device->SetStreamSource( array_index, dvbc->_vbuffer, 0, array_format->get_stride() );
1371 dxgsg9_cat.error() <<
"SetStreamSource failed" << D3DERRORSTRING(hr);
1379 hr = _d3d_device->SetFVF( fvf );
1381 dxgsg9_cat.error() <<
"SetFVF failed" << D3DERRORSTRING(hr);
1398 disable_standard_vertex_arrays() {
1399 for (
int array_index = 0; array_index < _num_bound_streams; ++array_index )
1401 _d3d_device->SetStreamSource( array_index, NULL, 0, 0 );
1403 _num_bound_streams = 0;
1415 _vertices_tri_pcollector.add_level(reader->get_num_vertices());
1416 _primitive_batches_tri_pcollector.add_level(1);
1418 if (reader->is_indexed()) {
1419 int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
1420 int max_vertex = reader->get_max_vertex();
1429 _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,
1431 min_vertex, max_vertex - min_vertex + 1,
1432 0, reader->get_num_primitives() );
1436 const unsigned char *index_pointer = reader->get_read_pointer(force);
1437 if (index_pointer == NULL) {
1441 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1442 if (vertex_pointer == NULL) {
1446 draw_indexed_primitive_up( D3DPT_TRIANGLELIST,
1447 min_vertex, max_vertex,
1448 reader->get_num_primitives(),
1449 index_pointer, index_type, vertex_pointer,
1450 _data_reader->get_format()->get_array(0)->get_stride() );
1454 _d3d_device->DrawPrimitive( D3DPT_TRIANGLELIST,
1455 reader->get_first_vertex(),
1456 reader->get_num_primitives() );
1460 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1461 if (vertex_pointer == NULL) {
1465 draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(),
1466 reader->get_first_vertex(),
1467 reader->get_num_vertices(), vertex_pointer,
1468 _data_reader->get_format()->get_array(0)->get_stride());
1484 if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) {
1487 _vertices_tristrip_pcollector.add_level(reader->get_num_vertices());
1488 _primitive_batches_tristrip_pcollector.add_level(1);
1490 if (reader->is_indexed()) {
1491 int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
1492 int max_vertex = reader->get_max_vertex();
1501 _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP,
1503 min_vertex, max_vertex - min_vertex + 1,
1504 0, reader->get_num_vertices() - 2 );
1508 const unsigned char *index_pointer = reader->get_read_pointer(force);
1509 if (index_pointer == NULL) {
1513 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1514 if (vertex_pointer == NULL) {
1518 draw_indexed_primitive_up
1519 (D3DPT_TRIANGLESTRIP,
1520 min_vertex, max_vertex,
1521 reader->get_num_vertices() - 2,
1522 index_pointer, index_type, vertex_pointer,
1523 _data_reader->get_format()->get_array(0)->get_stride());
1527 _d3d_device->DrawPrimitive( D3DPT_TRIANGLESTRIP,
1528 reader->get_first_vertex(),
1529 reader->get_num_vertices() - 2 );
1533 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1534 if (vertex_pointer == NULL) {
1537 draw_primitive_up(D3DPT_TRIANGLESTRIP,
1538 reader->get_num_vertices() - 2,
1539 reader->get_first_vertex(),
1540 reader->get_num_vertices(), vertex_pointer,
1541 _data_reader->get_format()->get_array(0)->get_stride());
1547 CPTA_int ends = reader->get_ends();
1548 _primitive_batches_tristrip_pcollector.add_level(ends.size());
1550 if (reader->is_indexed()) {
1551 CPTA_int ends = reader->get_ends();
1552 int index_stride = reader->get_index_stride();
1553 _primitive_batches_tristrip_pcollector.add_level(ends.size());
1557 nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
1558 reader->get_maxs()->get_num_rows() == (int)ends.size(),
false);
1567 unsigned int start = 0;
1568 for (
size_t i = 0; i < ends.size(); i++) {
1569 _vertices_tristrip_pcollector.add_level(ends[i] - start);
1570 unsigned int min = mins.get_data1i();
1571 unsigned int max = maxs.get_data1i();
1572 _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP,
1575 start, ends[i] - start - 2 );
1576 start = ends[i] + 2;
1581 int stride = _data_reader->get_format()->get_array(0)->get_stride();
1582 const unsigned char *index_pointer = reader->get_read_pointer(force);
1583 if (index_pointer == NULL) {
1587 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1588 if (vertex_pointer == NULL) {
1592 unsigned int start = 0;
1593 for (
size_t i = 0; i < ends.size(); i++) {
1594 _vertices_tristrip_pcollector.add_level(ends[i] - start);
1595 unsigned int min = mins.get_data1i();
1596 unsigned int max = maxs.get_data1i();
1597 draw_indexed_primitive_up
1598 (D3DPT_TRIANGLESTRIP,
1600 ends[i] - start - 2,
1601 index_pointer + start * index_stride, index_type,
1602 vertex_pointer, stride);
1604 start = ends[i] + 2;
1608 unsigned int first_vertex = reader->get_first_vertex();
1611 unsigned int start = 0;
1612 for (
size_t i = 0; i < ends.size(); i++) {
1613 _vertices_tristrip_pcollector.add_level(ends[i] - start);
1614 _d3d_device->DrawPrimitive( D3DPT_TRIANGLESTRIP,
1615 first_vertex + start,
1616 ends[i] - start - 2 );
1617 start = ends[i] + 2;
1622 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1623 if (vertex_pointer == NULL) {
1626 int stride = _data_reader->get_format()->get_array(0)->get_stride();
1628 unsigned int start = 0;
1629 for (
size_t i = 0; i < ends.size(); i++) {
1630 _vertices_tristrip_pcollector.add_level(ends[i] - start);
1631 draw_primitive_up(D3DPT_TRIANGLESTRIP, ends[i] - start - 2,
1632 first_vertex + start,
1634 vertex_pointer, stride);
1636 start = ends[i] + 2;
1653 CPTA_int ends = reader->get_ends();
1654 _primitive_batches_trifan_pcollector.add_level(ends.size());
1656 if (reader->is_indexed()) {
1657 int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
1658 int max_vertex = reader->get_max_vertex();
1662 int index_stride = reader->get_index_stride();
1666 nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
1667 reader->get_maxs()->get_num_rows() == (int)ends.size(),
false);
1676 unsigned int start = 0;
1677 for (
size_t i = 0; i < ends.size(); i++) {
1678 _vertices_trifan_pcollector.add_level(ends[i] - start);
1679 unsigned int min = mins.get_data1i();
1680 unsigned int max = maxs.get_data1i();
1681 _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLEFAN,
1684 start, ends[i] - start - 2 );
1690 int stride = _data_reader->get_format()->get_array(0)->get_stride();
1691 const unsigned char *index_pointer = reader->get_read_pointer(force);
1692 if (index_pointer == NULL) {
1696 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1697 if (vertex_pointer == NULL) {
1701 unsigned int start = 0;
1702 for (
size_t i = 0; i < ends.size(); i++) {
1703 _vertices_trifan_pcollector.add_level(ends[i] - start);
1704 unsigned int min = mins.get_data1i();
1705 unsigned int max = maxs.get_data1i();
1706 draw_indexed_primitive_up
1709 ends[i] - start - 2,
1710 index_pointer + start * index_stride, index_type,
1711 vertex_pointer, stride);
1717 unsigned int first_vertex = reader->get_first_vertex();
1720 unsigned int start = 0;
1721 for (
size_t i = 0; i < ends.size(); i++) {
1722 _vertices_trifan_pcollector.add_level(ends[i] - start);
1723 _d3d_device->DrawPrimitive( D3DPT_TRIANGLEFAN,
1724 first_vertex + start,
1725 ends[i] - start - 2 );
1731 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1732 if (vertex_pointer == NULL) {
1735 int stride = _data_reader->get_format()->get_array(0)->get_stride();
1737 unsigned int start = 0;
1738 for (
size_t i = 0; i < ends.size(); i++) {
1739 _vertices_trifan_pcollector.add_level(ends[i] - start);
1740 draw_primitive_up(D3DPT_TRIANGLEFAN,
1741 ends[i] - start - 2,
1744 vertex_pointer, stride);
1761 _vertices_other_pcollector.add_level(reader->get_num_vertices());
1762 _primitive_batches_other_pcollector.add_level(1);
1764 if (reader->is_indexed()) {
1765 int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
1766 int max_vertex = reader->get_max_vertex();
1775 _d3d_device->DrawIndexedPrimitive( D3DPT_LINELIST,
1777 min_vertex, max_vertex - min_vertex + 1,
1778 0, reader->get_num_primitives() );
1782 const unsigned char *index_pointer = reader->get_read_pointer(force);
1783 if (index_pointer == NULL) {
1787 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1788 if (vertex_pointer == NULL) {
1792 draw_indexed_primitive_up
1794 min_vertex, max_vertex,
1795 reader->get_num_primitives(),
1796 index_pointer, index_type, vertex_pointer,
1797 _data_reader->get_format()->get_array(0)->get_stride());
1801 _d3d_device->DrawPrimitive( D3DPT_LINELIST,
1802 reader->get_first_vertex(),
1803 reader->get_num_primitives() );
1807 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1808 if (vertex_pointer == NULL) {
1811 draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(),
1812 reader->get_first_vertex(),
1813 reader->get_num_vertices(), vertex_pointer,
1814 _data_reader->get_format()->get_array(0)->get_stride());
1839 _vertices_other_pcollector.add_level(reader->get_num_vertices());
1840 _primitive_batches_other_pcollector.add_level(1);
1844 nassertr(!reader->is_indexed(),
false);
1847 _d3d_device->DrawPrimitive( D3DPT_POINTLIST,
1848 reader->get_first_vertex(),
1849 reader->get_num_primitives() );
1853 const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force);
1854 if (vertex_pointer == NULL) {
1857 draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(),
1858 reader->get_first_vertex(),
1859 reader->get_num_vertices(), vertex_pointer,
1860 _data_reader->get_format()->get_array(0)->get_stride());
1877 if (_vertex_blending_enabled) {
1880 _vertex_blending_enabled =
false;
1883 if (_data_reader->is_vertex_transformed()) {
1885 LMatrix4f mat = LCAST(
float, _projection_mat->get_mat());
1886 _d3d_device->SetTransform(D3DTS_PROJECTION,
1905 set_read_buffer(rb);
1926 <<
"Unable to re-create texture " << *dtc->
get_texture() << endl;
1937 IDirect3DSurface9 *tex_level_0;
1940 dxgsg9_cat.error() <<
"GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
1945 D3DSURFACE_DESC texdesc;
1946 hr = tex_level_0->GetDesc(&texdesc);
1948 dxgsg9_cat.error() <<
"GetDesc failed in copy_texture" << D3DERRORSTRING(hr);
1949 SAFE_RELEASE(tex_level_0);
1955 SAFE_RELEASE(tex_level_0);
1959 <<
"Unable to re-create texture " << *dtc->
get_texture() << endl;
1964 dxgsg9_cat.error() <<
"GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
1967 hr = tex_level_0->GetDesc(&texdesc);
1969 dxgsg9_cat.error() <<
"GetDesc 2 failed in copy_texture" << D3DERRORSTRING(hr);
1970 SAFE_RELEASE(tex_level_0);
1978 <<
"Unable to copy to texture, texture is wrong size: " << *dtc->
get_texture() << endl;
1979 SAFE_RELEASE(tex_level_0);
1984 DWORD render_target_index;
1985 IDirect3DSurface9 *render_target;
1988 render_target_index = 0;
1990 hr = _d3d_device->GetRenderTarget(render_target_index, &render_target);
1993 <<
"GetRenderTarget failed in framebuffer_copy_to_texture"
1994 << D3DERRORSTRING(hr);
1995 SAFE_RELEASE(tex_level_0);
2002 src_rect.right = xo+w;
2004 src_rect.bottom = yo+h;
2010 D3DTEXTUREFILTERTYPE filter;
2012 filter = D3DTEXF_POINT;
2015 hr = _d3d_device->StretchRect(render_target, &src_rect,
2016 tex_level_0, &src_rect,
2020 <<
"StretchRect failed in framebuffer_copy_to_texture"
2021 << D3DERRORSTRING(hr);
2025 SAFE_RELEASE(render_target);
2026 SAFE_RELEASE(tex_level_0);
2030 dtc->
enqueue_lru(&_prepared_objects->_graphics_memory_lru);
2071 set_read_buffer(rb);
2074 nassertr(tex != NULL && dr != NULL,
false);
2083 case Texture::F_depth_stencil:
2088 format = Texture::F_rgb;
2089 component_type = Texture::T_unsigned_byte;
2092 Texture::TextureType texture_type;
2094 texture_type = Texture::TT_cube_map;
2096 texture_type = Texture::TT_2d_texture;
2105 component_type, format);
2110 rect.right = xo + w;
2111 rect.bottom = yo + h;
2112 bool copy_inverted =
false;
2114 IDirect3DSurface9 *temp_surface = NULL;
2120 if (_cur_read_pixel_buffer & RenderBuffer::T_back) {
2121 DWORD render_target_index;
2122 IDirect3DSurface9 *backbuffer = NULL;
2127 render_target_index = 0;
2128 hr = _d3d_device->GetRenderTarget(render_target_index, &backbuffer);
2131 dxgsg9_cat.error() <<
"GetRenderTarget failed" << D3DERRORSTRING(hr);
2139 D3DSURFACE_DESC surface_description;
2141 backbuffer -> GetDesc (&surface_description);
2143 pool = D3DPOOL_SYSTEMMEM;
2144 hr = _d3d_device->CreateOffscreenPlainSurface(
2145 surface_description.Width,
2146 surface_description.Height,
2147 surface_description.Format,
2153 <<
"CreateImageSurface failed in copy_pixel_buffer()"
2154 << D3DERRORSTRING(hr);
2155 backbuffer->Release();
2160 hr = _d3d_device -> GetRenderTargetData (backbuffer, temp_surface);
2162 dxgsg9_cat.error() <<
"GetRenderTargetData failed" << D3DERRORSTRING(hr);
2163 temp_surface->Release();
2164 backbuffer->Release();
2168 copy_inverted =
true;
2170 RELEASE(backbuffer, dxgsg9,
"backbuffer", RELEASE_ONCE);
2172 }
else if (_cur_read_pixel_buffer & RenderBuffer::T_front) {
2174 if (_screen->_presentation_params.Windowed) {
2181 minfo.cbSize =
sizeof(MONITORINFO);
2182 GetMonitorInfo(_screen->_monitor, &minfo);
2184 w = RECT_XSIZE(minfo.rcMonitor);
2185 h = RECT_YSIZE(minfo.rcMonitor);
2188 ClientToScreen(_screen->_window, (POINT*)&rect.left);
2189 ClientToScreen(_screen->_window, (POINT*)&rect.right);
2195 hr = _d3d_device->CreateOffscreenPlainSurface(w, h, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &temp_surface, NULL);
2198 <<
"CreateImageSurface failed in copy_pixel_buffer()"
2199 << D3DERRORSTRING(hr);
2206 hr = _d3d_device->GetFrontBufferData(swap_chain,temp_surface);
2208 if (hr == D3DERR_DEVICELOST) {
2210 <<
"copy_pixel_buffer failed: device lost\n";
2211 temp_surface->Release();
2215 copy_inverted =
true;
2219 <<
"copy_pixel_buffer: unhandled current_read_pixel_buffer type\n";
2220 temp_surface->Release();
2225 copy_inverted = !copy_inverted;
2228 copy_inverted, tex, view, z);
2230 RELEASE(temp_surface, dxgsg9,
"temp_surface", RELEASE_ONCE);
2236 void DXGraphicsStateGuardian9::reset_render_states (
void)
2239 int maximum_texture_stages;
2241 maximum_texture_stages = D3D_MAXTEXTURESTAGES;
2244 memset (_render_state_array, -1,
sizeof (_render_state_array));
2245 memset (_texture_stage_states_array, -1,
sizeof (_texture_stage_states_array));
2248 _render_state_array [D3DRS_FOGCOLOR] = 0;
2249 _render_state_array [D3DRS_AMBIENT] = 0;
2252 memset (_texture_render_states_array, 0,
sizeof (_texture_render_states_array));
2255 for (index = 0; index < MAXIMUM_TEXTURES; index++) {
2256 TextureRenderStates *texture_render_states;
2258 texture_render_states = &_texture_render_states_array [index];
2259 texture_render_states -> state_array [D3DSAMP_MAGFILTER] = D3DTEXF_POINT;
2260 texture_render_states -> state_array [D3DSAMP_MINFILTER] = D3DTEXF_POINT;
2261 texture_render_states -> state_array [D3DSAMP_MAXANISOTROPY] = 1;
2263 _num_active_texture_stages = 0;
2285 _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot());
2286 _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot());
2287 _inv_state_mask.clear_bit(ClipPlaneAttrib::get_class_slot());
2288 _inv_state_mask.clear_bit(ColorAttrib::get_class_slot());
2289 _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot());
2290 _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot());
2291 _inv_state_mask.clear_bit(DepthOffsetAttrib::get_class_slot());
2292 _inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot());
2293 _inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
2294 _inv_state_mask.clear_bit(RenderModeAttrib::get_class_slot());
2295 _inv_state_mask.clear_bit(RescaleNormalAttrib::get_class_slot());
2296 _inv_state_mask.clear_bit(ShadeModelAttrib::get_class_slot());
2297 _inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
2298 _inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
2299 _inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot());
2300 _inv_state_mask.clear_bit(TextureAttrib::get_class_slot());
2301 _inv_state_mask.clear_bit(TexGenAttrib::get_class_slot());
2302 _inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
2303 _inv_state_mask.clear_bit(MaterialAttrib::get_class_slot());
2304 _inv_state_mask.clear_bit(LightAttrib::get_class_slot());
2305 _inv_state_mask.clear_bit(StencilAttrib::get_class_slot());
2306 _inv_state_mask.clear_bit(FogAttrib::get_class_slot());
2307 _inv_state_mask.clear_bit(ScissorAttrib::get_class_slot());
2312 _supported_geom_rendering =
2313 Geom::GR_point | Geom::GR_point_uniform_size |
2314 Geom::GR_point_perspective | Geom::GR_point_sprite |
2315 Geom::GR_indexed_other |
2316 Geom::GR_triangle_strip | Geom::GR_triangle_fan |
2317 Geom::GR_flat_first_vertex;
2319 _auto_rescale_normal =
false;
2330 nassertv(_screen->_d3d9 != NULL);
2332 if (_d3d_device == NULL) {
2337 _d3d_device->GetDeviceCaps(&d3d_caps);
2339 _vertex_shader_version_major = D3DSHADER_VERSION_MAJOR (d3d_caps.VertexShaderVersion);
2340 _vertex_shader_version_minor = D3DSHADER_VERSION_MINOR (d3d_caps.VertexShaderVersion);
2341 _pixel_shader_version_major = D3DSHADER_VERSION_MAJOR (d3d_caps.PixelShaderVersion);
2342 _pixel_shader_version_minor = D3DSHADER_VERSION_MINOR (d3d_caps.PixelShaderVersion);
2344 _vertex_shader_profile = (
char *) D3DXGetVertexShaderProfile (_d3d_device);
2345 _pixel_shader_profile = (
char *) D3DXGetPixelShaderProfile (_d3d_device);
2347 _vertex_shader_maximum_constants = d3d_caps.MaxVertexShaderConst;
2349 switch (_pixel_shader_version_major)
2352 _shader_model = SM_00;
2355 _shader_model = SM_11;
2359 _shader_model = SM_20;
2360 if (d3d_caps.PS20Caps.NumInstructionSlots >= 512) {
2361 _shader_model = SM_2X;
2365 _shader_model = SM_30;
2368 _shader_model = SM_40;
2372 _shader_model = SM_50;
2376 _auto_detect_shader_model = _shader_model;
2381 _cg_context = cgCreateContext();
2383 if (cgD3D9IsProfileSupported(CG_PROFILE_PS_2_0) &&
2384 cgD3D9IsProfileSupported(CG_PROFILE_VS_2_0)) {
2385 _supports_basic_shaders =
true;
2386 _shader_caps._active_vprofile = (int)cgD3D9GetLatestVertexProfile();
2387 _shader_caps._active_fprofile = (int)cgD3D9GetLatestPixelProfile();
2388 _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VS_3_0;
2389 _shader_caps._ultimate_fprofile = (int)CG_PROFILE_PS_3_0;
2398 if (dxgsg9_cat.is_debug()) {
2399 CGprofile vertex_profile;
2400 CGprofile pixel_profile;
2402 vertex_profile = cgD3D9GetLatestVertexProfile();
2403 pixel_profile = cgD3D9GetLatestPixelProfile();
2405 const char *vertex_profile_str =
2406 cgGetProfileString(vertex_profile);
2407 const char *pixel_profile_str =
2408 cgGetProfileString(pixel_profile);
2410 if (vertex_profile_str == NULL) {
2411 vertex_profile_str =
"(null)";
2413 if (pixel_profile_str == NULL) {
2414 pixel_profile_str =
"(null)";
2418 <<
"\nCg latest vertex profile = " << vertex_profile_str <<
" id = " << vertex_profile
2419 <<
"\nCg latest pixel profile = " << pixel_profile_str <<
" id = " << pixel_profile
2420 <<
"\nshader model = " << _shader_model
2425 _supports_stream_offset = (d3d_caps.DevCaps2 & D3DDEVCAPS2_STREAMOFFSET) != 0;
2426 _screen->_supports_dynamic_textures = ((d3d_caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) != 0);
2427 _screen->_supports_automatic_mipmap_generation = ((d3d_caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0);
2429 if (support_stencil) {
2430 int min_stencil = D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR;
2431 if ((d3d_caps.StencilCaps & min_stencil) == min_stencil) {
2432 if (dxgsg9_cat.is_debug()) {
2434 <<
"Checking for stencil; mode = "
2435 << D3DFormatStr(_screen->_presentation_params.AutoDepthStencilFormat)
2438 switch (_screen->_presentation_params.AutoDepthStencilFormat) {
2442 case D3DFMT_D24X4S4:
2443 _supports_stencil =
true;
2444 if (dxgsg9_cat.is_debug()) {
2446 <<
"Stencils supported.\n";
2451 if (dxgsg9_cat.is_debug()) {
2453 <<
"Stencils NOT supported.\n";
2459 _supports_stencil_wrap = (d3d_caps.StencilCaps & D3DSTENCILCAPS_INCR) && (d3d_caps.StencilCaps & D3DSTENCILCAPS_DECR);
2460 _supports_two_sided_stencil = ((d3d_caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) != 0);
2462 _max_color_targets = d3d_caps.NumSimultaneousRTs;
2464 _supports_depth_bias = ((d3d_caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) == (D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS));
2466 _supports_gamma_calibration = ((d3d_caps.Caps2 & D3DCAPS2_CANCALIBRATEGAMMA) != 0);
2469 hr = _d3d_device->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL);
2470 _supports_occlusion_query = !FAILED(hr);
2472 if (dxgsg9_cat.is_error()) {
2474 <<
"\nHwTransformAndLight = " << ((d3d_caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
2475 <<
"\nMaxTextureWidth = " << d3d_caps.MaxTextureWidth
2476 <<
"\nMaxTextureHeight = " << d3d_caps.MaxTextureHeight
2477 <<
"\nMaxVolumeExtent = " << d3d_caps.MaxVolumeExtent
2478 <<
"\nMaxTextureAspectRatio = " << d3d_caps.MaxTextureAspectRatio
2479 <<
"\nTexCoordCount = " << (d3d_caps.FVFCaps & D3DFVFCAPS_TEXCOORDCOUNTMASK)
2480 <<
"\nMaxTextureBlendStages = " << d3d_caps.MaxTextureBlendStages
2481 <<
"\nMaxSimultaneousTextures = " << d3d_caps.MaxSimultaneousTextures
2482 <<
"\nMaxActiveLights = " << d3d_caps.MaxActiveLights
2483 <<
"\nMaxUserClipPlanes = " << d3d_caps.MaxUserClipPlanes
2484 <<
"\nMaxVertexBlendMatrices = " << d3d_caps.MaxVertexBlendMatrices
2485 <<
"\nMaxVertexBlendMatrixIndex = " << d3d_caps.MaxVertexBlendMatrixIndex
2486 <<
"\nMaxPointSize = " << d3d_caps.MaxPointSize
2487 <<
"\nMaxPrimitiveCount = " << d3d_caps.MaxPrimitiveCount
2488 <<
"\nMaxVertexIndex = " << d3d_caps.MaxVertexIndex
2489 <<
"\nMaxStreams = " << d3d_caps.MaxStreams
2490 <<
"\nMaxStreamStride = " << d3d_caps.MaxStreamStride
2491 <<
"\nD3DTEXOPCAPS_MULTIPLYADD = " << ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_MULTIPLYADD) != 0)
2492 <<
"\nD3DTEXOPCAPS_LERP = " << ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_LERP) != 0)
2493 <<
"\nD3DPMISCCAPS_TSSARGTEMP = " << ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) != 0)
2494 <<
"\nD3DPRASTERCAPS_DEPTHBIAS = " << ((d3d_caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS) != 0)
2495 <<
"\nD3DPRASTERCAPS_SLOPESCALEDEPTHBIAS = " << ((d3d_caps.RasterCaps & D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS) != 0)
2496 <<
"\nVertexShaderVersion = " << _vertex_shader_version_major <<
"." << _vertex_shader_version_minor
2497 <<
"\nPixelShaderVersion = " << _pixel_shader_version_major <<
"." << _pixel_shader_version_minor
2498 <<
"\nMaxVertexShaderConst = " << _vertex_shader_maximum_constants
2499 <<
"\nsupports_stream_offset = " << _supports_stream_offset
2500 <<
"\nsupports_dynamic_textures = " << _screen->_supports_dynamic_textures
2501 <<
"\nsupports_automatic_mipmap_generation = " << _screen->_supports_automatic_mipmap_generation
2502 <<
"\nsupports_stencil_wrap = " << _supports_stencil_wrap
2503 <<
"\nsupports_two_sided_stencil = " << _supports_two_sided_stencil
2504 <<
"\nsupports_occlusion_query = " << _supports_occlusion_query
2505 <<
"\nsupports_gamma_calibration = " << _supports_gamma_calibration
2506 <<
"\nMaxAnisotropy = " << d3d_caps.MaxAnisotropy
2507 <<
"\nNumSimultaneousRTs = " << d3d_caps.NumSimultaneousRTs
2508 <<
"\nD3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING = " << ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) != 0)
2509 <<
"\nDirectX SDK version " DIRECTX_SDK_VERSION
2514 _screen->_supports_automatic_mipmap_generation =
false;
2516 this -> reset_render_states ( );
2518 _max_vertices_per_array = d3d_caps.MaxVertexIndex;
2519 _max_vertices_per_primitive = d3d_caps.MaxPrimitiveCount;
2521 _max_texture_stages = d3d_caps.MaxSimultaneousTextures;
2523 _max_texture_dimension = min(d3d_caps.MaxTextureWidth, d3d_caps.MaxTextureHeight);
2525 _supports_tex_non_pow2 = !(d3d_caps.TextureCaps & D3DPTEXTURECAPS_POW2);
2527 _supports_texture_combine = ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_LERP) != 0);
2528 _supports_texture_saved_result = ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) != 0);
2529 _supports_texture_constant_color = ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT) != 0);
2530 _supports_texture_dot3 =
true;
2532 if (_supports_texture_constant_color) {
2533 _constant_color_operand = D3DTA_CONSTANT;
2535 _constant_color_operand = D3DTA_TFACTOR;
2538 _screen->_managed_textures = _gsg_managed_textures;
2539 _screen->_managed_vertex_buffers = _gsg_managed_vertex_buffers;
2540 _screen->_managed_index_buffers = _gsg_managed_index_buffers;
2542 UINT available_texture_memory;
2544 available_texture_memory = _d3d_device->GetAvailableTextureMem ( );
2545 if (dxgsg9_cat.is_debug()) {
2546 dxgsg9_cat.debug() <<
"*** GetAvailableTextureMem = " << available_texture_memory <<
"\n";
2548 _available_texture_memory = available_texture_memory;
2551 D3DDEVICE_CREATION_PARAMETERS creation_parameters;
2553 _supports_render_texture =
false;
2554 _screen->_render_to_texture_d3d_format = D3DFMT_UNKNOWN;
2555 _screen->_framebuffer_d3d_format = D3DFMT_UNKNOWN;
2557 #define TOTAL_RENDER_TO_TEXTURE_FORMATS 3
2559 D3DFORMAT render_to_texture_formats [TOTAL_RENDER_TO_TEXTURE_FORMATS] =
2566 render_to_texture_formats [TOTAL_RENDER_TO_TEXTURE_FORMATS - 1] = _screen->_display_mode.Format;
2568 hr = _d3d_device->GetCreationParameters (&creation_parameters);
2569 if (SUCCEEDED (hr)) {
2570 _screen->_framebuffer_d3d_format = _screen->_display_mode.Format;
2573 for (index = 0; index < TOTAL_RENDER_TO_TEXTURE_FORMATS; index++) {
2574 hr = _screen->_d3d9->CheckDeviceFormat (
2575 creation_parameters.AdapterOrdinal,
2576 creation_parameters.DeviceType,
2577 _screen->_display_mode.Format,
2578 D3DUSAGE_RENDERTARGET,
2580 render_to_texture_formats [index]);
2581 if (SUCCEEDED (hr)) {
2582 _screen->_render_to_texture_d3d_format = render_to_texture_formats [index];
2583 _supports_render_texture =
true;
2585 if (_supports_render_texture) {
2590 if (dxgsg9_cat.is_debug()) {
2591 dxgsg9_cat.debug() <<
"Render to Texture Support = " << _supports_render_texture <<
"\n";
2597 _supports_3d_texture = ((d3d_caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) != 0);
2598 if (_supports_3d_texture) {
2599 _max_3d_texture_dimension = d3d_caps.MaxVolumeExtent;
2601 _supports_cube_map = ((d3d_caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) != 0);
2602 if (_supports_cube_map) {
2603 _max_cube_map_dimension = _max_texture_dimension;
2606 _max_lights = (int)d3d_caps.MaxActiveLights;
2607 _max_clip_planes = (
int)d3d_caps.MaxUserClipPlanes;
2608 _max_vertex_transforms = d3d_caps.MaxVertexBlendMatrices;
2609 _max_vertex_transform_indices = d3d_caps.MaxVertexBlendMatrixIndex;
2613 _clip_plane_bits = 0;
2631 _has_scene_graph_color =
false;
2633 _last_testcooplevel_result = D3D_OK;
2635 if (dxgsg9_cat.is_debug()) {
2636 dxgsg9_cat.debug() <<
"Supported texture formats:\n";
2639 for(
int i = 0; i < MAX_POSSIBLE_TEXFMTS; i++) {
2641 D3DFORMAT_FLAG fmtflag = D3DFORMAT_FLAG(1 << i);
2642 hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format,
2643 0x0, D3DRTYPE_TEXTURE, g_D3DFORMATmap[fmtflag]);
2644 if (SUCCEEDED(hr)) {
2645 if (dxgsg9_cat.is_debug()) {
2646 dxgsg9_cat.debug() <<
" " << D3DFormatStr(g_D3DFORMATmap[fmtflag]) <<
"\n";
2648 _screen->_supported_tex_formats_mask |= fmtflag;
2653 #define CHECK_FOR_DXTVERSION(num) \
2654 if (_screen->_supported_tex_formats_mask & DXT##num##_FLAG) {\
2655 if (dxgsg9_cat.is_debug()) {\
2656 dxgsg9_cat.debug() << "Compressed texture format DXT" << #num << " supported\n";\
2658 _supports_compressed_texture = true;\
2659 _compressed_texture_formats.set_bit(Texture::CM_dxt##num);\
2662 if (_screen->_intel_compressed_texture_bug) {
2664 <<
"Buggy Intel driver detected; disabling compressed textures.\n";
2665 _screen->_supported_tex_formats_mask &=
2666 ~(DXT1_FLAG | DXT2_FLAG | DXT3_FLAG | DXT4_FLAG | DXT5_FLAG);
2670 CHECK_FOR_DXTVERSION(1);
2671 CHECK_FOR_DXTVERSION(2);
2672 CHECK_FOR_DXTVERSION(3);
2673 CHECK_FOR_DXTVERSION(4);
2674 CHECK_FOR_DXTVERSION(5);
2677 #undef CHECK_FOR_DXTVERSION
2679 _screen->_supports_rgba16f_texture_format =
false;
2680 hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format, 0x0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F);
2682 _screen->_supports_rgba16f_texture_format =
true;
2684 _screen->_supports_rgba32_texture_format =
false;
2685 hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format, 0x0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F);
2687 _screen->_supports_rgba32_texture_format =
true;
2691 if (_screen->_d3dcaps.MaxTextureWidth == 0)
2692 _screen->_d3dcaps.MaxTextureWidth = 256;
2694 if (_screen->_d3dcaps.MaxTextureHeight == 0)
2695 _screen->_d3dcaps.MaxTextureHeight = 256;
2697 if (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) {
2702 _do_fog_type = PerPixelFog;
2706 nassertv((_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGVERTEX) != 0);
2711 if (dx_no_vertex_fog) {
2712 _do_fog_type = None;
2714 _do_fog_type = PerVertexFog;
2717 if (dx_use_rangebased_fog && (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGRANGE)) {
2723 _screen->_can_direct_disable_color_writes = ((_screen->_d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0);
2729 bool dither_enabled = ((!dx_no_dithering) && IS_16BPP_DISPLAY_FORMAT(_screen->_presentation_params.BackBufferFormat)
2730 && (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_DITHER));
2737 if (_supports_two_sided_stencil) {
2745 _current_fill_mode = RenderModeAttrib::M_filled;
2753 _cull_face_mode = CullFaceAttrib::M_cull_none;
2764 _current_shader = (
Shader *)NULL;
2766 _vertex_array_shader = (
Shader *)NULL;
2768 _texture_binding_shader = (
Shader *)NULL;
2769 _texture_binding_shader_context = (CLP(
ShaderContext) *)NULL;
2771 PRINT_REFCNT(dxgsg9, _d3d_device);
2783 void DXGraphicsStateGuardian9::
2784 apply_fog(
Fog *fog) {
2785 if (_do_fog_type == None)
2788 Fog::Mode panda_fogmode = fog->get_mode();
2789 D3DFOGMODE d3dfogmode = get_fog_mode_type(panda_fogmode);
2795 MY_D3DRGBA(fog_colr[0], fog_colr[1], fog_colr[2], 0.0f));
2800 switch (panda_fogmode) {
2803 PN_stdfloat onset, opaque;
2807 *((LPDWORD) (&onset)));
2809 *((LPDWORD) (&opaque)));
2812 case Fog::M_exponential:
2813 case Fog::M_exponential_squared:
2818 *((LPDWORD) (&fog_density)));
2833 void DXGraphicsStateGuardian9::
2834 do_issue_transform() {
2835 const TransformState *transform = _internal_transform;
2836 DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
2838 if (_current_shader_context) {
2843 LMatrix4f mat = LCAST(
float, transform->get_mat());
2844 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)mat.
get_data();
2845 _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
2849 LMatrix4f mat = LCAST(
float, transform->get_mat());
2850 const D3DMATRIX *d3d_mat = (
const D3DMATRIX *)mat.
get_data();
2851 _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
2866 _transform_stale =
false;
2868 if (_auto_rescale_normal) {
2869 do_auto_rescale_normal();
2878 void DXGraphicsStateGuardian9::
2879 do_issue_alpha_test() {
2880 if (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) {
2884 AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->
get_mode();
2885 if (mode == AlphaTestAttrib::M_none) {
2901 void DXGraphicsStateGuardian9::
2906 if (_target_shader) {
2907 shader = (
Shader *)(_target_shader->get_shader());
2913 if (context == 0 || (context && context -> valid (
this) ==
false)) {
2914 if (_current_shader_context != 0) {
2915 _current_shader_context->
unbind(
this);
2916 _current_shader = 0;
2917 _current_shader_context = 0;
2918 disable_standard_texture_bindings();
2923 if (context != _current_shader_context) {
2926 if (_current_shader_context != 0) {
2927 _current_shader_context->
unbind(
this);
2928 _current_shader_context = 0;
2929 _current_shader = 0;
2930 disable_standard_texture_bindings();
2933 context->bind(
this);
2934 _current_shader = shader;
2935 _current_shader_context = context;
2948 void DXGraphicsStateGuardian9::
2949 do_issue_render_mode() {
2951 RenderModeAttrib::Mode mode = target_render_mode->
get_mode();
2954 case RenderModeAttrib::M_unchanged:
2955 case RenderModeAttrib::M_filled:
2956 case RenderModeAttrib::M_filled_flat:
2960 case RenderModeAttrib::M_wireframe:
2964 case RenderModeAttrib::M_point:
2970 <<
"Unknown render mode " << (int)mode << endl;
2974 PN_stdfloat point_size = target_render_mode->
get_thickness();
2980 LVector3 height(0.0f, point_size, 1.0f);
2981 height = height * _projection_mat->get_mat();
2982 PN_stdfloat s = height[1] / point_size;
2984 PN_stdfloat zero = 0.0f;
2985 PN_stdfloat one_over_s2 = 1.0f / (s * s);
2994 _current_fill_mode = mode;
3002 void DXGraphicsStateGuardian9::
3003 do_issue_rescale_normal() {
3005 RescaleNormalAttrib::Mode mode = target_rescale_normal->
get_mode();
3007 _auto_rescale_normal =
false;
3010 case RescaleNormalAttrib::M_none:
3014 case RescaleNormalAttrib::M_rescale:
3015 case RescaleNormalAttrib::M_normalize:
3019 case RescaleNormalAttrib::M_auto:
3020 _auto_rescale_normal =
true;
3021 do_auto_rescale_normal();
3026 <<
"Unknown rescale_normal mode " << (int)mode << endl;
3035 void DXGraphicsStateGuardian9::
3036 do_issue_depth_test() {
3038 DepthTestAttrib::PandaCompareFunc mode = target_depth_test->
get_mode();
3039 if (mode == DepthTestAttrib::M_none) {
3052 void DXGraphicsStateGuardian9::
3053 do_issue_depth_write() {
3055 DepthWriteAttrib::Mode mode = target_depth_write->
get_mode();
3056 if (mode == DepthWriteAttrib::M_on) {
3068 void DXGraphicsStateGuardian9::
3069 do_issue_cull_face() {
3073 switch (_cull_face_mode) {
3074 case CullFaceAttrib::M_cull_none:
3080 case CullFaceAttrib::M_cull_clockwise:
3086 case CullFaceAttrib::M_cull_counter_clockwise:
3094 <<
"invalid cull face mode " << (int)_cull_face_mode << endl;
3104 void DXGraphicsStateGuardian9::
3106 const FogAttrib *target_fog = DCAST(
FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot()));
3107 if (!target_fog->
is_off()) {
3110 nassertv(fog != (
Fog *)NULL);
3122 void DXGraphicsStateGuardian9::
3123 do_issue_depth_offset() {
3125 int offset = target_depth_offset->
get_offset();
3127 if (_supports_depth_bias && !dx_broken_depth_bias) {
3135 static const PN_stdfloat bias_scale = dx_depth_bias_scale;
3136 D3DVIEWPORT9 vp = _current_viewport;
3137 vp.MinZ -= bias_scale * offset;
3138 vp.MaxZ -= bias_scale * offset;
3139 _d3d_device->SetViewport(&vp);
3148 void DXGraphicsStateGuardian9::
3149 do_issue_shade_model() {
3151 switch (target_shade_model->
get_mode()) {
3152 case ShadeModelAttrib::M_smooth:
3156 case ShadeModelAttrib::M_flat:
3181 const TransformState *transform) {
3183 if (gsg_cat.is_spam()) {
3184 gsg_cat.spam() <<
"Setting GSG state to " << (
void *)target <<
":\n";
3185 target->write(gsg_cat.spam(
false), 2);
3188 _state_pcollector.add_level(1);
3189 PStatTimer timer1(_draw_set_state_pcollector);
3191 if (transform != _internal_transform) {
3193 _state_pcollector.add_level(1);
3194 _internal_transform = transform;
3195 do_issue_transform();
3198 if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) {
3201 _target_rs = target;
3203 _target_shader = DCAST(
ShaderAttrib, _target_rs->get_attrib_def(ShaderAttrib::get_class_slot()));
3205 int alpha_test_slot = AlphaTestAttrib::get_class_slot();
3206 if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) ||
3207 !_state_mask.get_bit(alpha_test_slot)) {
3209 do_issue_alpha_test();
3210 _state_mask.set_bit(alpha_test_slot);
3213 int clip_plane_slot = ClipPlaneAttrib::get_class_slot();
3214 if (_target_rs->get_attrib(clip_plane_slot) != _state_rs->get_attrib(clip_plane_slot) ||
3215 !_state_mask.get_bit(clip_plane_slot)) {
3217 do_issue_clip_plane();
3218 _state_mask.set_bit(clip_plane_slot);
3221 int color_slot = ColorAttrib::get_class_slot();
3222 int color_scale_slot = ColorScaleAttrib::get_class_slot();
3223 if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) ||
3224 _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) ||
3225 !_state_mask.get_bit(color_slot) ||
3226 !_state_mask.get_bit(color_scale_slot)) {
3229 do_issue_color_scale();
3230 _state_mask.set_bit(color_slot);
3231 _state_mask.set_bit(color_scale_slot);
3232 if (_current_shader_context) {
3238 int cull_face_slot = CullFaceAttrib::get_class_slot();
3239 if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) ||
3240 !_state_mask.get_bit(cull_face_slot)) {
3242 do_issue_cull_face();
3243 _state_mask.set_bit(cull_face_slot);
3246 int depth_offset_slot = DepthOffsetAttrib::get_class_slot();
3247 if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) ||
3248 !_state_mask.get_bit(depth_offset_slot)) {
3250 do_issue_depth_offset();
3251 _state_mask.set_bit(depth_offset_slot);
3254 int depth_test_slot = DepthTestAttrib::get_class_slot();
3255 if (_target_rs->get_attrib(depth_test_slot) != _state_rs->get_attrib(depth_test_slot) ||
3256 !_state_mask.get_bit(depth_test_slot)) {
3258 do_issue_depth_test();
3259 _state_mask.set_bit(depth_test_slot);
3262 int depth_write_slot = DepthWriteAttrib::get_class_slot();
3263 if (_target_rs->get_attrib(depth_write_slot) != _state_rs->get_attrib(depth_write_slot) ||
3264 !_state_mask.get_bit(depth_write_slot)) {
3266 do_issue_depth_write();
3267 _state_mask.set_bit(depth_write_slot);
3270 int render_mode_slot = RenderModeAttrib::get_class_slot();
3271 if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) ||
3272 !_state_mask.get_bit(render_mode_slot)) {
3274 do_issue_render_mode();
3275 _state_mask.set_bit(render_mode_slot);
3278 int rescale_normal_slot = RescaleNormalAttrib::get_class_slot();
3279 if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) ||
3280 !_state_mask.get_bit(rescale_normal_slot)) {
3282 do_issue_rescale_normal();
3283 _state_mask.set_bit(rescale_normal_slot);
3286 int shade_model_slot = ShadeModelAttrib::get_class_slot();
3287 if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) ||
3288 !_state_mask.get_bit(shade_model_slot)) {
3290 do_issue_shade_model();
3291 _state_mask.set_bit(shade_model_slot);
3294 int transparency_slot = TransparencyAttrib::get_class_slot();
3295 int color_write_slot = ColorWriteAttrib::get_class_slot();
3296 int color_blend_slot = ColorBlendAttrib::get_class_slot();
3297 if (_target_rs->get_attrib(transparency_slot) != _state_rs->get_attrib(transparency_slot) ||
3298 _target_rs->get_attrib(color_write_slot) != _state_rs->get_attrib(color_write_slot) ||
3299 _target_rs->get_attrib(color_blend_slot) != _state_rs->get_attrib(color_blend_slot) ||
3300 !_state_mask.get_bit(transparency_slot) ||
3301 !_state_mask.get_bit(color_write_slot) ||
3302 !_state_mask.get_bit(color_blend_slot) ||
3303 (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) !=
3304 _state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))) {
3306 do_issue_blending();
3307 _state_mask.set_bit(transparency_slot);
3308 _state_mask.set_bit(color_write_slot);
3309 _state_mask.set_bit(color_blend_slot);
3312 if (_target_shader != _state_shader) {
3315 _state_shader = _target_shader;
3316 _state_mask.clear_bit(TextureAttrib::get_class_slot());
3319 int texture_slot = TextureAttrib::get_class_slot();
3320 int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
3321 int tex_gen_slot = TexGenAttrib::get_class_slot();
3322 if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) ||
3323 _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
3324 _target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) ||
3325 !_state_mask.get_bit(texture_slot) ||
3326 !_state_mask.get_bit(tex_matrix_slot) ||
3327 !_state_mask.get_bit(tex_gen_slot)) {
3329 determine_target_texture();
3332 _state_texture = _target_texture;
3333 _state_mask.set_bit(texture_slot);
3334 _state_mask.set_bit(tex_matrix_slot);
3335 _state_mask.set_bit(tex_gen_slot);
3338 int material_slot = MaterialAttrib::get_class_slot();
3339 if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) ||
3340 !_state_mask.get_bit(material_slot)) {
3342 do_issue_material();
3343 _state_mask.set_bit(material_slot);
3344 if (_current_shader_context) {
3349 int light_slot = LightAttrib::get_class_slot();
3350 if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) ||
3351 !_state_mask.get_bit(light_slot)) {
3354 _state_mask.set_bit(light_slot);
3357 int stencil_slot = StencilAttrib::get_class_slot();
3358 if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) ||
3359 !_state_mask.get_bit(stencil_slot)) {
3362 _state_mask.set_bit(stencil_slot);
3365 int fog_slot = FogAttrib::get_class_slot();
3366 if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
3367 !_state_mask.get_bit(fog_slot)) {
3370 _state_mask.set_bit(fog_slot);
3371 if (_current_shader_context) {
3376 int scissor_slot = ScissorAttrib::get_class_slot();
3377 if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) ||
3378 !_state_mask.get_bit(scissor_slot)) {
3381 _state_mask.set_bit(scissor_slot);
3384 _state_rs = _target_rs;
3400 CPT(TransformState) transform = light.
get_transform(_scene_setup->get_camera_path());
3401 const LMatrix4 &light_mat = transform->get_mat();
3405 D3DCOLORVALUE black;
3406 black.r = black.g = black.b = black.a = 0.0f;
3408 alight.Type = D3DLIGHT_POINT;
3409 alight.Diffuse = get_light_color(light_obj);
3410 alight.Ambient = black ;
3412 alight.Specular = *(D3DCOLORVALUE *)(color.
get_data());
3416 alight.Position = *(D3DVECTOR *)pos.
get_data();
3418 alight.Range = __D3DLIGHT_RANGE_MAX;
3419 alight.Falloff = 1.0f;
3422 alight.Attenuation0 = att[0];
3423 alight.Attenuation1 = att[1];
3424 alight.Attenuation2 = att[2];
3426 HRESULT hr = _d3d_device->SetLight(light_id, &alight);
3428 wdxdisplay9_cat.warning()
3429 <<
"Could not set light properties for " << light
3430 <<
" to id " << light_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3444 static PStatCollector _draw_set_state_light_bind_directional_pcollector(
"Draw:Set State:Light:Bind:Directional");
3447 pair<DirectionalLights::iterator, bool> lookup = _dlights.insert(DirectionalLights::value_type(light, D3DLIGHT9()));
3448 D3DLIGHT9 &fdata = (*lookup.first).second;
3449 if (lookup.second) {
3453 CPT(TransformState) transform = light.
get_transform(_scene_setup->get_camera_path());
3454 const LMatrix4 &light_mat = transform->get_mat();
3458 D3DCOLORVALUE black;
3459 black.r = black.g = black.b = black.a = 0.0f;
3461 ZeroMemory(&fdata,
sizeof(D3DLIGHT9));
3463 fdata.Type = D3DLIGHT_DIRECTIONAL;
3464 fdata.Ambient = black ;
3466 fdata.Specular = *(D3DCOLORVALUE *)(color.
get_data());
3468 fdata.Direction = *(D3DVECTOR *)dir.
get_data();
3470 fdata.Range = __D3DLIGHT_RANGE_MAX;
3471 fdata.Falloff = 1.0f;
3473 fdata.Attenuation0 = 1.0f;
3474 fdata.Attenuation1 = 0.0f;
3475 fdata.Attenuation2 = 0.0f;
3481 fdata.Diffuse = get_light_color(light_obj);
3483 HRESULT hr = _d3d_device->SetLight(light_id, &fdata);
3485 wdxdisplay9_cat.warning()
3486 <<
"Could not set light properties for " << light
3487 <<
" to id " << light_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3502 nassertv(lens != (
Lens *)NULL);
3507 CPT(TransformState) transform = light.
get_transform(_scene_setup->get_camera_path());
3508 const LMatrix4 &light_mat = transform->get_mat();
3513 D3DCOLORVALUE black;
3514 black.r = black.g = black.b = black.a = 0.0f;
3517 ZeroMemory(&alight,
sizeof(D3DLIGHT9));
3519 alight.Type = D3DLIGHT_SPOT;
3520 alight.Ambient = black ;
3521 alight.Diffuse = get_light_color(light_obj);
3523 alight.Specular = *(D3DCOLORVALUE *)(color.
get_data());
3525 alight.Position = *(D3DVECTOR *)pos.
get_data();
3527 alight.Direction = *(D3DVECTOR *)dir.get_data();
3529 alight.Range = __D3DLIGHT_RANGE_MAX;
3534 PN_stdfloat fov = lens->
get_hfov();
3535 alight.Falloff = light_obj->
get_exponent() * (fov * fov * fov) / 1620000.0f;
3537 alight.Theta = 0.0f;
3538 alight.Phi = deg_2_rad(fov);
3541 alight.Attenuation0 = att[0];
3542 alight.Attenuation1 = att[1];
3543 alight.Attenuation2 = att[2];
3545 HRESULT hr = _d3d_device->SetLight(light_id, &alight);
3547 wdxdisplay9_cat.warning()
3548 <<
"Could not set light properties for " << light
3549 <<
" to id " << light_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
3561 switch (numeric_type) {
3562 case Geom::NT_uint16:
3563 return D3DFMT_INDEX16;
3565 case Geom::NT_uint32:
3566 return D3DFMT_INDEX32;
3570 <<
"Invalid index NumericType value (" << (int)numeric_type <<
")\n";
3571 return D3DFMT_INDEX16;
3579 void DXGraphicsStateGuardian9::
3580 do_issue_material() {
3584 if (target_material->
is_off()) {
3590 D3DMATERIAL9 cur_material;
3592 cur_material.Diffuse = *(D3DCOLORVALUE *)(color.
get_data());
3594 cur_material.Ambient = *(D3DCOLORVALUE *)(color.
get_data());
3596 cur_material.Specular = *(D3DCOLORVALUE *)(color.
get_data());
3598 cur_material.Emissive = *(D3DCOLORVALUE *)(color.
get_data());
3606 if (_has_material_force_color) {
3607 color = LCAST(
float, _material_force_color);
3608 cur_material.Diffuse = *(D3DCOLORVALUE *)color.
get_data();
3619 if (_has_material_force_color) {
3620 color = LCAST(
float, _material_force_color);
3621 cur_material.Ambient = *(D3DCOLORVALUE *)color.
get_data();
3640 _d3d_device->SetMaterial(&cur_material);
3648 void DXGraphicsStateGuardian9::
3649 do_issue_texture() {
3650 DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
3652 if (_texture_binding_shader_context==0) {
3653 if (_current_shader_context==0) {
3654 update_standard_texture_bindings();
3656 disable_standard_texture_bindings();
3660 if (_current_shader_context==0) {
3662 update_standard_texture_bindings();
3664 _current_shader_context->
3665 update_shader_texture_bindings(_texture_binding_shader_context,
this);
3668 _texture_binding_shader = _current_shader;
3669 _texture_binding_shader_context = _current_shader_context;
3677 void DXGraphicsStateGuardian9::
3678 disable_standard_texture_bindings() {
3680 for (
int i = 0; i < _num_active_texture_stages; i++) {
3683 hr = _d3d_device -> SetTexture (i, NULL);
3688 <<
", NULL) failed "
3689 << D3DERRORSTRING(hr);
3694 _num_active_texture_stages = 0;
3702 void DXGraphicsStateGuardian9::
3703 update_standard_texture_bindings() {
3704 DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
3706 int num_stages = _target_texture->get_num_on_ff_stages();
3707 int num_old_stages = _max_texture_stages;
3709 num_old_stages = _state_texture->get_num_on_ff_stages();
3712 nassertv(num_stages <= _max_texture_stages &&
3713 _num_active_texture_stages <= _max_texture_stages);
3715 _texture_involves_color_scale =
false;
3722 for (si = 0; si < num_stages; si++) {
3723 TextureStage *stage = _target_texture->get_on_ff_stage(si);
3724 int texcoord_index = _target_texture->get_ff_tc_index(si);
3726 Texture *texture = _target_texture->get_on_texture(stage);
3727 nassertv(texture != (
Texture *)NULL);
3728 const SamplerState &sampler = _target_texture->get_on_sampler(stage);
3735 set_texture_blend_mode(si, stage);
3737 int texcoord_dimensions = 2;
3739 CPT(TransformState) tex_mat = TransformState::make_identity();
3741 if (target_tex_matrix->has_stage(stage)) {
3742 tex_mat = target_tex_matrix->get_transform(stage);
3746 TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage);
3747 bool any_point_sprite =
false;
3750 case TexGenAttrib::M_off:
3751 case TexGenAttrib::M_unused2:
3755 case TexGenAttrib::M_eye_sphere_map:
3758 texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
3762 static CPT(TransformState) sphere_map =
3763 TransformState::make_mat(
LMatrix4(0.33, 0.0f, 0.0f, 0.0f,
3764 0.0f, 0.33, 0.0f, 0.0f,
3765 0.0f, 0.0f, 1.0f, 0.0f,
3766 0.5f, 0.5f, 0.0f, 1.0f));
3767 tex_mat = tex_mat->compose(sphere_map);
3768 texcoord_dimensions = 3;
3779 texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
3780 texcoord_dimensions = 3;
3781 CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
3782 tex_mat = tex_mat->compose(camera_transform->set_pos(
LVecBase3::zero()));
3788 texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
3789 tex_mat = tex_mat->compose(_inv_cs_transform);
3790 texcoord_dimensions = 3;
3800 texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
3801 texcoord_dimensions = 3;
3802 CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
3803 tex_mat = tex_mat->compose(camera_transform->set_pos(
LVecBase3::zero()));
3809 texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
3810 texcoord_dimensions = 3;
3811 tex_mat = tex_mat->compose(_inv_cs_transform);
3820 texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
3821 texcoord_dimensions = 3;
3822 CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
3823 tex_mat = tex_mat->compose(camera_transform);
3829 texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
3830 texcoord_dimensions = 3;
3831 tex_mat = tex_mat->compose(_inv_cs_transform);
3836 any_point_sprite = true;
3852 texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
3853 texcoord_dimensions = 3;
3855 const LTexCoord3 &v = _target_tex_gen->get_constant_value(stage);
3856 CPT(TransformState) squash =
3857 TransformState::make_pos_hpr_scale(v,
LVecBase3::zero(),
3859 tex_mat = tex_mat->compose(squash);
3866 if (!tex_mat->is_identity()) {
3867 if ( texcoord_dimensions <= 2) {
3869 LMatrix4 m = tex_mat->get_mat();
3871 mf.set(m(0, 0), m(0, 1), m(0, 3), 0.0f,
3872 m(1, 0), m(1, 1), m(1, 3), 0.0f,
3873 m(3, 0), m(3, 1), m(3, 3), 0.0f,
3874 0.0f, 0.0f, 0.0f, 1.0f);
3875 _d3d_device->SetTransform(get_tex_mat_sym(si), (D3DMATRIX *)mf.
get_data());
3879 LMatrix4f mf = LCAST(
float, tex_mat->get_mat());
3880 _d3d_device->SetTransform(get_tex_mat_sym(si), (D3DMATRIX *)mf.
get_data());
3881 DWORD transform_flags = texcoord_dimensions;
3885 transform_flags = D3DTTFF_COUNT4 | D3DTTFF_PROJECTED;
3897 _d3d_device->SetTransform(get_tex_mat_sym(si), &_d3d_ident_mat);
3902 for (si = num_stages; si < _num_active_texture_stages; si++) {
3904 _d3d_device->SetTexture(si, NULL);
3908 _num_active_texture_stages = num_stages;
3919 void DXGraphicsStateGuardian9::
3920 do_issue_blending() {
3926 unsigned int color_channels =
3927 target_color_write->
get_channels() & _color_write_mask;
3928 if (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write)) {
3929 color_channels &= ~(ColorWriteAttrib::C_alpha);
3931 if (color_channels == ColorWriteAttrib::C_off) {
3932 if (_screen->_can_direct_disable_color_writes) {
3942 if (_screen->_can_direct_disable_color_writes) {
3952 TransparencyAttrib::Mode transparency_mode = target_transparency->get_mode();
3958 switch (color_blend_mode) {
3959 case ColorBlendAttrib::M_add:
3963 case ColorBlendAttrib::M_subtract:
3967 case ColorBlendAttrib::M_inv_subtract:
3971 case ColorBlendAttrib::M_min:
3975 case ColorBlendAttrib::M_max:
3981 get_blend_func(color_blend->get_operand_a()));
3983 get_blend_func(color_blend->get_operand_b()));
3988 switch (transparency_mode) {
3989 case TransparencyAttrib::M_none:
3990 case TransparencyAttrib::M_binary:
3993 case TransparencyAttrib::M_alpha:
3994 case TransparencyAttrib::M_multisample:
3995 case TransparencyAttrib::M_multisample_mask:
3996 case TransparencyAttrib::M_dual:
4005 <<
"invalid transparency mode " << (int)transparency_mode << endl;
4021 void DXGraphicsStateGuardian9::
4022 reissue_transforms() {
4024 do_issue_transform();
4035 void DXGraphicsStateGuardian9::
4036 enable_lighting(
bool enable) {
4048 void DXGraphicsStateGuardian9::
4049 set_ambient_light(
const LColor &color) {
4051 c.set(c[0] * _light_color_scale[0],
4052 c[1] * _light_color_scale[1],
4053 c[2] * _light_color_scale[2],
4054 c[3] * _light_color_scale[3]);
4066 void DXGraphicsStateGuardian9::
4067 enable_light(
int light_id,
bool enable) {
4068 HRESULT hr = _d3d_device->LightEnable(light_id, enable);
4071 wdxdisplay9_cat.warning()
4072 <<
"Could not enable light " << light_id <<
": "
4073 << D3DERRORSTRING(hr) <<
"\n";
4085 void DXGraphicsStateGuardian9::
4086 enable_clip_plane(
int plane_id,
bool enable) {
4088 _clip_plane_bits |= ((DWORD)1 << plane_id);
4090 _clip_plane_bits &= ~((DWORD)1 << plane_id);
4103 void DXGraphicsStateGuardian9::
4104 bind_clip_plane(
const NodePath &plane,
int plane_id) {
4108 CPT(TransformState) transform = plane.get_transform(_scene_setup->get_camera_path());
4109 const LMatrix4 &plane_mat = transform->get_mat();
4110 LMatrix4 rel_mat = plane_mat * LMatrix4::convert_mat(CS_yup_left, CS_default);
4112 DCAST_INTO_V(plane_node, plane.node());
4113 LPlanef world_plane = LCAST(
float, plane_node->get_plane() * rel_mat);
4115 HRESULT hr = _d3d_device->SetClipPlane(plane_id, world_plane.get_data());
4117 wdxdisplay9_cat.warning()
4118 <<
"Could not set clip plane for " << plane
4119 <<
" to id " << plane_id <<
": " << D3DERRORSTRING(hr) <<
"\n";
4131 void DXGraphicsStateGuardian9::
4133 GraphicsStateGuardian::close_gsg();
4135 if (dxgsg9_cat.is_debug()) {
4137 <<
"Closing GSG, prepared_objects count = "
4138 << _prepared_objects->get_ref_count() <<
"\n";
4143 if (_prepared_objects->get_ref_count() == 1) {
4149 _prepared_objects->begin_frame(
this, current_thread);
4150 _prepared_objects->end_frame(current_thread);
4160 void DXGraphicsStateGuardian9::
4161 free_nondx_resources() {
4164 cgDestroyContext(_cg_context);
4176 void DXGraphicsStateGuardian9::
4179 _state_rs = RenderState::make_empty();
4180 _state_mask.clear();
4184 _dx_is_ready =
false;
4186 if (_d3d_device != NULL) {
4187 for(
int i = 0; i < D3D_MAXTEXTURESTAGES; i++) {
4189 _d3d_device->SetTexture(i, NULL);
4195 if (_d3d_device != NULL) {
4196 RELEASE(_d3d_device, dxgsg9,
"d3dDevice", RELEASE_DOWN_TO_ZERO);
4199 free_nondx_resources();
4212 void DXGraphicsStateGuardian9::
4214 dxgsg9_cat.fatal() <<
"DX set_draw_buffer unimplemented!!!";
4223 void DXGraphicsStateGuardian9::
4225 if (rb._buffer_type & RenderBuffer::T_front) {
4226 _cur_read_pixel_buffer = RenderBuffer::T_front;
4227 }
else if (rb._buffer_type & RenderBuffer::T_back) {
4228 _cur_read_pixel_buffer = RenderBuffer::T_back;
4229 }
else if (rb._buffer_type & RenderBuffer::T_aux_rgba_ALL) {
4230 _cur_read_pixel_buffer = RenderBuffer::T_back;
4232 dxgsg9_cat.error() <<
"Invalid or unimplemented Argument to set_read_buffer!\n";
4244 void DXGraphicsStateGuardian9::
4245 do_auto_rescale_normal() {
4246 if (_internal_transform->has_identity_scale()) {
4263 const D3DCOLORVALUE &DXGraphicsStateGuardian9::
4264 get_light_color(
Light *light)
const {
4267 cf.set(c[0] * _light_color_scale[0],
4268 c[1] * _light_color_scale[1],
4269 c[2] * _light_color_scale[2],
4270 c[3] * _light_color_scale[3]);
4271 return *(D3DCOLORVALUE *)cf.
get_data();
4280 D3DBLEND DXGraphicsStateGuardian9::
4281 get_blend_func(ColorBlendAttrib::Operand operand) {
4283 case ColorBlendAttrib::O_zero:
4284 return D3DBLEND_ZERO;
4286 case ColorBlendAttrib::O_one:
4287 return D3DBLEND_ONE;
4289 case ColorBlendAttrib::O_incoming_color:
4290 return D3DBLEND_SRCCOLOR;
4292 case ColorBlendAttrib::O_one_minus_incoming_color:
4293 return D3DBLEND_INVSRCCOLOR;
4295 case ColorBlendAttrib::O_fbuffer_color:
4296 return D3DBLEND_DESTCOLOR;
4298 case ColorBlendAttrib::O_one_minus_fbuffer_color:
4299 return D3DBLEND_INVDESTCOLOR;
4301 case ColorBlendAttrib::O_incoming_alpha:
4302 return D3DBLEND_SRCALPHA;
4304 case ColorBlendAttrib::O_one_minus_incoming_alpha:
4305 return D3DBLEND_INVSRCALPHA;
4307 case ColorBlendAttrib::O_fbuffer_alpha:
4308 return D3DBLEND_DESTALPHA;
4310 case ColorBlendAttrib::O_one_minus_fbuffer_alpha:
4311 return D3DBLEND_INVDESTALPHA;
4313 case ColorBlendAttrib::O_constant_color:
4315 return D3DBLEND_SRCCOLOR;
4317 case ColorBlendAttrib::O_one_minus_constant_color:
4319 return D3DBLEND_INVSRCCOLOR;
4321 case ColorBlendAttrib::O_constant_alpha:
4323 return D3DBLEND_SRCALPHA;
4325 case ColorBlendAttrib::O_one_minus_constant_alpha:
4327 return D3DBLEND_INVSRCALPHA;
4329 case ColorBlendAttrib::O_incoming_color_saturate:
4330 return D3DBLEND_SRCALPHASAT;
4334 <<
"Unknown color blend operand " << (int)operand << endl;
4335 return D3DBLEND_ZERO;
4343 void DXGraphicsStateGuardian9::
4344 report_texmgr_stats() {
4350 #ifdef TEXMGRSTATS_USES_GETAVAILVIDMEM
4351 DWORD dwTexTotal, dwTexFree, dwVidTotal, dwVidFree;
4353 if (_total_texmem_pcollector.is_active()) {
4356 ZeroMemory(&ddsCaps,
sizeof(ddsCaps));
4358 ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
4359 if (FAILED( hr = _d3d_device->GetAvailableVidMem(&ddsCaps, &dwVidTotal, &dwVidFree))) {
4360 dxgsg9_cat.fatal() <<
"report_texmgr GetAvailableVidMem for VIDMEM failed : result = " << D3DERRORSTRING(hr);
4361 throw_event(
"panda3d-render-error");
4365 ddsCaps.dwCaps = DDSCAPS_TEXTURE;
4366 if (FAILED( hr = _d3d_device->GetAvailableVidMem(&ddsCaps, &dwTexTotal, &dwTexFree))) {
4367 dxgsg9_cat.fatal() <<
"report_texmgr GetAvailableVidMem for TEXTURE failed : result = " << D3DERRORSTRING(hr);
4368 throw_event(
"panda3d-render-error");
4372 #endif // TEXMGRSTATS_USES_GETAVAILVIDMEM
4374 D3DDEVINFO_RESOURCEMANAGER all_resource_stats;
4375 ZeroMemory(&all_resource_stats,
sizeof(D3DDEVINFO_RESOURCEMANAGER));
4402 if (_texmgrmem_total_pcollector.is_active()) {
4404 _texmgrmem_total_pcollector.set_level(all_resource_stats.stats[D3DRTYPE_TEXTURE].TotalBytes);
4405 _texmgrmem_resident_pcollector.set_level(all_resource_stats.stats[D3DRTYPE_TEXTURE].WorkingSetBytes);
4407 #ifdef TEXMGRSTATS_USES_GETAVAILVIDMEM
4408 if (_total_texmem_pcollector.is_active()) {
4409 _total_texmem_pcollector.set_level(dwTexTotal);
4410 _used_texmem_pcollector.set_level(dwTexTotal - dwTexFree);
4412 #endif // TEXMGRSTATS_USES_GETAVAILVIDMEM
4421 void DXGraphicsStateGuardian9::
4423 nassertv(new_context != NULL);
4424 _screen = new_context;
4425 _d3d_device = _screen->_d3d_device;
4426 _swap_chain = _screen->_swap_chain;
4428 _screen->_dxgsg9 =
this;
4438 void DXGraphicsStateGuardian9::
4439 set_render_target() {
4440 if (_d3d_device == NULL) {
4444 LPDIRECT3DSURFACE9 back = NULL, stencil = NULL;
4452 _d3d_device->GetBackBuffer(swap_chain, 0, D3DBACKBUFFER_TYPE_MONO, &back);
4454 _swap_chain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &back);
4459 _d3d_device->GetDepthStencilSurface(&stencil);
4462 DWORD render_target_index;
4463 render_target_index = 0;
4464 _d3d_device->SetRenderTarget(render_target_index, back);
4479 void DXGraphicsStateGuardian9::
4480 set_texture_blend_mode(
int i,
const TextureStage *stage) {
4482 case TextureStage::M_modulate:
4483 case TextureStage::M_modulate_glow:
4484 case TextureStage::M_modulate_gloss:
4494 case TextureStage::M_decal:
4504 case TextureStage::M_replace:
4512 case TextureStage::M_add:
4522 case TextureStage::M_blend:
4523 case TextureStage::M_blend_color_scale:
4536 case TextureStage::M_combine:
4547 (i, D3DTSS_COLORARG0,
4554 (i, D3DTSS_COLORARG2,
4561 (i, D3DTSS_COLORARG1,
4578 (i, D3DTSS_ALPHAARG0,
4585 (i, D3DTSS_ALPHAARG2,
4592 (i, D3DTSS_ALPHAARG1,
4604 <<
"Unknown texture mode " << (int)stage->
get_mode() << endl;
4617 D3DCOLOR constant_color;
4620 color.set(color[0] * _current_color_scale[0],
4621 color[1] * _current_color_scale[1],
4622 color[2] * _current_color_scale[2],
4623 color[3] * _current_color_scale[3]);
4624 _texture_involves_color_scale =
true;
4629 if (_supports_texture_constant_color) {
4645 void DXGraphicsStateGuardian9::
4651 free_nondx_resources();
4652 PRINT_REFCNT(dxgsg9, _d3d_device);
4656 RELEASE(_d3d_device, dxgsg9,
"d3dDevice", RELEASE_DOWN_TO_ZERO);
4657 _screen->_d3d_device = NULL;
4673 HRESULT DXGraphicsStateGuardian9::
4674 reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
4678 nassertr(IS_VALID_PTR(presentation_params), E_FAIL);
4679 nassertr(IS_VALID_PTR(_screen->_d3d9), E_FAIL);
4680 nassertr(IS_VALID_PTR(_d3d_device), E_FAIL);
4684 _screen->_d3d9->GetAdapterDisplayMode(_screen->_card_id, &_screen->_display_mode);
4685 presentation_params->BackBufferFormat = _screen->_display_mode.Format;
4692 if (
true || !(_screen->_swap_chain)
4693 || (_presentation_reset.BackBufferWidth < presentation_params->BackBufferWidth)
4694 || (_presentation_reset.BackBufferHeight < presentation_params->BackBufferHeight)) {
4695 if (wdxdisplay9_cat.is_debug()) {
4696 wdxdisplay9_cat.debug()
4697 <<
"swap_chain = " << _screen->_swap_chain <<
" _presentation_reset = "
4698 << _presentation_reset.BackBufferWidth <<
"x" << _presentation_reset.BackBufferHeight
4699 <<
" presentation_params = "
4700 << presentation_params->BackBufferWidth <<
"x" << presentation_params->BackBufferHeight <<
"\n";
4705 if (_screen->_swap_chain) {
4706 _presentation_reset.BackBufferWidth = max(_presentation_reset.BackBufferWidth, presentation_params->BackBufferWidth);
4707 _presentation_reset.BackBufferHeight = max(_presentation_reset.BackBufferHeight, presentation_params->BackBufferHeight);
4710 _presentation_reset.BackBufferWidth = presentation_params->BackBufferWidth;
4711 _presentation_reset.BackBufferHeight = presentation_params->BackBufferHeight;
4726 _prepared_objects->begin_frame(
this, current_thread);
4731 list <wdxGraphicsBuffer9 **>::iterator graphics_buffer_iterator;
4733 for (graphics_buffer_iterator = _graphics_buffer_list.begin( ); graphics_buffer_iterator != _graphics_buffer_list.end( ); graphics_buffer_iterator++)
4735 graphics_buffer = **graphics_buffer_iterator;
4736 if (graphics_buffer -> _color_backing_store)
4738 graphics_buffer -> _color_backing_store -> Release ( );
4739 graphics_buffer -> _color_backing_store = 0;
4741 if (graphics_buffer -> _depth_backing_store)
4743 graphics_buffer -> _depth_backing_store -> Release ( );
4744 graphics_buffer -> _depth_backing_store = 0;
4750 hr = _d3d_device->Reset(&_presentation_reset);
4751 if (FAILED(hr) && hr != D3DERR_DEVICELOST) {
4760 if (presentation_params != &_screen->_presentation_params) {
4761 memcpy(&_screen->_presentation_params, presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
4768 if (_screen && _screen->_swap_chain) {
4769 _screen->_swap_chain->Release();
4770 wdxdisplay9_cat.debug()
4771 <<
"swap chain " << _screen->_swap_chain <<
" is released\n";
4772 _screen->_swap_chain = NULL;
4773 hr = _d3d_device->CreateAdditionalSwapChain(presentation_params, &_screen->_swap_chain);
4775 if (SUCCEEDED(hr)) {
4776 if (presentation_params != &_screen->_presentation_params) {
4777 memcpy(&_screen->_presentation_params, presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
4791 bool DXGraphicsStateGuardian9::
4792 check_cooperative_level() {
4793 bool bDoReactivateWindow =
false;
4794 if (_d3d_device == NULL) {
4798 HRESULT hr = _d3d_device->TestCooperativeLevel();
4800 if (SUCCEEDED(hr)) {
4801 nassertr(SUCCEEDED(_last_testcooplevel_result),
false);
4806 case D3DERR_DEVICENOTRESET:
4807 _dx_is_ready =
false;
4812 hr = reset_d3d_device(&_screen->_presentation_params);
4817 <<
"check_cooperative_level Reset() failed, hr = " << D3DERRORSTRING(hr);
4820 hr = _d3d_device->TestCooperativeLevel();
4824 <<
"TestCooperativeLevel following Reset() failed, hr = " << D3DERRORSTRING(hr);
4828 _dx_is_ready = TRUE;
4831 case D3DERR_DEVICELOST:
4835 if (SUCCEEDED(_last_testcooplevel_result)) {
4837 _dx_is_ready =
false;
4838 if (dxgsg9_cat.is_debug()) {
4839 dxgsg9_cat.debug() <<
"D3D Device was Lost, waiting...\n";
4845 _last_testcooplevel_result = hr;
4846 return SUCCEEDED(hr);
4854 void DXGraphicsStateGuardian9::
4856 if (_d3d_device == NULL) {
4866 hr = _swap_chain->Present((CONST RECT*)NULL, (CONST RECT*)NULL, (HWND)NULL, NULL, flags);
4868 hr = _d3d_device->Present((CONST RECT*)NULL, (CONST RECT*)NULL, (HWND)NULL, NULL);
4872 if (hr == D3DERR_DEVICELOST) {
4873 check_cooperative_level();
4876 <<
"show_frame() - Present() failed" << D3DERRORSTRING(hr);
4877 throw_event(
"panda3d-render-error");
4887 bool DXGraphicsStateGuardian9::
4895 hr = new_context->_d3d_device->CreateAdditionalSwapChain(&new_context->_presentation_params, &new_context->_swap_chain);
4897 wdxdisplay9_cat.debug() <<
"Swapchain creation failed :"<<D3DERRORSTRING(hr)<<
"\n";
4908 bool DXGraphicsStateGuardian9::
4911 if (new_context->_swap_chain) {
4912 hr = new_context->_swap_chain->Release();
4914 wdxdisplay9_cat.debug() <<
"Swapchain release failed:" << D3DERRORSTRING(hr) <<
"\n";
4926 void DXGraphicsStateGuardian9::
4928 memcpy(&_presentation_reset, &_screen->_presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
4936 D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian9::
4937 get_d3d_min_type(SamplerState::FilterType filter_type) {
4938 switch (filter_type) {
4939 case SamplerState::FT_nearest:
4940 return D3DTEXF_POINT;
4942 case SamplerState::FT_linear:
4943 return D3DTEXF_LINEAR;
4945 case SamplerState::FT_nearest_mipmap_nearest:
4946 return D3DTEXF_POINT;
4948 case SamplerState::FT_linear_mipmap_nearest:
4949 return D3DTEXF_LINEAR;
4951 case SamplerState::FT_nearest_mipmap_linear:
4952 return D3DTEXF_POINT;
4954 case SamplerState::FT_linear_mipmap_linear:
4955 return D3DTEXF_LINEAR;
4957 case SamplerState::FT_shadow:
4958 case SamplerState::FT_default:
4959 return D3DTEXF_LINEAR;
4963 <<
"Invalid FilterType value (" << (int)filter_type <<
")\n";
4964 return D3DTEXF_POINT;
4972 D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian9::
4973 get_d3d_mip_type(SamplerState::FilterType filter_type) {
4974 switch (filter_type) {
4975 case SamplerState::FT_nearest:
4976 return D3DTEXF_NONE;
4978 case SamplerState::FT_linear:
4979 return D3DTEXF_NONE;
4981 case SamplerState::FT_nearest_mipmap_nearest:
4982 return D3DTEXF_POINT;
4984 case SamplerState::FT_linear_mipmap_nearest:
4985 return D3DTEXF_POINT;
4987 case SamplerState::FT_nearest_mipmap_linear:
4988 return D3DTEXF_LINEAR;
4990 case SamplerState::FT_linear_mipmap_linear:
4991 return D3DTEXF_LINEAR;
4993 case SamplerState::FT_shadow:
4994 case SamplerState::FT_default:
4995 return D3DTEXF_NONE;
4999 <<
"Invalid FilterType value (" << (int)filter_type <<
")\n";
5000 return D3DTEXF_NONE;
5009 D3DTEXTUREOP DXGraphicsStateGuardian9::
5010 get_texture_operation(TextureStage::CombineMode mode,
int scale) {
5012 case TextureStage::CM_undefined:
5013 case TextureStage::CM_replace:
5014 return D3DTOP_SELECTARG1;
5016 case TextureStage::CM_modulate:
5018 return D3DTOP_MODULATE;
5019 }
else if (scale < 4) {
5020 return D3DTOP_MODULATE2X;
5022 return D3DTOP_MODULATE4X;
5025 case TextureStage::CM_add:
5028 case TextureStage::CM_add_signed:
5030 return D3DTOP_ADDSIGNED;
5032 return D3DTOP_ADDSIGNED2X;
5035 case TextureStage::CM_interpolate:
5038 case TextureStage::CM_subtract:
5039 return D3DTOP_SUBTRACT;
5041 case TextureStage::CM_dot3_rgb:
5042 case TextureStage::CM_dot3_rgba:
5043 return D3DTOP_DOTPRODUCT3;
5047 <<
"Invalid TextureStage::CombineMode value (" << (int)mode <<
")\n";
5048 return D3DTOP_DISABLE;
5058 DWORD DXGraphicsStateGuardian9::
5059 get_texture_argument(TextureStage::CombineSource source,
5060 TextureStage::CombineOperand operand)
const {
5062 case TextureStage::CS_undefined:
5063 case TextureStage::CS_texture:
5064 return D3DTA_TEXTURE | get_texture_argument_modifier(operand);
5066 case TextureStage::CS_constant:
5067 case TextureStage::CS_constant_color_scale:
5068 return _constant_color_operand | get_texture_argument_modifier(operand);
5070 case TextureStage::CS_primary_color:
5071 return D3DTA_DIFFUSE | get_texture_argument_modifier(operand);
5073 case TextureStage::CS_previous:
5074 return D3DTA_CURRENT | get_texture_argument_modifier(operand);
5076 case TextureStage::CS_last_saved_result:
5077 return D3DTA_TEMP | get_texture_argument_modifier(operand);
5080 <<
"Invalid TextureStage::CombineSource value (" << (int)source <<
")\n";
5081 return D3DTA_CURRENT;
5091 DWORD DXGraphicsStateGuardian9::
5092 get_texture_argument_modifier(TextureStage::CombineOperand operand) {
5094 case TextureStage::CO_src_color:
5097 case TextureStage::CO_one_minus_src_color:
5098 return D3DTA_COMPLEMENT;
5100 case TextureStage::CO_src_alpha:
5101 return D3DTA_ALPHAREPLICATE;
5103 case TextureStage::CO_one_minus_src_alpha:
5104 return D3DTA_ALPHAREPLICATE | D3DTA_COMPLEMENT;
5106 case TextureStage::CO_undefined:
5110 <<
"Invalid TextureStage::CombineOperand value (" << (int)operand <<
")\n";
5122 void DXGraphicsStateGuardian9::
5123 draw_primitive_up(D3DPRIMITIVETYPE primitive_type,
5124 unsigned int primitive_count,
5125 unsigned int first_vertex,
5126 unsigned int num_vertices,
5127 const unsigned char *buffer,
size_t stride) {
5135 const unsigned char *buffer_start = buffer + stride * first_vertex;
5136 const unsigned char *buffer_end = buffer_start + stride * num_vertices;
5138 if (buffer_end - buffer_start > 0x10000) {
5141 _d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
5142 buffer_start, stride);
5144 }
else if ((((
long)buffer_end ^ (
long)buffer_start) & ~0xffff) == 0) {
5146 _d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
5147 buffer_start, stride);
5153 unsigned char *safe_buffer_start = get_safe_buffer_start();
5154 memcpy(safe_buffer_start, buffer_start, buffer_end - buffer_start);
5155 _d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
5156 safe_buffer_start, stride);
5172 void DXGraphicsStateGuardian9::
5173 draw_indexed_primitive_up(D3DPRIMITIVETYPE primitive_type,
5174 unsigned int min_index,
unsigned int max_index,
5175 unsigned int num_primitives,
5176 const unsigned char *index_data,
5177 D3DFORMAT index_type,
5178 const unsigned char *buffer,
size_t stride) {
5181 const unsigned char *buffer_start = buffer + stride * min_index;
5182 const unsigned char *buffer_end = buffer + stride * (max_index + 1);
5184 if (buffer_end - buffer_start > 0x10000) {
5187 _d3d_device->DrawIndexedPrimitiveUP
5188 (primitive_type, min_index, max_index - min_index + 1, num_primitives,
5189 index_data, index_type, buffer, stride);
5191 }
else if ((((
long)buffer_end ^ (
long)buffer_start) & ~0xffff) == 0) {
5193 _d3d_device->DrawIndexedPrimitiveUP
5194 (primitive_type, min_index, max_index - min_index + 1, num_primitives,
5195 index_data, index_type, buffer, stride);
5201 unsigned char *safe_buffer_start = get_safe_buffer_start();
5202 memcpy(safe_buffer_start, buffer_start, buffer_end - buffer_start);
5203 _d3d_device->DrawIndexedPrimitiveUP
5204 (primitive_type, min_index, max_index - min_index + 1, num_primitives,
5205 index_data, index_type, safe_buffer_start - stride * min_index, stride);
5233 case D3DERR_OUTOFVIDEOMEMORY:
5237 size_t current_size = _prepared_objects->_graphics_memory_lru.get_total_size();
5238 size_t target_size = max(current_size - allocation_size * attempts, (
size_t) 0);
5239 _prepared_objects->_graphics_memory_lru.evict_to(target_size);
5241 <<
"Evicted " << current_size - _prepared_objects->_graphics_memory_lru.get_total_size() <<
" bytes of texture memory to make room for more.\n";
5242 if (_prepared_objects->_graphics_memory_lru.get_total_size() < current_size) {
5259 static int dx_stencil_comparison_function_array[] = {
5266 D3DCMP_GREATEREQUAL,
5270 static int dx_stencil_operation_array[] = {
5273 D3DSTENCILOP_REPLACE,
5276 D3DSTENCILOP_INVERT,
5278 D3DSTENCILOP_INCRSAT,
5279 D3DSTENCILOP_DECRSAT,
5287 void DXGraphicsStateGuardian9::
5288 do_issue_stencil() {
5289 if (!_supports_stencil) {
5298 dxgsg9_cat.debug() <<
"STENCIL STATE CHANGE\n";
5299 dxgsg9_cat.debug() <<
"\n"
5300 <<
"SRS_front_comparison_function " << stencil->
get_render_state(StencilAttrib::SRS_front_comparison_function) <<
"\n"
5301 <<
"SRS_front_stencil_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_front_stencil_fail_operation) <<
"\n"
5302 <<
"SRS_front_stencil_pass_z_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation) <<
"\n"
5303 <<
"SRS_front_stencil_pass_z_pass_operation " << stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation) <<
"\n"
5304 <<
"SRS_reference " << stencil->
get_render_state(StencilAttrib::SRS_reference) <<
"\n"
5305 <<
"SRS_read_mask " << stencil->
get_render_state(StencilAttrib::SRS_read_mask) <<
"\n"
5306 <<
"SRS_write_mask " << stencil->
get_render_state(StencilAttrib::SRS_write_mask) <<
"\n"
5307 <<
"SRS_back_comparison_function " << stencil->
get_render_state(StencilAttrib::SRS_back_comparison_function) <<
"\n"
5308 <<
"SRS_back_stencil_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_back_stencil_fail_operation) <<
"\n"
5309 <<
"SRS_back_stencil_pass_z_fail_operation " << stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation) <<
"\n"
5310 <<
"SRS_back_stencil_pass_z_pass_operation " << stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) <<
"\n";
5315 unsigned int front_compare;
5316 front_compare = stencil->
get_render_state(StencilAttrib::SRS_front_comparison_function);
5318 if (front_compare != RenderAttrib::M_none) {
5320 set_render_state(D3DRS_STENCILFUNC, dx_stencil_comparison_function_array[front_compare]);
5322 stencil->
get_render_state(StencilAttrib::SRS_front_stencil_fail_operation)]);
5324 stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation)]);
5326 stencil->
get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation)]);
5332 if (_supports_two_sided_stencil) {
5333 unsigned int back_compare;
5334 back_compare = stencil->
get_render_state(StencilAttrib::SRS_back_comparison_function);
5336 if (back_compare != RenderAttrib::M_none) {
5338 set_render_state(D3DRS_CCW_STENCILFUNC, dx_stencil_comparison_function_array[back_compare]);
5340 stencil->
get_render_state(StencilAttrib::SRS_back_stencil_fail_operation)]);
5342 stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation)]);
5344 stencil->
get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation)]);
5358 _d3d_device->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 0.0f, stencil->
get_render_state(StencilAttrib::SRS_clear_value));
5364 dxgsg9_cat.debug() <<
"STENCIL STATE CHANGE TO OFF\n";
5368 if (_supports_two_sided_stencil) {
5379 void DXGraphicsStateGuardian9::
5380 do_issue_scissor() {
5385 r.left = _current_viewport.X + _current_viewport.Width * frame[0];
5386 r.top = _current_viewport.Y + _current_viewport.Height * (1.0f - frame[3]);
5387 r.right = _current_viewport.X + _current_viewport.Width * frame[1];
5388 r.bottom = _current_viewport.Y + _current_viewport.Height * (1.0f - frame[2]);
5389 _d3d_device->SetScissorRect(&r);
5401 DWORD multisampletype, DWORD multisamplequality) {
5404 int r=0, g=0, b=0, a=0;
5406 case D3DFMT_R8G8B8: r=8; g=8; b=8; a=0;
break;
5407 case D3DFMT_A8R8G8B8: r=8; g=8; b=8; a=8;
break;
5408 case D3DFMT_X8R8G8B8: r=8; g=8; b=8; a=0;
break;
5409 case D3DFMT_R5G6B5: r=5; g=6; b=5; a=0;
break;
5410 case D3DFMT_X1R5G5B5: r=5; g=5; b=5; a=0;
break;
5411 case D3DFMT_A1R5G5B5: r=5; g=5; b=5; a=1;
break;
5412 case D3DFMT_A4R4G4B4: r=4; g=4; b=4; a=4;
break;
5413 case D3DFMT_R3G3B2: r=3; g=3; b=2; a=0;
break;
5414 case D3DFMT_A8R3G3B2: r=3; g=3; b=2; a=8;
break;
5415 case D3DFMT_X4R4G4B4: r=4; g=4; b=4; a=0;
break;
5416 case D3DFMT_A2B10G10R10: r=10;g=10;b=10;a=2;
break;
5417 case D3DFMT_A8P8: index=8; a=8;
break;
5418 case D3DFMT_P8: index=8; a=0;
break;
5422 props.set_rgb_color(0);
5423 props.set_indexed_color(1);
5425 }
else if (r + g + b > 0) {
5426 props.set_rgb_color(1);
5427 props.set_indexed_color(0);
5430 props.set_alpha_bits(a);
5435 case D3DFMT_D32: depth=32; stencil=0;
break;
5436 case D3DFMT_D15S1: depth=15; stencil=1;
break;
5437 case D3DFMT_D24S8: depth=24; stencil=8;
break;
5438 case D3DFMT_D16: depth=16; stencil=0;
break;
5439 case D3DFMT_D24X8: depth=24; stencil=0;
break;
5440 case D3DFMT_D24X4S4: depth=24; stencil=4;
break;
5443 props.set_depth_bits(depth);
5444 props.set_stencil_bits(stencil);
5445 if (multisampletype == D3DMULTISAMPLE_NONMASKABLE) {
5446 props.set_multisamples(2);
5448 props.set_multisamples(multisampletype);
5454 #define GAMMA_1 (255.0 * 256.0)
5456 static bool _gamma_table_initialized =
false;
5457 static unsigned short _orignial_gamma_table [256 * 3];
5459 void _create_gamma_table (PN_stdfloat gamma,
unsigned short *original_red_table,
unsigned short *original_green_table,
unsigned short *original_blue_table,
unsigned short *red_table,
unsigned short *green_table,
unsigned short *blue_table) {
5461 double gamma_correction;
5467 gamma_correction = 1.0 / (double) gamma;
5469 for (i = 0; i < 256; i++) {
5474 if (original_red_table) {
5475 r = (double) original_red_table [i] / GAMMA_1;
5476 g = (double) original_green_table [i] / GAMMA_1;
5477 b = (double) original_blue_table [i] / GAMMA_1;
5480 r = ((double) i / 255.0);
5485 r = pow (r, gamma_correction);
5486 g = pow (g, gamma_correction);
5487 b = pow (b, gamma_correction);
5504 green_table [i] = g;
5519 if (_gamma_table_initialized ==
false) {
5520 HDC hdc = GetDC(NULL);
5523 if (GetDeviceGammaRamp (hdc, (LPVOID) _orignial_gamma_table)) {
5524 _gamma_table_initialized =
true;
5528 ReleaseDC (NULL, hdc);
5544 HDC hdc = GetDC(NULL);
5548 unsigned short ramp [256 * 3];
5550 if (restore && _gamma_table_initialized) {
5551 _create_gamma_table (gamma, &_orignial_gamma_table [0], &_orignial_gamma_table [256], &_orignial_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
5554 _create_gamma_table (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]);
5557 if (SetDeviceGammaRamp (hdc, ramp)) {
5561 ReleaseDC (NULL, hdc);
5617 CGprofile profile = cgGetProfile(name.c_str());
5619 if (profile == CG_PROFILE_UNKNOWN) {
5620 dxgsg9_cat.error() << name <<
", unknown Cg-profile\n";
5623 return cgD3D9IsProfileSupported(cgGetProfile(name.c_str())) != 0;
5637 if (_cg_device != cg_device) {
5638 cgD3D9SetDevice(cg_device);
5639 _cg_device = cg_device;
5650 int secondary_count;
5658 int total_key_elements;
5668 key_element -> key = key;
5669 key_element -> count = 1;
5670 key_element -> secondary_count = 0;
5671 key_element -> next = 0;
5673 key_list -> total_key_elements++;
5680 return key_list -> key_element;
5685 return key_element -> next;
5688 void delete_key_list (
KEY_LIST *key_list)
5695 key_element = first_key_element (key_list);
5698 key_element_next = next_key_element (key_element);
5700 key_element = key_element_next;
5712 memset (key_list, 0,
sizeof (
KEY_LIST));
5724 last_key_element = 0;
5725 current_key_element = key_list -> key_element;
5726 if (current_key_element == 0)
5728 key_element = new_key_element (key, key_list);
5729 key_list -> key_element = key_element;
5733 while (current_key_element)
5735 if (key < current_key_element -> key)
5737 key_element = new_key_element (key, key_list);
5738 key_element -> next = current_key_element;
5740 if (last_key_element == 0)
5742 key_list -> key_element = key_element;
5746 last_key_element -> next = key_element;
5752 if (key > current_key_element -> key)
5754 if (current_key_element -> next == 0)
5756 key_element = new_key_element (key, key_list);
5757 current_key_element -> next = key_element;
5767 current_key_element -> count++;
5772 last_key_element = current_key_element;
5773 current_key_element = current_key_element -> next;
void get_linear_range(PN_stdfloat &onset, PN_stdfloat &opaque)
Retrieves the current onset and offset ranges.
Format get_format() const
Returns the format of the texture, which represents both the semantic meaning of the texels and...
A GraphicsStateGuardian for rendering into DirectX9 contexts.
A light shining from infinitely far away in a particular direction, like sunlight.
static bool is_srgb(Format format)
Returns true if the indicated format is in the sRGB color space, false otherwise. ...
bool changed_size(const GeomPrimitivePipelineReader *reader) const
Returns true if the data has changed size since the last time mark_loaded() was called.
FilterType get_effective_magfilter() const
Returns the filter mode of the texture for magnification, with special treatment for FT_default...
const float * get_data() const
Returns the address of the first of the four data elements in the vector.
The abstract interface to all kinds of lights.
int get_rgb_scale() const
See set_rgb_scale().
HRESULT set_sampler_state(DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value)
This function creates a common layer between DX and Panda.
virtual void end_frame(Thread *current_thread)
Called after each frame is rendered, to allow the GSG a chance to do any internal cleanup after rende...
Encapsulates the data from a DisplayRegion, pre-fetched for one stage of the pipeline.
This is the base class for all three-component vectors and points.
Mode get_mode() const
Return the mode of this stage.
void release_shader(ShaderContext *sc)
Releases the resources allocated by prepare_shader.
int get_alpha_scale() const
See set_alpha_scale().
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...
PN_stdfloat get_exp_density() const
Returns the density of the fog for exponential calculations.
LVecBase4f get_col(int col) const
Retrieves the indicated column of the matrix as a 4-component vector.
bool do_framebuffer_copy_to_ram(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb, bool inverted)
This is the implementation of framebuffer_copy_to_ram(); it adds one additional parameter, which should be true if the framebuffer is to be inverted during the copy (as in the same way it copies to texture memory).
const LColor & get_ambient() const
Returns the ambient color setting, if it has been set.
This is a base class for GraphicsWindow (actually, GraphicsOutput) and DisplayRegion, both of which are conceptually rectangular regions into which drawing commands may be issued.
Enables or disables writing to the depth buffer.
static LMatrix4f scale_mat(const LVecBase3f &scale)
Returns a matrix that applies the indicated scale in each of the three axes.
const float * get_data() const
Returns the address of the first of the three data elements in the vector.
A base class for any number of different kinds of lenses, linear and otherwise.
bool has_ambient() const
Returns true if the ambient color has been explicitly set for this material, false otherwise...
static bool static_set_gamma(bool restore, PN_stdfloat gamma)
Static function for setting gamma which is needed for atexit.
Enables or disables writing to the color buffer.
HRESULT set_texture_stage_state(DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value)
This function creates a common layer between DX and Panda.
bool was_modified(const GeomPrimitivePipelineReader *reader) const
Returns true if the data has been modified since the last time mark_loaded() was called.
bool is_off() const
Returns true if the MaterialAttrib is an 'off' MaterialAttrib, indicating that it should disable the ...
bool has_specular() const
Returns true if the specular color has been explicitly set for this material, false otherwise...
bool was_modified() const
Returns true if the texture properties or image have been modified since the last time mark_loaded() ...
virtual bool extract_texture_data(Texture *tex)
This method should only be called by the GraphicsEngine.
IDirect3DBaseTexture9 * get_d3d_texture() const
Returns the Direct3D object that represents the texture, whatever kind of texture it is...
Indicates which, if any, material should be applied to geometry.
This object describes how the vertex animation, if any, represented in a GeomVertexData is encoded...
Enables or disables writing to the depth buffer.
CombineSource get_combine_alpha_source0() const
Get source0 of combine_alpha_mode.
virtual void prepare_display_region(DisplayRegionPipelineReader *dr)
Makes the specified DisplayRegion current.
ComponentType get_component_type() const
Returns the numeric interpretation of each component of the texture.
virtual void end_draw_primitives()
Called after a sequence of draw_primitive() functions are called, this should do whatever cleanup is ...
const LPoint3 & get_point() const
Returns the point in space at which the light is located.
void release_all()
Releases all prepared objects.
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...
This controls the enabling of transparency.
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected triangles.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
This is a special class object that holds all the information returned by a particular GSG to indicat...
CombineMode get_combine_alpha_mode() const
Get combine_alpha_mode.
const LVector3 & get_view_vector() const
Returns the axis along which the lens is facing.
WrapMode get_wrap_v() const
Returns the wrap mode of the texture in the V direction.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
unsigned int get_channels() const
Returns the mask of color channels that are enabled by this attrib.
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...
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, const GeomVertexDataPipelineReader *data_reader, bool force)
Called before a sequence of draw_primitive() functions are called, this should prepare the vertex dat...
Specifies whether flat shading (per-polygon) or smooth shading (per-vertex) is in effect...
bool get_perspective() const
Returns the perspective flag.
void apply_texture(int i, TextureContext *tc, const SamplerState &sampler)
Makes the texture the currently available texture for rendering on the ith stage. ...
This is a special class object that holds all the information returned by a particular GSG to indicat...
unsigned int get_render_state(StencilRenderState render_state_identifier) const
Returns render state.
PandaCompareFunc get_mode() const
Returns the depth write mode.
Material * get_material() const
If the MaterialAttrib is not an 'off' MaterialAttrib, returns the material that is associated...
const LColor & get_border_color() const
Returns the solid color of the texture's border.
void unbind(GSG *gsg)
This function disables a currently-bound shader.
bool create_texture(DXScreenData &scrn)
Use panda texture's pixelbuffer to create a texture for the specified device.
static D3DFORMAT get_index_type(Geom::NumericType numeric_type)
Maps from the Geom's internal numeric type symbols to DirectX's.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
void issue_parameters(GSG *gsg, int altered)
This function gets called whenever the RenderState or TransformState has changed, but the Shader itse...
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
CombineOperand get_combine_alpha_operand2() const
Get operand2 of combine_alpha_mode.
void disable_shader_texture_bindings(GSG *gsg)
Disable all the texture bindings used by this shader.
Caches a GeomPrimitive in the DirectX device as an index buffer.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Texture * get_texture() const
Returns the pointer to the associated Texture object.
PN_stdfloat get_shininess() const
Returns the shininess exponent of the material.
virtual void set_state_and_transform(const RenderState *state, const TransformState *transform)
Simultaneously resets the render state and the transform state.
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
Encapsulates the data from a Geom, pre-fetched for one stage of the pipeline.
void do_issue_color()
This method is defined in the base class because it is likely that this functionality will be used fo...
static const LMatrix4f & convert_mat(CoordinateSystem from, CoordinateSystem to)
Returns a matrix that transforms from the indicated coordinate system to the indicated coordinate sys...
PN_stdfloat get_exponent() const FINAL
Returns the exponent that controls the amount of light falloff from the center of the spotlight...
virtual void end_scene()
Called between begin_frame() and end_frame() to mark the end of drawing commands for a "scene" (usual...
static bool get_gamma_table(void)
Static function for getting the original gamma.
virtual bool framebuffer_copy_to_texture(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)
Copy the pixels within the indicated display region from the framebuffer into texture memory...
const LColor & get_emission() const
Returns the emission color setting, if it has been set.
const float * get_data() const
Returns the address of the first of the nine data elements in the matrix.
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
static void atexit_function(void)
This function is passed to the atexit function.
PN_stdfloat get_hfov() const
Returns the horizontal component of fov only.
The ShaderContext is meant to contain the compiled version of a shader string.
void disable_shader_vertex_arrays(GSG *gsg)
Disable all the vertex arrays used by this shader.
LColor get_color() const
return the color for this stage
const LColor & get_specular_color() const FINAL
Returns the color of specular highlights generated by the light.
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
void enqueue_lru(AdaptiveLru *lru)
Adds the page to the LRU for the first time, or marks it recently-accessed if it has already been add...
Indicates which faces should be culled based on their vertex ordering.
void reset_all_windows(bool swapchain)
Resets the framebuffer of the current window.
bool was_simple_image_modified() const
Returns true if the texture's "simple" image has been modified since the last time mark_simple_loaded...
CombineMode get_combine_rgb_mode() const
Get the combine_rgb_mode.
Mode get_mode() const
Returns the depth write mode.
Applies a Fog to the geometry at and below this node.
void set_size_padded(int x=1, int y=1, int z=1)
Changes the size of the texture, padding if necessary, and setting the pad region as well...
AnimationType get_animation_type() const
Returns the type of animation represented by this spec.
A lightweight class that represents a single element that may be timed and/or counted via stats...
int get_num_combine_rgb_operands() const
Returns the number of meaningful operands that may be retrieved via get_combine_rgb_sourceN() and get...
bool involves_color_scale() const
Returns true if the TextureStage is affected by the setting of the current ColorScaleAttrib, false otherwise.
Mode get_effective_mode() const
Returns the effective culling mode.
bool is_off() const
Returns true if the FogAttrib is an 'off' FogAttrib, indicating that it should disable fog...
Mode get_mode() const
Returns the shade mode.
PandaCompareFunc get_mode() const
Returns the alpha write mode.
An offscreen render buffer.
bool check_dx_allocation(HRESULT result, int allocation_size, int attempts)
This function is called after the creation of textures, vertex buffers, and index buffers to check if...
const LColor & get_color() const
Returns the color of the fog.
A StencilAttrib is a collection of all stencil render states.
PN_stdfloat get_reference_alpha() const
Returns the alpha reference value.
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...
int get_z_size() const
Returns the depth of the texture image in texels.
int get_num_views() const
Returns the number of "views" in the texture.
void restore_gamma()
Restore original gamma.
This is a 4-by-4 transform matrix.
static void set_cg_device(LPDIRECT3DDEVICE9 cg_device)
Sets the global Cg device pointer.
void mark_new()
Marks the GSG as "new", so that the next call to reset_if_new() will be effective.
bool uses_color() const
Returns true if the TextureStage makes use of whatever color is specified in set_color(), false otherwise.
virtual void reset()
Resets all internal state as if the gsg were newly created.
virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of line strips.
const LVector3 & get_direction() const
Returns the direction in which the light is aimed.
CompressionMode get_ram_image_compression() const
Returns the compression mode in which the ram image is already stored pre-compressed.
Specifies how atmospheric fog effects are applied to geometry.
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.
CombineOperand get_combine_rgb_operand2() const
Get operand2 of combine_rgb_mode.
virtual PreparedGraphicsObjects * get_prepared_objects()
Returns the set of texture and geom objects that have been prepared with this GSG (and possibly other...
int get_current_tex_view_offset() const
Returns the current tex view offset, as set by the last call to prepare_display_region().
CombineSource get_combine_rgb_source0() const
Get source0 of combine_rgb_mode.
An object to create GraphicsOutputs that share a particular 3-D API.
CombineOperand get_combine_alpha_operand1() const
Get operand1 of combine_alpha_mode.
ShaderContext * prepare_shader(Shader *se)
Compile a vertex/fragment shader body.
const LColor & get_specular_color() const FINAL
Returns the color of specular highlights generated by the light.
CombineSource get_combine_alpha_source2() const
Get source2 of combine_alpha_mode.
virtual void begin_occlusion_query()
Begins a new occlusion query.
This specialization on GeomMunger finesses vertices for DirectX rendering.
virtual bool get_supports_cg_profile(const string &name) const
Returns true if this particular GSG supports the specified Cg Shader Profile.
A light originating from a single point in space, and shining in a particular direction, with a cone-shaped falloff.
const LColor & get_specular() const
Returns the specular color setting, if it has been set.
virtual void do_issue_light()
This implementation of do_issue_light() assumes we have a limited number of hardware lights available...
int get_effective_anisotropic_degree() const
Returns the degree of anisotropic filtering that should be applied to the texture.
bool apply_index_buffer(IndexBufferContext *ibc, const GeomPrimitivePipelineReader *reader, bool force)
Updates the index buffer with the current data, and makes it the current index buffer for rendering...
bool set_gamma(PN_stdfloat gamma)
Non static version of setting gamma.
void set_render_to_texture(bool render_to_texture)
Sets a flag on the texture that indicates whether the texture is intended to be used as a direct-rend...
CombineOperand get_combine_alpha_operand0() const
Get operand0 of combine_alpha_mode.
WrapMode get_wrap_u() const
Returns the wrap mode of the texture in the U direction.
bool get_indexed_transforms() const
This is only meaningful for animation_type AT_hardware.
virtual void end_frame(Thread *current_thread)
Called after each frame is rendered, to allow the GSG a chance to do any internal cleanup after rende...
virtual void end_draw_primitives()
Called after a sequence of draw_primitive() functions are called, this should do whatever cleanup is ...
const LColor & get_specular_color() const FINAL
Returns the color of specular highlights generated by the light.
Enables or disables writing of pixel to framebuffer based on its alpha value relative to a reference ...
TextureType get_texture_type() const
Returns the overall interpretation of the texture.
virtual bool update_texture(TextureContext *tc, bool force)
Ensures that the current Texture data is refreshed onto the GSG.
Defines the way an object appears in the presence of lighting.
bool has_simple_ram_image() const
Returns true if the Texture has a "simple" image available in main RAM.
bool upload_data(const GeomPrimitivePipelineReader *reader, bool force)
Copies the latest data from the client store to DirectX.
int get_offset() const
Returns the depth offset represented by this attrib.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Mode get_mode() const
Returns the render mode.
bool has_mipmaps() const
Returns true if the texture was created with mipmaps, false otherwise.
int get_tex_view_offset() const
Returns the current setting of the tex_view_offset.
const LVecBase3 & get_attenuation() const FINAL
Returns the terms of the attenuation equation for the light.
static void add_gsg(GraphicsStateGuardianBase *gsg)
Called by a GSG after it has been initialized, to add a new GSG to the available list.
Represents a set of settings that indicate how a texture is sampled.
void mark_loaded(const GeomPrimitivePipelineReader *reader)
Should be called after the IndexBufferContext has been loaded into graphics memory, this updates the internal flags for changed_size() and modified().
virtual TextureContext * prepare_texture(Texture *tex, int view)
Creates a new retained-mode representation of the given texture, and returns a newly-allocated Textur...
TextureContext * prepare_now(int view, PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg)
Creates a context for the texture on the particular GSG, if it does not already exist.
virtual void bind_light(PointLight *light_obj, const NodePath &light, int light_id)
Called the first time a particular light has been bound to a given id within a frame, this should set up the associated hardware light with the light's properties.
This is the base class for all three-component vectors and points.
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, const GeomVertexDataPipelineReader *data_reader, bool force)
Called before a sequence of draw_primitive() functions are called, this should prepare the vertex dat...
Applies a transform matrix to UV's before they are rendered.
static DWORD LColor_to_D3DCOLOR(const LColor &cLColor)
Converts Panda's floating-point LColor structure to DirectX's D3DCOLOR packed structure.
bool has_diffuse() const
Returns true if the diffuse color has been explicitly set for this material, false otherwise...
virtual bool prepare_lens()
Makes the current lens (whichever lens was most recently specified with set_scene()) active...
Mode get_mode() const
Returns the render mode.
This specifies how colors are blended into the frame buffer, for special effects. ...
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.
CombineOperand get_combine_rgb_operand1() const
Get operand1 of combine_rgb_mode.
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 ...
virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected line segments.
A thread; that is, a lightweight process.
void update_data_size_bytes(size_t new_data_size_bytes)
Should be called (usually by a derived class) when the on-card size of this object has changed...
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
virtual void prepare_display_region(DisplayRegionPipelineReader *dr)
Prepare a display region for rendering (set up scissor region and viewport)
This is a special kind of attribute that instructs the graphics driver to apply an offset or bias to ...
virtual bool begin_frame(Thread *current_thread)
Called before each frame is rendered, to allow the GSG a chance to do any internal cleanup before beg...
void mark_loaded()
Should be called after the texture has been loaded into graphics memory, this updates the internal fl...
This is a special class object that holds all the information returned by a particular GSG to indicat...
Encapsulates all the communication with a particular instance of a given rendering backend...
Specifies how polygons are to be drawn.
bool get_saved_result() const
Returns the current setting of the saved_result flag.
void set_active(bool flag)
Changes the active flag associated with this object.
FilterType get_effective_minfilter() const
Returns the filter mode of the texture for minification, with special treatment for FT_default...
virtual void end_scene()
Called between begin_frame() and end_frame() to mark the end of drawing commands for a "scene" (usual...
const LColor & get_color() const
Returns the basic color of the light.
FrameBufferProperties calc_fb_properties(DWORD cformat, DWORD dformat, DWORD multisampletype, DWORD multisamplequality)
Convert DirectX framebuffer format ids into a FrameBufferProperties structure.
bool has_ram_image() const
Returns true if the Texture has its image contents available in main RAM, false if it exists only in ...
Specifies how polygons are to be drawn.
int release_all_index_buffers()
Frees the resources for all index buffers associated with this GSG.
A rectangular subregion within a window for rendering into.
virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle fans.
PN_stdfloat get_thickness() const
Returns the line width or point thickness.
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
const LVecBase3 & get_attenuation() const FINAL
Returns the terms of the attenuation equation for the light.
int release_all_vertex_buffers()
Frees the resources for all vertex buffers associated with this GSG.
bool has_uncompressed_ram_image() const
Returns true if the Texture has its image contents available in main RAM and is uncompressed, false otherwise.
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
void set_color_bits(int n)
Sets the number of requested color bits as a single number that represents the sum of the individual ...
This restricts rendering to within a rectangular region of the scene, without otherwise affecting the...
virtual void release_texture(TextureContext *tc)
Frees the GL resources previously allocated for the texture.
Returned from a GSG in response to begin_occlusion_query() .
int get_num_combine_alpha_operands() const
Returns the number of meaningful operands that may be retrieved via get_combine_alpha_sourceN() and g...
This class is the main interface to controlling the render process.
CombineOperand get_combine_rgb_operand0() const
Get operand0 of combine_rgb_mode.
virtual void reset()
Resets all internal state as if the gsg were newly created.
void mark_unloaded()
Should be called after the texture has been forced out of texture memory.
virtual bool begin_scene()
Called between begin_frame() and end_frame() to mark the beginning of drawing commands for a "scene" ...
bool get_local() const
Returns the local viewer flag.
virtual bool begin_frame(Thread *current_thread)
Called before each frame is rendered, to allow the GSG a chance to do any internal cleanup before beg...
void create_ibuffer(DXScreenData &scrn, const GeomPrimitivePipelineReader *reader)
Creates a new index buffer (but does not upload data to it).
virtual IndexBufferContext * prepare_index_buffer(GeomPrimitive *data)
Creates a new retained-mode representation of the given data, and returns a newly-allocated IndexBuff...
TypeHandle is the identifier used to differentiate C++ class types.
virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle strips.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
const LVecBase4 & get_frame() const
Returns the left, right, bottom, top coordinates of the scissor frame.
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
Fog * get_fog() const
If the FogAttrib is not an 'off' FogAttrib, returns the fog that is associated.
Defines the properties of a named stage of the multitexture pipeline.
bool upload_texture(DXTextureContext9 *dtc, bool force)
Creates a texture surface on the graphics card and fills it with its pixel data.
Computes texture coordinates for geometry automatically based on vertex position and/or normal...
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...
const LColor & get_diffuse() const
Returns the diffuse color setting, if it has been set.
ShaderContext * prepare_now(PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg)
Creates a context for the shader on the particular GSG, if it does not already exist.
HRESULT set_render_state(D3DRENDERSTATETYPE state, DWORD value)
This function creates a common layer between DX and Panda for SetRenderState.
LPoint3 get_nodal_point() const
Returns the center point of the lens: the point from which the lens is viewing.
int get_y_size() const
Returns the height of the texture image in texels.
A RenderBuffer is an arbitrary subset of the various layers (depth buffer, color buffer, etc.) of a drawing region.
bool might_have_ram_image() const
Returns true if the texture's image contents are currently available in main RAM, or there is reason ...
virtual bool framebuffer_copy_to_ram(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)
Copy the pixels within the indicated display region from the framebuffer into system memory...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
virtual bool draw_points(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected points.
WrapMode get_wrap_w() const
Returns the wrap mode of the texture in the W direction.
A light originating from a single point in space, and shining in all directions.
int get_x_size() const
Returns the width of the texture image in texels.
int get_num_transforms() const
This is only meaningful for animation_type AT_hardware.
void delete_texture()
Release the surface used to store the texture.
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 node that contains a plane.
CombineSource get_combine_rgb_source2() const
Get source2 of combine_rgb_mode.
PN_stdfloat get_lod_bias() const
Returns the bias that will be added to the texture level of detail when sampling this texture...
CombineSource get_combine_rgb_source1() const
Get source1 of combine_rgb_mode.
Similar to PointerToArray, except that its contents may not be modified.
This is the data for one array of a GeomVertexData structure.
virtual bool begin_scene()
Called between begin_frame() and end_frame() to mark the beginning of drawing commands for a "scene" ...
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
CombineSource get_combine_alpha_source1() const
Get source1 of combine_alpha_mode.
virtual void release_index_buffer(IndexBufferContext *ibc)
Frees the GL resources previously allocated for the data.
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...