From bf2f4cb236fcf7b6d5e637f820781cc5d20b94e1 Mon Sep 17 00:00:00 2001 From: Hleb Valoshka <375gnu@gmail.com> Date: Wed, 20 Nov 2019 20:34:54 +0300 Subject: [PATCH] Replace gluPerspective with own implementation --- src/celengine/render.cpp | 24 +++++++----------------- src/celengine/vecgl.h | 10 ++++++++++ src/celmath/geomutil.h | 28 ++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/celengine/render.cpp b/src/celengine/render.cpp index ce04b611..49eb2caa 100644 --- a/src/celengine/render.cpp +++ b/src/celengine/render.cpp @@ -2479,9 +2479,7 @@ void Renderer::draw(const Observer& observer, pixelSize = calcPixelSize(fov, (float) windowHeight); // Set up the projection we'll use for rendering stars. - gluPerspective(fov, - (float) windowWidth / (float) windowHeight, - NEAR_DIST, FAR_DIST); + glMatrix(Perspective(fov, getAspectRatio(), NEAR_DIST, FAR_DIST)); // Set the modelview matrix glMatrixMode(GL_MODELVIEW); @@ -3337,11 +3335,9 @@ void Renderer::draw(const Observer& observer, // Set up a perspective projection using the current interval's near and // far clip planes. glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(fov, - (float) windowWidth / (float) windowHeight, - nearPlaneDistance, - farPlaneDistance); + glLoadMatrix(Perspective(fov, getAspectRatio(), + nearPlaneDistance, + farPlaneDistance)); glMatrixMode(GL_MODELVIEW); Frustum intervalFrustum(degToRad(fov), @@ -3494,10 +3490,7 @@ void Renderer::draw(const Observer& observer, renderForegroundAnnotations(FontNormal); glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(fov, - (float) windowWidth / (float) windowHeight, - NEAR_DIST, FAR_DIST); + glLoadMatrix(Perspective(fov, getAspectRatio(), NEAR_DIST, FAR_DIST)); glMatrixMode(GL_MODELVIEW); if (!selectionVisible && (renderFlags & ShowMarkers)) @@ -6747,11 +6740,8 @@ void DSORenderer::process(DeepSkyObject* const & dso, glMatrixMode(GL_PROJECTION); glPushMatrix(); - glLoadIdentity(); - gluPerspective(fov, - (float) wWidth / (float) wHeight, - nearZ, - farZ); + float t = (float) wWidth / (float) wHeight; + glLoadMatrix(Perspective(fov, t, nearZ, farZ)); glMatrixMode(GL_MODELVIEW); } diff --git a/src/celengine/vecgl.h b/src/celengine/vecgl.h index 55a78755..08f75f15 100644 --- a/src/celengine/vecgl.h +++ b/src/celengine/vecgl.h @@ -77,6 +77,16 @@ inline void glMatrix(const Eigen::Matrix4d& m) glMultMatrixd(m.data()); } +inline void glLoadMatrix(const Eigen::Matrix4f& m) +{ + glLoadMatrixf(m.data()); +} + +inline void glLoadMatrix(const Eigen::Matrix4d& m) +{ + glLoadMatrixd(m.data()); +} + inline void glScale(const Eigen::Vector3f& scale) { glScalef(scale.x(), scale.y(), scale.z()); diff --git a/src/celmath/geomutil.h b/src/celmath/geomutil.h index 0aa51936..9ed8e720 100644 --- a/src/celmath/geomutil.h +++ b/src/celmath/geomutil.h @@ -87,6 +87,34 @@ Project(const Eigen::Matrix& from, return true; } +/*! Return an perspective projection matrix + */ +template Eigen::Matrix +Perspective(T fovy, T aspect, T nearZ, T farZ) +{ + if (aspect == T(0.0)) + return Eigen::Matrix::Identity(); + + T deltaZ = farZ - nearZ; + if (deltaZ == T(0.0)) + return Eigen::Matrix::Identity(); + + T angle = degToRad(fovy / 2); + T sine = sin(angle); + if (sine == T(0.0)) + return Eigen::Matrix::Identity(); + T ctg = cos(angle) / sine; + + Eigen::Matrix m = Eigen::Matrix::Identity(); + m(0, 0) = ctg / aspect; + m(1, 1) = ctg; + m(2, 2) = -(farZ + nearZ) / deltaZ; + m(2, 3) = T(-2.0) * nearZ * farZ / deltaZ; + m(3, 2) = T(-1.0); + m(3, 3) = T(0.0); + return m; +} + }; // namespace celmath #endif // _CELMATH_GEOMUTIL_H_