Mercurial > touhou
diff pytouhou/opengl/gamerenderer.pyx @ 131:fab7ad2f0d8b
Use Cython, improve performances!
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Sun, 11 Sep 2011 02:02:59 +0200 |
parents | pytouhou/opengl/gamerenderer.py@11ab06f4c4c6 |
children | 982b21222602 |
line wrap: on
line diff
copy from pytouhou/opengl/gamerenderer.py copy to pytouhou/opengl/gamerenderer.pyx --- a/pytouhou/opengl/gamerenderer.py +++ b/pytouhou/opengl/gamerenderer.pyx @@ -12,116 +12,55 @@ ## GNU General Public License for more details. ## -import struct -from itertools import chain +from libc.stdlib cimport malloc, free + import ctypes -import pyglet +import struct + from pyglet.gl import * from pytouhou.opengl.texture import TextureManager -from pytouhou.opengl.sprite import get_sprite_rendering_data +from pytouhou.opengl.sprite cimport get_sprite_rendering_data from pytouhou.opengl.background import get_background_rendering_data MAX_ELEMENTS = 10000 -class GameRenderer(pyglet.window.Window): +cdef struct Vertex: + float x, y, z + float u, v + unsigned char r, g, b, a + + +cdef class GameRenderer: + cdef public texture_manager + cdef public game + cdef public background + + cdef Vertex *vertex_buffer + + + def __cinit__(self, resource_loader, game=None, background=None): + # Allocate buffers + self.vertex_buffer = <Vertex*> malloc(MAX_ELEMENTS * sizeof(Vertex)) + + + def __dealloc__(self): + free(self.vertex_buffer) + + def __init__(self, resource_loader, game=None, background=None): - pyglet.window.Window.__init__(self, caption='PyTouhou', resizable=False) - self.keys = pyglet.window.key.KeyStateHandler() - self.push_handlers(self.keys) - self.texture_manager = TextureManager(resource_loader) - self.fps_display = pyglet.clock.ClockDisplay() - self.game = game self.background = background - def start(self, width=384, height=448): - self.set_size(width, height) - - # Initialize OpenGL - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - gluPerspective(30, float(width)/float(height), - 101010101./2010101., 101010101./10101.) - - glEnable(GL_BLEND) - glEnable(GL_TEXTURE_2D) - glEnable(GL_FOG) - glHint(GL_FOG_HINT, GL_NICEST) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) - glEnableClientState(GL_COLOR_ARRAY) - glEnableClientState(GL_VERTEX_ARRAY) - glEnableClientState(GL_TEXTURE_COORD_ARRAY) - - # Allocate buffers - buff = ctypes.c_buffer(MAX_ELEMENTS * 4 * (3 * 4 + 2 * 4 + 4)) - self.buffers = (buff, - ctypes.byref(buff, 3 * 4), - ctypes.byref(buff, 3 * 4 + 2 * 4)) - - # Use our own loop to ensure 60 (for now, 120) fps - pyglet.clock.set_fps_limit(120) - while not self.has_exit: - pyglet.clock.tick() - self.dispatch_events() - self.update() - self.on_draw() - self.flip() - - - def on_resize(self, width, height): - glViewport(0, 0, width, height) - + cdef render_elements(self, elements): + cdef unsigned short nb_vertices = 0 - def on_key_press(self, symbol, modifiers): - if symbol == pyglet.window.key.ESCAPE: - self.has_exit = True - # XXX: Fullscreen will be enabled the day pyglet stops sucking - elif symbol == pyglet.window.key.F11: - self.set_fullscreen(not self.fullscreen) - - - def update(self): - if self.background: - self.background.update(self.game.game_state.frame) - if self.game: - #TODO: allow user settings - keystate = 0 - if self.keys[pyglet.window.key.W]: - keystate |= 1 - if self.keys[pyglet.window.key.X]: - keystate |= 2 - #TODO: on some configurations, LSHIFT is Shift_L when pressed - # and ISO_Prev_Group when released, confusing the hell out of pyglet - # and leading to a always-on LSHIFT... - if self.keys[pyglet.window.key.LSHIFT]: - keystate |= 4 - if self.keys[pyglet.window.key.UP]: - keystate |= 16 - if self.keys[pyglet.window.key.DOWN]: - keystate |= 32 - if self.keys[pyglet.window.key.LEFT]: - keystate |= 64 - if self.keys[pyglet.window.key.RIGHT]: - keystate |= 128 - if self.keys[pyglet.window.key.LCTRL]: - keystate |= 256 - self.game.run_iter(keystate) #TODO: self.keys... - - - def render_elements(self, elements): - texture_manager = self.texture_manager - - pack_data = struct.Struct('fff ff BBBB' * 4).pack_into - _vertices, _uvs, _colors = self.buffers - - nb_vertices = 0 indices_by_texture = {} for element in elements: @@ -135,22 +74,10 @@ class GameRenderer(pyglet.window.Window) (x1, y1, z1), (x2, y2, z2), (x3, y3, z3), (x4, y4, z4) = vertices r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3, r4, g4, b4, a4 = colors u1, v1, u2, v2, u3, v3, u4, v4 = uvs - pack_data(_vertices, nb_vertices * (3 * 4 + 2 * 4 + 4), - x1 + ox, y1 + oy, z1, - u1, v1, - r1, g1, b1, a1, - - x2 + ox, y2 + oy, z2, - u2, v2, - r2, g2, b2, a2, - - x3 + ox, y3 + oy, z3, - u3, v3, - r3, g3, b3, a3, - - x4 + ox, y4 + oy, z4, - u4, v4, - r4, g4, b4, a4) + self.vertex_buffer[nb_vertices] = Vertex(x1 + ox, y1 + oy, z1, u1, v1, r1, g1, b1, a1) + self.vertex_buffer[nb_vertices+1] = Vertex(x2 + ox, y2 + oy, z2, u2, v2, r2, g2, b2, a2) + self.vertex_buffer[nb_vertices+2] = Vertex(x3 + ox, y3 + oy, z3, u3, v3, r3, g3, b3, a3) + self.vertex_buffer[nb_vertices+3] = Vertex(x4 + ox, y4 + oy, z4, u4, v4, r4, g4, b4, a4) # Add indices index = nb_vertices @@ -158,19 +85,19 @@ class GameRenderer(pyglet.window.Window) nb_vertices += 4 - glVertexPointer(3, GL_FLOAT, 24, _vertices) - glTexCoordPointer(2, GL_FLOAT, 24, _uvs) - glColorPointer(4, GL_UNSIGNED_BYTE, 24, _colors) + glVertexPointer(3, GL_FLOAT, 24, <long> &self.vertex_buffer[0].x) + glTexCoordPointer(2, GL_FLOAT, 24, <long> &self.vertex_buffer[0].u) + glColorPointer(4, GL_UNSIGNED_BYTE, 24, <long> &self.vertex_buffer[0].r) for (texture_key, blendfunc), indices in indices_by_texture.items(): nb_indices = len(indices) indices = struct.pack(str(nb_indices) + 'H', *indices) glBlendFunc(GL_SRC_ALPHA, (GL_ONE_MINUS_SRC_ALPHA, GL_ONE)[blendfunc]) - glBindTexture(GL_TEXTURE_2D, texture_manager[texture_key].id) + glBindTexture(GL_TEXTURE_2D, self.texture_manager[texture_key].id) glDrawElements(GL_QUADS, nb_indices, GL_UNSIGNED_SHORT, indices) - def on_draw(self): + def render(self): glClear(GL_DEPTH_BUFFER_BIT) back = self.background @@ -227,10 +154,3 @@ class GameRenderer(pyglet.window.Window) self.render_elements(game.players) glEnable(GL_FOG) - #TODO - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() - gluLookAt(192., 224., 835.979370, - 192, 224., 0., 0., 1., 0.) - self.fps_display.draw() -