From 86adbefc018c98ff18d7c4f6f52d97b53f3537fc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alexis=20Laferri=C3=A8re?= Date: Tue, 19 Jan 2016 12:26:58 -0500 Subject: [PATCH] lib/gamnit depth: add stereoscopic view module MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- lib/gamnit/depth/stereoscopic_view.nit | 88 ++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 lib/gamnit/depth/stereoscopic_view.nit diff --git a/lib/gamnit/depth/stereoscopic_view.nit b/lib/gamnit/depth/stereoscopic_view.nit new file mode 100644 index 0000000..2857e7d --- /dev/null +++ b/lib/gamnit/depth/stereoscopic_view.nit @@ -0,0 +1,88 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Refine `EulerCamera` and `App::frame_core_draw` to get a stereoscopic view +module stereoscopic_view + +import depth +intrude import cameras + +redef class EulerCamera + redef var mvp_matrix = new Matrix.identity(4) + + # Half of the distance between the eyes + var eye_separation: Float = 0.03125 + + # MVP matrix for the left eye + fun mvp_matrix_left: Matrix do return mvp_matrix_eye(eye_separation) + + # MVP matrix for the right eye + fun mvp_matrix_right: Matrix do return mvp_matrix_eye(-eye_separation) + + # Get an MVP matrix for an eye at `diff` world unit from the center + private fun mvp_matrix_eye(diff: Float): Matrix + do + var view = new Matrix.identity(4) + + # Translate the world away from the camera + view.translate(-position.x/2.0, -position.y/2.0, -position.z/2.0) + + # Rotate the camera, first by looking left or right, then up or down + view = view * rotation_matrix + + # Apply eye transformation + var translation = new Matrix.identity(4) + translation.translate(diff, 0.0, 0.0) + view = view * translation + + # Use a projection matrix with a depth + var projection = new Matrix.perspective(pi*field_of_view_y/2.0, + display.aspect_ratio, near, far) + + return view * projection + end +end + +redef class GamnitDisplay + + # With stereoscopic view, the aspect ratio (in each eye) is half of the screen + redef fun aspect_ratio do return super / 2.0 +end + +redef class App + redef fun frame_core_draw(display) do frame_core_stereoscopic display + + # Split the screen in two, and call `frame_core_depth` for each eyes + protected fun frame_core_stereoscopic(display: GamnitDisplay) + do + var half_width = display.width / 2 + + # Left eye + glViewport(0, 0, half_width, display.height) + world_camera.mvp_matrix = world_camera.mvp_matrix_left + frame_core_depth display + + # Right eye + glViewport(half_width, 0, half_width, display.height) + world_camera.mvp_matrix = world_camera.mvp_matrix_right + frame_core_depth display + + # We reset the viewport for selection + glViewport(0, 0, display.width, display.height) + + # Check for errors + var gl_error = glGetError + assert gl_error == gl_NO_ERROR else print gl_error + end +end -- 1.7.9.5