gengl.py :  » Game-2D-3D » PyOpenGL » PyOpenGL-3.0.1 » src » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Game 2D 3D » PyOpenGL 
PyOpenGL » PyOpenGL 3.0.1 » src » gengl.py
#!/usr/bin/env python
'''Hacked version of Pyglet's gengl that produces PyOpenGL-based modules

To use, you have to do an svn co of pyglet to get the "tools" directory,
add the package "wraptypes" to your site-packages and you should be able 
to run this script.

Note: currently the AGL module can only be generated on OS-X, GLX can only
be generated on a GLX platform (e.g. Linux), WGL should generate anywhere
as I'm using Alex's hacked/derived wgl.h as the source for it.

TODO:
    This wrapper is missing a lot of the operations from theoriginal import 
    openglgenerator module.  It's only appropriate for generating the 
    platform-specific modules (GLX, WGL, AGL).  Eventually should port 
    the code from theopenglgeneratormoduletosupportcreatingthe import 
    extensions and core GL modules.
'''
# Copyright (c) 2006-2008 Alex Holkner
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions 
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above copyright 
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
#  * Neither the name of pyglet nor the names of its
#    contributors may be used to endorse or promote products
#    derived from this software without specific prior written
#    permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
__docformat__ = 'restructuredtext'
__version__ = '$Id: gengl.py,v 1.3 2008/05/02 18:49:57 mcfletch Exp $'

import marshal
import optparse
import os.path
import urllib2
import sys
import textwrap
import re

# monkey-patching the tool to support argument names...
from wraptypes import ctypesparser
class CtypesFunction( ctypesparser.CtypesFunction ):
    def __init__(self, restype, parameters):
        if parameters and parameters[-1] == '...':
             parameters = parameters[:-1]    
        self.argnames = [ self.argname(p.declarator) for p in parameters ]
        super( CtypesFunction, self ).__init__( restype, parameters )
    def argname( self, parameter ):
        if not getattr( parameter, 'pointer', None ):
            return parameter
        else:
            return self.argname( parameter.pointer )
ctypesparser.CtypesFunction = CtypesFunction

from wraptypes import wrap

script_dir = os.path.abspath(os.path.dirname(__file__))

GLEXT_ABI_H = 'http://oss.sgi.com/projects/ogl-sample/ABI/glext.h'
GLEXT_NV_H = 'http://developer.download.nvidia.com/opengl/includes/glext.h'
GLXEXT_ABI_H = 'http://oss.sgi.com/projects/ogl-sample/ABI/glxext.h'
GLXEXT_NV_H = 'http://developer.download.nvidia.com/opengl/includes/glxext.h'
WGLEXT_ABI_H = 'http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h'
WGLEXT_NV_H = 'http://developer.download.nvidia.com/opengl/includes/wglext.h'

AGL_H = '/System/Library/Frameworks/AGL.framework/Headers/agl.h'
GL_H = '/usr/include/GL/gl.h'
GLU_H = '/usr/include/GL/glu.h'
GLX_H = '/usr/include/GL/glx.h'
WGL_H = os.path.join(script_dir, 'wgl.h')

CACHE_FILE = os.path.join(script_dir, '.gengl.cache')
_cache = {}


def load_cache():
    global _cache
    if os.path.exists(CACHE_FILE):
        try:
            _cache = marshal.load(open(CACHE_FILE, 'rb')) or {}
        except:
            pass
    _cache = {}

def save_cache():
    try:
        marshal.dump(_cache, open(CACHE_FILE, 'wb'))
    except:
        pass

def read_url(url):
    if url in _cache:
        return _cache[url]
    if os.path.exists(url):
        data = open(url).read()
    else:
        data = urllib2.urlopen(url).read()
    _cache[url] = data
    save_cache()
    return data

