Просмотр исходного кода

optimized directx perspective calculation and fixed orthographic projection

Asad M. Zaman 22 лет назад
Родитель
Сommit
1b5e1c6ecf

+ 25 - 2
panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx

@@ -802,6 +802,7 @@ prepare_lens() {
     return false;
   }
 
+  // lets get the lens perspective matrix
   const LMatrix4f &projection_mat = _current_lens->get_projection_mat();
 
   // The projection matrix must always be left-handed Y-up internally,
@@ -810,9 +811,31 @@ prepare_lens() {
     LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()) *
     projection_mat;
 
+  float vfov = _current_lens->get_vfov();
+  float nearf = _current_lens->get_near();
+  float farf = _current_lens->get_far();
+
+  //dxgsg7_cat.debug() << new_projection_mat << endl;
+  
   HRESULT hr;
-  hr = _pScrn->pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION,
-                                     (LPD3DMATRIX)new_projection_mat.get_data());
+  if (_current_lens->get_type().get_name() == "PerspectiveLens") {
+    ((LPD3DMATRIX)new_projection_mat.get_data())->_33 = farf / (farf-nearf);
+    ((LPD3DMATRIX)new_projection_mat.get_data())->_43 = -nearf * farf / (farf - nearf);
+
+    hr = _pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION,
+                                   (D3DMATRIX*)new_projection_mat.get_data());
+    //dxgsg7_cat.debug() << new_projection_mat << endl;
+    //dxgsg7_cat.debug() << "using perspective projection" << endl;
+  }
+  else {
+    ((LPD3DMATRIX)new_projection_mat.get_data())->_33 = 1/(farf-nearf);
+    ((LPD3DMATRIX)new_projection_mat.get_data())->_43 = -nearf/(farf-nearf);
+    
+    hr = _pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION,
+                                   (LPD3DMATRIX)new_projection_mat.get_data());
+    //dxgsg7_cat.debug() << new_projection_mat << endl;
+    //dxgsg7_cat.debug() << "using ortho projection" << endl;
+  }
   return SUCCEEDED(hr);
 }
 

+ 32 - 16
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -1030,40 +1030,56 @@ prepare_lens() {
     return false;
   }
 
-  HRESULT hr;
+  // lets get the lens perspective matrix
+  const LMatrix4f &projection_mat = _current_lens->get_projection_mat();
+  
+  // The projection matrix must always be left-handed Y-up internally,
+  // even if our coordinate system of choice is otherwise.
+  LMatrix4f new_projection_mat =
+    LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()) *
+    projection_mat;
+  
+  float vfov = _current_lens->get_vfov();
+  float nearf = _current_lens->get_near();
+  float farf = _current_lens->get_far();
 
+  //dxgsg8_cat.debug() << new_projection_mat << endl;
+  
+  HRESULT hr;
   if (_current_lens->get_type().get_name() == "PerspectiveLens") {
-    // new method, still in test
+#if 0
     const LMatrix4f mat_temp;
+
     float hfov = _current_lens->get_hfov();
-    float vfov = _current_lens->get_vfov();
     float ar = _current_lens->get_aspect_ratio();
     float nearf = _current_lens->get_near();
     float farf = _current_lens->get_far();
-    //dxgsg8_cat.debug() << "hfov " << hfov << " vfov " << vfov << " ar " << ar << " near " << nearf << " far " << farf << endl;
-    
     double vfov_radian = vfov * 0.0174532925;
-    
+
+    dxgsg8_cat.debug() << "hfov " << hfov << " vfov " << vfov << " ar " << ar << " near " << nearf << " far " << farf << endl;
     D3DXMatrixPerspectiveFovLH( (D3DXMATRIX*)mat_temp.get_data(), vfov_radian, ar, nearf, farf );
-    
+
     hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
                                    (D3DMATRIX*)mat_temp.get_data());
-    //dxgsg8_cat.debug() << mat_temp << endl;
+    dxgsg8_cat.debug() << mat_temp << endl;
+#endif
+    
+    ((D3DXMATRIX*)new_projection_mat.get_data())->_33 = farf / (farf-nearf);
+    ((D3DXMATRIX*)new_projection_mat.get_data())->_43 = -nearf * farf / (farf - nearf);
+
+    hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
+                                   (D3DMATRIX*)new_projection_mat.get_data());
+    //dxgsg8_cat.debug() << new_projection_mat << endl;
     //dxgsg8_cat.debug() << "using perspective projection" << endl;
   }
   else {
-    const LMatrix4f &projection_mat = _current_lens->get_projection_mat();
+    ((D3DXMATRIX*)new_projection_mat.get_data())->_33 = 1/(farf-nearf);
+    ((D3DXMATRIX*)new_projection_mat.get_data())->_43 = -nearf/(farf-nearf);
     
-    // The projection matrix must always be left-handed Y-up internally,
-    // even if our coordinate system of choice is otherwise.
-    LMatrix4f new_projection_mat =
-      LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()) *
-      projection_mat;
- 
     hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
                                    (D3DMATRIX*)new_projection_mat.get_data());
     //dxgsg8_cat.debug() << new_projection_mat << endl;
-    //dxgsg8_cat.debug() << "using other projection" << endl;
+    //dxgsg8_cat.debug() << "using ortho projection" << endl;
   }
   return SUCCEEDED(hr);
 }