Source code for gloopy.view.render

import logging

from OpenGL.GL.ARB.vertex_array_object import glBindVertexArray

import pyglet
from pyglet.event import EVENT_HANDLED
from pyglet import gl

from .glyph import Glyph
from .modelview import ModelView
from .projection import Projection
from .shader import Shader
from ..geom.vector import Vector
from ..geom.orientation import Orientation
from ..shapes.shape_to_glyph import shape_to_glyph


log = logging.getLogger(__name__)


[docs]def log_opengl_version(): ''' Send OpenGL version and driver info to logfile ''' log.info('\n '.join([ 'opengl:', gl.gl_info.get_vendor(), gl.gl_info.get_renderer(), gl.gl_info.get_version(), ]) )
[docs]class Render(object): ''' Render class does all the OpenGL rendering .. function:: __init__(window, camera, options) `world`: instance of :class:`~gloopy.world.World`. `window`: instance of pyglet Window class `camera`: gloopy camera (might be a GameItem instance) `options`: instance of :class:`~gloopy.util.options.Options`. '''
[docs] def __init__(self, world, window, camera, options): self.world = world self.window = window self.projection = Projection(window) self.modelview = ModelView(camera) self.options = options self._bind_shape_to_glyph() self.clock_display = pyglet.clock.ClockDisplay()
def _bind_shape_to_glyph(self): # adding items to the world should convert their shapes to a glyph def convert_item_shape_to_glyph(item): if item.shape: item.glyph = shape_to_glyph(item.shape) self.world.item_added += convert_item_shape_to_glyph
[docs] def init(self): ''' Set all initial OpenGL state, such as enabling DEPTH_TEST. Also loads a the lighting shader. ''' log_opengl_version() gl.glEnable(gl.GL_DEPTH_TEST) gl.glEnable(gl.GL_POLYGON_SMOOTH) gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glHint(gl.GL_POLYGON_SMOOTH_HINT, gl.GL_NICEST) self.backface_culling = True self.shader = Shader( 'lighting.vert', 'lighting.frag', attribs=['position', 'color', 'normal'] ) Glyph.shader = self.shader
def _set_backface_culling(self, value): self._backface_culling = value if self._backface_culling: gl.glCullFace(gl.GL_BACK) gl.glEnable(gl.GL_CULL_FACE) else: gl.glDisable(gl.GL_CULL_FACE) backface_culling = property( lambda s: s._backface_culling, _set_backface_culling, None, "Boolean property to get or set backface culling." )
[docs] def clear_window(self, color): ''' Clear window color and depth buffers, using the given color ''' r, g, b = color.as_floats()[:3] gl.glClearColor(r, g, b, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
[docs] def draw_window(self): ''' Redraw the whole window ''' self.clear_window(self.world.background_color) self.projection.set_perspective(45) self.modelview.set_world() with self.shader: self.draw_world_items() if self.options.fps: self.draw_hud() self.window.invalid = False return EVENT_HANDLED
[docs] def draw_world_items(self): ''' Draw all items that have been added to the world ''' for item in self.world: if not item.glyph: continue gl.glPushMatrix() if item.position and item.position != Vector.Origin: gl.glTranslatef(*item.position) if ( item.orientation and item.orientation != Orientation.Identity ): gl.glMultMatrixf(item.orientation.matrix) glBindVertexArray(item.glyph.vao) gl.glDrawElements( gl.GL_TRIANGLES, len(item.glyph.glindices), item.glyph.index_type, item.glyph.glindices ) gl.glPopMatrix() glBindVertexArray(0)
[docs] def draw_hud(self): ''' Draw any display items overlaid on the world, such as FPS counter ''' self.projection.set_screen() self.modelview.set_identity() gl.glEnableClientState(gl.GL_VERTEX_ARRAY) gl.glEnableClientState(gl.GL_COLOR_ARRAY) self.clock_display.draw() gl.glDisableClientState(gl.GL_VERTEX_ARRAY) gl.glDisableClientState(gl.GL_COLOR_ARRAY)