class GLWrapper(wrap.CtypesWrapper):
    requires = None
    requires_prefix = None

    def __init__(self, header, match_re):
        self.header = header
        self.match_re = match_re
        super(GLWrapper, self).__init__()
    def handle_declaration(self, declaration, filename, lineno):
        """Overridden solely to pass in the argument names"""
        t = wrap.get_ctypes_type(declaration.type, declaration.declarator)
        declarator = declaration.declarator
        if declarator is None:
            # XXX TEMPORARY while struct with no typedef not filled in
            return
        while declarator.pointer:
            declarator = declarator.pointer
        name = declarator.identifier
        if declaration.storage == 'typedef':
            self.handle_ctypes_type_definition(
                name, wrap.remove_function_pointer(t), filename, lineno)
        elif type(t) == CtypesFunction:
            # this is the line we override
            self.handle_ctypes_function(
                name, t.restype, t.argtypes, filename, lineno, t.argnames)
        elif declaration.storage != 'static':
            self.handle_ctypes_variable(name, t, filename, lineno)

    def print_preamble(self):
        import time
        print >> self.file, textwrap.dedent("""
            # This content is generated by %(script)s.
            # Wrapper for %(header)s
            from OpenGL import platform, constant
            from ctypes import *
            c_void = None
        """ % {
            'header': self.header,
            'date': time.ctime(),
            'script': __file__,
        }).lstrip()

    def libFromRequires( self, requires  ):
        return 'platform.GL'

    def handle_ctypes_function(self, name, restype, argtypes, filename, lineno, argnames):
        if self.does_emit(name, filename):
            self.emit_type(restype)
            for a in argtypes:
                self.emit_type(a)

            self.all_names.append(name)
            #print >> self.file, '# %s:%d' % (filename, lineno)
            print >> self.file, '''%(name)s = platform.createBaseFunction(
    %(name)r, dll=%(libname)s, resultType=%(returnType)s, 
    argTypes=[%(argTypes)s],
    doc=%(documentation)r, 
    argNames=%(argNames)r,
)'''%dict(
    name = name,
    libname = self.libFromRequires( self.requires  ),
    returnType = restype,
    argTypes = ', '.join([str(a) for a in argtypes]),
    documentation = self.documentation(
        name, argnames, argtypes, restype
    ),
    argNames = [str(x) for x in argnames],
)
            print >> self.file
    def documentation( self, name, argnames, args, returntype ):
        """Customisation point for documenting a given function"""
        return str("%s( %s ) -> %s"%(
            name,
            ", ".join(
                [ '%s(%s)'%( typ, name) for (typ,name) in zip(args,argnames) ]
            ),
            returntype,
        ))

    def handle_ifndef(self, name, filename, lineno):
        if (
            self.requires_prefix and 
            name[:len(self.requires_prefix)] == self.requires_prefix
        ):
            self.requires = name[len(self.requires_prefix):]
            print >> self.file, '# %s (%s:%d)'  % \
                (self.requires, filename, lineno)
    def handle_ctypes_constant(self, name, value, filename, lineno):
        if self.does_emit( name, filename ):
            print >> self.file, '%(name)s = constant.Constant( %(name)r, %(value)r )'%locals()
            self.all_names.append(name)
    def does_emit(self, symbol, filename):
        base = super( GLWrapper, self ).does_emit( symbol, filename )
        if base:
            if self.match_re:
                if self.match_re.match( symbol ):
                    return True 
                else:
                    return False 
        return base

def progress(msg):
    print >> sys.stderr, msg

marker_begin = '# BEGIN GENERATED CONTENT (do not edit below this line)\n'
marker_end = '# END GENERATED CONTENT (do not edit above this line)\n'

