regularize projection transform and near plane correction

This commit is contained in:
David Rose 2004-03-04 18:43:25 +00:00
parent 0e084fe310
commit 9ca106399c
4 changed files with 56 additions and 143 deletions

View File

@ -677,10 +677,6 @@ make_mesh_geom(Geom *geom, Lens *lens, LMatrix4f &rel_mat) {
// dimensions so the Z coordinate remains meaningful.
LPoint3f film(0.0f, 0.0f, 0.0f);
lens->project(vert * rel_mat, film);
// This might be necessary to compensate for DX's weird near plane
// definition. Investigate further later.
//film[2] = ((film[2] + 1.0f) / 2.0f);
new_coords.push_back(film);
}

View File

@ -27,7 +27,6 @@
#include "graphicsWindow.h"
#include "graphicsChannel.h"
#include "lens.h"
#include "perspectiveLens.h"
#include "ambientLight.h"
#include "directionalLight.h"
#include "pointLight.h"
@ -802,40 +801,30 @@ prepare_lens() {
return false;
}
// lets get the lens perspective matrix
// Start with the projection matrix from the lens.
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;
// 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());
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;
// 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);
HRESULT hr;
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);
LMatrix4f new_projection_mat =
convert_mat * projection_mat * rescale_mat;
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);
HRESULT hr =
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);
}

View File

@ -28,8 +28,6 @@
#include "graphicsEngine.h"
#include "graphicsChannel.h"
#include "lens.h"
#include "perspectiveLens.h"
#include "orthographicLens.h"
#include "ambientLight.h"
#include "directionalLight.h"
#include "pointLight.h"
@ -1032,64 +1030,30 @@ prepare_lens() {
return false;
}
// lets get the lens perspective matrix
// Start with the projection matrix from the lens.
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.
// 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);
LMatrix4f new_projection_mat =
LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()) *
projection_mat;
float nearf = _current_lens->get_near();
float farf = _current_lens->get_far();
//dxgsg8_cat.debug() << new_projection_mat << endl;
HRESULT hr;
if (false && _current_lens->is_of_type(PerspectiveLens::get_class_type())) {
/*
const LMatrix4f mat_temp;
float vfov = _current_lens->get_vfov();
float hfov = _current_lens->get_hfov();
float ar = _current_lens->get_aspect_ratio();
float nearf = _current_lens->get_near();
float farf = _current_lens->get_far();
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;
*/
new_projection_mat(2, 2) = farf / (farf-nearf);
new_projection_mat(3, 2) = -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 if (false && _current_lens->is_of_type(OrthographicLens::get_class_type())) {
new_projection_mat(2, 2) = 1 / (farf - nearf);
new_projection_mat(3, 2) = -nearf / (farf - nearf);
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)new_projection_mat.get_data());
//dxgsg8_cat.debug() << new_projection_mat << endl;
//dxgsg8_cat.debug() << "using ortho projection" << endl;
} else {
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)new_projection_mat.get_data());
//dxgsg8_cat.debug() << new_projection_mat << endl;
//dxgsg8_cat.debug() << "using matrix projection" << endl;
}
convert_mat * projection_mat * rescale_mat;
HRESULT hr =
_pD3DDevice->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)new_projection_mat.get_data());
return SUCCEEDED(hr);
}

View File

@ -28,8 +28,6 @@
#include "graphicsEngine.h"
#include "graphicsChannel.h"
#include "lens.h"
#include "perspectiveLens.h"
#include "orthographicLens.h"
#include "ambientLight.h"
#include "directionalLight.h"
#include "pointLight.h"
@ -1047,64 +1045,30 @@ prepare_lens() {
return false;
}
// lets get the lens perspective matrix
// Start with the projection matrix from the lens.
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.
// 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);
LMatrix4f new_projection_mat =
LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()) *
projection_mat;
float nearf = _current_lens->get_near();
float farf = _current_lens->get_far();
//dxgsg9_cat.debug() << new_projection_mat << endl;
HRESULT hr;
if (false && _current_lens->is_of_type(PerspectiveLens::get_class_type())) {
/*
const LMatrix4f mat_temp;
float vfov = _current_lens->get_vfov();
float hfov = _current_lens->get_hfov();
float ar = _current_lens->get_aspect_ratio();
float nearf = _current_lens->get_near();
float farf = _current_lens->get_far();
double vfov_radian = vfov * 0.0174532925;
dxgsg9_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());
dxgsg9_cat.debug() << mat_temp << endl;
*/
new_projection_mat(2, 2) = farf / (farf-nearf);
new_projection_mat(3, 2) = -nearf * farf / (farf - nearf);
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)new_projection_mat.get_data());
//dxgsg9_cat.debug() << new_projection_mat << endl;
//dxgsg9_cat.debug() << "using perspective projection" << endl;
} else if (false && _current_lens->is_of_type(OrthographicLens::get_class_type())) {
new_projection_mat(2, 2) = 1 / (farf - nearf);
new_projection_mat(3, 2) = -nearf / (farf - nearf);
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)new_projection_mat.get_data());
//dxgsg9_cat.debug() << new_projection_mat << endl;
//dxgsg9_cat.debug() << "using ortho projection" << endl;
} else {
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)new_projection_mat.get_data());
//dxgsg9_cat.debug() << new_projection_mat << endl;
//dxgsg9_cat.debug() << "using matrix projection" << endl;
}
convert_mat * projection_mat * rescale_mat;
HRESULT hr =
_pD3DDevice->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)new_projection_mat.get_data());
return SUCCEEDED(hr);
}