From 1a8504fcd9641741d5309e12f341784154e3ac5f Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Tue, 3 Nov 2015 16:46:32 +0300 Subject: [PATCH] perspective projection, part 1 --- src/dlangui/graphics/gldrawbuf.d | 4 +-- src/dlangui/graphics/glsupport.d | 50 ++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/dlangui/graphics/gldrawbuf.d b/src/dlangui/graphics/gldrawbuf.d index a597a2eb..80377410 100644 --- a/src/dlangui/graphics/gldrawbuf.d +++ b/src/dlangui/graphics/gldrawbuf.d @@ -59,7 +59,7 @@ class GLDrawBuf : DrawBuf, GLConfigCallback { override void saveConfiguration() { } override void restoreConfiguration() { - glSupport.setOrthoProjection(_dx, _dy); + glSupport.setOrthoProjection(Rect(0, 0, _dx, _dy)); } /// reserved for hardware-accelerated drawing - begins drawing batch @@ -74,7 +74,7 @@ class GLDrawBuf : DrawBuf, GLConfigCallback { /// reserved for hardware-accelerated drawing - ends drawing batch override void afterDrawing() { - glSupport.setOrthoProjection(_dx, _dy); + glSupport.setOrthoProjection(Rect(0, 0, _dx, _dy)); _scene.draw(); glSupport.flushGL(); destroy(_scene); diff --git a/src/dlangui/graphics/glsupport.d b/src/dlangui/graphics/glsupport.d index 3c6137a7..822010a3 100644 --- a/src/dlangui/graphics/glsupport.d +++ b/src/dlangui/graphics/glsupport.d @@ -1089,13 +1089,53 @@ class GLSupport { qtmatrix[y * 4 + x] = m[y][x]; } - void setOrthoProjection(int dx, int dy) { - bufferDx = dx; - bufferDy = dy; - QMatrix4x4_ortho(0, dx, 0, dy, 0.5f, 50.0f); - glViewport(0, 0, dx, dy); + void QMatrix4x4_perspective(float angle, float aspect, float nearPlane, float farPlane) + { + import std.math; + // Bail out if the projection volume is zero-sized. + if (nearPlane == farPlane || aspect == 0.0f) + return; + + // Construct the projection. + float[4][4] m; + float radians = (angle / 2.0f) * PI / 180.0f; + float sine = sin(radians); + if (sine == 0.0f) + return; + float cotan = cos(radians) / sine; + float clip = farPlane - nearPlane; + m[0][0] = cotan / aspect; + m[1][0] = 0.0f; + m[2][0] = 0.0f; + m[3][0] = 0.0f; + m[0][1] = 0.0f; + m[1][1] = cotan; + m[2][1] = 0.0f; + m[3][1] = 0.0f; + m[0][2] = 0.0f; + m[1][2] = 0.0f; + m[2][2] = -(nearPlane + farPlane) / clip; + m[3][2] = -(2.0f * nearPlane * farPlane) / clip; + m[0][3] = 0.0f; + m[1][3] = 0.0f; + m[2][3] = -1.0f; + m[3][3] = 0.0f; + + for (int y = 0; y < 4; y++) + for (int x = 0; x < 4; x++) + qtmatrix[y * 4 + x] = m[y][x]; + } + + void setOrthoProjection(Rect view) { + bufferDx = view.width; + bufferDy = view.height; + QMatrix4x4_ortho(view.left, view.right, view.top, view.bottom, 0.5f, 50.0f); + glViewport(view.left, view.top, view.right, view.bottom); checkError("glViewport"); } + void setPerspectiveProjection(float fieldOfView, float aspectRatio, float nearPlane, float farPlane) { + // TODO + } }