def enum(self, element, context=None): if isinstance(context, EnumNamespace): name, value = as_str(element.get("name")), element.get("value") enum = Enum(name, value) context.append(enum) self.enumeration_set[name] = enum elif isinstance(context, (Require, Remove)): context.append(self.enumeration_set[element.get("name")]) elif isinstance(context, EnumGroup): name = element.get("name") assert name, "No name on %s" % ET.tostring(element) context.append(as_str(name))
def SFString( self, table, buffer): '''Return the (escaped) string as a simple Python string''' ((tag, start, stop, sublist),) = table result = [] for element in sublist: if element[0] == 'CHARNODBLQUOTE': result.append( as_str(buffer[element[1]:element[2]]) ) elif element[0] == 'ESCAPEDCHAR': result.append( as_str(buffer[element[1]+1:element[2]]) ) elif element[0] == 'SIMPLEBACKSLASH': result.append( as_str('\\') ) return "".join( result )
def compile(self, mode, shader=None): """Compile into GLSL linked object""" holder = self.holderDepend(mode.cache.holder(self, None)) # TODO: depend on shader.material as well... # TODO: the compiled shader needs to depend on *everything* # down the set of objects... program = glCreateProgram() holder.data = program subShaders = [] for shader in self.shaders: # TODO: cache links... subShader = shader.compile() if subShader: glAttachShader(program, subShader) subShaders.append(subShader) elif shader.source: log.warning( 'Failure compiling: %s\n%s', as_str(shader.compileLog), shader.url or "".join([as_str(s) for s in shader.source])) return None if len(subShaders) == len(self.shaders): glLinkProgram(program) glUseProgram(program) # TODO: retrieve maximum texture count and restrict to that... i = 0 for texture in self.textures: if texture.bind(self, mode, i): i += 1 glValidateProgram(program) validation = glGetProgramiv(program, GL_VALIDATE_STATUS) if validation == GL_FALSE: self.compileLog += """Validation failure (%s): %s""" % ( validation, glGetProgramInfoLog(program), ) program = False else: link_status = glGetProgramiv(program, GL_LINK_STATUS) if link_status == GL_FALSE: self.compileLog += """Link failure (%s): %s""" % ( link_status, glGetProgramInfoLog(program), ) program = False for subShader in subShaders: glDeleteShader(subShader) holder.data = program return program else: log.debug('Not done loading shader source yet') holder.data = 0 return None
def MFString( self, tuples, buffer ): bigresult = [] for (tag, start, stop, sublist) in tuples: result = [] for element in sublist: if element[0] == 'CHARNODBLQUOTE': result.append( as_str(buffer[element[1]:element[2]]) ) elif element[0] == 'ESCAPEDCHAR': result.append( as_str(buffer[element[1]+1:element[2]]) ) elif element[0] == 'SIMPLEBACKSLASH': result.append( '\\' ) bigresult.append( "".join( result) ) return bigresult
def loadBackground(self, client, url, contexts): overall = [None] * len(url) threads = [] for i, value in enumerate(url): import threading t = threading.Thread( name="Background load of %s" % (value), target=self.subLoad, args=(client, value, i, overall), ) t.start() threads.append(t) for t in threads: t.join() result = [x for x in overall if x is not None] if len(result) == len(overall): client.source = '\n'.join([as_str(r) for r in result]) # TODO: make this an observation that causes the # contexts to redraw, *not* something the node does # explicitly... for c_holder in contexts: c = c_holder() if c: c.triggerRedraw(1) return
def getVariable(self, name): """Retrieve uniform/attribute by name""" name = as_str(name) for uniform in self.uniforms: if uniform.name == name: return uniform return None
def captureEvents(self, eventType, manager=None): """Temporarily capture events of a particular type. This temporarily replaces a particular manager within the dispatch set with provided manager. This will normally be used to create "modal" interfaces such as active drag functions (where the interface is in a different "interaction mode", so that actions have different meaning than in the "default mode"). Passing None as the manager will restore the previous manager to functioning. Note: this function does not perform a "system capture" of input (that is, mouse movements are only available if they occur over the context's window and that window has focus). Note: for capturing mouse input, you will likely want to capture both movement and button events, it should be possible to define a single handler to deal with both event types, and pass that handler twice, once for each event type. """ eventType = as_str(eventType) if manager: previous = self.addEventManager(eventType, manager) self.__uncaptureDict[eventType] = previous else: previous = self.__uncaptureDict.get(eventType) self.addEventManager(eventType, previous) if previous: del self.__uncaptureDict[eventType]
def enums(self, element, context=None): name = as_str(element.get("namespace")) if name not in self.enum_namespaces: namespace = EnumNamespace(name) self.enum_namespaces[name] = namespace else: namespace = self.enum_namespaces[name] self.dispatch(element, namespace)
def main(displayfunc, api): major, minor = ctypes.c_long(), ctypes.c_long() display = eglGetDisplay(EGL_DEFAULT_DISPLAY) log.info("Display return value: %s", display) log.info("Display address: %s", display.address) #display = display.as_voidp #print "wrapped", display if not eglInitialize(display, major, minor): log.error("Unable to initialize") return log.info("EGL version %s.%s", major.value, minor.value) num_configs = ctypes.c_long() eglGetConfigs(display, None, 0, num_configs) log.info("%s configs", num_configs.value) configs = (EGLConfig * num_configs.value)() eglGetConfigs(display, configs, num_configs.value, num_configs) for config_id in configs: #print config_id describe_config(display, config_id) log.info("Attempting to bind and create contexts/apis") try: eglBindAPI(0x3333) # junk value except GLError: pass else: assert False, "Should have generated error on bind to non-existent api" eglBindAPI(api) # now need to get a raw X window handle... pygame.init() pygame.display.set_mode((500, 500)) window = pygame.display.get_wm_info()["window"] surface = eglCreateWindowSurface(display, configs[0], window, None) ctx = eglCreateContext(display, configs[0], EGL_NO_CONTEXT, None) if ctx == EGL_NO_CONTEXT: log.error("Unable to create the regular context") return else: log.info("Created regular context") def _displayfunc(): displayfunc(display, surface, ctx) mainloop(_displayfunc) pbufAttribs = (EGLint * 5)(*[EGL_WIDTH, 500, EGL_HEIGHT, 500, EGL_NONE]) pbuffer = eglCreatePbufferSurface(display, configs[0], pbufAttribs) if (pbuffer == EGL_NO_SURFACE): log.error("Unable to create pbuffer surface") else: log.info("created pbuffer surface") log.info( "Available EGL extensions:\n %s", "\n ".join( [as_str(ext) for ext in EGLQuerier.getExtensions().split()]))
def main(displayfunc, api): major,minor = ctypes.c_long(),ctypes.c_long() display = eglGetDisplay(EGL_DEFAULT_DISPLAY) log.info( 'Display return value: %s', display ) log.info( 'Display address: %s', display.address) #display = display.as_voidp #print 'wrapped', display if not eglInitialize( display, major, minor): log.error( 'Unable to initialize' ) return log.info( 'EGL version %s.%s', major.value,minor.value) num_configs = ctypes.c_long() eglGetConfigs(display, None, 0, num_configs) log.info( '%s configs', num_configs.value) configs = (EGLConfig * num_configs.value)() eglGetConfigs(display,configs,num_configs.value,num_configs) for config_id in configs: #print config_id describe_config( display, config_id ) log.info( 'Attempting to bind and create contexts/apis' ) try: eglBindAPI( 0x3333 ) # junk value except GLError: pass else: assert False, "Should have generated error on bind to non-existent api" eglBindAPI(api) # now need to get a raw X window handle... pygame.init() pygame.display.set_mode( (500,500) ) window = pygame.display.get_wm_info()['window'] surface = eglCreateWindowSurface(display, configs[0], window, None ) ctx = eglCreateContext(display, configs[0], EGL_NO_CONTEXT, None) if ctx == EGL_NO_CONTEXT: log.error( 'Unable to create the regular context' ) return else: log.info( 'Created regular context' ) def _displayfunc( ): displayfunc( display, surface, ctx ) mainloop( _displayfunc ) pbufAttribs = (EGLint * 5)(* [EGL_WIDTH,500, EGL_HEIGHT, 500, EGL_NONE]) pbuffer = eglCreatePbufferSurface(display, configs[0], pbufAttribs); if (pbuffer == EGL_NO_SURFACE): log.error( 'Unable to create pbuffer surface' ) else: log.info( 'created pbuffer surface' ) log.info( 'Available EGL extensions:\n %s', "\n ".join([ as_str(ext) for ext in EGLQuerier.getExtensions().split() ]))
def command(self, element, context=None): """Parse command definition into structured format""" proto = element.find("proto") if proto is not None: name = as_str(proto.find("name").text) assert name, "No name in command: %s" % (ET.tostring(element)) return_type = self._type_decl(proto) assert return_type, "No return type in command: %s" % ( ET.tostring(element)) arg_names = [] arg_types = [] lengths = {} groups = {} for param in [x for x in element if x.tag == "param"]: pname = as_str(param.find("name").text) arg_names.append(pname) arg_types.append(self._type_decl(param)) if param.get("len"): length = param.get("len") while length.endswith("*1"): length = length[:-2] length = LENGTH_OVERRIDES.get(name, {}).get(pname, length) lengths[pname] = length if param.get("group"): groups[pname] = param.get("group") aliases = [] for alias in [x for x in element if x.tag == "alias"]: aliases.append(alias.get("name")) # Process lengths to look for output parameters outputs = self.output_mapping.get(name) command = Command(name, return_type, arg_names, arg_types, aliases, lengths, groups, outputs=outputs) self.command_set[name] = command elif isinstance(context, (Require, Remove)): context.append(self.command_set[element.get("name")])
def render(self, mode, shader=None): """Render our shaders in the current mode""" renderer = mode.cache.getData(self) if renderer is None: renderer = self.compile(mode, shader) if renderer is False: log.warn( """%s""", self.compileLog, ) if renderer not in (None, False): try: GL_shaders.glUseProgram(renderer) except error.GLError: log.error( '''Failure compiling/linking: %s''', '\n'.join([ '%s: %s' % (as_str(sh.url or sh.source), as_str(sh.compileLog)) for sh in self.shaders ])) raise else: for uniform in mode.uniforms: uniform.render(self, mode) for uniform in self.uniforms: try: uniform.render(self, mode) except Exception as err: err.args += (uniform, self) raise # TODO: retrieve maximum texture count and restrict to that... i = 0 for texture in self.textures: if texture.render(self, mode, i): i += 1 else: log.info('Renderer for %s was null (likely loading): %s', self, self.compileLog) return True, True, True, None return True, True, True, renderer
def getLocation(self, mode, name, uniform=True): """Retrieve attribute/uniform location""" name = as_str(name) locationMap = mode.cache.getData(self, 'locationMap') if locationMap is None: locationMap = {} mode.cache.holder(self, locationMap, 'locationMap') self.holderDepend( mode.cache.holder(self, locationMap, 'locationMap')) try: return locationMap[name] except KeyError as err: program = self.program(mode) if program: try: if uniform: location = glGetUniformLocation( program, as_8_bit(name)) else: location = glGetAttribLocation(program, as_8_bit(name)) except error.GLError as err: if err.err == GL_INVALID_VALUE: self.compileLog += """Attribute access failure (%s): %s""" % ( name, glGetProgramInfoLog(program), ) program = False raise RuntimeError(self.compileLog) raise locationMap[name] = location if location == -1: log.info('Unable to resolve uniform name %s', as_str(name)) return location else: raise RuntimeError( 'Attempting to get attribute/uniform from failed compile')
def registerCallback(self, name=None, state=0, modifiers=(0, 0, 0), function=None): """Register a function to receive keyboard events matching the given specification To deregister, pass None as the function. name -- string name for the key in which you are interested if this is None, the entire key is None and will be matched only after all other names fail. Valid Values: characters > 32 and < 256 '<return>', '<tab>' '<insert>', '<delete>', '<up>','<down>', '<left>','<right>', '<pageup>','<pagedown>', '<home>','<end>', '<escape>', '<start>', '<numlock>', '<scroll>', '<capslock>', '<F1>' to '<F12>', to '<F24>' on some platforms '<shift>', '<ctrl>', '<alt>' Note: the characters are reported as their "lowercase" values, though the key might be known as "B" to the underlying system. Note: the names are always the "un-shifted" keys, that is, on a US keyboard, you'll never get "&" as the event name, you'll get "7" with the modifiers showing shift as being down. state -- key state (0 = up, 1 = down) function -- function taking a single argument (a KeyboardEvent) or None to deregister the callback. returns the previous handler or None """ if name is not None: key = as_str(name), state, modifiers else: key = None return super(KeyboardEventManager, self).registerCallback(key, function)
def parse(self, data, baseURL, *args, **named): """Parse the loaded data (with the provided meta-information)""" self.LOCK.acquire() try: success, results, next = _parser.parse( as_str(data), processor=parseprocessor.ParseProcessor( basePrototypes=self.prototypes, baseURI=baseURL, )) if success: sg = results[1] else: sg = None return success, sg finally: self.LOCK.release()
def addEventHandler(self, eventType, *arguments, **namedarguments): """Add a new event handler function for the given event type This is the primary client API for dealing with the event system. Each event class will define a particular set of data values required to form the routing key for the event. Each event handler class will define a registerCallback function which converts its arguments into a matching key. This function merely determines the appropriate handler then dispatches to the handler's registerCallback method (without the eventType argument). See: mouseevents, keyboardevents """ manager = self.getEventManager(as_str(eventType)) if manager: manager.registerCallback(*arguments, **namedarguments) else: raise KeyError("""Unrecognised EventManager type %s""" % (repr(eventType)))
def registerCallback(self, name=None, modifiers=(0, 0, 0), function=None): """Register a function to receive keyboard events matching the given specification To deregister, pass None as the function. name -- string name for the key in which you are interested if this is None, the entire key is None and will be matched only after all other names fail. Valid Values: characters > 32 and < 256 '<return>', '<tab>' '<insert>', '<delete>', '<up>','<down>', '<left>','<right>', '<pageup>','<pagedown>', '<home>','<end>', '<escape>', '<F1>' to '<F12>', to '<F24>' on some platforms Note: Attempts will be made to convert the character to the "real" character typed (i.e. if shift is down you should get 'F' instead of 'f' unless caps-lock is also down). This is going to be fragile because it may require trying to figure it out just from the modifier states, and that won't work across keyboard types. modifiers -- (shift, control, alt) as a tuple of booleans. function -- function taking a single argument (a KeypressEvent) or None to deregister the callback. returns the previous handler or None """ if name is not None: key = as_str(name), modifiers else: key = None return super(KeypressEventManager, self).registerCallback(key, function)
def getString( *args, **named ): base = _getString(*args,**named) return as_str(base)
def gl_usage(self): return self.GL_USAGE_MAPPING[as_str(self.usage)]
def name(self, value): value = as_str(value) self._name = value return self._name
def output_wrapping(self): """Generate output wrapping statements for our various functions""" try: statements = [] for function in self.registry.commands(): dependencies = function.size_dependencies if dependencies: # temporarily just do single-output functions... base = [] for param, dependency in sorted(dependencies.items()): param = as_str(param) if isinstance(dependency, xmlreg.Output): statements.append( f"# {function.name}.{param} is OUTPUT without known output size" ) if isinstance(dependency, xmlreg.Staticsize): base.append( f".setOutput({param}, size=({dependency},), orPassIn=True)" ) elif isinstance(dependency, xmlreg.Dynamicsize): base.append( f".setOutput({param}, size=lambda x:(x,), pnameArg={dependency}, orPassIn=True)" ) elif isinstance(dependency, xmlreg.Multiple): pname, multiple = dependency base.append( f".setOutput({param}, size=lambda x:(x, {multiple}), pnameArg={pname}, orPassIn=True)" ) elif isinstance(dependency, xmlreg.Compsize): if len(dependency) == 1: pname = dependency[0] base.append( f".setOutput({param}, size=_glgets._glget_size_mapping, " "pnameArg={pname}, orPassIn=True)") else: statements.append( f"# OUTPUT {function.name}.{param} COMPSIZE({', '.join(dependency)})" ) elif isinstance(dependency, xmlreg.StaticInput): base.append( f".setInputArraySize({param}, {dependency})") elif isinstance(dependency, (xmlreg.DynamicInput, xmlreg.MultipleInput, xmlreg.Input)): if dependency is None: continue statements.append( f"# INPUT {function.name}.{param} size not checked against {dependency}" ) base.append(f".setInputArraySize({param}, None)") if base: base.insert( 0, f"{function.name.lstrip('gl')} = wrapper.wrapper({function.name})" ) # ^ rip that C namespace nonsese off and use the python namespace # - glVertex3d -> gl.Vertex3d statements.append("".join(base)) return "\n".join(statements) except Exception: traceback.print_exc() import pdb pdb.set_trace()
def __init__(self, registry, overall, api=None): self.registry = registry self.overall = overall name = registry.name if name in ("GL_ES_VERSION_3_1", "GL_ES_VERSION_3_0"): api = "gles3" name = "GLES3" + name[5:] if api: self.prefix = api.upper() else: if hasattr(self.registry, "api"): self.prefix = self.registry.api.upper() else: self.prefix = name.split("_")[0] name = name.split("_", 1)[1] try: self.owner, self.module = name.split("_", 1) self.sentinelConstant = f"{self.owner}_{self.module}" except ValueError: if name.endswith("SGIX"): self.prefix = "GL" self.owner = "SGIX" self.module = name[3:-4] self.sentinelConstant = f"{self.module}{self.owner}" else: log.error(f"""Unable to parse module name: {name}""") raise self.dll = f"_p.PLATFORM.{self.prefix}" if self.module[0].isdigit(): self.module = f"{self.prefix}_{self.module}" if self.module == "async": self.module = "async_" self.camelModule = "".join([x.title() for x in self.module.split("_")]) self.rawModule = self.module self.rawOwner = self.owner while self.owner and self.owner[0].isdigit(): self.owner = self.owner[1:] self.rawPathName = os.path.join(self.overall.raw_target_directory, self.prefix, self.owner, self.module + ".py") self.pathName = os.path.join(self.overall.target_directory, self.prefix, self.owner, self.module + ".py") self.constant_module = f"{self.prefix}_{self.owner}_{self.rawModule}" specification = self.getSpecification() self.constantsFromSpec() self.overview = "" if self.overall.include_overviews: for title, section in specification.blocks(specification.source): if title.startswith("Overview"): if isinstance(section, bytes): section = section.decode( "latin-1" ) # seems to not be utf; at least in some cases s = indent( as_unicode( as_str(section).replace("\xd4", "O").replace( "\xd5", "O")).encode("ascii", "ignore").decode( "ascii", "ignore")) self.overview = f"Overview (from the spec)\n{s}\n\n" break
def output_wrapping(self): """Generate output wrapping statements for our various functions""" try: statements = [] for function in self.registry.commands(): dependencies = function.size_dependencies if dependencies: # temporarily just do single-output functions... base = [] for param, dependency in sorted(dependencies.items()): param = as_str(param) if isinstance(dependency, xmlreg.Output): statements.append( '# %s.%s is OUTPUT without known output size' % ( function.name, param, )) if isinstance(dependency, xmlreg.Staticsize): base.append( '.setOutput(\n %(param)r,size=(%(dependency)r,),orPassIn=True\n)' % locals()) elif isinstance(dependency, xmlreg.Dynamicsize): base.append( '.setOutput(\n %(param)r,size=lambda x:(x,),pnameArg=%(dependency)r,orPassIn=True\n)' % locals()) elif isinstance(dependency, xmlreg.Multiple): pname, multiple = dependency base.append( '.setOutput(\n %(param)r,size=lambda x:(x,%(multiple)s),pnameArg=%(pname)r,orPassIn=True\n)' % locals()) elif isinstance(dependency, xmlreg.Compsize): if len(dependency) == 1: pname = dependency[0] base.append( '.setOutput(\n %(param)r,size=_glgets._glget_size_mapping,pnameArg=%(pname)r,orPassIn=True\n)' % locals()) else: statements.append( '# OUTPUT %s.%s COMPSIZE(%s) ' % (function.name, param, ', '.join(dependency))) elif isinstance(dependency, xmlreg.StaticInput): base.append( '.setInputArraySize(\n %(param)r, %(dependency)s\n)' % locals()) elif isinstance(dependency, (xmlreg.DynamicInput, xmlreg.MultipleInput, xmlreg.Input)): if dependency is None: continue statements.append( '# INPUT %s.%s size not checked against %s' % (function.name, param, dependency)) base.append( '.setInputArraySize(\n %(param)r, None\n)' % locals()) if base: base.insert( 0, '%s=wrapper.wrapper(%s)' % (function.name, function.name)) statements.append(''.join(base)) return '\n'.join(statements) except Exception as err: traceback.print_exc() import pdb pdb.set_trace()
def __init__(self, registry, overall, api=None): self.registry = registry self.overall = overall name = registry.name if name in ('GL_ES_VERSION_3_1', 'GL_ES_VERSION_3_0'): api = 'gles3' name = 'GLES3' + name[5:] if api: self.prefix = api.upper() else: if hasattr(self.registry, 'api'): self.prefix = self.registry.api.upper() else: self.prefix = name.split('_')[0] name = name.split('_', 1)[1] try: self.owner, self.module = name.split('_', 1) self.sentinelConstant = '%s_%s' % (self.owner, self.module) except ValueError: if name.endswith('SGIX'): self.prefix = "GL" self.owner = 'SGIX' self.module = name[3:-4] self.sentinelConstant = '%s%s' % (self.module, self.owner) else: log.error("""Unable to parse module name: %s""", name) raise self.dll = '_p.PLATFORM.%s' % (self.prefix, ) if self.module[0].isdigit(): self.module = '%s_%s' % ( self.prefix, self.module, ) if self.module == 'async': self.module = 'async_' self.camelModule = "".join([x.title() for x in self.module.split('_')]) self.rawModule = self.module self.rawOwner = self.owner while self.owner and self.owner[0].isdigit(): self.owner = self.owner[1:] self.rawPathName = os.path.join(self.overall.rawTargetDirectory, self.prefix, self.owner, self.module + '.py') self.pathName = os.path.join(self.overall.targetDirectory, self.prefix, self.owner, self.module + '.py') self.constantModule = '%(prefix)s_%(owner)s_%(rawModule)s' % self specification = self.getSpecification() self.constantsFromSpec() self.overview = '' if self.overall.includeOverviews: for title, section in specification.blocks(specification.source): if title.startswith('Overview'): if isinstance(section, bytes): section = section.decode( 'latin-1' ) # seems not to be utf in at lest some cases self.overview = 'Overview (from the spec)\n%s\n\n' % ( indent( as_unicode( as_str(section).replace('\xd4', 'O').replace( '\xd5', 'O')).encode( 'ascii', 'ignore').decode( 'ascii', 'ignore'))) break
def gl_target(self): return self.GL_TYPE_MAPPING[as_str(self.type)]
def type(self, element, context=None): name = element.get("name") if not name: name = element.find("name").text self.type_set[as_str(name)] = element