# HG changeset patch # User Emmanuel Gil Peyrot # Date 1371054608 -7200 # Node ID 5fe6cd6ceb48f8ea65c0e0ded000ae047adf6450 # Parent 2428296cccab475329ff87f409a14387b10f39b7 Refactor the maths functions out of Renderer. diff --git a/pytouhou/ui/anmrenderer.py b/pytouhou/ui/anmrenderer.py --- a/pytouhou/ui/anmrenderer.py +++ b/pytouhou/ui/anmrenderer.py @@ -29,6 +29,7 @@ from pytouhou.game.sprite import Sprite from pytouhou.vm.anmrunner import ANMRunner from pytouhou.utils.helpers import get_logger +from pytouhou.utils.maths import perspective, setup_camera from .renderer import Renderer from .shaders.eosd import GameShader @@ -77,9 +78,9 @@ class ANMRenderer(pyglet.window.Window, glEnableClientState(GL_TEXTURE_COORD_ARRAY) # Switch to game projection - proj = self.perspective(30, float(self.width) / float(self.height), - 101010101./2010101., 101010101./10101.) - view = self.setup_camera(0, 0, 1) + proj = perspective(30, float(self.width) / float(self.height), + 101010101./2010101., 101010101./10101.) + view = setup_camera(0, 0, 1) if not self.use_fixed_pipeline: shader = GameShader() diff --git a/pytouhou/ui/gamerenderer.py b/pytouhou/ui/gamerenderer.py --- a/pytouhou/ui/gamerenderer.py +++ b/pytouhou/ui/gamerenderer.py @@ -22,6 +22,7 @@ from pyglet.gl import (glClear, glMatrix GL_FOG_END, GL_FOG_COLOR, GL_COLOR_BUFFER_BIT, GLfloat) from pytouhou.utils.matrix import Matrix +from pytouhou.utils.maths import setup_camera from .renderer import Renderer @@ -84,7 +85,7 @@ class GameRenderer(Renderer): model = Matrix() model.data[3] = [-x, -y, -z, 1] - view = self.setup_camera(dx, dy, dz) + view = setup_camera(dx, dy, dz) model_view_projection = model * view * self.proj mvp = model_view_projection.get_c_data() diff --git a/pytouhou/ui/gamerunner.py b/pytouhou/ui/gamerunner.py --- a/pytouhou/ui/gamerunner.py +++ b/pytouhou/ui/gamerunner.py @@ -25,7 +25,7 @@ from pyglet.gl import (glMatrixMode, glL GL_SCISSOR_TEST) from pytouhou.utils.helpers import get_logger -from pytouhou.utils.matrix import Matrix +from pytouhou.utils.maths import perspective, setup_camera, ortho_2d from .gamerenderer import GameRenderer from .music import MusicPlayer, SFXPlayer, NullPlayer @@ -109,11 +109,11 @@ class GameRunner(pyglet.window.Window, G glEnableClientState(GL_VERTEX_ARRAY) glEnableClientState(GL_TEXTURE_COORD_ARRAY) - self.proj = self.perspective(30, float(self.game.width) / float(self.game.height), - 101010101./2010101., 101010101./10101.) - game_view = self.setup_camera(0, 0, 1) + self.proj = perspective(30, float(self.game.width) / float(self.game.height), + 101010101./2010101., 101010101./10101.) + game_view = setup_camera(0, 0, 1) self.game_mvp = game_view * self.proj - self.interface_mvp = self.ortho_2d(0., float(self.width), float(self.height), 0.) + self.interface_mvp = ortho_2d(0., float(self.width), float(self.height), 0.) if self.fps_limit > 0: pyglet.clock.set_fps_limit(self.fps_limit) diff --git a/pytouhou/ui/renderer.pxd b/pytouhou/ui/renderer.pxd --- a/pytouhou/ui/renderer.pxd +++ b/pytouhou/ui/renderer.pxd @@ -20,7 +20,3 @@ cdef class Renderer: cpdef render_elements(self, elements) cpdef render_background(self) cpdef prerender_background(self, background) - cpdef ortho_2d(self, left, right, bottom, top) - cpdef look_at(self, eye, center, up) - cpdef perspective(self, fovy, aspect, zNear, zFar) - cpdef setup_camera(self, dx, dy, dz) diff --git a/pytouhou/ui/renderer.pyx b/pytouhou/ui/renderer.pyx --- a/pytouhou/ui/renderer.pyx +++ b/pytouhou/ui/renderer.pyx @@ -13,8 +13,6 @@ ## from libc.stdlib cimport malloc, free, realloc -from libc.math cimport tan -from math import radians from itertools import chain import ctypes @@ -32,8 +30,6 @@ from pyglet.gl import (glVertexPointer, from .sprite cimport get_sprite_rendering_data from .texture cimport TextureManager -from pytouhou.utils.matrix cimport Matrix -from pytouhou.utils.vector import Vector, normalize, cross, dot MAX_ELEMENTS = 640*4*3 @@ -172,58 +168,3 @@ cdef class Renderer: glBindBuffer(GL_ARRAY_BUFFER, self.back_vbo) glBufferData(GL_ARRAY_BUFFER, nb_vertices * sizeof(VertexFloat), &self.background_vertex_buffer[0], GL_STATIC_DRAW) glBindBuffer(GL_ARRAY_BUFFER, 0) - - - cpdef ortho_2d(self, left, right, bottom, top): - mat = Matrix() - data = mat.data - data[0][0] = 2 / (right - left) - data[1][1] = 2 / (top - bottom) - data[2][2] = -1 - data[3][0] = -(right + left) / (right - left) - data[3][1] = -(top + bottom) / (top - bottom) - return mat - - - cpdef look_at(self, eye, center, up): - eye = Vector(eye) - center = Vector(center) - up = Vector(up) - - f = normalize(center - eye) - u = normalize(up) - s = normalize(cross(f, u)) - u = cross(s, f) - - return Matrix([[s[0], u[0], -f[0], 0], - [s[1], u[1], -f[1], 0], - [s[2], u[2], -f[2], 0], - [-dot(s, eye), -dot(u, eye), dot(f, eye), 1]]) - - - cpdef perspective(self, fovy, aspect, z_near, z_far): - top = tan(radians(fovy / 2)) * z_near - bottom = -top - left = -top * aspect - right = top * aspect - - mat = Matrix() - data = mat.data - data[0][0] = (2 * z_near) / (right - left) - data[1][1] = (2 * z_near) / (top - bottom) - data[2][2] = -(z_far + z_near) / (z_far - z_near) - data[2][3] = -1 - data[3][2] = -(2 * z_far * z_near) / (z_far - z_near) - data[3][3] = 0 - return mat - - - cpdef setup_camera(self, dx, dy, dz): - # Some explanations on the magic constants: - # 192. = 384. / 2. = width / 2. - # 224. = 448. / 2. = height / 2. - # 835.979370 = 224./math.tan(math.radians(15)) = (height/2.)/math.tan(math.radians(fov/2)) - # This is so that objects on the (O, x, y) plane use pixel coordinates - return self.look_at((192., 224., - 835.979370 * dz), - (192. + dx, 224. - dy, 0.), (0., -1., 0.)) - diff --git a/pytouhou/utils/maths.pxd b/pytouhou/utils/maths.pxd new file mode 100644 --- /dev/null +++ b/pytouhou/utils/maths.pxd @@ -0,0 +1,4 @@ +cpdef ortho_2d(left, right, bottom, top) +cpdef look_at(eye, center, up) +cpdef perspective(fovy, aspect, zNear, zFar) +cpdef setup_camera(dx, dy, dz) diff --git a/pytouhou/utils/maths.pyx b/pytouhou/utils/maths.pyx new file mode 100644 --- /dev/null +++ b/pytouhou/utils/maths.pyx @@ -0,0 +1,73 @@ +# -*- encoding: utf-8 -*- +## +## Copyright (C) 2013 Emmanuel Gil Peyrot +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published +## by the Free Software Foundation; version 3 only. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +from math import radians +from libc.math cimport tan + +from .matrix cimport Matrix +from .vector import Vector, normalize, cross, dot + + +cpdef ortho_2d(left, right, bottom, top): + mat = Matrix() + data = mat.data + data[0][0] = 2 / (right - left) + data[1][1] = 2 / (top - bottom) + data[2][2] = -1 + data[3][0] = -(right + left) / (right - left) + data[3][1] = -(top + bottom) / (top - bottom) + return mat + + +cpdef look_at(eye, center, up): + eye = Vector(eye) + center = Vector(center) + up = Vector(up) + + f = normalize(center - eye) + u = normalize(up) + s = normalize(cross(f, u)) + u = cross(s, f) + + return Matrix([[s[0], u[0], -f[0], 0], + [s[1], u[1], -f[1], 0], + [s[2], u[2], -f[2], 0], + [-dot(s, eye), -dot(u, eye), dot(f, eye), 1]]) + + +cpdef perspective(fovy, aspect, z_near, z_far): + top = tan(radians(fovy / 2)) * z_near + bottom = -top + left = -top * aspect + right = top * aspect + + mat = Matrix() + data = mat.data + data[0][0] = (2 * z_near) / (right - left) + data[1][1] = (2 * z_near) / (top - bottom) + data[2][2] = -(z_far + z_near) / (z_far - z_near) + data[2][3] = -1 + data[3][2] = -(2 * z_far * z_near) / (z_far - z_near) + data[3][3] = 0 + return mat + + +cpdef setup_camera(dx, dy, dz): + # Some explanations on the magic constants: + # 192. = 384. / 2. = width / 2. + # 224. = 448. / 2. = height / 2. + # 835.979370 = 224./math.tan(math.radians(15)) = (height/2.)/math.tan(math.radians(fov/2)) + # This is so that objects on the (O, x, y) plane use pixel coordinates + return look_at((192., 224., - 835.979370 * dz), + (192. + dx, 224. - dy, 0.), (0., -1., 0.)) diff --git a/pytouhou/utils/matrix.pyx b/pytouhou/utils/matrix.pyx --- a/pytouhou/utils/matrix.pyx +++ b/pytouhou/utils/matrix.pyx @@ -95,4 +95,3 @@ cdef class Matrix: sin_a = sin(angle) d1[0], d1[1] = ([cos_a * d1[0][i] - sin_a * d1[1][i] for i in range(4)], [sin_a * d1[0][i] + cos_a * d1[1][i] for i in range(4)]) -