class ModuleWrapper(object):
    def __init__(
        self, header, filename,
        prologue='', requires_prefix=None, system_header=None,
        match_re=None,
    ):
        self.header = header
        self.filename = filename
        self.prologue = prologue
        self.requires_prefix = requires_prefix
        self.system_header = system_header
        self.match_re = match_re

    def wrap(self, dir):
        progress('Updating %s...' % self.filename)
        source = read_url(self.header) 
        filename = os.path.join(dir, self.filename)

        prologue = []
        epilogue = []
        state = 'prologue'
        try:
            for line in open(filename):
                if state == 'prologue':
                    prologue.append(line)
                    if line == marker_begin:
                        state = 'generated'
                elif state == 'generated':
                    if line == marker_end:
                        state = 'epilogue'
                        epilogue.append(line)
                elif state == 'epilogue':
                    epilogue.append(line)
        except IOError:
            prologue = [marker_begin]
            epilogue = [marker_end]
            state = 'epilogue'
        if state != 'epilogue':
            raise Exception('File exists, but generated markers are corrupt '
                            'or missing')

        outfile = open(filename, 'w')
        print >> outfile, ''.join(prologue)
        wrapper = GLWrapper(self.header, self.match_re)
        if self.system_header:
            wrapper.preprocessor_parser.system_headers[self.system_header] = \
                source
        header_name = self.system_header or self.header
        wrapper.requires_prefix = self.requires_prefix
        wrapper.begin_output(outfile, 
                             library=None,
                             emit_filenames=(header_name,))
        source = self.prologue + source
        wrapper.wrap(header_name, source)
        wrapper.end_output()
        print >> outfile, ''.join(epilogue)

modules = {
#  'gl':  
#    ModuleWrapper(GL_H, 'gl.py'),
#  'glu': 
#    ModuleWrapper(GLU_H, 'glu.py'),
#  'glext_arb': 
#    ModuleWrapper(GLEXT_ABI_H, 'glext_arb.py', 
#      requires_prefix='GL_', system_header='GL/glext.h',
#      prologue='#define GL_GLEXT_PROTOTYPES\n#include <GL/gl.h>\n'),
#  'glext_nv': 
#    ModuleWrapper(GLEXT_NV_H, 'glext_nv.py',
#      requires_prefix='GL_', system_header='GL/glext.h',
#      prologue='#define GL_GLEXT_PROTOTYPES\n#include <GL/gl.h>\n'),
    'glx': 
        ModuleWrapper(GLX_H, '_GLX.py', 
            requires_prefix='GLX_',
            match_re = re.compile( 'glX|GLX' ),
        ),
    'glx_arb': 
        ModuleWrapper(GLXEXT_ABI_H, '_GLX_ARB.py', requires_prefix='GLX_',
            system_header='GL/glxext.h',
            prologue='#define GLX_GLXEXT_PROTOTYPES\n#include <GL/glx.h>\n',
            match_re = re.compile( 'glX|GLX_' ),
        ),
    'glx_nv': 
        ModuleWrapper(GLXEXT_NV_H, '_GLX_NV.py', requires_prefix='GLX_',
            system_header='GL/glxext.h',
            prologue='#define GLX_GLXEXT_PROTOTYPES\n#include <GL/glx.h>\n',
            match_re = re.compile( 'glX|GLX_' ),
        ),
    'agl':
        ModuleWrapper(AGL_H, 'AGL.py'),
    'wgl':
        ModuleWrapper(WGL_H, '_WGL.py'),
    'wgl_arb':
        ModuleWrapper(WGLEXT_ABI_H, '_WGL_ARB.py', requires_prefix='WGL_',
            prologue='#define WGL_WGLEXT_PROTOTYPES\n'\
                     '#include "%s"\n' % WGL_H.encode('string_escape')),
    'wgl_nv':
        ModuleWrapper(WGLEXT_NV_H, '_WGL_NV.py', requires_prefix='WGL_',
            prologue='#define WGL_WGLEXT_PROTOTYPES\n'\
                     '#include "%s"\n' % WGL_H.encode('string_escape')),
}


if __name__ == '__main__':
    op = optparse.OptionParser()
    op.add_option('-D', '--dir', dest='dir',
                  help='output directory')
    op.add_option('-r', '--refresh-cache', dest='refresh_cache',
                  help='clear cache first', action='store_true')
    options, args = op.parse_args()

    if not options.refresh_cache:
        load_cache()
    else:
        save_cache()

    if not args:
        print >> sys.stderr, 'Specify module(s) to generate:'
        print >> sys.stderr, '  %s' % ' '.join(modules.keys())

    if not options.dir:
        options.dir = os.path.join(script_dir, os.path.pardir, 'OpenGL', 'raw')
    if not os.path.exists(options.dir):
        os.makedirs(options.dir)

    for arg in args:
        if arg not in modules:
            print >> sys.stderr, "Don't know how to make '%s'" % arg
            continue

        modules[arg].wrap(options.dir)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.