<s> '''<STR_LIT>''' <EOL> __docformat__ = '<STR_LIT>' <EOL> __version__ = '<STR_LIT>' <EOL> import ctypes <EOL> import re <EOL> from pyglet . gl import * <EOL> from pyglet . graphics import allocation , vertexattribute , vertexbuffer <EOL> _usage_format_re = re . compile ( r'''<STR_LIT>''' , re . VERBOSE ) <EOL> _gl_usages = { <EOL> '<STR_LIT>' : GL_STATIC_DRAW , <EOL> '<STR_LIT>' : GL_DYNAMIC_DRAW , <EOL> '<STR_LIT>' : GL_STREAM_DRAW , <EOL> '<STR_LIT:none>' : GL_STREAM_DRAW_ARB , <EOL> } <EOL> def _nearest_pow2 ( v ) : <EOL> v -= <NUM_LIT:1> <EOL> v |= v >> <NUM_LIT:1> <EOL> v |= v >> <NUM_LIT:2> <EOL> v |= v >> <NUM_LIT:4> <EOL> v |= v >> <NUM_LIT:8> <EOL> v |= v >> <NUM_LIT:16> <EOL> return v + <NUM_LIT:1> <EOL> def create_attribute_usage ( format ) : <EOL> '''<STR_LIT>''' <EOL> match = _usage_format_re . match ( format ) <EOL> attribute_format = match . group ( '<STR_LIT>' ) <EOL> attribute = vertexattribute . create_attribute ( attribute_format ) <EOL> usage = match . group ( '<STR_LIT>' ) <EOL> if usage : <EOL> vbo = not usage == '<STR_LIT:none>' <EOL> usage = _gl_usages [ usage ] <EOL> else : <EOL> usage = GL_DYNAMIC_DRAW <EOL> vbo = True <EOL> return ( attribute , usage , vbo ) <EOL> def create_domain ( * attribute_usage_formats ) : <EOL> '''<STR_LIT>''' <EOL> attribute_usages = [ create_attribute_usage ( f ) for f in attribute_usage_formats ] <EOL> return VertexDomain ( attribute_usages ) <EOL> def create_indexed_domain ( * attribute_usage_formats ) : <EOL> '''<STR_LIT>''' <EOL> attribute_usages = [ create_attribute_usage ( f ) for f in attribute_usage_formats ] <EOL> return IndexedVertexDomain ( attribute_usages ) <EOL> class VertexDomain ( object ) : <EOL> '''<STR_LIT>''' <EOL> _version = <NUM_LIT:0> <EOL> _initial_count = <NUM_LIT:16> <EOL> def __init__ ( self , attribute_usages ) : <EOL> self . allocator = allocation . Allocator ( self . _initial_count ) <EOL> have_multi_texcoord = False <EOL> for attribute , _ , _ in attribute_usages : <EOL> if isinstance ( attribute , vertexattribute . MultiTexCoordAttribute ) : <EOL> have_multi_texcoord = True <EOL> break <EOL> static_attributes = [ ] <EOL> attributes = [ ] <EOL> self . buffer_attributes = [ ] <EOL> for attribute , usage , vbo in attribute_usages : <EOL> if ( have_multi_texcoord and <EOL> isinstance ( attribute , vertexattribute . TexCoordAttribute ) ) : <EOL> attribute . convert_to_multi_tex_coord_attribute ( ) <EOL> if usage == GL_STATIC_DRAW : <EOL> static_attributes . append ( attribute ) <EOL> attributes . append ( attribute ) <EOL> else : <EOL> attributes . append ( attribute ) <EOL> attribute . buffer = vertexbuffer . create_mappable_buffer ( <EOL> attribute . stride * self . allocator . capacity , <EOL> usage = usage , vbo = vbo ) <EOL> attribute . buffer . element_size = attribute . stride <EOL> attribute . buffer . attributes = ( attribute , ) <EOL> self . buffer_attributes . append ( <EOL> ( attribute . buffer , ( attribute , ) ) ) <EOL> if static_attributes : <EOL> vertexattribute . interleave_attributes ( static_attributes ) <EOL> stride = static_attributes [ <NUM_LIT:0> ] . stride <EOL> buffer = vertexbuffer . create_mappable_buffer ( <EOL> stride * self . allocator . capacity , usage = GL_STATIC_DRAW ) <EOL> buffer . element_size = stride <EOL> self . buffer_attributes . append ( <EOL> ( buffer , static_attributes ) ) <EOL> attributes . extend ( static_attributes ) <EOL> for attribute in static_attributes : <EOL> attribute . buffer = buffer <EOL> self . attributes = attributes <EOL> self . attribute_names = { } <EOL> for attribute in attributes : <EOL> if isinstance ( attribute , vertexattribute . GenericAttribute ) : <EOL> index = attribute . index <EOL> if '<STR_LIT>' not in self . attribute_names : <EOL> self . attribute_names [ '<STR_LIT>' ] = { } <EOL> assert index not in self . attribute_names [ '<STR_LIT>' ] , '<STR_LIT>' % index <EOL> self . attribute_names [ '<STR_LIT>' ] [ index ] = attribute <EOL> elif isinstance ( attribute , vertexattribute . MultiTexCoordAttribute ) : <EOL> texture = attribute . texture <EOL> if '<STR_LIT>' not in self . attribute_names : <EOL> self . attribute_names [ '<STR_LIT>' ] = { } <EOL> assert texture not in self . attribute_names [ '<STR_LIT>' ] , '<STR_LIT>' % texture <EOL> self . attribute_names [ '<STR_LIT>' ] [ texture ] = attribute <EOL> else : <EOL> name = attribute . plural <EOL> assert name not in self . attributes , '<STR_LIT>' % name <EOL> self . attribute_names [ name ] = attribute <EOL> def __del__ ( self ) : <EOL> for attribute in self . attributes : <EOL> try : <EOL> del attribute . buffer <EOL> except AttributeError : <EOL> pass <EOL> def _safe_alloc ( self , count ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> return self . allocator . alloc ( count ) <EOL> except allocation . AllocatorMemoryException , e : <EOL> capacity = _nearest_pow2 ( e . requested_capacity ) <EOL> self . _version += <NUM_LIT:1> <EOL> for buffer , _ in self . buffer_attributes : <EOL> buffer . resize ( capacity * buffer . element_size ) <EOL> self . allocator . set_capacity ( capacity ) <EOL> return self . allocator . alloc ( count ) <EOL> def _safe_realloc ( self , start , count , new_count ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> return self . allocator . realloc ( start , count , new_count ) <EOL> except allocation . AllocatorMemoryException , e : <EOL> capacity = _nearest_pow2 ( e . requested_capacity ) <EOL> self . _version += <NUM_LIT:1> <EOL> for buffer , _ in self . buffer_attributes : <EOL> buffer . resize ( capacity * buffer . element_size ) <EOL> self . allocator . set_capacity ( capacity ) <EOL> return self . allocator . realloc ( start , count , new_count ) <EOL> def create ( self , count ) : <EOL> '''<STR_LIT>''' <EOL> start = self . _safe_alloc ( count ) <EOL> return VertexList ( self , start , count ) <EOL> def draw ( self , mode , vertex_list = None ) : <EOL> '''<STR_LIT>''' <EOL> glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ) <EOL> for buffer , attributes in self . buffer_attributes : <EOL> buffer . bind ( ) <EOL> for attribute in attributes : <EOL> attribute . enable ( ) <EOL> attribute . set_pointer ( attribute . buffer . ptr ) <EOL> if vertexbuffer . _workaround_vbo_finish : <EOL> glFinish ( ) <EOL> if vertex_list is not None : <EOL> glDrawArrays ( mode , vertex_list . start , vertex_list . count ) <EOL> else : <EOL> starts , sizes = self . allocator . get_allocated_regions ( ) <EOL> primcount = len ( starts ) <EOL> if primcount == <NUM_LIT:0> : <EOL> pass <EOL> elif primcount == <NUM_LIT:1> : <EOL> glDrawArrays ( mode , starts [ <NUM_LIT:0> ] , sizes [ <NUM_LIT:0> ] ) <EOL> elif gl_info . have_version ( <NUM_LIT:1> , <NUM_LIT:4> ) : <EOL> starts = ( GLint * primcount ) ( * starts ) <EOL> sizes = ( GLsizei * primcount ) ( * sizes ) <EOL> glMultiDrawArrays ( mode , starts , sizes , primcount ) <EOL> else : <EOL> for start , size in zip ( starts , sizes ) : <EOL> glDrawArrays ( mode , start , size ) <EOL> for buffer , _ in self . buffer_attributes : <EOL> buffer . unbind ( ) <EOL> glPopClientAttrib ( ) <EOL> def _is_empty ( self ) : <EOL> return not self . allocator . starts <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . __class__ . __name__ , id ( self ) , <EOL> self . allocator ) <EOL> class VertexList ( object ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , domain , start , count ) : <EOL> self . domain = domain <EOL> self . start = start <EOL> self . count = count <EOL> def get_size ( self ) : <EOL> '''<STR_LIT>''' <EOL> return self . count <EOL> def get_domain ( self ) : <EOL> '''<STR_LIT>''' <EOL> return self . domain <EOL> def draw ( self , mode ) : <EOL> '''<STR_LIT>''' <EOL> self . domain . draw ( mode , self ) <EOL> def resize ( self , count ) : <EOL> '''<STR_LIT>''' <EOL> new_start = self . domain . _safe_realloc ( self . start , self . count , count ) <EOL> if new_start != self . start : <EOL> for attribute in self . domain . attributes : <EOL> old = attribute . get_region ( attribute . buffer , <EOL> self . start , self . count ) <EOL> new = attribute . get_region ( attribute . buffer , <EOL> new_start , self . count ) <EOL> new . array [ : ] = old . array [ : ] <EOL> new . invalidate ( ) <EOL> self . start = new_start <EOL> self . count = count <EOL> self . _colors_cache_version = None <EOL> self . _fog_coords_cache_version = None <EOL> self . _edge_flags_cache_version = None <EOL> self . _normals_cache_version = None <EOL> self . _secondary_colors_cache_version = None <EOL> self . _tex_coords_cache_version = None <EOL> self . _vertices_cache_version = None <EOL> def delete ( self ) : <EOL> '''<STR_LIT>''' <EOL> self . domain . allocator . dealloc ( self . start , self . count ) <EOL> def migrate ( self , domain ) : <EOL> '''<STR_LIT>''' <EOL> assert domain . attribute_names . keys ( ) == self . domain . attribute_names . keys ( ) , '<STR_LIT>' <EOL> new_start = domain . _safe_alloc ( self . count ) <EOL> for key , old_attribute in self . domain . attribute_names . items ( ) : <EOL> old = old_attribute . get_region ( old_attribute . buffer , <EOL> self . start , self . count ) <EOL> new_attribute = domain . attribute_names [ key ] <EOL> new = new_attribute . get_region ( new_attribute . buffer , <EOL> new_start , self . count ) <EOL> new . array [ : ] = old . array [ : ] <EOL> new . invalidate ( ) <EOL> self . domain . allocator . dealloc ( self . start , self . count ) <EOL> self . domain = domain <EOL> self . start = new_start <EOL> self . _colors_cache_version = None <EOL> self . _fog_coords_cache_version = None <EOL> self . _edge_flags_cache_version = None <EOL> self . _normals_cache_version = None <EOL> self . _secondary_colors_cache_version = None <EOL> self . _tex_coords_cache_version = None <EOL> self . _vertices_cache_version = None <EOL> def _set_attribute_data ( self , i , data ) : <EOL> attribute = self . domain . attributes [ i ] <EOL> region = attribute . get_region ( attribute . buffer , self . start , self . count ) <EOL> region . array [ : ] = data <EOL> region . invalidate ( ) <EOL> def _get_colors ( self ) : <EOL> if ( self . _colors_cache_version != self . domain . _version ) : <EOL> domain = self . domain <EOL> attribute = domain . attribute_names [ '<STR_LIT>' ] <EOL> self . _colors_cache = attribute . get_region ( <EOL> attribute . buffer , self . start , self . count ) <EOL> self . _colors_cache_version = domain . _version <EOL> region = self . _colors_cache <EOL> region . invalidate ( ) <EOL> return region . array <EOL> def _set_colors ( self , data ) : <EOL> self . _get_colors ( ) [ : ] = data <EOL> _colors_cache = None <EOL> _colors_cache_version = None <EOL> colors = property ( _get_colors , _set_colors , <EOL> doc = '''<STR_LIT>''' ) <EOL> def _get_fog_coords ( self ) : <EOL> if ( self . _fog_coords_cache_version != self . domain . _version ) : <EOL> domain = self . domain <EOL> attribute = domain . attribute_names [ '<STR_LIT>' ] <EOL> self . _fog_coords_cache = attribute . get_region ( <EOL> attribute . buffer , self . start , self . count ) <EOL> self . _fog_coords_cache_version = domain . _version <EOL> region = self . _fog_coords_cache <EOL> region . invalidate ( ) <EOL> return region . array <EOL> def _set_fog_coords ( self , data ) : <EOL> self . _get_fog_coords ( ) [ : ] = data <EOL> _fog_coords_cache = None <EOL> _fog_coords_cache_version = None <EOL> fog_coords = property ( _get_fog_coords , _set_fog_coords , <EOL> doc = '''<STR_LIT>''' ) <EOL> def _get_edge_flags ( self ) : <EOL> if ( self . _edge_flags_cache_version != self . domain . _version ) : <EOL> domain = self . domain <EOL> attribute = domain . attribute_names [ '<STR_LIT>' ] <EOL> self . _edge_flags_cache = attribute . get_region ( <EOL> attribute . buffer , self . start , self . count ) <EOL> self . _edge_flags_cache_version = domain . _version <EOL> region = self . _edge_flags_cache <EOL> region . invalidate ( ) <EOL> return region . array <EOL> def _set_edge_flags ( self , data ) : <EOL> self . _get_edge_flags ( ) [ : ] = data <EOL> _edge_flags_cache = None <EOL> _edge_flags_cache_version = None <EOL> edge_flags = property ( _get_edge_flags , _set_edge_flags , <EOL> doc = '''<STR_LIT>''' ) <EOL> def _get_normals ( self ) : <EOL> if ( self . _normals_cache_version != self . domain . _version ) : <EOL> domain = self . domain <EOL> attribute = domain . attribute_names [ '<STR_LIT>' ] <EOL> self . _normals_cache = attribute . get_region ( <EOL> attribute . buffer , self . start , self . count ) <EOL> self . _normals_cache_version = domain . _version <EOL> region = self . _normals_cache <EOL> region . invalidate ( ) <EOL> return region . array <EOL> def _set_normals ( self , data ) : <EOL> self . _get_normals ( ) [ : ] = data <EOL> _normals_cache = None <EOL> _normals_cache_version = None <EOL> normals = property ( _get_normals , _set_normals , <EOL> doc = '''<STR_LIT>''' ) <EOL> def _get_secondary_colors ( self ) : <EOL> if ( self . _secondary_colors_cache_version != self . domain . _version ) : <EOL> domain = self . domain <EOL> attribute = domain . attribute_names [ '<STR_LIT>' ] <EOL> self . _secondary_colors_cache = attribute . get_region ( <EOL> attribute . buffer , self . start , self . count ) <EOL> self . _secondary_colors_cache_version = domain . _version <EOL> region = self . _secondary_colors_cache <EOL> region . invalidate ( ) <EOL> return region . array <EOL> def _set_secondary_colors ( self , data ) : <EOL> self . _get_secondary_colors ( ) [ : ] = data <EOL> _secondary_colors_cache = None <EOL> _secondary_colors_cache_version = None <EOL> secondary_colors = property ( _get_secondary_colors , _set_secondary_colors , <EOL> doc = '''<STR_LIT>''' ) <EOL> _tex_coords_cache = None <EOL> _tex_coords_cache_version = None <EOL> def _get_tex_coords ( self ) : <EOL> if ( self . _tex_coords_cache_version != self . domain . _version ) : <EOL> domain = self . domain <EOL> attribute = domain . attribute_names [ '<STR_LIT>' ] <EOL> self . _tex_coords_cache = attribute . get_region ( <EOL> attribute . buffer , self . start , self . count ) <EOL> self . _tex_coords_cache_version = domain . _version <EOL> region = self . _tex_coords_cache <EOL> region . invalidate ( ) <EOL> return region . array <EOL> def _set_tex_coords ( self , data ) : <EOL> self . _get_tex_coords ( ) [ : ] = data <EOL> tex_coords = property ( _get_tex_coords , _set_tex_coords , <EOL> doc = '''<STR_LIT>''' ) <EOL> _vertices_cache = None <EOL> _vertices_cache_version = None <EOL> def _get_vertices ( self ) : <EOL> if ( self . _vertices_cache_version != self . domain . _version ) : <EOL> domain = self . domain <EOL> attribute = domain . attribute_names [ '<STR_LIT>' ] <EOL> self . _vertices_cache = attribute . get_region ( <EOL> attribute . buffer , self . start , self . count ) <EOL> self . _vertices_cache_version = domain . _version <EOL> region = self . _vertices_cache <EOL> region . invalidate ( ) <EOL> return region . array <EOL> def _set_vertices ( self , data ) : <EOL> self . _get_vertices ( ) [ : ] = data <EOL> vertices = property ( _get_vertices , _set_vertices , <EOL> doc = '''<STR_LIT>''' ) <EOL> class IndexedVertexDomain ( VertexDomain ) : <EOL> '''<STR_LIT>''' <EOL> _initial_index_count = <NUM_LIT:16> <EOL> def __init__ ( self , attribute_usages , index_gl_type = GL_UNSIGNED_INT ) : <EOL> super ( IndexedVertexDomain , self ) . __init__ ( attribute_usages ) <EOL> self . index_allocator = allocation . Allocator ( self . _initial_index_count ) <EOL> self . index_gl_type = index_gl_type <EOL> self . index_c_type = vertexattribute . _c_types [ index_gl_type ] <EOL> self . index_element_size = ctypes . sizeof ( self . index_c_type ) <EOL> self . index_buffer = vertexbuffer . create_mappable_buffer ( <EOL> self . index_allocator . capacity * self . index_element_size , <EOL> target = GL_ELEMENT_ARRAY_BUFFER ) <EOL> def _safe_index_alloc ( self , count ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> return self . index_allocator . alloc ( count ) <EOL> except allocation . AllocatorMemoryException , e : <EOL> capacity = _nearest_pow2 ( e . requested_capacity ) <EOL> self . _version += <NUM_LIT:1> <EOL> self . index_buffer . resize ( capacity * self . index_element_size ) <EOL> self . index_allocator . set_capacity ( capacity ) <EOL> return self . index_allocator . alloc ( count ) <EOL> def _safe_index_realloc ( self , start , count , new_count ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> return self . index_allocator . realloc ( start , count , new_count ) <EOL> except allocation . AllocatorMemoryException , e : <EOL> capacity = _nearest_pow2 ( e . requested_capacity ) <EOL> self . _version += <NUM_LIT:1> <EOL> self . index_buffer . resize ( capacity * self . index_element_size ) <EOL> self . index_allocator . set_capacity ( capacity ) <EOL> return self . index_allocator . realloc ( start , count , new_count ) <EOL> def create ( self , count , index_count ) : <EOL> '''<STR_LIT>''' <EOL> start = self . _safe_alloc ( count ) <EOL> index_start = self . _safe_index_alloc ( index_count ) <EOL> return IndexedVertexList ( self , start , count , index_start , index_count ) <EOL> def get_index_region ( self , start , count ) : <EOL> '''<STR_LIT>''' <EOL> byte_start = self . index_element_size * start <EOL> byte_count = self . index_element_size * count <EOL> ptr_type = ctypes . POINTER ( self . index_c_type * count ) <EOL> return self . index_buffer . get_region ( byte_start , byte_count , ptr_type ) <EOL> def draw ( self , mode , vertex_list = None ) : <EOL> '''<STR_LIT>''' <EOL> glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ) <EOL> for buffer , attributes in self . buffer_attributes : <EOL> buffer . bind ( ) <EOL> for attribute in attributes : <EOL> attribute . enable ( ) <EOL> attribute . set_pointer ( attribute . buffer . ptr ) <EOL> self . index_buffer . bind ( ) <EOL> if vertexbuffer . _workaround_vbo_finish : <EOL> glFinish ( ) <EOL> if vertex_list is not None : <EOL> glDrawElements ( mode , vertex_list . index_count , self . index_gl_type , <EOL> self . index_buffer . ptr + <EOL> vertex_list . index_start * self . index_element_size ) <EOL> else : <EOL> starts , sizes = self . index_allocator . get_allocated_regions ( ) <EOL> primcount = len ( starts ) <EOL> if primcount == <NUM_LIT:0> : <EOL> pass <EOL> elif primcount == <NUM_LIT:1> : <EOL> glDrawElements ( mode , sizes [ <NUM_LIT:0> ] , self . index_gl_type , <EOL> self . index_buffer . ptr + starts [ <NUM_LIT:0> ] ) <EOL> elif gl_info . have_version ( <NUM_LIT:1> , <NUM_LIT:4> ) : <EOL> starts = [ s * self . index_element_size + self . index_buffer . ptr for s in starts ] <EOL> starts = ctypes . cast ( ( GLuint * primcount ) ( * starts ) , ctypes . POINTER ( ctypes . c_void_p ) ) <EOL> sizes = ( GLsizei * primcount ) ( * sizes ) <EOL> glMultiDrawElements ( mode , sizes , GL_UNSIGNED_INT , starts , <EOL> primcount ) <EOL> else : <EOL> for start , size in zip ( starts , sizes ) : <EOL> glDrawElements ( mode , size , self . index_gl_type , <EOL> self . index_buffer . ptr + <EOL> start * self . index_element_size ) <EOL> self . index_buffer . unbind ( ) <EOL> for buffer , _ in self . buffer_attributes : <EOL> buffer . unbind ( ) <EOL> glPopClientAttrib ( ) <EOL> class IndexedVertexList ( VertexList ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , domain , start , count , index_start , index_count ) : <EOL> super ( IndexedVertexList , self ) . __init__ ( domain , start , count ) <EOL> self . index_start = index_start <EOL> self . index_count = index_count <EOL> def draw ( self , mode ) : <EOL> self . domain . draw ( mode , self ) <EOL> def resize ( self , count , index_count ) : <EOL> '''<STR_LIT>''' <EOL> old_start = self . start <EOL> super ( IndexedVertexList , self ) . resize ( count ) <EOL> if old_start != self . start : <EOL> diff = self . start - old_start <EOL> self . indices [ : ] = map ( lambda i : i + diff , self . indices ) <EOL> new_start = self . domain . _safe_index_realloc ( <EOL> self . index_start , self . index_count , index_count ) <EOL> if new_start != self . index_start : <EOL> old = self . domain . get_index_region ( <EOL> self . index_start , self . index_count ) <EOL> new = self . domain . get_index_region ( <EOL> self . index_start , self . index_count ) <EOL> new . array [ : ] = old . array [ : ] <EOL> new . invalidate ( ) <EOL> self . index_start = new_start <EOL> self . index_count = index_count <EOL> self . _indices_cache_version = None <EOL> def delete ( self ) : <EOL> '''<STR_LIT>''' <EOL> super ( IndexedVertexList , self ) . delete ( ) <EOL> self . domain . index_allocator . dealloc ( self . index_start , self . index_count ) <EOL> def _set_index_data ( self , data ) : <EOL> region = self . domain . get_index_region ( <EOL> self . index_start , self . index_count ) <EOL> region . array [ : ] = data <EOL> region . invalidate ( ) <EOL> def _get_indices ( self ) : <EOL> if self . _indices_cache_version != self . domain . _version : <EOL> domain = self . domain <EOL> self . _indices_cache = domain . get_index_region ( <EOL> self . index_start , self . index_count ) <EOL> self . _indices_cache_version = domain . _version <EOL> region = self . _indices_cache <EOL> region . invalidate ( ) <EOL> return region . array <EOL> def _set_indices ( self , data ) : <EOL> self . _get_indices ( ) [ : ] = data <EOL> _indices_cache = None <EOL> _indices_cache_version = None <EOL> indices = property ( _get_indices , _set_indices , <EOL> doc = '''<STR_LIT>''' ) </s>
