diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index d8b6301e05..e5aaee410f 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -595,6 +595,50 @@ prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) { } } +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian8::calc_projection_mat +// Access: Public, Virtual +// Description: Given a lens, calculates the appropriate projection +// matrix for use with this gsg. Note that the +// projection matrix depends a lot upon the coordinate +// system of the rendering API. +// +// The return value is a TransformState if the lens is +// acceptable, NULL if it is not. +//////////////////////////////////////////////////////////////////// +CPT(TransformState) DXGraphicsStateGuardian8:: +calc_projection_mat(const Lens *lens) { + if (lens == (Lens *)NULL) { + return NULL; + } + + if (!lens->is_linear()) { + return NULL; + } + + // DirectX also uses a Z range of 0 to 1, whereas the Panda + // convention is for the projection matrix to produce a Z range of + // -1 to 1. We have to rescale to compensate. + static const LMatrix4f rescale_mat + (1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 0.5, 0, + 0, 0, 0.5, 1); + + LMatrix4f result = + LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()) * + lens->get_projection_mat(_current_stereo_channel) * + rescale_mat; + + if (_scene_setup->get_inverted()) { + // If the scene is supposed to be inverted, then invert the + // projection matrix. + result *= LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f); + } + + return TransformState::make_mat(result); +} + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian8::prepare_lens // Access: Public, Virtual @@ -609,44 +653,9 @@ prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) { //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: prepare_lens() { - if (_current_lens == (Lens *)NULL) { - return false; - } - - if (!_current_lens->is_linear()) { - return false; - } - - // Start with the projection matrix from the lens. - const LMatrix4f &lens_mat = _current_lens->get_projection_mat(_current_stereo_channel); - - // The projection matrix must always be left-handed Y-up internally, - // to match DirectX's convention, even if our coordinate system of - // choice is otherwise. - const LMatrix4f &convert_mat = - LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()); - - // DirectX also uses a Z range of 0 to 1, whereas the Panda - // convention is for the projection matrix to produce a Z range of - // -1 to 1. We have to rescale to compensate. - static const LMatrix4f rescale_mat - (1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 0.5, 0, - 0, 0, 0.5, 1); - - _projection_mat = convert_mat * lens_mat * rescale_mat; - - if (_scene_setup->get_inverted()) { - // If the scene is supposed to be inverted, then invert the - // projection matrix. - static LMatrix4f invert_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f); - _projection_mat *= invert_mat; - } - HRESULT hr = _d3d_device->SetTransform(D3DTS_PROJECTION, - (D3DMATRIX*)_projection_mat.get_data()); + (D3DMATRIX*)_projection_mat->get_mat().get_data()); return SUCCEEDED(hr); } @@ -1302,7 +1311,7 @@ end_draw_primitives() { if (_vertex_data->is_vertex_transformed()) { // Restore the projection matrix that we wiped out above. _d3d_device->SetTransform(D3DTS_PROJECTION, - (D3DMATRIX*)_projection_mat.get_data()); + (D3DMATRIX*)_projection_mat->get_mat().get_data()); } GraphicsStateGuardian::end_draw_primitives(); @@ -1727,7 +1736,6 @@ reset() { _d3d_device->SetRenderState(D3DRS_FOGENABLE, FALSE); - _projection_mat = LMatrix4f::ident_mat(); _has_scene_graph_color = false; _last_testcooplevel_result = D3D_OK; @@ -1941,7 +1949,7 @@ do_issue_render_mode() { _d3d_device->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); LVector3f height(0.0f, point_size, 1.0f); - height = height * _projection_mat; + height = height * _projection_mat->get_mat(); float s = height[1] / point_size; float zero = 0.0f; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 69ef4cff38..3dd1f6ed9f 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -67,6 +67,7 @@ public: virtual void do_clear(const RenderBuffer &buffer); virtual void prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel); + virtual CPT(TransformState) calc_projection_mat(const Lens *lens); virtual bool prepare_lens(); virtual bool begin_frame(); @@ -219,8 +220,6 @@ protected: CullFaceAttrib::Mode _cull_face_mode; RenderModeAttrib::Mode _current_fill_mode; //point/wireframe/solid - LMatrix4f _projection_mat; - const DXVertexBufferContext8 *_active_vbuffer; const DXIndexBufferContext8 *_active_ibuffer; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index bc081d7791..3bf2c2ad5e 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -810,6 +810,50 @@ prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) { } } +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian8::calc_projection_mat +// Access: Public, Virtual +// Description: Given a lens, calculates the appropriate projection +// matrix for use with this gsg. Note that the +// projection matrix depends a lot upon the coordinate +// system of the rendering API. +// +// The return value is a TransformState if the lens is +// acceptable, NULL if it is not. +//////////////////////////////////////////////////////////////////// +CPT(TransformState) DXGraphicsStateGuardian9:: +calc_projection_mat(const Lens *lens) { + if (lens == (Lens *)NULL) { + return NULL; + } + + if (!lens->is_linear()) { + return NULL; + } + + // DirectX also uses a Z range of 0 to 1, whereas the Panda + // convention is for the projection matrix to produce a Z range of + // -1 to 1. We have to rescale to compensate. + static const LMatrix4f rescale_mat + (1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 0.5, 0, + 0, 0, 0.5, 1); + + LMatrix4f result = + LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()) * + lens->get_projection_mat(_current_stereo_channel) * + rescale_mat; + + if (_scene_setup->get_inverted()) { + // If the scene is supposed to be inverted, then invert the + // projection matrix. + result *= LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f); + } + + return TransformState::make_mat(result); +} + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian9::prepare_lens // Access: Public, Virtual @@ -824,44 +868,9 @@ prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) { //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian9:: prepare_lens() { - if (_current_lens == (Lens *)NULL) { - return false; - } - - if (!_current_lens->is_linear()) { - return false; - } - - // Start with the projection matrix from the lens. - const LMatrix4f &lens_mat = _current_lens->get_projection_mat(_current_stereo_channel); - - // The projection matrix must always be left-handed Y-up internally, - // to match DirectX's convention, even if our coordinate system of - // choice is otherwise. - const LMatrix4f &convert_mat = - LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()); - - // DirectX also uses a Z range of 0 to 1, whereas the Panda - // convention is for the projection matrix to produce a Z range of - // -1 to 1. We have to rescale to compensate. - static const LMatrix4f rescale_mat - (1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 0.5, 0, - 0, 0, 0.5, 1); - - _projection_mat = convert_mat * lens_mat * rescale_mat; - - if (_scene_setup->get_inverted()) { - // If the scene is supposed to be inverted, then invert the - // projection matrix. - static LMatrix4f invert_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f); - _projection_mat *= invert_mat; - } - HRESULT hr = _d3d_device->SetTransform(D3DTS_PROJECTION, - (D3DMATRIX*)_projection_mat.get_data()); + (D3DMATRIX*)_projection_mat->get_mat().get_data()); return SUCCEEDED(hr); } @@ -1808,7 +1817,7 @@ end_draw_primitives() { if (_vertex_data->is_vertex_transformed()) { // Restore the projection matrix that we wiped out above. _d3d_device->SetTransform(D3DTS_PROJECTION, - (D3DMATRIX*)_projection_mat.get_data()); + (D3DMATRIX*)_projection_mat->get_mat().get_data()); } GraphicsStateGuardian::end_draw_primitives(); @@ -2577,7 +2586,6 @@ reset() { set_render_state(D3DRS_FOGENABLE, FALSE); - _projection_mat = LMatrix4f::ident_mat(); _has_scene_graph_color = false; _last_testcooplevel_result = D3D_OK; @@ -2876,7 +2884,7 @@ do_issue_render_mode() { set_render_state(D3DRS_POINTSCALEENABLE, TRUE); LVector3f height(0.0f, point_size, 1.0f); - height = height * _projection_mat; + height = height * _projection_mat->get_mat(); float s = height[1] / point_size; float zero = 0.0f; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 7cf2f403f0..55f6058c29 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -103,6 +103,7 @@ public: virtual void do_clear(const RenderBuffer &buffer); virtual void prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel); + virtual CPT(TransformState) calc_projection_mat(const Lens *lens); virtual bool prepare_lens(); virtual bool begin_frame(); @@ -276,8 +277,6 @@ protected: CullFaceAttrib::Mode _cull_face_mode; RenderModeAttrib::Mode _current_fill_mode; //point/wireframe/solid - LMatrix4f _projection_mat; - PT(ShaderExpansion) _current_shader_expansion; CLP(ShaderContext) *_current_shader_context; PT(ShaderExpansion) _vertex_array_shader_expansion; diff --git a/panda/src/dxgsg9/dxShaderContext9.cxx b/panda/src/dxgsg9/dxShaderContext9.cxx index 18e929491a..25a9a3ea66 100644 --- a/panda/src/dxgsg9/dxShaderContext9.cxx +++ b/panda/src/dxgsg9/dxShaderContext9.cxx @@ -1204,7 +1204,7 @@ issue_cg_auto_bind(const ShaderAutoBind &bind, GSG *gsg) break; case CG_GL_PROJECTION_MATRIX: - p_matrix = &gsg->_projection_mat; + p_matrix = &gsg->_projection_mat->get_mat(); if (_transpose_matrix) { temp_matrix.transpose_from (*p_matrix); @@ -1232,7 +1232,7 @@ issue_cg_auto_bind(const ShaderAutoBind &bind, GSG *gsg) DBG_SH4 dxgsg9_cat.debug ( ) << "SHADER: issue_cg_auto_bind CG_GL_MODELVIEW_PROJECTION_MATRIX " << bind.value << "\n"; DBG_E - projection_matrix = &gsg->_projection_mat; + projection_matrix = &gsg->_projection_mat->get_mat(); // which matrix ????? // which multiply order ????? diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 58de52de92..abe1d8ece8 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1013,7 +1013,7 @@ calc_projection_mat(const Lens *lens) { // matrix, and store the conversion to our coordinate system of // choice in the modelview matrix. - LMatrix4f &result = + LMatrix4f result = LMatrix4f::convert_mat(CS_yup_right, _current_lens->get_coordinate_system()) * lens->get_projection_mat(_current_stereo_channel);