initial version

This commit is contained in:
josch 2008-11-23 21:07:47 +01:00
commit 242d4a972b
107 changed files with 86684 additions and 0 deletions

409
extract.py Normal file
View file

@ -0,0 +1,409 @@
#!/usr/bin/python
"""
homm3lodextract - extract data from heroes of might and magic 3 lod
archives and convert pcx images and def animations to png
images
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import zlib, os
import struct
import sys
import Image, ImageDraw
def read_frame_3(width, height, data):
length = height*width/32 #length of scanline
#UNSIGNED short here!!
offsets = struct.unpack("%dH"%length, data[:length*2])
offsets += (len(data),)
raw = ""
for i in xrange(len(offsets)-1):
line = data[offsets[i]:offsets[i+1]]
pos = 0
while pos < len(line):
count = ord(line[pos])
if 0x00 <= count <= 0x1F: #empty
raw += '\x00'*(count+1)
pos +=1
elif 0x20 <= count <= 0x3F: #light shadow
raw += '\x01'*(count-31)
pos +=1
elif 0x40 <= count <= 0x5F: #only used in Tshre.def and AvGnoll.def
raw += '\x02'*(count-63)
pos +=1
elif 0x60 <= count <= 0x7F: #only used in Tshre.def
raw += '\x03'*(count-95)
pos +=1
elif 0x80 <= count <= 0x9F: #strong shadow
raw += '\x04'*(count-127)
pos +=1
elif 0xA0 <= count <= 0xBF: #replaced by player color
raw += '\x05'*(count-159)
pos +=1
elif 0xE0 <= count <= 0xFF: #normal colors
raw += line[pos+1:pos+count-222]
pos += count-222
else:
raise Exception("%02X"%count)
return raw
def read_frame_1(width, height, data):
try:
offsets = struct.unpack("%di"%height, data[:height*4])
except:
#this failes for SGTWMTB.def
print "cannot read scanline offses"
return None
offsets += (len(data),)
raw = ""
for i in xrange(len(offsets)-1):
line = data[offsets[i]:offsets[i+1]]
pos = 0
while pos < len(line):
try:
count = ord(line[pos+1])+1
except IndexError:
#this failes for SGTWMTA.def, SGTWMTB.def
print "cannot read scanline"
return None
if ord(line[pos]) is 0xFF:
raw+=line[pos+2:pos+2+count]
pos+=2+count
else:
raw+=line[pos]*count
pos+=2
return raw
def save_frame(path, num, data, palette, width, height, fname):
(data_size, frame_type, fwidth, fheight, img_width, img_height, offset_x,
offset_y) = struct.unpack("8i", data[0:32])
#this only does not match in OVSLOT.def
if width != fwidth:
print "frame width %d does not match def width %d"%(fwidth, width)
if height != fheight:
print "frame height %d does not match def height %d"%(fheight, height)
data = data[32:32+data_size]
if frame_type is 0:
#type 0 is raw indexed image data
buffer = data
elif frame_type is 1:
buffer = read_frame_1(img_width, img_height, data)
elif frame_type is 2:
#this is seldomly used and seems to decode fine using type3
buffer = read_frame_3(img_width, img_height, data)
elif frame_type is 3:
buffer = read_frame_3(img_width, img_height, data)
else:
raise Exception("frame type %d not supported"%frame_type)
if buffer is not None:
im = Image.new("P", (fwidth, fheight), 0x00)
im.paste(
Image.frombuffer(
'RGB',
(img_width, img_height),
buffer,
'raw', 'P', 0, 1),
(offset_x, offset_y))
if fname == "clrrvr.def":
path = os.path.join(path, "%d"%num)
if not os.path.exists(path):
os.makedirs(path)
for i in xrange(12):
im.putpalette(palette[:189*3]
+palette[201*3-i*3:201*3]
+palette[189*3:201*3-i*3]
+palette[201*3:])
im2 = im.convert("RGBA")
data = im2.load()
for x in xrange(im.size[0]):
for y in xrange(im.size[1]):
if data[x, y] == (0, 255, 255, 255):
data[x, y] = (0, 0, 0, 0)
if os.path.exists(os.path.join(path, "%d.png"%i)):
print "overwriting %s" % os.path.join(path, "%d.png"%i)
im2.save(os.path.join(path, "%d.png"%i), "PNG")
elif fname == "lavrvr.def":
path = os.path.join(path, "%d"%num)
if not os.path.exists(path):
os.makedirs(path)
for i in xrange(9):
im.putpalette(palette[:240*3]
+palette[249*3-i*3:249*3]
+palette[240*3:249*3-i*3]
+palette[249*3:])
im2 = im.convert("RGBA")
data = im2.load()
for x in xrange(im.size[0]):
for y in xrange(im.size[1]):
if data[x, y] == (0, 255, 255, 255):
data[x, y] = (0, 0, 0, 0)
if os.path.exists(os.path.join(path, "%d.png"%i)):
print "overwriting %s" % os.path.join(path, "%d.png"%i)
im2.save(os.path.join(path, "%d.png"%i), "PNG")
elif fname == "mudrvr.def":
path = os.path.join(path, "%d"%num)
if not os.path.exists(path):
os.makedirs(path)
for i in xrange(12):
im.putpalette(palette[:228*3]
+palette[240*3-i*3:240*3]
+palette[228*3:240*3-i*3]
+palette[240*3:])
im2 = im.convert("RGBA")
data = im2.load()
for x in xrange(im.size[0]):
for y in xrange(im.size[1]):
if data[x, y] == (0, 255, 255, 255):
data[x, y] = (0, 0, 0, 0)
if os.path.exists(os.path.join(path, "%d.png"%i)):
print "overwriting %s" % os.path.join(path, "%d.png"%i)
im2.save(os.path.join(path, "%d.png"%i), "PNG")
elif fname == "watrtl.def":
path = os.path.join(path, "%d"%num)
if not os.path.exists(path):
os.makedirs(path)
for i in xrange(12):
im.putpalette(palette[:229*3]
+palette[241*3-i*3:241*3]
+palette[229*3:241*3-i*3]
+palette[241*3:242*3]
+palette[254*3-i*3:254*3]
+palette[242*3:254*3-i*3]
+palette[254*3:])
if os.path.exists(os.path.join(path, "%d.png"%i)):
print "overwriting %s" % os.path.join(path, "%d.png"%i)
im.convert("RGBA").save(os.path.join(path, "%d.png"%i), "PNG")
else:
im.putpalette(palette)
im = im.convert("RGBA")
data = im.load()
for x in xrange(im.size[0]):
for y in xrange(im.size[1]):
if data[x, y] == (0, 255, 255, 255):
data[x, y] = (0, 0, 0, 0)
elif data[x, y] == (255, 150, 255, 255):
data[x, y] = (0, 0, 0, 64)
elif data[x, y] == (255, 151, 255, 255):
data[x, y] = (0, 0, 0, 64)
elif data[x, y] == (255, 0, 255, 255):
data[x, y] = (0, 0, 0, 128)
if os.path.exists(os.path.join(path, "%d.png"%num)):
print "overwriting %s" % os.path.join(path, "%d.png"%num)
im.save(os.path.join(path, "%d.png"%num), "PNG")
else:
print "invalid frame"
def save_file(fid, name, ftype, data):
if not os.path.exists(os.path.join("data", ftype)):
os.makedirs(os.path.join("data", ftype))
if os.path.exists(os.path.join("data", ftype, name)):
print "overwriting %s" % os.path.join("data", ftype, name)
file = open(os.path.join("data", ftype, name), "w")
file.write(data)
file.close()
def lod_extract(filename):
lod = open(filename)
if lod.read(4) != "LOD\x00":
raise Exception("not an LOD archive")
(version, files_count) = struct.unpack("2i", lod.read(8))
print "Version: %d, File Count: %d"%(version, files_count) #RoE: 200, AB: 500
for fid in xrange(files_count):
lod.seek(92+(fid*32))
name = lod.read(16).split('\x00')[0].lower()
(offset, size_orig, ftype, size_comp) = \
struct.unpack("4i", lod.read(16))
lod.seek(offset)
if size_comp:
pcx = zlib.decompress(lod.read(size_comp))
else:
pcx = lod.read(size_orig)
if ftype == 1: #h3c file
print fid, name, ftype
save_file(fid, name, "campaigns", pcx)
elif ftype == 2: #txt file
print fid, name, ftype
save_file(fid, name, "txt", pcx)
elif ftype == 16: #pcx palette image
(size, width, height) = struct.unpack("3i", pcx[:12])
print fid, name, width, height
if not os.path.exists(os.path.join("data", "pcx_palette")):
os.makedirs(os.path.join("data", "pcx_palette"))
im = Image.frombuffer('RGB', (width, height), pcx[12:size+12],
'raw', 'P', 0, 1)
im.putpalette(pcx[12+size:12+size+3*256])
if os.path.exists(os.path.join("data", "pcx_palette", name)):
print "overwriting %s" % os.path.join("data", "pcx_palette", name)
im.save(os.path.join("data", "pcx_palette", name), "PNG")
elif ftype == 17: #pcx rgb image
(size, width, height) = struct.unpack("3i", pcx[:12])
print fid, name, width, height
if not os.path.exists(os.path.join("data", "pcx_rgb")):
os.makedirs(os.path.join("data", "pcx_rgb"))
im = Image.frombuffer('RGB', (width, height), pcx[12:size+12],
'raw', 'RGB', 0, 1)
if os.path.exists(os.path.join("data", "pcx_rgb", name)):
print "overwriting %s" % os.path.join("data", "pcx_rgb", name)
im.save(os.path.join("data", "pcx_rgb", name), "PNG")
elif ftype in (64, 65, 66, 67, 68, 69, 70, 71, 73,): #def animation
#in 0.2% of all def files the internal def type does not match the
#type given in the lod archive header but tests show that in this
#case the type given in the def file is more important
(ftype, width, height, sequences_count) = \
struct.unpack("4i", pcx[0:16])
palette = pcx[16:784]
print fid, name, ftype
#all def sequences are thrown into the same folder
#there are no 65 def types - only 65 file types
if ftype == 64:
parent = os.path.join("data", "combat_spells", name)
elif ftype == 66:
parent = os.path.join("data", "combat_creatures", name)
elif ftype == 67:
parent = os.path.join("data", "advmap_objects", name)
elif ftype == 68:
parent = os.path.join("data", "advmap_heroes", name)
elif ftype == 69:
parent = os.path.join("data", "advmap_tiles", name)
elif ftype == 70:
parent = os.path.join("data", "cursors", name)
elif ftype == 71:
parent = os.path.join("data", "interface", name)
elif ftype == 73:
parent = os.path.join("data", "combat_heroes", name)
else:
raise NotImplementedError
if not os.path.exists(parent):
os.makedirs(parent)
pos = 784
for i in xrange(sequences_count):
(index, length, unkown1, unkown2) = \
struct.unpack("4i", pcx[pos:pos+16])
pos+=16
folder = parent
#create subfolder for defs with more than one sequence
if sequences_count > 1:
folder = os.path.join(parent, str(i))
if not os.path.exists(folder):
os.makedirs(folder)
pos+=13*length #read filenames
offsets = struct.unpack("%di"%length, pcx[pos:pos+4*length])
pos+=4*length
lengths = []
for j in xrange(length):
lengths.append(struct.unpack("i", pcx[offsets[j]:offsets[j]+4])[0])
for j in xrange(length):
data = pcx[offsets[j]:offsets[j]+32+lengths[j]]
save_frame(folder, j, data, palette, width, height, name)
elif ftype == 79: #msk file
print fid, name, ftype
save_file(fid, name, "msk", pcx)
elif ftype == 80: #fnt file
print fid, name, ftype
save_file(fid, name, "fonts", pcx)
elif ftype == 96: #pal file
print fid, name, ftype
save_file(fid, name, "palettes", pcx)
else:
raise Exception("type of %s not supported: %d"%(name, ftype))
lod.close()
def snd_extract(filename):
lod = open(filename)
(files_count,) = struct.unpack("i", lod.read(4))
print files_count
if not os.path.exists(os.path.join("data", "sounds")):
os.makedirs(os.path.join("data", "sounds"))
for fid in xrange(files_count):
lod.seek(4+(fid*48))
filename = '.'.join([lod.read(40).split('\x00', 1)[0], "wav"])
(offset, size) = struct.unpack("ii", lod.read(8))
lod.seek(offset)
wav = open(os.path.join("data", "sounds", filename), "w")
wav.write(lod.read(size))
wav.close()
lod.close()
def vid_extract(filename):
lod = open(filename)
(files_count,) = struct.unpack("i", lod.read(4))
print files_count
offsets = []
files = []
for fid in xrange(files_count):
lod.seek(4+(fid*44))
files.append(lod.read(40).rstrip('\x00'))
offsets.append(struct.unpack("i", lod.read(4))[0])
offsets.append(os.stat(filename)[6])
if not os.path.exists(os.path.join("data", "videos")):
os.makedirs(os.path.join("data", "videos"))
for i in xrange(len(offsets)-1):
print files[i]
lod.seek(offsets[i])
vid = open(os.path.join("data", "videos", files[i]), "w")
vid.write(lod.read(offsets[i+1]-offsets[i]))
vid.close()
lod.close()
def main(args):
path = "."
if len(args) > 1:
path = args[1]
lod_extract(os.path.join(path, "H3bitmap.lod"))
lod_extract(os.path.join(path, "H3ab_bmp.lod"))
lod_extract(os.path.join(path, "H3sprite.lod"))
lod_extract(os.path.join(path, "H3ab_spr.lod"))
snd_extract(os.path.join(path, "Heroes3.snd"))
snd_extract(os.path.join(path, "H3ab_ahd.snd"))
vid_extract(os.path.join(path, "VIDEO.VID"))
vid_extract(os.path.join(path, "H3ab_ahd.vid"))
if __name__ == '__main__':
sys.exit(main(sys.argv))

51
hr.py Normal file
View file

@ -0,0 +1,51 @@
#!/usr/bin/env python
"""
heroes renaissance
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
from lib.mapset import *
from lib.interface import *
from lib.mapview import *
from lib.window import Window
class LoadScreen(object):
def __init__(self, window):
self.window = window
self.label = pyglet.text.Label('',
font_name="Linux Libertine",
font_size=28,
x=self.window.width-10, y=10,
anchor_x='right', anchor_y='bottom')
self.label.text = "INITIATING MAPSET..."
mapset = MapSet("Deluge")
self.label.text = "INITIATING MAPVIEW..."
mapview = MapView(mapset, self.window)
interface = Interface(self.window)
self.window.pop_handlers()
self.window.push_handlers(mapview)
self.window.push_handlers(interface)
self.window.push_handlers(self.window.keys)
if __name__ == '__main__':
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA,
pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
window.push_handlers(LoadScreen(window))
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
pyglet.app.run()

0
lib/__init__.py Normal file
View file

596
lib/h3m.py Normal file
View file

@ -0,0 +1,596 @@
#!/usr/bin/env python
"""
heroes renaissance
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import gzip
import struct
import pyglet
def extract(filename):
h3m_data = gzip.open(filename)
map_data = {}
#read general info
(map_data["version"], ) = struct.unpack("<I", h3m_data.read(4))
if map_data["version"] != 0x1C:
return
(map_data["hero_present"], map_data["map_size"], map_data["underworld"],
) = struct.unpack("<BIB", h3m_data.read(6))
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
map_data["map_name"] = h3m_data.read(name_length)
(desc_length, ) = struct.unpack("<I", h3m_data.read(4))
map_data["map_desc"] = h3m_data.read(desc_length)
(map_data["difficulty"], map_data["level_limit"],
) = struct.unpack("<BB", h3m_data.read(2))
#player info
for color in ("Red", "Blue", "Tan", "Green", "Orange", "Purple", "Teal", "Pink"):
map_data[color] = {}
(map_data[color]["is_human"], map_data[color]["is_computer"],
map_data[color]["behaviour"], map_data[color]["isCityTypesOpt"],
map_data[color]["cityTypes"], map_data[color]["randomCity"],
) = struct.unpack("<BBBBHB", h3m_data.read(7))
(main_city, ) = struct.unpack("<B", h3m_data.read(1))
if main_city:
map_data[color]["main_city"] = {}
(map_data[color]["main_city"]["generate_hero"],
map_data[color]["main_city"]["type"],
) = struct.unpack("<BB", h3m_data.read(2))
map_data[color]["main_city"]["coords"] = struct.unpack("<BBB", h3m_data.read(3))
(map_data[color]["random_hero"], map_data[color]["hero_type"],
) = struct.unpack("<BB", h3m_data.read(2))
if map_data[color]["hero_type"] != 0xFF:
(map_data[color]["hero_portrait"], ) = struct.unpack("<B", h3m_data.read(1))
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
map_data[color]["hero_name"] = h3m_data.read(name_length)
h3m_data.read(1) #junk
(map_data[color]["heroes_count"], ) = struct.unpack("<I", h3m_data.read(4))
if map_data[color]["heroes_count"] > 0:
map_data[color]["heroes"] = {}
for i in xrange(map_data[color]["heroes_count"]):
(map_data[color]["heroes"]["portrait"], ) = struct.unpack("<B", h3m_data.read(1))
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
map_data[color]["heroes"]["name"] = h3m_data.read(name_length)
#special victory condition
(map_data["victory_conditions"], ) = struct.unpack("<B", h3m_data.read(1))
if map_data["victory_conditions"] != 0xFF:
map_data["victory_conditions"] = {"id":map_data["victory_conditions"]}
(map_data["victory_conditions"]["canStandardEnd"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["victory_conditions"]["canComputer"], ) = struct.unpack("<B", h3m_data.read(1))
if map_data["victory_conditions"]["id"] == 0x00:
(map_data["victory_conditions"]["artID"], ) = struct.unpack("<B", h3m_data.read(1))
elif map_data["victory_conditions"]["id"] == 0x01:
(map_data["victory_conditions"]["creatureID"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["victory_conditions"]["creatureCount"], ) = struct.unpack("<H", h3m_data.read(2))
elif map_data["victory_conditions"]["id"] == 0x02:
(map_data["victory_conditions"]["resID"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["victory_conditions"]["resCount"], ) = struct.unpack("<I", h3m_data.read(4))
elif map_data["victory_conditions"]["id"] == 0x03:
raise NotImplementedError
elif map_data["victory_conditions"]["id"] in (0x04, 0x05, 0x06, 0x07):
(map_data["victory_conditions"]["x"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["victory_conditions"]["y"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["victory_conditions"]["z"], ) = struct.unpack("<B", h3m_data.read(1))
elif map_data["victory_conditions"]["id"] in (0x08, 0x09):
pass
elif map_data["victory_conditions"]["id"] == 0x0A:
raise NotImplementedError
else:
raise NotImplementedError
#special loss condition
(map_data["loss_conditions"], ) = struct.unpack("<B", h3m_data.read(1))
if map_data["loss_conditions"] != 0xFF:
map_data["loss_conditions"] = {"id":map_data["loss_conditions"]}
if map_data["loss_conditions"]["id"] in (0x00, 0x01):
(map_data["loss_conditions"]["x"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["loss_conditions"]["y"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["loss_conditions"]["z"], ) = struct.unpack("<B", h3m_data.read(1))
elif map_data["loss_conditions"]["id"] == 0x02:
#to be researched
struct.unpack("<B", h3m_data.read(1))
struct.unpack("<B", h3m_data.read(1))
elif map_data["loss_conditions"]["id"] == 0x03:
(map_data["loss_conditions"]["days"], ) = struct.unpack("<H", h3m_data.read(1))
else:
raise NotImplementedError
#Teams
(map_data["commands_count"], ) = struct.unpack("<B", h3m_data.read(1))
if map_data["commands_count"] > 0:
map_data["commands"] = struct.unpack("<8B", h3m_data.read(8))
#Free Heroes
h3m_data.read(20) #free heroes
h3m_data.read(4) #junk
(map_data["heroes_count"], ) = struct.unpack("<B", h3m_data.read(1))
if map_data["heroes_count"] > 0:
map_data["free_heroes"] = []
for i in xrange(map_data["heroes_count"]):
(hero_id, ) = struct.unpack("<B", h3m_data.read(1))
(hero_portrait, ) = struct.unpack("<B", h3m_data.read(1))
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
hero_name = h3m_data.read(name_length)
(hero_players, ) = struct.unpack("<B", h3m_data.read(1))
map_data["free_heroes"].append({"id": hero_id, "portrait":hero_portrait, "name":hero_name, "players":hero_players})
h3m_data.read(31) #junk
#artefacts
h3m_data.read(18)
#spells
h3m_data.read(9)
#sec skillz
h3m_data.read(4)
#rumors
(map_data["rumor_count"], ) = struct.unpack("<I", h3m_data.read(4))
if map_data["rumor_count"] > 0:
map_data["rumors"] = []
for i in xrange(map_data["rumor_count"]):
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
rumor_name = h3m_data.read(name_length)
(text_length, ) = struct.unpack("<I", h3m_data.read(4))
rumor_text = h3m_data.read(text_length)
map_data["rumors"].append({"name":rumor_name, "text":rumor_text})
#hero options
for i in xrange(156):
(hero_enable, ) = struct.unpack("<B", h3m_data.read(1))
if hero_enable == 1:
(isExp, ) = struct.unpack("<B", h3m_data.read(1))
if isExp == 0x01:
(exp, ) = struct.unpack("<I", h3m_data.read(4))
(isSecSkill, ) = struct.unpack("<B", h3m_data.read(1))
if isSecSkill == 0x01:
(skills_count) = struct.unpack("<I", h3m_data.read(4))
for i in xrange(skills_count):
(skill_id, ) = struct.unpack("<B", h3m_data.read(1))
(skill_lvl, ) = struct.unpack("<B", h3m_data.read(1))
(isArtifact, ) = struct.unpack("<B", h3m_data.read(1))
if isArtifact == 0x01:
raise NotImplementedError
(isBiography, ) = struct.unpack("<B", h3m_data.read(1))
if isBiography == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
biography = h3m_data.read(length)
(gender, ) = struct.unpack("<B", h3m_data.read(1))
(isSpells, ) = struct.unpack("<B", h3m_data.read(1))
if isSpells == 0x01:
spells = struct.unpack("<9B", h3m_data.read(9))
(isPrimarySkills, ) = struct.unpack("<B", h3m_data.read(1))
if isPrimarySkills == 0x01:
(attack, defense, power, knowledge) = struct.unpack("<4B", h3m_data.read(4))
map_data["upper_terrain"] = [[] for i in xrange(map_data["map_size"])]
#read upper world
for i in xrange(map_data["map_size"]**2):
x = i%map_data["map_size"]
y = (i-x)/map_data["map_size"]
map_data["upper_terrain"][y].append(struct.unpack("<7B", h3m_data.read(7)))
#read underworld
if map_data["underworld"]:
map_data["lower_terrain"] = [[] for i in xrange(map_data["map_size"])]
for i in xrange(map_data["map_size"]**2):
x = i%map_data["map_size"]
y = (i-x)/map_data["map_size"]
map_data["lower_terrain"][y].append(struct.unpack("<7B", h3m_data.read(7)))
(map_data["object_count"], ) = struct.unpack("<I", h3m_data.read(4))
map_data["objects"] = []
for i in xrange(map_data["object_count"]):
(length, ) = struct.unpack("<I", h3m_data.read(4))
filename = h3m_data.read(length)
h3m_data.read(6) #passability
h3m_data.read(6) #actions
h3m_data.read(2) #landscape
h3m_data.read(2) #land_edit_groups
(obj_class, ) = struct.unpack("<I", h3m_data.read(4)) #class
(obj_number, ) = struct.unpack("<I", h3m_data.read(4)) #number
(obj_group, ) = struct.unpack("<B", h3m_data.read(1)) #group
h3m_data.read(1) #isOverlay
h3m_data.read(16) #junk
map_data["objects"].append({"filename":filename.lower(), "class":obj_class,
"number":obj_number, "group":obj_group})
(map_data["tunedobj_count"], ) = struct.unpack("<I", h3m_data.read(4))
map_data["tunedobj"] = []
for i in xrange(map_data["tunedobj_count"]):
(x, y, z) = struct.unpack("<3B", h3m_data.read(3))
(object_id, ) = struct.unpack("<I", h3m_data.read(4))
#print x,y,z,object_id,
junk = h3m_data.read(5) #junk
if junk != "\x00\x00\x00\x00\x00":
for c in junk:
print "%02d"%ord(c),
break
#print i, map_data["objects"][object_id]["filename"],
#print map_data["objects"][object_id]["class"]
map_data["tunedobj"].append({"id":object_id, "x":x, "y":y, "z":z})
if object_id in (0,1):
pass
elif map_data["objects"][object_id]["class"] == 53:
if map_data["objects"][object_id]["number"] == 7:
h3m_data.read(4)
else:
h3m_data.read(4)
elif map_data["objects"][object_id]["class"] in (76, 79):
(isText, ) = struct.unpack("<B", h3m_data.read(1))
if isText == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
if isGuards == 0x01:
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(4) #junk
(quantity, ) = struct.unpack("<I", h3m_data.read(4))
h3m_data.read(4) #junk
elif map_data["objects"][object_id]["class"] in (34, 70, 62):
(hero_id, color, hero) = struct.unpack("<IBB", h3m_data.read(6))
(isName, ) = struct.unpack("<B", h3m_data.read(1))
if isName == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
name = h3m_data.read(length)
(isExp, ) = struct.unpack("<B", h3m_data.read(1))
if isExp == 0x01:
(exp, ) = struct.unpack("<I", h3m_data.read(4))
(isPortrait, ) = struct.unpack("<B", h3m_data.read(1))
if isPortrait == 0x01:
(portrait, ) = struct.unpack("<B", h3m_data.read(1))
(isSecSkill, ) = struct.unpack("<B", h3m_data.read(1))
if isSecSkill == 0x01:
(skills_count, ) = struct.unpack("<I", h3m_data.read(4))
for i in xrange(skills_count):
(skill_id, ) = struct.unpack("<B", h3m_data.read(1))
(skill_lvl, ) = struct.unpack("<B", h3m_data.read(1))
(isCreature, ) = struct.unpack("<B", h3m_data.read(1))
if isCreature == 0x01:
for i in xrange(7):
(guard_id, ) = struct.unpack("<H", h3m_data.read(2))
(guard_count, ) = struct.unpack("<H", h3m_data.read(2))
(creaturesFormation, ) = struct.unpack("<B", h3m_data.read(1))
(isArtifact, ) = struct.unpack("<B", h3m_data.read(1))
if isArtifact == 0x01:
(headID, shouldersID, neckID, rightHandID, leftHandID,
trunkID, rightRingID, leftRingID, legsID, misc1ID, misc2ID,
misc3ID, misc4ID, machine1ID, machine2ID, machine3ID,
machine4ID, magicbook, misc5ID) \
= struct.unpack("<19H", h3m_data.read(38))
(knapsack_count, ) = struct.unpack("<H", h3m_data.read(2))
if knapsack_count > 0:
for i in xrange(knapsack_count):
(knapsackID, ) = struct.unpack("<H", h3m_data.read(2))
(zoneRadius, ) = struct.unpack("<B", h3m_data.read(1))
(isBiography, ) = struct.unpack("<B", h3m_data.read(1))
if isBiography == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
biography = h3m_data.read(length)
(gender, ) = struct.unpack("<B", h3m_data.read(1))
(isSpells, ) = struct.unpack("<B", h3m_data.read(1))
if isSpells == 0x01:
spells = struct.unpack("<9B", h3m_data.read(9))
(isPrimarySkills, ) = struct.unpack("<B", h3m_data.read(1))
if isPrimarySkills == 0x01:
(attack, defense, power, knowledge) = struct.unpack("<4B", h3m_data.read(4))
h3m_data.read(16) #unknown
elif map_data["objects"][object_id]["class"] in (17, 20, 42):
(owner, ) = struct.unpack("<I", h3m_data.read(4))
elif map_data["objects"][object_id]["class"] == 93:
(isText, ) = struct.unpack("<B", h3m_data.read(1))
if isText == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
if isGuards == 0x01:
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(4) #junk
(spell_id, ) = struct.unpack("<I", h3m_data.read(4))
elif map_data["objects"][object_id]["class"] == 216:
(owner, ) = struct.unpack("<I", h3m_data.read(4))
(junk, ) = struct.unpack("<I", h3m_data.read(4))
if junk == 0x00:
(towns, ) = struct.unpack("<H", h3m_data.read(2))
(minlevel, maxlevel, ) = struct.unpack("<2B", h3m_data.read(2))
elif map_data["objects"][object_id]["class"] in (54, 71, 72, 73, 74, 75, 162, 163, 164):
(monster_id, ) = struct.unpack("<I", h3m_data.read(4))
(monster_count, ) = struct.unpack("<H", h3m_data.read(2))
(mood, ) = struct.unpack("<B", h3m_data.read(1))
(isTreasureOrText, ) = struct.unpack("<B", h3m_data.read(1))
if isTreasureOrText == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
(wood, mercury, ore, sulfur, crystal, gem, gold, artefactID) \
= struct.unpack("<7IH", h3m_data.read(30))
(mosterNeverRunAway, ) = struct.unpack("<B", h3m_data.read(1))
(monsterDontGrowUp, ) = struct.unpack("<B", h3m_data.read(1))
h3m_data.read(2) #junk
elif map_data["objects"][object_id]["class"] in (98, 77):
h3m_data.read(4) #junk
(owner, ) = struct.unpack("<B", h3m_data.read(1))
(isName, ) = struct.unpack("<B", h3m_data.read(1))
if isName == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
name = h3m_data.read(length)
(isGuard, ) = struct.unpack("<B", h3m_data.read(1))
if isGuard == 0x01:
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
(formation, ) = struct.unpack("<B", h3m_data.read(1))
(isBuildings, ) = struct.unpack("<B", h3m_data.read(1))
if isBuildings == 0x01:
build = struct.unpack("6B", h3m_data.read(6))
active = struct.unpack("6B", h3m_data.read(6))
else:
(isFort, ) = struct.unpack("<B", h3m_data.read(1))
mustSpells = struct.unpack("<9B", h3m_data.read(9))
canSpells = struct.unpack("<9B", h3m_data.read(9))
(eventQuantity, ) = struct.unpack("<I", h3m_data.read(4))
if eventQuantity > 0:
for i in xrange(eventQuantity):
(length, ) = struct.unpack("<I", h3m_data.read(4))
event_name = h3m_data.read(length)
(length, ) = struct.unpack("<I", h3m_data.read(4))
event_text = h3m_data.read(length)
(wood, mercury, ore, sulfur, crystal, gem, gold,
players_affected, human_affected, ai_affected,
day_of_first_event, event_iteration) \
= struct.unpack("<7I3B2H", h3m_data.read(35))
h3m_data.read(16) #junk
buildings = struct.unpack("<6B", h3m_data.read(6))
creatures = struct.unpack("<7H", h3m_data.read(14))
h3m_data.read(4) #junk
h3m_data.read(4) #junk
elif map_data["objects"][object_id]["class"] in (5, 65, 66, 67, 68, 69):
(isText, ) = struct.unpack("<B", h3m_data.read(1))
if isText == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
if isGuards == 0x01:
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(4) #junk
elif map_data["objects"][object_id]["class"] in (33, 219):
(color, ) = struct.unpack("<I", h3m_data.read(4))
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
(undeleteSoldiers, ) = struct.unpack("<B", h3m_data.read(1))
h3m_data.read(8)
elif map_data["objects"][object_id]["class"] == 87:
(owner, ) = struct.unpack("<I", h3m_data.read(4))
elif map_data["objects"][object_id]["class"] == 83:
(quest, ) = struct.unpack("<B", h3m_data.read(1))
if quest == 0x00:
pass
elif quest == 0x01:
(level, ) = struct.unpack("<I", h3m_data.read(4))
elif quest == 0x02:
(offence, defence, power, knowledge) = struct.unpack("4B", h3m_data.read(4))
elif quest == 0x03:
(hero_id, ) = struct.unpack("<I", h3m_data.read(4))
elif quest == 0x04:
(monster_id, ) = struct.unpack("<I", h3m_data.read(4))
elif quest == 0x05:
(art_quantity, ) = struct.unpack("<B", h3m_data.read(1))
for i in xrange(art_quantity):
(art, ) = struct.unpack("<H", h3m_data.read(2))
elif quest == 0x06:
(creatures_quantity, ) = struct.unpack("<B", h3m_data.read(1))
for i in xrange(creatures_quantity):
(guard_id, ) = struct.unpack("<H", h3m_data.read(2))
(guard_count, ) = struct.unpack("<H", h3m_data.read(2))
elif quest == 0x07:
resources = struct.unpack("7I", h3m_data.read(28))
elif quest == 0x08:
(hero_id, ) = struct.unpack("<B", h3m_data.read(1))
elif quest == 0x09:
(player, ) = struct.unpack("<B", h3m_data.read(1))
else:
raise NotImplementedError
(time_limit, ) = struct.unpack("<I", h3m_data.read(4))
(length, ) = struct.unpack("<I", h3m_data.read(4))
quest_begin = h3m_data.read(length)
(length, ) = struct.unpack("<I", h3m_data.read(4))
quest_running = h3m_data.read(length)
(length, ) = struct.unpack("<I", h3m_data.read(4))
quest_end = h3m_data.read(length)
(reward, ) = struct.unpack("<B", h3m_data.read(1))
if reward == 0x00:
pass
elif reward == 0x01:
(exp, ) = struct.unpack("<I", h3m_data.read(4))
elif reward == 0x02:
(spell_points, ) = struct.unpack("<I", h3m_data.read(4))
elif reward == 0x03:
(morale, ) = struct.unpack("<B", h3m_data.read(1))
elif reward == 0x04:
(lucky, ) = struct.unpack("<B", h3m_data.read(1))
elif reward == 0x05:
(resID, ) = struct.unpack("<B", h3m_data.read(1))
(res_quantity, ) = struct.unpack("<I", h3m_data.read(4))
elif reward == 0x06:
(priSkillID, ) = struct.unpack("<B", h3m_data.read(1))
(priSkillBonus, ) = struct.unpack("<B", h3m_data.read(1))
elif reward == 0x07:
(secSkillID, ) = struct.unpack("<B", h3m_data.read(1))
(secSkillBonus, ) = struct.unpack("<B", h3m_data.read(1))
elif reward == 0x08:
(artID, ) = struct.unpack("<H", h3m_data.read(2))
elif reward == 0x09:
(spellID, ) = struct.unpack("<B", h3m_data.read(1))
elif reward == 0x0A:
(creatureID, ) = struct.unpack("<H", h3m_data.read(2))
(creatureQuantity, ) = struct.unpack("<H", h3m_data.read(2))
else:
raise NotImplementedError
h3m_data.read(2) #junk
elif map_data["objects"][object_id]["class"] in (91, 59):
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
h3m_data.read(4) #junk
elif map_data["objects"][object_id]["class"] == 113:
(secSkills, ) = struct.unpack("<I", h3m_data.read(4))
elif map_data["objects"][object_id]["class"] in (88, 89, 90):
(spellID, ) = struct.unpack("<I", h3m_data.read(4))
elif map_data["objects"][object_id]["class"] == 215:
(quest, ) = struct.unpack("<B", h3m_data.read(1))
if quest == 0x00:
pass
elif quest == 0x01:
(level, ) = struct.unpack("<I", h3m_data.read(4))
elif quest == 0x02:
(offence, defence, power, knowledge) = struct.unpack("4B", h3m_data.read(4))
elif quest == 0x03:
(hero_id, ) = struct.unpack("<I", h3m_data.read(4))
elif quest == 0x04:
(monster_id, ) = struct.unpack("<I", h3m_data.read(4))
elif quest == 0x05:
(art_quantity, ) = struct.unpack("<B", h3m_data.read(1))
for i in xrange(art_quantity):
(art, ) = struct.unpack("<H", h3m_data.read(2))
elif quest == 0x06:
(creatures_quantity, ) = struct.unpack("<B", h3m_data.read(1))
for i in xrange(creatures_quantity):
(guard_id, ) = struct.unpack("<H", h3m_data.read(2))
(guard_count, ) = struct.unpack("<H", h3m_data.read(2))
elif quest == 0x07:
resources = struct.unpack("7I", h3m_data.read(28))
elif quest == 0x08:
(hero_id, ) = struct.unpack("<B", h3m_data.read(1))
elif quest == 0x09:
(player, ) = struct.unpack("<B", h3m_data.read(1))
else:
raise NotImplementedError
(time_limit, ) = struct.unpack("<I", h3m_data.read(4))
(length, ) = struct.unpack("<I", h3m_data.read(4))
quest_begin = h3m_data.read(length)
(length, ) = struct.unpack("<I", h3m_data.read(4))
quest_running = h3m_data.read(length)
(length, ) = struct.unpack("<I", h3m_data.read(4))
quest_end = h3m_data.read(length)
elif map_data["objects"][object_id]["class"] == 36:
(radius, ) = struct.unpack("<B", h3m_data.read(1))
h3m_data.read(3) #junk
elif map_data["objects"][object_id]["class"] == 220:
(resources, ) = struct.unpack("<B", h3m_data.read(1))
h3m_data.read(3) #junk
elif map_data["objects"][object_id]["class"] == 217:
(owner, towns) = struct.unpack("<II", h3m_data.read(8))
if towns==0x00:
(towns,) = struct.unpack("<H", h3m_data.read(2))
elif map_data["objects"][object_id]["class"] == 218:
(owner, minlvl, maxlvl) = struct.unpack("<IBB", h3m_data.read(6))
elif map_data["objects"][object_id]["class"] == 81:
(bonus_type, primaryID) = struct.unpack("<BI", h3m_data.read(5))
h3m_data.read(3) #junk
elif map_data["objects"][object_id]["class"] == 6:
(isText, ) = struct.unpack("<B", h3m_data.read(1))
if isText == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
if isGuards == 0x01:
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(4) #junk
(exp, spell_points, morals, luck, wood, mercury, ore, sulfur,
crystal, gem, gold, offence, defence, power, knowledge) = \
struct.unpack("<IIBBIIIIIIIBBBB", h3m_data.read(42))
(secSkills, ) = struct.unpack("<B", h3m_data.read(1))
if secSkills > 0:
for i in xrange(secSkills):
(skill_id, skill_lvl) = struct.unpack("<BB", h3m_data.read(2))
(artefacts, ) = struct.unpack("<B", h3m_data.read(1))
if artefacts > 0:
for i in xrange(artefacts):
(artID, ) = struct.unpack("<H", h3m_data.read(2))
(spells, ) = struct.unpack("<B", h3m_data.read(1))
if spells > 0:
for i in xrange(spells):
(spellID, ) = struct.unpack("<B", h3m_data.read(1))
(monsters, ) = struct.unpack("<B", h3m_data.read(1))
if monsters > 0:
for i in xrange(monsters):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(8) #junk
elif map_data["objects"][object_id]["class"] == 26:
(isText, ) = struct.unpack("<B", h3m_data.read(1))
if isText == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
if isGuards == 0x01:
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(4) #junk
(exp, spell_points, morals, luck, wood, mercury, ore, sulfur,
crystal, gem, gold, offence, defence, power, knowledge) = \
struct.unpack("<IIBBIIIIIIIBBBB", h3m_data.read(42))
(secSkills, ) = struct.unpack("<B", h3m_data.read(1))
if secSkills > 0:
for i in xrange(secSkills):
(skill_id, skill_lvl) = struct.unpack("<BB", h3m_data.read(2))
(artefacts, ) = struct.unpack("<B", h3m_data.read(1))
if artefacts > 0:
for i in xrange(artefacts):
(artID, ) = struct.unpack("<H", h3m_data.read(2))
(spells, ) = struct.unpack("<B", h3m_data.read(1))
if spells > 0:
for i in xrange(spells):
(spellID, ) = struct.unpack("<B", h3m_data.read(1))
(monsters, ) = struct.unpack("<B", h3m_data.read(1))
if monsters > 0:
for i in xrange(monsters):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(8) #junk
(players, isAICan, disableAfterFirstDay) = struct.unpack("<BBB", h3m_data.read(3))
h3m_data.read(4) #junk
try:
(gevents_count, ) = struct.unpack("<I", h3m_data.read(4))
for i in xrange(gevents_count):
(length, ) = struct.unpack("<I", h3m_data.read(4))
name = h3m_data.read(length)
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
h3m_data.read(7*4) #resources
(players_affected, ) = struct.unpack("<B", h3m_data.read(1))
(human_affected, ) = struct.unpack("<B", h3m_data.read(1))
(ai_affected, ) = struct.unpack("<B", h3m_data.read(1))
(day_of_first_event,) = struct.unpack("<H", h3m_data.read(2))
(event_iteration,) = struct.unpack("<H", h3m_data.read(2))
h3m_data.read(16) #junk
except:
print "d'ough...'"
h3m_data.read(124) #junk
return map_data

38
lib/interface.py Normal file
View file

@ -0,0 +1,38 @@
#!/usr/bin/env python
"""
heroes renaissance
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
IF_BOTTOM = 48
IF_RIGHT = 200
IF_TOP = IF_LEFT = 8
class Interface(object):
def __init__(self, window):
self.window = window
def on_mouse_motion(self, x, y, dx, dy):
if IF_LEFT < x < (self.window.width-IF_RIGHT):
pass
else:
return pyglet.event.EVENT_HANDLED
if IF_BOTTOM < y < (self.window.height-IF_TOP):
pass
else:
return pyglet.event.EVENT_HANDLED

382
lib/mapset.py Normal file
View file

@ -0,0 +1,382 @@
#!/usr/bin/env python
"""
heroes renaissance
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
from ctypes import create_string_buffer, memmove
from lib import h3m
import os
class OrderedTextureGroup(pyglet.graphics.Group):
def __init__(self, order, texture, parent=None):
super(OrderedTextureGroup, self).__init__(parent)
self.texture = texture
self.order = order
def set_state(self):
pyglet.gl.glEnable(self.texture.target)
pyglet.gl.glBindTexture(self.texture.target, self.texture.id)
def unset_state(self):
pyglet.gl.glDisable(self.texture.target)
def __hash__(self):
return hash((self.order, self.texture.target, self.texture.id,
self.parent))
def __eq__(self, other):
return (self.__class__ is other.__class__ and
self.order == other.order and
self.texture.target == other.texture.target and
self.texture.id == other.texture.id and
self.parent == self.parent)
def __repr__(self):
return '%s(id=%d)' % (self.__class__.__name__, self.order,
self.texture.id)
def __cmp__(self, other):
if isinstance(other, OrderedTextureGroup):
return cmp(self.order, other.order)
return -1
class Animation(object):
def __init__(self, tex_region, frames, flip_x=False, flip_y=False):
self.texgroup = tex_region.group
if flip_x or flip_y:
self.tex = tex_region.get_transform(flip_x=flip_x, flip_y=flip_y)
else:
self.tex = tex_region
self.__frames = []
for img in frames:
data_pitch = abs(img._current_pitch)
buf = create_string_buffer(len(img._current_data))
memmove(buf, img._current_data, len(img._current_data))
data = buf.raw
rows = [data[i:i + abs(data_pitch)] for i in
xrange(len(img._current_data)-abs(data_pitch),
-1, -abs(data_pitch))]
self.__frames.append(''.join(rows))
self.__animation = 0
self.width = self.tex.width
self.height = self.tex.height
self.__hash = hash(self.__frames[0])
def next_frame(self):
self.__animation = (self.__animation + 1) % len(self.__frames)
return self.__frames[self.__animation]
@property
def tex_coords(self):
return self.tex.tex_coords
@property
def group(self):
return self.texgroup
def __hash__(self):
return self.__hash
def __eq__(self, other):
return self.__hash == other.__hash
class MapSet(object):
def load_map_object(self, file, order=0):
image = pyglet.image.load(None, file=pyglet.resource.file(file))
try:
texture_region = self.current_atlas.add(image)
except pyglet.image.atlas.AllocatorException:
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
texture_region = self.current_atlas.add(image)
group = OrderedTextureGroup(order, self.current_atlas.texture)
if group not in self.groups:
self.groups.append(group)
texture_region.group = self.groups.index(group)
return texture_region
def __init__(self, map_name):
h3m_data = h3m.extract(os.path.join(pyglet.resource._default_loader._script_home,"maps","%s.h3m" % map_name))
edge_map = [[] for i in xrange(len(h3m_data["upper_terrain"])+16)]
for num in xrange(len(edge_map)):
if num < 7 or num > len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(h3m_data["upper_terrain"][0])+18)])
elif num == 7:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 16, 0, 0, 0, 0, 0])
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m_data["upper_terrain"][0]))])
line.append([-1, 17, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
elif num == len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 19, 0, 0, 0, 0, 0])
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m_data["upper_terrain"][0]))])
line.append([-1, 18, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
else:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
line.extend(h3m_data["upper_terrain"][num-8])
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
edge_map[num] = line
h3m_data["upper_terrain"] = edge_map
self.width = len(h3m_data["upper_terrain"][0])
self.height = len(h3m_data["upper_terrain"])
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
self.groups = []
self.__tiles = {}
tile_textures = {}
for y, line in enumerate(h3m_data["upper_terrain"]):
for x, tile in enumerate(line):
if tile[0] == -1: #edge
if "edg" not in tile_textures.keys():
tile_textures["edg"] = [self.load_map_object('data/advmap_tiles/edg.def/%d.png'%i, 100) for i in xrange(36)]
self.__tiles[x,y] = [tile_textures["edg"][tile[1]]]
elif tile[0] == 0: #dirt
if "dirttl" not in tile_textures.keys():
tile_textures["dirttl"] = [self.load_map_object('data/advmap_tiles/dirttl.def/%d.png'%i, 0) for i in xrange(46)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["dirttl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["dirttl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["dirttl"][tile[1]]]
elif tile[0] == 1: #sand
if "sandtl" not in tile_textures.keys():
tile_textures["sandtl"] = [self.load_map_object('data/advmap_tiles/sandtl.def/%d.png'%i, 0) for i in xrange(24)]
self.__tiles[x,y] = [tile_textures["sandtl"][tile[1]]]
elif tile[0] == 2: #grass
if "grastl" not in tile_textures.keys():
tile_textures["grastl"] = [self.load_map_object('data/advmap_tiles/grastl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["grastl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["grastl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["grastl"][tile[1]]]
elif tile[0] == 3: #snow
if "snowtl" not in tile_textures.keys():
tile_textures["snowtl"] = [self.load_map_object('data/advmap_tiles/snowtl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["snowtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["snowtl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["snowtl"][tile[1]]]
elif tile[0] == 4: #swamp
if "swmptl" not in tile_textures.keys():
tile_textures["swmptl"] = [self.load_map_object('data/advmap_tiles/swmptl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["swmptl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["swmptl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["swmptl"][tile[1]]]
elif tile[0] == 5: #rough
if "rougtl" not in tile_textures.keys():
tile_textures["rougtl"] = [self.load_map_object('data/advmap_tiles/rougtl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["rougtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["rougtl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["rougtl"][tile[1]]]
elif tile[0] == 7: #lava
if "lavatl" not in tile_textures.keys():
tile_textures["lavatl"] = [self.load_map_object('data/advmap_tiles/lavatl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["lavatl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["lavatl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["lavatl"][tile[1]]]
elif tile[0] == 8: #water 12 anims
if "watrtl" not in tile_textures.keys():
textures = [self.load_map_object('data/advmap_tiles/watrtl.def/%d/0.png'%i, 0) for i in xrange(33)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/advmap_tiles/watrtl.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(33)]
tile_textures["watrtl"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>0)&1
flip_y = (tile[6]>>1)&1
self.__tiles[x,y] = [tile_textures["watrtl"][flip_x, flip_y][tile[1]]]
elif tile[0] == 9: #rock
if "rocktl" not in tile_textures.keys():
tile_textures["rocktl"] = [self.load_map_object('data/advmap_tiles/rocktl.def/%d.png'%i, 0) for i in xrange(48)]
self.__tiles[x,y] = [tile_textures["rocktl"][tile[1]]]
else:
raise NotImplementedError
if tile[2] == 0: #no river
pass
elif tile[2] == 1: #clrrvr 12 anims
if "clrrvr" not in tile_textures.keys():
textures = [self.load_map_object('data/advmap_tiles/clrrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/advmap_tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
tile_textures["clrrvr"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>2)&1
flip_y = (tile[6]>>3)&1
self.__tiles[x,y].append(tile_textures["clrrvr"][flip_x, flip_y][tile[3]])
elif tile[2] == 2: #icyrvr
if "icyrvr" not in tile_textures.keys():
tile_textures["icyrvr"] = [self.load_map_object('data/advmap_tiles/icyrvr.def/%d.png'%i, 1) for i in xrange(13)]
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
new = tile_textures["icyrvr"][tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["icyrvr"][tile[3]].group
self.__tiles[x, y].append(new)
else:
self.__tiles[x, y].append(tile_textures["icyrvr"][tile[3]])
elif tile[2] == 3: #mudrvr
if "mudrvr" not in tile_textures.keys():
textures = [self.load_map_object('data/advmap_tiles/mudrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/advmap_tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
tile_textures["mudrvr"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>2)&1
flip_y = (tile[6]>>3)&1
self.__tiles[x,y].append(tile_textures["mudrvr"][flip_x, flip_y][tile[3]])
elif tile[2] == 4: #lavrvr
if "lavrvr" not in tile_textures.keys():
textures = [self.load_map_object('data/advmap_tiles/lavrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/advmap_tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(9)] for i in xrange(13)]
tile_textures["lavrvr"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>2)&1
flip_y = (tile[6]>>3)&1
self.__tiles[x,y].append(tile_textures["lavrvr"][flip_x, flip_y][tile[3]])
else:
raise NotImplementedError, tile[2]
if tile[4] == 0: #no road
pass
elif tile[4] == 1: #dirtrd
if "dirtrd" not in tile_textures.keys():
tile_textures["dirtrd"] = [self.load_map_object('data/advmap_tiles/dirtrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["dirtrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["dirtrd"][tile[5]].group
self.__tiles[x, y].append(new)
else:
self.__tiles[x, y].append(tile_textures["dirtrd"][tile[5]])
elif tile[4] == 2: #gravrd
if "gravrd" not in tile_textures.keys():
tile_textures["gravrd"] = [self.load_map_object('data/advmap_tiles/gravrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["gravrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["gravrd"][tile[5]].group
self.__tiles[x, y].append(new)
else:
self.__tiles[x, y].append(tile_textures["gravrd"][tile[5]])
elif tile[4] == 3: #cobbrd
if "cobbrd" not in tile_textures.keys():
tile_textures["cobbrd"] = [self.load_map_object('data/advmap_tiles/cobbrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["cobbrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["cobbrd"][tile[5]].group
self.__tiles[x, y].append(new)
else:
self.__tiles[x, y].append(tile_textures["cobbrd"][tile[5]])
else:
raise NotImplementedError, tile[4]
images = []
for order, obj in enumerate(h3m_data["objects"]):
imgs = []
i = 0
while 1:
imgs.append(pyglet.image.load(None, file=pyglet.resource.file("data/advmap_objects/" + obj["filename"] + "/%d.png"%i)))
i += 1
if "data/advmap_objects/" + obj["filename"] + "/%d.png" % i not in pyglet.resource._default_loader._index.keys():
break;
images.append((imgs, order))
self.objects = []
for imgs in sorted(images, key=lambda i:i[0][0].height, reverse=True):
try:
texture = self.current_atlas.add(imgs[0][0])
except pyglet.image.atlas.AllocatorException:
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
texture = self.current_atlas.add(imgs[0][0])
group = OrderedTextureGroup(2, self.current_atlas.texture)
if group not in self.groups:
self.groups.append(group)
group = self.groups.index(group)
texture.group = group
self.objects.append((Animation(texture, imgs[0]), imgs[1]))
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
self.tunedobj = {}
for obj in [i for i in h3m_data["tunedobj"] if i["z"]==0]:
self.__tiles[obj["x"] + 9,obj["y"] + 8].append(self.objects[obj["id"]])
def get_tiles(self, tiles_x, tiles_y, div_x, div_y):
for y in xrange(tiles_y - 1, -6, -1):
y1 = y * 32
for x in xrange(tiles_x + 5 - 1, -1, -1):
for obj in self.__tiles.get((x - div_x, div_y - y), []):
x1 = x * 32 - obj.width + 32
x2 = x1 + obj.width
y2 = y1 + obj.height
yield obj, [x1, y1, x2, y1, x2, y2, x1, y2]

335
lib/mapview.py Normal file
View file

@ -0,0 +1,335 @@
#!/usr/bin/env python
"""
heroes renaissance
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
from lib.interface import *
from lib.mapset import *
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self._first_time_init()
self._init_view()
# mouse position
self.label = pyglet.text.Label('',
font_name="",
font_size=36,
bold=True,
color=(128, 128, 128, 128),
x=self.window.width - 10, y=0,
anchor_x='right', anchor_y='bottom')
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _first_time_init(self):
self.tile_size = 32
# size of the viewport
self.vp_width = self.window.width-IF_RIGHT-IF_LEFT
self.vp_height = self.window.height-IF_BOTTOM-IF_TOP
# center map
self.x = (self.mapset.width * self.tile_size - self.vp_width +
self.tile_size) // 2
self.y = (self.mapset.height * self.tile_size - self.vp_height +
self.tile_size) // 2
self.mouse_x = self.mouse_dx = 0
self.mouse_y = self.mouse_dy = 0
def _init_view(self):
# initiate new batch
self.batch = pyglet.graphics.Batch()
# initiate new vertex list
self.vl_objects = [None for value in self.mapset.groups]
# size of the viewport
self.vp_width = self.window.width - IF_RIGHT - IF_LEFT
self.vp_height = self.window.height - IF_BOTTOM - IF_TOP
# center map when viewport is too large, else check if map still fills
# whole viewport and if not adjust position accordingly
self.center_x = False
if self.mapset.width * self.tile_size < self.vp_width:
# center the map in x direction
self.center_x = True
self.x = (self.mapset.width * self.tile_size - self.vp_width) // 2
elif self.x > self.tile_size * self.mapset.width - self.vp_width:
# move map back to the right
self.x = self.tile_size * self.mapset.width - self.vp_width
elif self.x < 0:
# move map to the left
self.x = 0
self.center_y = False
if self.mapset.height * self.tile_size < self.vp_height:
# center the map in y direction
self.center_y = True
self.y = (self.mapset.height * self.tile_size -
self.vp_height) // 2
elif self.y > self.tile_size * self.mapset.height - self.vp_height:
# move map up
self.y = self.tile_size * self.mapset.height - self.vp_height
elif self.y < 0:
# move map down
self.y = 0
# tiles to be drawn with the current viewport size
self.tiles_x = min((self.vp_width // self.tile_size) + 2,
self.mapset.width)
self.tiles_y = min((self.vp_height // self.tile_size) + 2,
self.mapset.height)
# undrawn map size in pixels
self.undrawn_x = self.tile_size * (self.mapset.width - self.tiles_x)
self.undrawn_y = self.tile_size * (self.mapset.height - self.tiles_y)
# reset mouse or keyboard movement
self.dx = 0
self.dy = 0
# calculate modulo pixel position of the map
if self.x - self.tile_size > self.undrawn_x:
# dont go right beyond map borders
mod_x = self.tile_size - self.x + self.undrawn_x
elif self.x > 0:
# calculate modulo of current position and tile_size
mod_x = (self.tile_size - self.x) % self.tile_size
else:
# dont go left beyond map borders
mod_x = self.tile_size - self.x
if self.y - self.tile_size > self.undrawn_y:
# dont go up beyond map borders
mod_y = self.tile_size - self.y + self.undrawn_y
elif self.y > 0:
# calculate modulo of current position and tile_size
mod_y = (self.tile_size - self.y) % self.tile_size
else:
# dont go down beyond map borders
mod_y = self.tile_size - self.y
# calculate tile position of the map, turn y coordinates upside down
self.div_x = (self.tile_size - self.x - mod_x) // self.tile_size
self.div_y = (self.tile_size - self.y - mod_y) // self.tile_size + \
self.mapset.height - 1
# update vertex lists with the gathered information
self.update_vertex_lists()
# update current current position that is to be glTranslated
# XXX: dont ask me why i have to add 1/4 and 3/2 but when i do not
# there are black borders when zooming out
# plz explain wtf is going on there
self.view_x = mod_x - self.tile_size - (self.tile_size - 32) // 4
self.view_y = mod_y - self.tile_size - ((self.tile_size - 32) * 3) // 2
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
pyglet.gl.glPushMatrix()
pyglet.gl.glTranslatef(self.view_x+IF_LEFT, self.view_y+IF_BOTTOM, 0)
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
self.batch.draw()
pyglet.gl.glPopMatrix()
pyglet.gl.glLoadIdentity()
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glColor4f(1, 0, 1, 1)
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
self.label.draw()
def _move(self, dx, dy):
# new map position
new_x = self.x - dx
new_y = self.y - dy
# only update textures and vertices when necessary
retex = False
# if x or y jump is too big, adjust new position accordingly
if new_x < 0:
# move map to the left
new_x = 0
retex = True
if new_x > self.tile_size * self.mapset.width - self.vp_width:
# move map to the right
new_x = self.tile_size * self.mapset.width - self.vp_width
retex = True
if new_y < 0:
# move map down
new_y = 0
retex = True
if new_y > self.tile_size * self.mapset.height - self.vp_height:
# move map up
new_y = self.tile_size * self.mapset.height - self.vp_height
retex = True
# find out how many steps and pixels we have to move and wether we have
# to retex
if new_x - self.tile_size > self.undrawn_x:
# we are at the right border
mod_x = self.tile_size - new_x + self.undrawn_x
# only retex if the last position was not at the border
if self.x - self.tile_size <= self.undrawn_x:
retex = True
elif new_x > 0:
# normal movement: calculate the amount of steps and the modulo
div_x, mod_x = divmod(self.tile_size - new_x, self.tile_size)
# only retex if the number of moved steps is not equal to last
if div_x != (self.tile_size - self.x) // self.tile_size:
retex = True
else:
# we are at the left border
mod_x = self.tile_size - new_x
if new_y - self.tile_size > self.undrawn_y:
# we are at the top
mod_y = self.tile_size - new_y + self.undrawn_y
# only retex if the last position was not at the border
if self.y - self.tile_size <= self.undrawn_y:
retex = True
elif new_y > 0:
# normal movement: calculate the amount of steps and the modulo
div_y, mod_y = divmod(self.tile_size - new_y, self.tile_size)
# only retex if the number of moved steps is not equal to last
if div_y != (self.tile_size - self.y) // self.tile_size:
retex = True
else:
# we are at the bottom
mod_y = self.tile_size - new_y
# if we have to update vertices and textures
if retex:
# calculate the current position on the tilemap
self.div_x = (self.tile_size - new_x - mod_x) // \
self.tile_size
self.div_y = (self.tile_size - new_y - mod_y) // \
self.tile_size + self.mapset.height - 1
self.update_vertex_lists()
# update position if not centered
# XXX: dont ask me why i have to add 1/4 and 3/2 but when i do not
# there are black borders when zooming out
# plz explain wtf is going on there
if not self.center_x:
self.view_x = mod_x-self.tile_size-(self.tile_size-32)//4
self.x = new_x
if not self.center_y:
self.view_y = mod_y-self.tile_size-((self.tile_size-32)*3)//2
self.y = new_y
def update_vertex_lists(self):
# initiate lists of vertex lists, vertices, texture coords, vertices
# counts and map objects for each group
vertices = [[] for value in self.mapset.groups]
tex_coords = [[] for value in self.mapset.groups]
count = [0 for value in self.mapset.groups]
self.cur_objects = [[] for value in self.mapset.groups]
# for each tile in the viewport, update the list of the specific group
for obj, coords in self.mapset.get_tiles(self.tiles_x, self.tiles_y,
self.div_x, self.div_y):
tex_coords[obj.group].extend(obj.tex_coords)
vertices[obj.group].extend(coords)
count[obj.group]+=4
if isinstance(obj, Animation):
self.cur_objects[obj.group].append(obj)
for i, group in enumerate(self.mapset.groups):
if count[i] == 0:
if self.vl_objects[i] is None:
# let the vertex list be None
pass
else:
# there was a vertex list but now no more - delete it
self.vl_objects[i].delete()
self.vl_objects[i] = None
else:
if self.vl_objects[i] is None:
# there was no vertex list but ther now is one - create it
self.vl_objects[i] = self.batch.add(count[i],
pyglet.gl.GL_QUADS,
group,
('v2i', vertices[i]),
('t3f', tex_coords[i]),
('c4B', (255,255,255,255)*count[i]))
else:
# there already is a vertex list - resize and refill
self.vl_objects[i].resize(count[i])
self.vl_objects[i].tex_coords = tex_coords[i]
self.vl_objects[i].vertices = vertices[i]
self.vl_objects[i].colors = (255,255,255,255)*count[i]
# make object list unique
self.cur_objects[i] = list(set(self.cur_objects[i]))
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
elif self.window.keys[pyglet.window.key.PLUS] and \
self.tile_size < 32:
self.tile_size+=8
self._init_view()
elif self.window.keys[pyglet.window.key.MINUS] and \
self.tile_size > 16:
self.tile_size-=8
self._init_view()
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
# mouse position:
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
self.mouse_x = self.mouse_dx
self.mouse_y = self.mouse_dy
x = (self.mouse_x-IF_LEFT-self.view_x
-(self.tile_size-32)//4)//self.tile_size
y = (self.mouse_y-IF_BOTTOM-self.view_y
-((self.tile_size-32)*3)//2)//self.tile_size
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_mouse_motion(self, x, y, dx, dy):
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
for i, group in enumerate(self.mapset.groups):
if len(self.cur_objects[i]) > 0:
pyglet.gl.glBindTexture(self.cur_objects[i][0].tex.target,
self.cur_objects[i][0].tex.id)
for obj in self.cur_objects[i]:
pyglet.gl.glTexSubImage2D(obj.tex.owner.target,
obj.tex.owner.level,
obj.tex.x, obj.tex.y,
obj.tex.width, obj.tex.height,
pyglet.gl.GL_RGBA, pyglet.gl.GL_UNSIGNED_BYTE,
obj.next_frame())

52
lib/window.py Normal file
View file

@ -0,0 +1,52 @@
#!/usr/bin/env python
"""
heroes renaissance
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(1280, 1024, resizable=True, vsync=False)
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
pyglet.clock.schedule(lambda dt: None)
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
elif symbol == pyglet.window.key.P:
pyglet.image.get_buffer_manager().get_color_buffer().save(
'screenshot.png', encoder=PNGRGBEncoder())
class PNGRGBEncoder(pyglet.image.codecs.ImageEncoder):
def encode(self, image, file, filename):
import Image
image = image.get_image_data()
format = image.format
pitch = -(image.width * len(format))
pil_image = Image.fromstring(
format, (image.width, image.height), image.get_data(format, pitch))
try:
#.convert('P', palette=Image.WEB)
pil_image.convert("RGB").save(file)
except Exception, e:
raise ImageEncodeException(e)

363
pyglet/__init__.py Normal file
View file

@ -0,0 +1,363 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''pyglet is a cross-platform games and multimedia package.
Detailed documentation is available at http://www.pyglet.org
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: __init__.py 2284 2008-10-04 02:29:50Z Alex.Holkner $'
import os
import sys
_is_epydoc = hasattr(sys, 'is_epydoc') and sys.is_epydoc
#: The release version of this pyglet installation.
#:
#: Valid only if pyglet was installed from a source or binary distribution
#: (i.e. not in a checked-out copy from SVN).
#:
#: Use setuptools if you need to check for a specific release version, e.g.::
#:
#: >>> import pyglet
#: >>> from pkg_resources import parse_version
#: >>> parse_version(pyglet.version) >= parse_version('1.1')
#: True
#:
version = '1.1.2'
def _require_ctypes_version(version):
# Check ctypes version
import ctypes
req = [int(i) for i in version.split('.')]
have = [int(i) for i in ctypes.__version__.split('.')]
if not tuple(have) >= tuple(req):
raise ImportError('pyglet requires ctypes %s or later.' % version)
_require_ctypes_version('1.0.0')
_enable_optimisations = not __debug__
if getattr(sys, 'frozen', None):
_enable_optimisations = True
#: Global dict of pyglet options. To change an option from its default, you
#: must import ``pyglet`` before any sub-packages. For example::
#:
#: import pyglet
#: pyglet.options['debug_gl'] = False
#:
#: The default options can be overridden from the OS environment. The
#: corresponding environment variable for each option key is prefaced by
#: ``PYGLET_``. For example, in Bash you can set the ``debug_gl`` option with::
#:
#: PYGLET_DEBUG_GL=True; export PYGLET_DEBUG_GL
#:
#: For options requiring a tuple of values, separate each value with a comma.
#:
#: The non-development options are:
#:
#: audio
#: A sequence of the names of audio modules to attempt to load, in
#: order of preference. Valid driver names are:
#:
#: * directsound, the Windows DirectSound audio module (Windows only)
#: * alsa, the ALSA audio module (Linux only)
#: * openal, the OpenAL audio module
#: * silent, no audio
#: debug_lib
#: If True, prints the path of each dynamic library loaded.
#: debug_gl
#: If True, all calls to OpenGL functions are checked afterwards for
#: errors using ``glGetError``. This will severely impact performance,
#: but provides useful exceptions at the point of failure. By default,
#: this option is enabled if ``__debug__`` is (i.e., if Python was not run
#: with the -O option). It is disabled by default when pyglet is "frozen"
#: within a py2exe or py2app library archive.
#: shadow_window
#: By default, pyglet creates a hidden window with a GL context when
#: pyglet.gl is imported. This allows resources to be loaded before
#: the application window is created, and permits GL objects to be
#: shared between windows even after they've been closed. You can
#: disable the creation of the shadow window by setting this option to
#: False. Recommended for advanced devlopers only.
#:
#: **Since:** pyglet 1.1
#: vsync
#: If set, the `pyglet.window.Window.vsync` property is ignored, and
#: this option overrides it (to either force vsync on or off). If unset,
#: or set to None, the `pyglet.window.Window.vsync` property behaves
#: as documented.
#: xsync
#: If set (the default), pyglet will attempt to synchronise the drawing of
#: double-buffered windows to the border updates of the X11 window
#: manager. This improves the appearance of the window during resize
#: operations. This option only affects double-buffered windows on
#: X11 servers supporting the Xsync extension with a window manager
#: that implements the _NET_WM_SYNC_REQUEST protocol.
#:
#: **Since:** pyglet 1.1
#:
options = {
'audio': ('directsound', 'openal', 'alsa', 'silent'),
'font': ('gdiplus', 'win32'), # ignored outside win32; win32 is deprecated
'debug_font': False,
'debug_gl': not _enable_optimisations,
'debug_gl_trace': False,
'debug_gl_trace_args': False,
'debug_graphics_batch': False,
'debug_lib': False,
'debug_media': False,
'debug_texture': False,
'debug_trace': False,
'debug_trace_args': False,
'debug_trace_depth': 1,
'debug_trace_flush': True,
'debug_win32': False,
'debug_x11': False,
'graphics_vbo': True,
'shadow_window': True,
'vsync': None,
'xsync': True,
}
_option_types = {
'audio': tuple,
'font': tuple,
'debug_font': bool,
'debug_gl': bool,
'debug_gl_trace': bool,
'debug_gl_trace_args': bool,
'debug_graphics_batch': bool,
'debug_lib': bool,
'debug_media': bool,
'debug_texture': bool,
'debug_trace': bool,
'debug_trace_args': bool,
'debug_trace_depth': int,
'debug_trace_flush': bool,
'debug_win32': bool,
'debug_x11': bool,
'graphics_vbo': bool,
'shadow_window': bool,
'vsync': bool,
'xsync': bool,
}
def _read_environment():
'''Read defaults for options from environment'''
for key in options:
env = 'PYGLET_%s' % key.upper()
try:
value = os.environ['PYGLET_%s' % key.upper()]
if _option_types[key] is tuple:
options[key] = value.split(',')
elif _option_types[key] is bool:
options[key] = value in ('true', 'TRUE', 'True', '1')
elif _option_types[key] is int:
options[key] = int(value)
except KeyError:
pass
_read_environment()
if sys.platform == 'cygwin':
# This hack pretends that the posix-like ctypes provides windows
# functionality. COM does not work with this hack, so there is no
# DirectSound support.
import ctypes
ctypes.windll = ctypes.cdll
ctypes.oledll = ctypes.cdll
ctypes.WINFUNCTYPE = ctypes.CFUNCTYPE
ctypes.HRESULT = ctypes.c_long
# Call tracing
# ------------
_trace_filename_abbreviations = {}
def _trace_repr(value, size=40):
value = repr(value)
if len(value) > size:
value = value[:size//2-2] + '...' + value[-size//2-1:]
return value
def _trace_frame(frame, indent):
from pyglet import lib
import os
if frame.f_code is lib._TraceFunction.__call__.func_code:
is_ctypes = True
func = frame.f_locals['self']._func
name = func.__name__
location = '[ctypes]'
else:
is_ctypes = False
code = frame.f_code
name = code.co_name
path = code.co_filename
line = code.co_firstlineno
try:
filename = _trace_filename_abbreviations[path]
except KeyError:
# Trim path down
dir = ''
path, filename = os.path.split(path)
while len(dir + filename) < 30:
filename = os.path.join(dir, filename)
path, dir = os.path.split(path)
if not dir:
filename = os.path.join('', filename)
break
else:
filename = os.path.join('...', filename)
_trace_filename_abbreviations[path] = filename
location = '(%s:%d)' % (filename, line)
if indent:
name = 'Called from %s' % name
print '%s%s %s' % (indent, name, location)
if _trace_args:
if is_ctypes:
args = [_trace_repr(arg) for arg in frame.f_locals['args']]
print ' %sargs=(%s)' % (indent, ', '.join(args))
else:
for argname in code.co_varnames[:code.co_argcount]:
try:
argvalue = _trace_repr(frame.f_locals[argname])
print ' %s%s=%s' % (indent, argname, argvalue)
except:
pass
if _trace_flush:
sys.stdout.flush()
def _trace_func(frame, event, arg):
if event == 'call':
indent = ''
for i in range(_trace_depth):
_trace_frame(frame, indent)
indent += ' '
frame = frame.f_back
if not frame:
break
elif event == 'exception':
(exception, value, traceback) = arg
print 'First chance exception raised:', repr(exception)
def _install_trace():
sys.setprofile(_trace_func)
_trace_args = options['debug_trace_args']
_trace_depth = options['debug_trace_depth']
_trace_flush = options['debug_trace_flush']
if options['debug_trace']:
_install_trace()
# Lazy loading
# ------------
class _ModuleProxy(object):
_module = None
def __init__(self, name):
self.__dict__['_module_name'] = name
def __getattr__(self, name):
try:
return getattr(self._module, name)
except AttributeError:
if self._module is not None:
raise
import_name = 'pyglet.%s' % self._module_name
__import__(import_name)
module = sys.modules[import_name]
object.__setattr__(self, '_module', module)
globals()[self._module_name] = module
return getattr(module, name)
def __setattr__(self, name, value):
try:
setattr(self._module, name, value)
except AttributeError:
if self._module is not None:
raise
import_name = 'pyglet.%s' % self._module_name
__import__(import_name)
module = sys.modules[import_name]
object.__setattr__(self, '_module', module)
globals()[self._module_name] = module
setattr(module, name, value)
if not _is_epydoc:
app = _ModuleProxy('app')
clock = _ModuleProxy('clock')
com = _ModuleProxy('com')
event = _ModuleProxy('event')
font = _ModuleProxy('font')
gl = _ModuleProxy('gl')
graphics = _ModuleProxy('graphics')
image = _ModuleProxy('image')
lib = _ModuleProxy('lib')
media = _ModuleProxy('media')
resource = _ModuleProxy('resource')
sprite = _ModuleProxy('sprite')
text = _ModuleProxy('text')
window = _ModuleProxy('window')
# Fool py2exe, py2app into including all top-level modules (doesn't understand
# lazy loading)
if False:
import app
import clock
import com
import event
import font
import gl
import graphics
import image
import lib
import media
import resource
import sprite
import text
import window
# Hack around some epydoc bug that causes it to think pyglet.window is None.
if _is_epydoc:
import window

297
pyglet/app/__init__.py Normal file
View file

@ -0,0 +1,297 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Application-wide functionality.
Most applications need only call `run` after creating one or more windows
to begin processing events. For example, a simple application consisting of
one window is::
from pyglet import app
from pyglet import window
win = window.Window()
app.run()
To handle events on the main event loop, instantiate it manually. The
following example exits the application as soon as any window is closed (the
default policy is to wait until all windows are closed)::
event_loop = app.EventLoop()
@event_loop.event
def on_window_close(window):
event_loop.exit()
:since: pyglet 1.1
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: __init__.py 2140 2008-07-27 04:15:52Z Alex.Holkner $'
import sys
import weakref
from pyglet import clock
from pyglet import event
_is_epydoc = hasattr(sys, 'is_epydoc') and sys.is_epydoc
class WeakSet(object):
'''Set of objects, referenced weakly.
Adding an object to this set does not prevent it from being garbage
collected. Upon being garbage collected, the object is automatically
removed from the set.
'''
def __init__(self):
self._dict = weakref.WeakKeyDictionary()
def add(self, value):
self._dict[value] = True
def remove(self, value):
del self._dict[value]
def __iter__(self):
for key in self._dict.keys():
yield key
def __contains__(self, other):
return other in self._dict
def __len__(self):
return len(self._dict)
#: Set of all open displays. Instances of `Display` are automatically added
#: to this set upon construction. The set uses weak references, so displays
#: are removed from the set when they are no longer referenced.
#:
#: :type: `WeakSet`
displays = WeakSet()
#: Set of all open windows (including invisible windows). Instances of
#: `Window` are automatically added to this set upon construction. The set
#: uses weak references, so windows are removed from the set when they are no
#: longer referenced or are closed explicitly.
#:
#: :type: `WeakSet`
windows = WeakSet()
class BaseEventLoop(event.EventDispatcher):
'''The main run loop of the application.
Calling `run` begins the application event loop, which processes
operating system events, calls `pyglet.clock.tick` to call scheduled
functions and calls `pyglet.window.Window.on_draw` and
`pyglet.window.Window.flip` to update window contents.
Applications can subclass `EventLoop` and override certain methods
to integrate another framework's run loop, or to customise processing
in some other way. You should not in general override `run`, as
this method contains platform-specific code that ensures the application
remains responsive to the user while keeping CPU usage to a minimum.
'''
#: Flag indicating if the event loop will exit in the next iteration.
#: This is
has_exit = False
def run(self):
'''Begin processing events, scheduled functions and window updates.
This method returns when `has_exit` is set to True.
Developers are discouraged from overriding this method, as the
implementation is platform-specific.
'''
raise NotImplementedError('abstract')
def _setup(self):
global event_loop
event_loop = self
# Disable event queuing for dispatch_events
from pyglet.window import Window
Window._enable_event_queue = False
# Dispatch pending events
for window in windows:
window.switch_to()
window.dispatch_pending_events()
def _idle_chance(self):
'''If timeout has expired, manually force an idle loop.
Called by window that have blocked the event loop (e.g. during
resizing).
'''
def idle(self):
'''Called during each iteration of the event loop.
The method is called immediately after any window events (i.e., after
any user input). The method can return a duration after which
the idle method will be called again. The method may be called
earlier if the user creates more input events. The method
can return `None` to only wait for user events.
For example, return ``1.0`` to have the idle method called every
second, or immediately after any user events.
The default implementation dispatches the
`pyglet.window.Window.on_draw` event for all windows and uses
`pyglet.clock.tick` and `pyglet.clock.get_sleep_time` on the default
clock to determine the return value.
This method should be overridden by advanced users only. To have
code execute at regular intervals, use the
`pyglet.clock.schedule` methods.
:rtype: float
:return: The number of seconds before the idle method should
be called again, or `None` to block for user input.
'''
dt = clock.tick(True)
# Redraw all windows
for window in windows:
if window.invalid:
window.switch_to()
window.dispatch_event('on_draw')
window.flip()
# Update timout
return clock.get_sleep_time(True)
def exit(self):
'''Safely exit the event loop at the end of the current iteration.
This method is convenience for setting `has_exit` to ``True``.
'''
self.has_exit = True
def on_window_close(self, window):
'''Default window close handler.'''
if not windows:
self.exit()
if _is_epydoc:
def on_window_close(window):
'''A window was closed.
This event is dispatched when a window is closed. It is not
dispatched if the window's close button was pressed but the
window did not close.
The default handler calls `exit` if no more windows are open. You
can override this handler to base your application exit on some
other policy.
:event:
'''
def on_enter():
'''The event loop is about to begin.
This is dispatched when the event loop is prepared to enter
the main run loop, and represents the last chance for an
application to initialise itself.
:event:
'''
def on_exit():
'''The event loop is about to exit.
After dispatching this event, the `run` method returns (the
application may not actually exit if you have more code
following the `run` invocation).
:event:
'''
BaseEventLoop.register_event_type('on_window_close')
BaseEventLoop.register_event_type('on_enter')
BaseEventLoop.register_event_type('on_exit')
#: The global event loop. Set to the correct instance when an `EventLoop` is
#: started.
#:
#: :type: `EventLoop`
event_loop = None
def run():
'''Begin processing events, scheduled functions and window updates.
This is a convenience function, equivalent to::
EventLoop().run()
'''
EventLoop().run()
def exit():
'''Exit the application event loop.
Causes the application event loop to finish, if an event loop is currently
running. The application may not necessarily exit (for example, there may
be additional code following the `run` invocation).
This is a convenience function, equivalent to::
event_loop.exit()
'''
if event_loop:
event_loop.exit()
if _is_epydoc:
EventLoop = BaseEventLoop
EventLoop.__name__ = 'EventLoop'
del BaseEventLoop
else:
# Permit cyclic import.
import pyglet
pyglet.app = sys.modules[__name__]
if sys.platform == 'darwin':
from pyglet.app.carbon import CarbonEventLoop as EventLoop
elif sys.platform in ('win32', 'cygwin'):
from pyglet.app.win32 import Win32EventLoop as EventLoop
else:
from pyglet.app.xlib import XlibEventLoop as EventLoop

144
pyglet/app/carbon.py Normal file
View file

@ -0,0 +1,144 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: $'
import ctypes
from pyglet.app import windows, BaseEventLoop
from pyglet.window.carbon import carbon, types, constants, _oscheck
EventLoopTimerProc = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p)
kEventDurationForever = ctypes.c_double(constants.kEventDurationForever)
class CarbonEventLoop(BaseEventLoop):
def run(self):
self._setup()
e = ctypes.c_void_p()
event_dispatcher = carbon.GetEventDispatcherTarget()
self._event_loop = event_loop = carbon.GetMainEventLoop()
event_queue = carbon.GetMainEventQueue()
self._timer = timer = ctypes.c_void_p()
idle_event_proc = EventLoopTimerProc(self._timer_proc)
carbon.InstallEventLoopTimer(event_loop,
ctypes.c_double(0.1), #?
kEventDurationForever,
idle_event_proc,
None,
ctypes.byref(timer))
self._force_idle = False
self._allow_polling = True
self.dispatch_event('on_enter')
while not self.has_exit:
if self._force_idle:
duration = 0
else:
duration = kEventDurationForever
if carbon.ReceiveNextEvent(0, None, duration,
True, ctypes.byref(e)) == 0:
carbon.SendEventToEventTarget(e, event_dispatcher)
carbon.ReleaseEvent(e)
# Manual idle event
if carbon.GetNumEventsInQueue(event_queue) == 0 or self._force_idle:
self._force_idle = False
self._timer_proc(timer, None, False)
carbon.RemoveEventLoopTimer(self._timer)
self.dispatch_event('on_exit')
def _stop_polling(self):
carbon.SetEventLoopTimerNextFireTime(self._timer, ctypes.c_double(0.0))
def _enter_blocking(self):
carbon.SetEventLoopTimerNextFireTime(self._timer, ctypes.c_double(0.0))
self._allow_polling = False
def _exit_blocking(self):
self._allow_polling = True
def _timer_proc(self, timer, data, in_events=True):
allow_polling = True
for window in windows:
# Check for live resizing
if window._resizing is not None:
allow_polling = False
old_width, old_height = window._resizing
rect = types.Rect()
carbon.GetWindowBounds(window._window,
constants.kWindowContentRgn,
ctypes.byref(rect))
width = rect.right - rect.left
height = rect.bottom - rect.top
if width != old_width or height != old_height:
window._resizing = width, height
window.switch_to()
window.dispatch_event('on_resize', width, height)
# Check for live dragging
if window._dragging:
allow_polling = False
# Check for deferred recreate
if window._recreate_deferred:
if in_events:
# Break out of ReceiveNextEvent so it can be processed
# in next iteration.
carbon.QuitEventLoop(self._event_loop)
self._force_idle = True
else:
# Do it now.
window._recreate_immediate()
sleep_time = self.idle()
if sleep_time is None:
sleep_time = constants.kEventDurationForever
elif sleep_time < 0.01 and allow_polling and self._allow_polling:
# Switch event loop to polling.
if in_events:
carbon.QuitEventLoop(self._event_loop)
self._force_idle = True
sleep_time = constants.kEventDurationForever
carbon.SetEventLoopTimerNextFireTime(timer, ctypes.c_double(sleep_time))

106
pyglet/app/win32.py Normal file
View file

@ -0,0 +1,106 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id:$
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import ctypes
import time
from pyglet.app import windows, BaseEventLoop
from pyglet.window.win32 import _user32, types, constants
class Win32EventLoop(BaseEventLoop):
def run(self):
self._setup()
self._timer_proc = types.TIMERPROC(self._timer_func)
self._timer = timer = _user32.SetTimer(0, 0, 0, self._timer_proc)
self._polling = False
self._allow_polling = True
msg = types.MSG()
self.dispatch_event('on_enter')
while not self.has_exit:
if self._polling:
while _user32.PeekMessageW(ctypes.byref(msg),
0, 0, 0, constants.PM_REMOVE):
_user32.TranslateMessage(ctypes.byref(msg))
_user32.DispatchMessageW(ctypes.byref(msg))
self._timer_func(0, 0, timer, 0)
else:
_user32.GetMessageW(ctypes.byref(msg), 0, 0, 0)
_user32.TranslateMessage(ctypes.byref(msg))
_user32.DispatchMessageW(ctypes.byref(msg))
# Manual idle event
msg_types = \
_user32.GetQueueStatus(constants.QS_ALLINPUT) & 0xffff0000
if (msg.message != constants.WM_TIMER and
not msg_types & ~(constants.QS_TIMER<<16)):
self._timer_func(0, 0, timer, 0)
self.dispatch_event('on_exit')
def _idle_chance(self):
if (self._next_idle_time is not None and
self._next_idle_time <= time.time()):
self._timer_func(0, 0, self._timer, 0)
def _timer_func(self, hwnd, msg, timer, t):
sleep_time = self.idle()
if sleep_time is None:
# Block indefinitely
millis = constants.USER_TIMER_MAXIMUM
self._next_idle_time = None
self._polling = False
_user32.SetTimer(0, timer, millis, self._timer_proc)
elif sleep_time < 0.01 and self._allow_polling:
# Degenerate to polling
millis = constants.USER_TIMER_MAXIMUM
self._next_idle_time = 0.
if not self._polling:
self._polling = True
_user32.SetTimer(0, timer, millis, self._timer_proc)
else:
# Block until timer
# XXX hack to avoid oversleep; needs to be api
sleep_time = max(sleep_time - 0.01, 0)
millis = int(sleep_time * 1000)
self._next_idle_time = time.time() + sleep_time
self._polling = False
_user32.SetTimer(0, timer, millis, self._timer_proc)

99
pyglet/app/xlib.py Normal file
View file

@ -0,0 +1,99 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: xlib.py 2045 2008-05-01 16:59:49Z Alex.Holkner $'
import select
import weakref
from pyglet.app import displays, windows, BaseEventLoop
from pyglet.window.xlib import xlib
class XlibEventLoop(BaseEventLoop):
def run(self):
self._setup()
e = xlib.XEvent()
t = 0
sleep_time = 0.
self.dispatch_event('on_enter')
while not self.has_exit:
# Check for already pending events
for display in displays:
if xlib.XPending(display._display):
pending_displays = (display,)
break
else:
# None found; select on all file descriptors or timeout
iwtd = self.get_select_files()
pending_displays, _, _ = select.select(iwtd, (), (), sleep_time)
# Dispatch platform events
for display in pending_displays:
while xlib.XPending(display._display):
xlib.XNextEvent(display._display, e)
# Key events are filtered by the xlib window event
# handler so they get a shot at the prefiltered event.
if e.xany.type not in (xlib.KeyPress, xlib.KeyRelease):
if xlib.XFilterEvent(e, e.xany.window):
continue
try:
window = display._window_map[e.xany.window]
except KeyError:
continue
window.dispatch_platform_event(e)
# Dispatch resize events
for window in windows:
if window._needs_resize:
window.switch_to()
window.dispatch_event('on_resize',
window._width, window._height)
window.dispatch_event('on_expose')
window._needs_resize = False
sleep_time = self.idle()
self.dispatch_event('on_exit')
def get_select_files(self):
return list(displays)

948
pyglet/clock.py Normal file
View file

@ -0,0 +1,948 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Precise framerate calculation, scheduling and framerate limiting.
Measuring time
==============
The `tick` and `get_fps` functions can be used in conjunction to fulfil most
games' basic requirements::
from pylet import clock
while True:
dt = clock.tick()
# ... update and render ...
print 'FPS is %f' % clock.get_fps()
The ``dt`` value returned gives the number of seconds (as a float) since the
last "tick".
The `get_fps` function averages the framerate over a sliding window of
approximately 1 second. (You can calculate the instantaneous framerate by
taking the reciprocal of ``dt``).
Always remember to `tick` the clock!
Limiting frame-rate
===================
The framerate can be limited::
clock.set_fps_limit(60)
This causes `clock` to sleep during each `tick` in an attempt to keep the
number of ticks (frames) per second below 60.
The implementation uses platform-dependent high-resolution sleep functions
to achieve better accuracy with busy-waiting than would be possible using
just the `time` module.
Scheduling
==========
You can schedule a function to be called every time the clock is ticked::
def callback(dt):
print '%f seconds since last callback' % dt
clock.schedule(callback)
The `schedule_interval` method causes a function to be called every "n"
seconds::
clock.schedule_interval(callback, .5) # called twice a second
The `schedule_once` method causes a function to be called once "n" seconds
in the future::
clock.schedule_once(callback, 5) # called in 5 seconds
All of the `schedule` methods will pass on any additional args or keyword args
you specify ot the callback function::
def animate(dt, velocity, sprite):
sprite.position += dt * velocity
clock.schedule(animate, velocity=5.0, sprite=alien)
You can cancel a function scheduled with any of these methods using
`unschedule`::
clock.unschedule(animate)
Displaying FPS
==============
The ClockDisplay class provides a simple FPS counter. You should create
an instance of ClockDisplay once during the application's start up::
fps_display = clock.ClockDisplay()
Call draw on the ClockDisplay object for each frame::
fps_display.draw()
There are several options to change the font, color and text displayed
within the __init__ method.
Using multiple clocks
=====================
The clock functions are all relayed to an instance of `Clock` which is
initalised with the module. You can get this instance to use directly::
clk = clock.get_default()
You can also replace the default clock with your own:
myclk = clock.Clock()
clock.set_default(myclk)
Each clock maintains its own set of scheduled functions and FPS
limiting/measurement. Each clock must be "ticked" separately.
Multiple and derived clocks potentially allow you to separate "game-time" and
"wall-time", or to synchronise your clock to an audio or video stream instead
of the system clock.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: clock.py 2298 2008-10-06 09:13:09Z Alex.Holkner $'
import time
import sys
import operator
import ctypes
import ctypes.util
import pyglet.lib
if sys.platform in ('win32', 'cygwin'):
# Win32 Sleep function is only 10-millisecond resolution, so instead
# use a waitable timer object, which has up to 100-nanosecond resolution
# (hardware and implementation dependent, of course).
_kernel32 = ctypes.windll.kernel32
class _ClockBase(object):
def __init__(self):
self._timer = _kernel32.CreateWaitableTimerA(ctypes.c_void_p(),
True, ctypes.c_void_p())
def sleep(self, microseconds):
delay = ctypes.c_longlong(int(-microseconds * 10))
_kernel32.SetWaitableTimer(self._timer, ctypes.byref(delay),
0, ctypes.c_void_p(), ctypes.c_void_p(), False)
_kernel32.WaitForSingleObject(self._timer, 0xffffffff)
else:
_c = pyglet.lib.load_library('c', darwin='/usr/lib/libc.dylib')
_c.usleep.argtypes = [ctypes.c_ulong]
class _ClockBase(object):
def sleep(self, microseconds):
_c.usleep(int(microseconds))
class _ScheduledItem(object):
__slots__ = ['func', 'args', 'kwargs']
def __init__(self, func, args, kwargs):
self.func = func
self.args = args
self.kwargs = kwargs
class _ScheduledIntervalItem(object):
__slots__ = ['func', 'interval', 'last_ts', 'next_ts',
'args', 'kwargs']
def __init__(self, func, interval, last_ts, next_ts, args, kwargs):
self.func = func
self.interval = interval
self.last_ts = last_ts
self.next_ts = next_ts
self.args = args
self.kwargs = kwargs
def _dummy_schedule_func(*args, **kwargs):
'''Dummy function that does nothing, placed onto zombie scheduled items
to ensure they have no side effect if already queued inside tick() method.
'''
pass
class Clock(_ClockBase):
'''Class for calculating and limiting framerate, and for calling scheduled
functions.
'''
#: The minimum amount of time in seconds this clock will attempt to sleep
#: for when framerate limiting. Higher values will increase the
#: accuracy of the limiting but also increase CPU usage while
#: busy-waiting. Lower values mean the process sleeps more often, but is
#: prone to over-sleep and run at a potentially lower or uneven framerate
#: than desired.
MIN_SLEEP = 0.005
#: The amount of time in seconds this clock subtracts from sleep values
#: to compensate for lazy operating systems.
SLEEP_UNDERSHOOT = MIN_SLEEP - 0.001
# List of functions to call every tick.
_schedule_items = None
# List of schedule interval items kept in sort order.
_schedule_interval_items = None
# If True, a sleep(0) is inserted on every tick.
_force_sleep = False
def __init__(self, fps_limit=None, time_function=time.time):
'''Initialise a Clock, with optional framerate limit and custom
time function.
:Parameters:
`fps_limit` : float
If not None, the maximum allowable framerate. Defaults
to None. Deprecated in pyglet 1.1.
`time_function` : function
Function to return the elapsed time of the application,
in seconds. Defaults to time.time, but can be replaced
to allow for easy time dilation effects or game pausing.
'''
super(Clock, self).__init__()
self.time = time_function
self.next_ts = self.time()
self.last_ts = None
self.times = []
self.set_fps_limit(fps_limit)
self.cumulative_time = 0
self._schedule_items = []
self._schedule_interval_items = []
def tick(self, poll=False):
'''Signify that one frame has passed.
This will call any scheduled functions that have elapsed.
:Parameters:
`poll` : bool
If True, the function will call any scheduled functions
but will not sleep or busy-wait for any reason. Recommended
for advanced applications managing their own sleep timers
only.
Since pyglet 1.1.
:rtype: float
:return: The number of seconds since the last "tick", or 0 if this was
the first frame.
'''
if poll:
if self.period_limit:
self.next_ts = self.next_ts + self.period_limit
else:
if self.period_limit:
self._limit()
if self._force_sleep:
self.sleep(0)
ts = self.time()
if self.last_ts is None:
delta_t = 0
else:
delta_t = ts - self.last_ts
self.times.insert(0, delta_t)
if len(self.times) > self.window_size:
self.cumulative_time -= self.times.pop()
self.cumulative_time += delta_t
self.last_ts = ts
# Call functions scheduled for every frame
# Dupe list just in case one of the items unchedules itself
for item in list(self._schedule_items):
item.func(delta_t, *item.args, **item.kwargs)
# Call all scheduled interval functions and reschedule for future.
need_resort = False
# Dupe list just in case one of the items unchedules itself
for item in list(self._schedule_interval_items):
if item.next_ts > ts:
break
item.func(ts - item.last_ts, *item.args, **item.kwargs)
if item.interval:
# Try to keep timing regular, even if overslept this time;
# but don't schedule in the past (which could lead to
# infinitely-worsing error).
item.next_ts = item.last_ts + item.interval
item.last_ts = ts
if item.next_ts <= ts:
if ts - item.next_ts < 0.05:
# Only missed by a little bit, keep the same schedule
item.next_ts = ts + item.interval
else:
# Missed by heaps, do a soft reschedule to avoid
# lumping everything together.
item.next_ts = self._get_soft_next_ts(ts, item.interval)
# Fake last_ts to avoid repeatedly over-scheduling in
# future. Unfortunately means the next reported dt is
# incorrect (looks like interval but actually isn't).
item.last_ts = item.next_ts - item.interval
need_resort = True
else:
item.next_ts = None
# Remove finished one-shots.
self._schedule_interval_items = \
[item for item in self._schedule_interval_items \
if item.next_ts is not None]
if need_resort:
# TODO bubble up changed items might be faster
self._schedule_interval_items.sort(key=lambda a: a.next_ts)
return delta_t
def _limit(self):
'''Sleep until the next frame is due. Called automatically by
`tick` if a framerate limit has been set.
This method uses several heuristics to determine whether to
sleep or busy-wait (or both).
'''
ts = self.time()
# Sleep to just before the desired time
sleeptime = self.get_sleep_time(False)
while sleeptime - self.SLEEP_UNDERSHOOT > self.MIN_SLEEP:
self.sleep(1000000 * (sleeptime - self.SLEEP_UNDERSHOOT))
sleeptime = self.get_sleep_time(False)
# Busy-loop CPU to get closest to the mark
sleeptime = self.next_ts - self.time()
while sleeptime > 0:
sleeptime = self.next_ts - self.time()
if sleeptime < -2 * self.period_limit:
# Missed the time by a long shot, let's reset the clock
# print >> sys.stderr, 'Step %f' % -sleeptime
self.next_ts = ts + 2 * self.period_limit
else:
# Otherwise keep the clock steady
self.next_ts = self.next_ts + self.period_limit
def get_sleep_time(self, sleep_idle):
'''Get the time until the next item is scheduled.
This method considers all scheduled items and the current
``fps_limit``, if any.
Applications can choose to continue receiving updates at the
maximum framerate during idle time (when no functions are scheduled),
or they can sleep through their idle time and allow the CPU to
switch to other processes or run in low-power mode.
If `sleep_idle` is ``True`` the latter behaviour is selected, and
``None`` will be returned if there are no scheduled items.
Otherwise, if `sleep_idle` is ``False``, a sleep time allowing
the maximum possible framerate (considering ``fps_limit``) will
be returned; or an earlier time if a scheduled function is ready.
:Parameters:
`sleep_idle` : bool
If True, the application intends to sleep through its idle
time; otherwise it will continue ticking at the maximum
frame rate allowed.
:rtype: float
:return: Time until the next scheduled event in seconds, or ``None``
if there is no event scheduled.
:since: pyglet 1.1
'''
if self._schedule_items or not sleep_idle:
if not self.period_limit:
return 0.
else:
wake_time = self.next_ts
if self._schedule_interval_items:
wake_time = min(wake_time,
self._schedule_interval_items[0].next_ts)
return max(wake_time - self.time(), 0.)
if self._schedule_interval_items:
return max(self._schedule_interval_items[0].next_ts - self.time(),
0)
return None
def set_fps_limit(self, fps_limit):
'''Set the framerate limit.
The framerate limit applies only when a function is scheduled
for every frame. That is, the framerate limit can be exceeded by
scheduling a function for a very small period of time.
:Parameters:
`fps_limit` : float
Maximum frames per second allowed, or None to disable
limiting.
:deprecated: Use `pyglet.app.run` and `schedule_interval` instead.
'''
if not fps_limit:
self.period_limit = None
else:
self.period_limit = 1. / fps_limit
self.window_size = fps_limit or 60
def get_fps_limit(self):
'''Get the framerate limit.
:rtype: float
:return: The framerate limit previously set in the constructor or
`set_fps_limit`, or None if no limit was set.
'''
if self.period_limit:
return 1. / self.period_limit
else:
return 0
def get_fps(self):
'''Get the average FPS of recent history.
The result is the average of a sliding window of the last "n" frames,
where "n" is some number designed to cover approximately 1 second.
:rtype: float
:return: The measured frames per second.
'''
if not self.cumulative_time:
return 0
return len(self.times) / self.cumulative_time
def schedule(self, func, *args, **kwargs):
'''Schedule a function to be called every frame.
The function should have a prototype that includes ``dt`` as the
first argument, which gives the elapsed time, in seconds, since the
last clock tick. Any additional arguments given to this function
are passed on to the callback::
def callback(dt, *args, **kwargs):
pass
:Parameters:
`func` : function
The function to call each frame.
'''
item = _ScheduledItem(func, args, kwargs)
self._schedule_items.append(item)
def _schedule_item(self, func, last_ts, next_ts, interval, *args, **kwargs):
item = _ScheduledIntervalItem(
func, interval, last_ts, next_ts, args, kwargs)
# Insert in sort order
for i, other in enumerate(self._schedule_interval_items):
if other.next_ts > next_ts:
self._schedule_interval_items.insert(i, item)
break
else:
self._schedule_interval_items.append(item)
def schedule_interval(self, func, interval, *args, **kwargs):
'''Schedule a function to be called every `interval` seconds.
Specifying an interval of 0 prevents the function from being
called again (see `schedule` to call a function as often as possible).
The callback function prototype is the same as for `schedule`.
:Parameters:
`func` : function
The function to call when the timer lapses.
`interval` : float
The number of seconds to wait between each call.
'''
last_ts = self.last_ts or self.next_ts
# Schedule from now, unless now is sufficiently close to last_ts, in
# which case use last_ts. This clusters together scheduled items that
# probably want to be scheduled together. The old (pre 1.1.1)
# behaviour was to always use self.last_ts, and not look at ts. The
# new behaviour is needed because clock ticks can now be quite
# irregular, and span several seconds.
ts = self.time()
if ts - last_ts > 0.2:
last_ts = ts
next_ts = last_ts + interval
self._schedule_item(func, last_ts, next_ts, interval, *args, **kwargs)
def schedule_interval_soft(self, func, interval, *args, **kwargs):
'''Schedule a function to be called every `interval` seconds,
beginning at a time that does not coincide with other scheduled
events.
This method is similar to `schedule_interval`, except that the
clock will move the interval out of phase with other scheduled
functions so as to distribute CPU more load evenly over time.
This is useful for functions that need to be called regularly,
but not relative to the initial start time. `pyglet.media`
does this for scheduling audio buffer updates, which need to occur
regularly -- if all audio updates are scheduled at the same time
(for example, mixing several tracks of a music score, or playing
multiple videos back simultaneously), the resulting load on the
CPU is excessive for those intervals but idle outside. Using
the soft interval scheduling, the load is more evenly distributed.
Soft interval scheduling can also be used as an easy way to schedule
graphics animations out of phase; for example, multiple flags
waving in the wind.
:since: pyglet 1.1
:Parameters:
`func` : function
The function to call when the timer lapses.
`interval` : float
The number of seconds to wait between each call.
'''
last_ts = self.last_ts or self.next_ts
# See schedule_interval
ts = self.time()
if ts - last_ts > 0.2:
last_ts = ts
next_ts = self._get_soft_next_ts(last_ts, interval)
last_ts = next_ts - interval
self._schedule_item(func, last_ts, next_ts, interval, *args, **kwargs)
def _get_soft_next_ts(self, last_ts, interval):
def taken(ts, e):
'''Return True if the given time has already got an item
scheduled nearby.
'''
for item in self._schedule_interval_items:
if abs(item.next_ts - ts) <= e:
return True
elif item.next_ts > ts + e:
return False
return False
# Binary division over interval:
#
# 0 interval
# |--------------------------|
# 5 3 6 2 7 4 8 1 Order of search
#
# i.e., first scheduled at interval,
# then at interval/2
# then at interval/4
# then at interval*3/4
# then at ...
#
# Schedule is hopefully then evenly distributed for any interval,
# and any number of scheduled functions.
next_ts = last_ts + interval
if not taken(next_ts, interval / 4):
return next_ts
dt = interval
divs = 1
while True:
next_ts = last_ts
for i in range(divs - 1):
next_ts += dt
if not taken(next_ts, dt / 4):
return next_ts
dt /= 2
divs *= 2
# Avoid infinite loop in pathological case
if divs > 16:
return next_ts
def schedule_once(self, func, delay, *args, **kwargs):
'''Schedule a function to be called once after `delay` seconds.
The callback function prototype is the same as for `schedule`.
:Parameters:
`func` : function
The function to call when the timer lapses.
`delay` : float
The number of seconds to wait before the timer lapses.
'''
last_ts = self.last_ts or self.next_ts
# See schedule_interval
ts = self.time()
if ts - last_ts > 0.2:
last_ts = ts
next_ts = last_ts + delay
self._schedule_item(func, last_ts, next_ts, 0, *args, **kwargs)
def unschedule(self, func):
'''Remove a function from the schedule.
If the function appears in the schedule more than once, all occurances
are removed. If the function was not scheduled, no error is raised.
:Parameters:
`func` : function
The function to remove from the schedule.
'''
# First replace zombie items' func with a dummy func that does
# nothing, in case the list has already been cloned inside tick().
# (Fixes issue 326).
for item in self._schedule_items:
if item.func == func:
item.func = _dummy_schedule_func
for item in self._schedule_interval_items:
if item.func == func:
item.func = _dummy_schedule_func
# Now remove matching items from both schedule lists.
self._schedule_items = \
[item for item in self._schedule_items \
if item.func is not _dummy_schedule_func]
self._schedule_interval_items = \
[item for item in self._schedule_interval_items \
if item.func is not _dummy_schedule_func]
# Default clock.
_default = Clock()
def set_default(default):
'''Set the default clock to use for all module-level functions.
By default an instance of `Clock` is used.
:Parameters:
`default` : `Clock`
The default clock to use.
'''
global _default
_default = default
def get_default():
'''Return the `Clock` instance that is used by all module-level
clock functions.
:rtype: `Clock`
:return: The default clock.
'''
return _default
def tick(poll=False):
'''Signify that one frame has passed on the default clock.
This will call any scheduled functions that have elapsed.
:Parameters:
`poll` : bool
If True, the function will call any scheduled functions
but will not sleep or busy-wait for any reason. Recommended
for advanced applications managing their own sleep timers
only.
Since pyglet 1.1.
:rtype: float
:return: The number of seconds since the last "tick", or 0 if this was the
first frame.
'''
return _default.tick(poll)
def get_sleep_time(sleep_idle):
'''Get the time until the next item is scheduled on the default clock.
See `Clock.get_sleep_time` for details.
:Parameters:
`sleep_idle` : bool
If True, the application intends to sleep through its idle
time; otherwise it will continue ticking at the maximum
frame rate allowed.
:rtype: float
:return: Time until the next scheduled event in seconds, or ``None``
if there is no event scheduled.
:since: pyglet 1.1
'''
return _default.get_sleep_time(sleep_idle)
def get_fps():
'''Return the current measured FPS of the default clock.
:rtype: float
'''
return _default.get_fps()
def set_fps_limit(fps_limit):
'''Set the framerate limit for the default clock.
:Parameters:
`fps_limit` : float
Maximum frames per second allowed, or None to disable
limiting.
:deprecated: Use `pyglet.app.run` and `schedule_interval` instead.
'''
_default.set_fps_limit(fps_limit)
def get_fps_limit():
'''Get the framerate limit for the default clock.
:return: The framerate limit previously set by `set_fps_limit`, or None if
no limit was set.
'''
return _default.get_fps_limit()
def schedule(func, *args, **kwargs):
'''Schedule 'func' to be called every frame on the default clock.
The arguments passed to func are ``dt``, followed by any ``*args`` and
``**kwargs`` given here.
:Parameters:
`func` : function
The function to call each frame.
'''
_default.schedule(func, *args, **kwargs)
def schedule_interval(func, interval, *args, **kwargs):
'''Schedule 'func' to be called every 'interval' seconds on the default
clock.
The arguments passed to 'func' are 'dt' (time since last function call),
followed by any ``*args`` and ``**kwargs`` given here.
:Parameters:
`func` : function
The function to call when the timer lapses.
`interval` : float
The number of seconds to wait between each call.
'''
_default.schedule_interval(func, interval, *args, **kwargs)
def schedule_interval_soft(func, interval, *args, **kwargs):
'''Schedule 'func' to be called every 'interval' seconds on the default
clock, beginning at a time that does not coincide with other scheduled
events.
The arguments passed to 'func' are 'dt' (time since last function call),
followed by any ``*args`` and ``**kwargs`` given here.
:see: `Clock.schedule_interval_soft`
:since: pyglet 1.1
:Parameters:
`func` : function
The function to call when the timer lapses.
`interval` : float
The number of seconds to wait between each call.
'''
_default.schedule_interval_soft(func, interval, *args, **kwargs)
def schedule_once(func, delay, *args, **kwargs):
'''Schedule 'func' to be called once after 'delay' seconds (can be
a float) on the default clock. The arguments passed to 'func' are
'dt' (time since last function call), followed by any ``*args`` and
``**kwargs`` given here.
If no default clock is set, the func is queued and will be scheduled
on the default clock as soon as it is created.
:Parameters:
`func` : function
The function to call when the timer lapses.
`delay` : float
The number of seconds to wait before the timer lapses.
'''
_default.schedule_once(func, delay, *args, **kwargs)
def unschedule(func):
'''Remove 'func' from the default clock's schedule. No error
is raised if the func was never scheduled.
:Parameters:
`func` : function
The function to remove from the schedule.
'''
_default.unschedule(func)
class ClockDisplay(object):
'''Display current clock values, such as FPS.
This is a convenience class for displaying diagnostics such as the
framerate. See the module documentation for example usage.
:Ivariables:
`label` : `pyglet.font.Text`
The label which is displayed.
'''
def __init__(self,
font=None,
interval=0.25,
format='%(fps).2f',
color=(.5, .5, .5, .5),
clock=None):
'''Create a ClockDisplay.
All parameters are optional. By default, a large translucent
font will be used to display the FPS to two decimal places.
:Parameters:
`font` : `pyglet.font.Font`
The font to format text in.
`interval` : float
The number of seconds between updating the display.
`format` : str
A format string describing the format of the text. This
string is modulated with the dict ``{'fps' : fps}``.
`color` : 4-tuple of float
The color, including alpha, passed to ``glColor4f``.
`clock` : `Clock`
The clock which determines the time. If None, the default
clock is used.
'''
if clock is None:
clock = _default
self.clock = clock
self.clock.schedule_interval(self.update_text, interval)
if not font:
from pyglet.font import load as load_font
font = load_font('', 36, bold=True)
import pyglet.font
self.label = pyglet.font.Text(font, '', color=color, x=10, y=10)
self.format = format
def unschedule(self):
'''Remove the display from its clock's schedule.
`ClockDisplay` uses `Clock.schedule_interval` to periodically update
its display label. Even if the ClockDisplay is not being used any
more, its update method will still be scheduled, which can be a
resource drain. Call this method to unschedule the update method
and allow the ClockDisplay to be garbage collected.
:since: pyglet 1.1
'''
self.clock.unschedule(self.update_text)
def update_text(self, dt=0):
'''Scheduled method to update the label text.'''
fps = self.clock.get_fps()
self.label.text = self.format % {'fps': fps}
def draw(self):
'''Method called each frame to render the label.'''
self.label.draw()
def test_clock():
import sys
import getopt
test_seconds = 1
test_fps = 60
show_fps = False
options, args = getopt.getopt(sys.argv[1:], 'vht:f:',
['time=', 'fps=', 'help'])
for key, value in options:
if key in ('-t', '--time'):
test_seconds = float(value)
elif key in ('-f', '--fps'):
test_fps = float(value)
elif key in ('-v'):
show_fps = True
elif key in ('-h', '--help'):
print ('Usage: clock.py <options>\n'
'\n'
'Options:\n'
' -t --time Number of seconds to run for.\n'
' -f --fps Target FPS.\n'
'\n'
'Tests the clock module by measuring how close we can\n'
'get to the desired FPS by sleeping and busy-waiting.')
sys.exit(0)
set_fps_limit(test_fps)
start = time.time()
# Add one because first frame has no update interval.
n_frames = int(test_seconds * test_fps + 1)
print 'Testing %f FPS for %f seconds...' % (test_fps, test_seconds)
for i in xrange(n_frames):
tick()
if show_fps:
print get_fps()
total_time = time.time() - start
total_error = total_time - test_seconds
print 'Total clock error: %f secs' % total_error
print 'Total clock error / secs: %f secs/secs' % \
(total_error / test_seconds)
# Not fair to add the extra frame in this calc, since no-one's interested
# in the startup situation.
print 'Average FPS: %f' % ((n_frames - 1) / total_time)
if __name__ == '__main__':
test_clock()

154
pyglet/com.py Normal file
View file

@ -0,0 +1,154 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id:$
'''Minimal Windows COM interface.
Allows pyglet to use COM interfaces on Windows without comtypes. Unlike
comtypes, this module does not provide property interfaces, read typelibs,
nice-ify return values or permit Python implementations of COM interfaces. We
don't need anything that sophisticated to work with DirectX.
All interfaces should derive from IUnknown (defined in this module). The
Python COM interfaces are actually pointers to the implementation (take note
when translating methods that take an interface as argument).
Interfaces can define methods::
class IDirectSound8(com.IUnknown):
_methods_ = [
('CreateSoundBuffer', com.STDMETHOD()),
('GetCaps', com.STDMETHOD(LPDSCAPS)),
...
]
Only use STDMETHOD or METHOD for the method types (not ordinary ctypes
function types). The 'this' pointer is bound automatically... e.g., call::
device = IDirectSound8()
DirectSoundCreate8(None, ctypes.byref(device), None)
caps = DSCAPS()
device.GetCaps(caps)
Because STDMETHODs use HRESULT as the return type, there is no need to check
the return value.
Don't forget to manually manage memory... call Release() when you're done with
an interface.
'''
import ctypes
import sys
if sys.platform != 'win32':
raise ImportError('pyglet.com requires a Windows build of Python')
class GUID(ctypes.Structure):
_fields_ = [
('Data1', ctypes.c_ulong),
('Data2', ctypes.c_ushort),
('Data3', ctypes.c_ushort),
('Data4', ctypes.c_ubyte * 8)
]
def __init__(self, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8):
self.Data1 = l
self.Data2 = w1
self.Data3 = w2
self.Data4[:] = (b1, b2, b3, b4, b5, b6, b7, b8)
LPGUID = ctypes.POINTER(GUID)
IID = GUID
REFIID = ctypes.POINTER(IID)
class METHOD(object):
'''COM method.'''
def __init__(self, restype, *args):
self.restype = restype
self.argtypes = args
def get_field(self):
return ctypes.WINFUNCTYPE(self.restype, *self.argtypes)
class STDMETHOD(METHOD):
'''COM method with HRESULT return value.'''
def __init__(self, *args):
super(STDMETHOD, self).__init__(ctypes.HRESULT, *args)
class COMMethodInstance(object):
'''Binds a COM interface method.'''
def __init__(self, name, i, method):
self.name = name
self.i = i
self.method = method
def __get__(self, obj, tp):
if obj is not None:
return lambda *args: \
self.method.get_field()(self.i, self.name)(obj, *args)
raise AttributeError()
class COMInterface(ctypes.Structure):
'''Dummy struct to serve as the type of all COM pointers.'''
_fields_ = [
('lpVtbl', ctypes.c_void_p),
]
class InterfaceMetaclass(type(ctypes.POINTER(COMInterface))):
'''Creates COM interface pointers.'''
def __new__(cls, name, bases, dct):
methods = []
for base in bases[::-1]:
methods.extend(base.__dict__.get('_methods_', ()))
methods.extend(dct.get('_methods_', ()))
for i, (n, method) in enumerate(methods):
dct[n] = COMMethodInstance(n, i, method)
dct['_type_'] = COMInterface
return super(InterfaceMetaclass, cls).__new__(cls, name, bases, dct)
class Interface(ctypes.POINTER(COMInterface)):
'''Base COM interface pointer.'''
__metaclass__ = InterfaceMetaclass
class IUnknown(Interface):
_methods_ = [
('QueryInterface', STDMETHOD(REFIID, ctypes.c_void_p)),
('AddRef', METHOD(ctypes.c_int)),
('Release', METHOD(ctypes.c_int))
]

435
pyglet/event.py Normal file
View file

@ -0,0 +1,435 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Event dispatch framework.
All objects that produce events in pyglet implement `EventDispatcher`,
providing a consistent interface for registering and manipulating event
handlers. A commonly used event dispatcher is `pyglet.window.Window`.
Event types
===========
For each event dispatcher there is a set of events that it dispatches; these
correspond with the type of event handlers you can attach. Event types are
identified by their name, for example, ''on_resize''. If you are creating a
new class which implements `EventDispatcher`, you must call
`EventDispatcher.register_event_type` for each event type.
Attaching event handlers
========================
An event handler is simply a function or method. You can attach an event
handler by setting the appropriate function on the instance::
def on_resize(width, height):
# ...
dispatcher.on_resize = on_resize
There is also a convenience decorator that reduces typing::
@dispatcher.event
def on_resize(width, height):
# ...
You may prefer to subclass and override the event handlers instead::
class MyDispatcher(DispatcherClass):
def on_resize(self, width, height):
# ...
Event handler stack
===================
When attaching an event handler to a dispatcher using the above methods, it
replaces any existing handler (causing the original handler to no longer be
called). Each dispatcher maintains a stack of event handlers, allowing you to
insert an event handler "above" the existing one rather than replacing it.
There are two main use cases for "pushing" event handlers:
* Temporarily intercepting the events coming from the dispatcher by pushing a
custom set of handlers onto the dispatcher, then later "popping" them all
off at once.
* Creating "chains" of event handlers, where the event propogates from the
top-most (most recently added) handler to the bottom, until a handler
takes care of it.
Use `EventDispatcher.push_handlers` to create a new level in the stack and
attach handlers to it. You can push several handlers at once::
dispatcher.push_handlers(on_resize, on_key_press)
If your function handlers have different names to the events they handle, use
keyword arguments::
dispatcher.push_handlers(on_resize=my_resize,
on_key_press=my_key_press)
After an event handler has processed an event, it is passed on to the
next-lowest event handler, unless the handler returns `EVENT_HANDLED`, which
prevents further propogation.
To remove all handlers on the top stack level, use
`EventDispatcher.pop_handlers`.
Note that any handlers pushed onto the stack have precedence over the
handlers set directly on the instance (for example, using the methods
described in the previous section), regardless of when they were set.
For example, handler ``foo`` is called before handler ``bar`` in the following
example::
dispatcher.push_handlers(on_resize=foo)
dispatcher.on_resize = bar
Dispatching events
==================
pyglet uses a single-threaded model for all application code. Event
handlers are only ever invoked as a result of calling
EventDispatcher.dispatch_events`.
It is up to the specific event dispatcher to queue relevant events until they
can be dispatched, at which point the handlers are called in the order the
events were originally generated.
This implies that your application runs with a main loop that continously
updates the application state and checks for new events::
while True:
dispatcher.dispatch_events()
# ... additional per-frame processing
Not all event dispatchers require the call to ``dispatch_events``; check with
the particular class documentation.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: event.py 1824 2008-02-28 09:22:01Z Alex.Holkner $'
import inspect
EVENT_HANDLED = True
EVENT_UNHANDLED = None
class EventException(Exception):
'''An exception raised when an event handler could not be attached.
'''
pass
class EventDispatcher(object):
'''Generic event dispatcher interface.
See the module docstring for usage.
'''
# Placeholder empty stack; real stack is created only if needed
_event_stack = ()
@classmethod
def register_event_type(cls, name):
'''Register an event type with the dispatcher.
Registering event types allows the dispatcher to validate event
handler names as they are attached, and to search attached objects for
suitable handlers.
:Parameters:
`name` : str
Name of the event to register.
'''
if not hasattr(cls, 'event_types'):
cls.event_types = []
cls.event_types.append(name)
return name
def push_handlers(self, *args, **kwargs):
'''Push a level onto the top of the handler stack, then attach zero or
more event handlers.
If keyword arguments are given, they name the event type to attach.
Otherwise, a callable's `__name__` attribute will be used. Any other
object may also be specified, in which case it will be searched for
callables with event names.
'''
# Create event stack if necessary
if type(self._event_stack) is tuple:
self._event_stack = []
# Place dict full of new handlers at beginning of stack
self._event_stack.insert(0, {})
self.set_handlers(*args, **kwargs)
def _get_handlers(self, args, kwargs):
'''Implement handler matching on arguments for set_handlers and
remove_handlers.
'''
for object in args:
if inspect.isroutine(object):
# Single magically named function
name = object.__name__
if name not in self.event_types:
raise EventException('Unknown event "%s"' % name)
yield name, object
else:
# Single instance with magically named methods
for name in dir(object):
if name in self.event_types:
yield name, getattr(object, name)
for name, handler in kwargs.items():
# Function for handling given event (no magic)
if name not in self.event_types:
raise EventException('Unknown event "%s"' % name)
yield name, handler
def set_handlers(self, *args, **kwargs):
'''Attach one or more event handlers to the top level of the handler
stack.
See `push_handlers` for the accepted argument types.
'''
# Create event stack if necessary
if type(self._event_stack) is tuple:
self._event_stack = [{}]
for name, handler in self._get_handlers(args, kwargs):
self.set_handler(name, handler)
def set_handler(self, name, handler):
'''Attach a single event handler.
:Parameters:
`name` : str
Name of the event type to attach to.
`handler` : callable
Event handler to attach.
'''
# Create event stack if necessary
if type(self._event_stack) is tuple:
self._event_stack = [{}]
self._event_stack[0][name] = handler
def pop_handlers(self):
'''Pop the top level of event handlers off the stack.
'''
assert self._event_stack and 'No handlers pushed'
del self._event_stack[0]
def remove_handlers(self, *args, **kwargs):
'''Remove event handlers from the event stack.
See `push_handlers` for the accepted argument types. All handlers
are removed from the first stack frame that contains any of the given
handlers. No error is raised if any handler does not appear in that
frame, or if no stack frame contains any of the given handlers.
If the stack frame is empty after removing the handlers, it is
removed from the stack. Note that this interferes with the expected
symmetry of `push_handlers` and `pop_handlers`.
'''
handlers = list(self._get_handlers(args, kwargs))
# Find the first stack frame containing any of the handlers
def find_frame():
for frame in self._event_stack:
for name, handler in handlers:
try:
if frame[name] == handler:
return frame
except KeyError:
pass
frame = find_frame()
# No frame matched; no error.
if not frame:
return
# Remove each handler from the frame.
for name, handler in handlers:
try:
if frame[name] == handler:
del frame[name]
except KeyError:
pass
# Remove the frame if it's empty.
if not frame:
self._event_stack.remove(frame)
def remove_handler(self, name, handler):
'''Remove a single event handler.
The given event handler is removed from the first handler stack frame
it appears in. The handler must be the exact same callable as passed
to `set_handler`, `set_handlers` or `push_handlers`; and the name
must match the event type it is bound to.
No error is raised if the event handler is not set.
:Parameters:
`name` : str
Name of the event type to remove.
`handler` : callable
Event handler to remove.
'''
for frame in self._event_stack:
try:
if frame[name] is handler:
del frame[name]
break
except KeyError:
pass
def dispatch_event(self, event_type, *args):
'''Dispatch a single event to the attached handlers.
The event is propogated to all handlers from from the top of the stack
until one returns `EVENT_HANDLED`. This method should be used only by
`EventDispatcher` implementors; applications should call
the ``dispatch_events`` method.
:Parameters:
`event_type` : str
Name of the event.
`args` : sequence
Arguments to pass to the event handler.
'''
assert event_type in self.event_types
# Search handler stack for matching event handlers
for frame in list(self._event_stack):
handler = frame.get(event_type, None)
if handler:
try:
if handler(*args):
return
except TypeError:
self._raise_dispatch_exception(event_type, args, handler)
# Check instance for an event handler
if hasattr(self, event_type):
try:
getattr(self, event_type)(*args)
except TypeError:
self._raise_dispatch_exception(
event_type, args, getattr(self, event_type))
def _raise_dispatch_exception(self, event_type, args, handler):
# A common problem in applications is having the wrong number of
# arguments in an event handler. This is caught as a TypeError in
# dispatch_event but the error message is obfuscated.
#
# Here we check if there is indeed a mismatch in argument count,
# and construct a more useful exception message if so. If this method
# doesn't find a problem with the number of arguments, the error
# is re-raised as if we weren't here.
n_args = len(args)
# Inspect the handler
handler_args, handler_varargs, _, handler_defaults = \
inspect.getargspec(handler)
n_handler_args = len(handler_args)
# Remove "self" arg from handler if it's a bound method
if inspect.ismethod(handler) and handler.im_self:
n_handler_args -= 1
# Allow *args varargs to overspecify arguments
if handler_varargs:
n_handler_args = max(n_handler_args, n_args)
# Allow default values to overspecify arguments
if (n_handler_args > n_args and
handler_defaults and
n_handler_args - len(handler_defaults) <= n_args):
n_handler_args = n_args
if n_handler_args != n_args:
if inspect.isfunction(handler) or inspect.ismethod(handler):
descr = '%s at %s:%d' % (
handler.func_name,
handler.func_code.co_filename,
handler.func_code.co_firstlineno)
else:
descr = repr(handler)
raise TypeError(
'%s event was dispatched with %d arguments, but '
'handler %s has an incompatible function signature' %
(event_type, len(args), descr))
else:
raise
def event(self, *args):
'''Function decorator for an event handler.
Usage::
win = window.Window()
@win.event
def on_resize(self, width, height):
# ...
or::
@win.event('on_resize')
def foo(self, width, height):
# ...
'''
if len(args) == 0: # @window.event()
def decorator(func):
name = func.__name__
self.set_handler(name, func)
return func
return decorator
elif inspect.isroutine(args[0]): # @window.event
func = args[0]
name = func.__name__
self.set_handler(name, func)
return args[0]
elif type(args[0]) in (str, unicode): # @window.event('on_resize')
name = args[0]
def decorator(func):
self.set_handler(name, func)
return func
return decorator

695
pyglet/font/__init__.py Normal file
View file

@ -0,0 +1,695 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Load fonts and render text.
This is a fairly-low level interface to text rendering. Obtain a font using
`load`::
from pyglet import font
arial = font.load('Arial', 14, bold=True, italic=False)
pyglet will load any system-installed fonts. You can add additional fonts
(for example, from your program resources) using `add_file` or
`add_directory`.
Obtain a list of `Glyph` objects for a string of text using the `Font`
object::
text = 'Hello, world!'
glyphs = arial.get_glyphs(text)
The most efficient way to render these glyphs is with a `GlyphString`::
glyph_string = GlyphString(text, glyphs)
glyph_string.draw()
There are also a variety of methods in both `Font` and
`GlyphString` to facilitate word-wrapping.
A convenient way to render a string of text is with a `Text`::
text = Text(font, text)
text.draw()
See the `pyglet.font.base` module for documentation on the base classes used
by this package.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: __init__.py 2136 2008-07-24 00:50:15Z Alex.Holkner $'
import sys
import os
import math
import weakref
import pyglet
from pyglet.gl import *
from pyglet import gl
from pyglet import image
from pyglet import window
class GlyphString(object):
'''An immutable string of glyphs that can be rendered quickly.
This class is ideal for quickly rendering single or multi-line strings
of text that use the same font. To wrap text using a glyph string,
call `get_break_index` to find the optimal breakpoint for each line,
the repeatedly call `draw` for each breakpoint.
:deprecated: Use `pyglet.text.layout` classes.
'''
def __init__(self, text, glyphs, x=0, y=0):
'''Create a glyph string.
The `text` string is used to determine valid breakpoints; all glyphs
must have already been determined using
`pyglet.font.base.Font.get_glyphs`. The string
will be positioned with the baseline of the left-most glyph at the
given coordinates.
:Parameters:
`text` : str or unicode
String to represent.
`glyphs` : list of `pyglet.font.base.Glyph`
Glyphs representing `text`.
`x` : float
X coordinate of the left-side bearing of the left-most glyph.
`y` : float
Y coordinate of the baseline.
'''
# Create an interleaved array in GL_T2F_V3F format and determine
# state changes required.
lst = []
texture = None
self.text = text
self.states = []
self.cumulative_advance = [] # for fast post-string breaking
state_from = 0
state_length = 0
for i, glyph in enumerate(glyphs):
if glyph.owner != texture:
if state_length:
self.states.append((state_from, state_length, texture))
texture = glyph.owner
state_from = i
state_length = 0
state_length += 1
t = glyph.tex_coords
lst += [t[0], t[1], t[2], 1.,
x + glyph.vertices[0], y + glyph.vertices[1], 0., 1.,
t[3], t[4], t[5], 1.,
x + glyph.vertices[2], y + glyph.vertices[1], 0., 1.,
t[6], t[7], t[8], 1.,
x + glyph.vertices[2], y + glyph.vertices[3], 0., 1.,
t[9], t[10], t[11], 1.,
x + glyph.vertices[0], y + glyph.vertices[3], 0., 1.]
x += glyph.advance
self.cumulative_advance.append(x)
self.states.append((state_from, state_length, texture))
self.array = (c_float * len(lst))(*lst)
self.width = x
def get_break_index(self, from_index, width):
'''Find a breakpoint within the text for a given width.
Returns a valid breakpoint after `from_index` so that the text
between `from_index` and the breakpoint fits within `width` pixels.
This method uses precomputed cumulative glyph widths to give quick
answer, and so is much faster than
`pyglet.font.base.Font.get_glyphs_for_width`.
:Parameters:
`from_index` : int
Index of text to begin at, or 0 for the beginning of the
string.
`width` : float
Maximum width to use.
:rtype: int
:return: the index of text which will be used as the breakpoint, or
`from_index` if there is no valid breakpoint.
'''
to_index = from_index
if from_index >= len(self.text):
return from_index
if from_index:
width += self.cumulative_advance[from_index-1]
for i, (c, w) in enumerate(
zip(self.text[from_index:],
self.cumulative_advance[from_index:])):
if c in u'\u0020\u200b':
to_index = i + from_index + 1
if c == '\n':
return i + from_index + 1
if w > width:
return to_index
return to_index
def get_subwidth(self, from_index, to_index):
'''Return the width of a slice of this string.
:Parameters:
`from_index` : int
The start index of the string to measure.
`to_index` : int
The end index (exclusive) of the string to measure.
:rtype: float
'''
if to_index <= from_index:
return 0
width = self.cumulative_advance[to_index-1]
if from_index:
width -= self.cumulative_advance[from_index-1]
return width
def draw(self, from_index=0, to_index=None):
'''Draw a region of the glyph string.
Assumes texture state is enabled. To enable the texture state::
from pyglet.gl import *
glEnable(GL_TEXTURE_2D)
:Parameters:
`from_index` : int
Start index of text to render.
`to_index` : int
End index (exclusive) of text to render.
'''
if from_index >= len(self.text) or \
from_index == to_index or \
not self.text:
return
# XXX Safe to assume all required textures will use same blend state I
# think. (otherwise move this into loop)
self.states[0][2].apply_blend_state()
if from_index:
glPushMatrix()
glTranslatef(-self.cumulative_advance[from_index-1], 0, 0)
if to_index is None:
to_index = len(self.text)
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
glInterleavedArrays(GL_T4F_V4F, 0, self.array)
for state_from, state_length, texture in self.states:
if state_from + state_length < from_index:
continue
state_from = max(state_from, from_index)
state_length = min(state_length, to_index - state_from)
if state_length <= 0:
break
glBindTexture(GL_TEXTURE_2D, texture.id)
glDrawArrays(GL_QUADS, state_from * 4, state_length * 4)
glPopClientAttrib()
if from_index:
glPopMatrix()
class _TextZGroup(pyglet.graphics.Group):
z = 0
def set_state(self):
glTranslatef(0, 0, self.z)
def unset_state(self):
glTranslatef(0, 0, -self.z)
class Text(object):
'''Simple displayable text.
This is a convenience class for rendering strings of text. It takes
care of caching the vertices so the text can be rendered every frame with
little performance penalty.
Text can be word-wrapped by specifying a `width` to wrap into. If the
width is not specified, it gives the width of the text as laid out.
:Ivariables:
`x` : int
X coordinate of the text
`y` : int
Y coordinate of the text
:deprecated: Use `pyglet.text.Label`.
'''
# Alignment constants
#: Align the left edge of the text to the given X coordinate.
LEFT = 'left'
#: Align the horizontal center of the text to the given X coordinate.
CENTER = 'center'
#: Align the right edge of the text to the given X coordinate.
RIGHT = 'right'
#: Align the bottom of the descender of the final line of text with the
#: given Y coordinate.
BOTTOM = 'bottom'
#: Align the baseline of the first line of text with the given Y
#: coordinate.
BASELINE = 'baseline'
#: Align the top of the ascender of the first line of text with the given
#: Y coordinate.
TOP = 'top'
# None: no multiline
# 'width': multiline, wrapped to width
# 'multiline': multiline, no wrap
_wrap = None
# Internal bookkeeping for wrap only.
_width = None
def __init__(self, font, text='', x=0, y=0, z=0, color=(1,1,1,1),
width=None, halign=LEFT, valign=BASELINE):
'''Create displayable text.
:Parameters:
`font` : `Font`
Font to render the text in.
`text` : str
Initial string to render.
`x` : float
X coordinate of the left edge of the text.
`y` : float
Y coordinate of the baseline of the text. If the text is
word-wrapped, this refers to the first line of text.
`z` : float
Z coordinate of the text plane.
`color` : 4-tuple of float
Color to render the text in. Alpha values can be specified
in the fourth component.
`width` : float
Width to limit the rendering to. Text will be word-wrapped
if necessary.
`halign` : str
Alignment of the text. See `Text.halign` for details.
`valign` : str
Controls positioning of the text based off the y coordinate.
One of BASELINE, BOTTOM, CENTER or TOP. Defaults to BASELINE.
'''
multiline = False
if width is not None:
self._width = width
self._wrap = 'width'
multiline = True
elif '\n' in text:
self._wrap = 'multiline'
multiline = True
self._group = _TextZGroup()
self._document = pyglet.text.decode_text(text)
self._layout = pyglet.text.layout.TextLayout(self._document,
width=width,
multiline=multiline,
dpi=font.dpi,
group=self._group)
self._layout.begin_update()
if self._wrap == 'multiline':
self._document.set_style(0, len(text), dict(wrap=False))
self.font = font
self.color = color
self._x = x
self.y = y
self.z = z
self.width = width
self.halign = halign
self.valign = valign
self._update_layout_halign()
self._layout.end_update()
def _get_font(self):
return self._font
def _set_font(self, font):
self._font = font
self._layout.begin_update()
self._document.set_style(0, len(self._document.text), {
'font_name': font.name,
'font_size': font.size,
'bold': font.bold,
'italic': font.italic,
})
self._layout._dpi = font.dpi
self._layout.end_update()
font = property(_get_font, _set_font)
def _get_color(self):
color = self._document.get_style('color')
if color is None:
return (1., 1., 1., 1.)
return tuple([c/255. for c in color])
def _set_color(self, color):
color = [int(c * 255) for c in color]
self._document.set_style(0, len(self._document.text), {
'color': color,
})
color = property(_get_color, _set_color)
def _update_layout_halign(self):
if self._layout.multiline:
# TextLayout has a different interpretation of halign that doesn't
# consider the width to be a special factor; here we emulate the
# old behaviour by fudging the layout x value.
if self._layout.anchor_x == 'left':
self._layout.x = self.x
elif self._layout.anchor_x == 'center':
self._layout.x = self.x + self._layout.width - \
self._layout.content_width // 2
elif self._layout.anchor_x == 'right':
self._layout.x = self.x + 2 * self._layout.width - \
self._layout.content_width
else:
self._layout.x = self.x
def _get_x(self):
return self._x
def _set_x(self, x):
self._x = x
self._update_layout_halign()
x = property(_get_x, _set_x)
def _get_y(self):
return self._layout.y
def _set_y(self, y):
self._layout.y = y
y = property(_get_y, _set_y)
def _get_z(self):
return self._group.z
def _set_z(self, z):
self._group.z = z
z = property(_get_z, _set_z)
def _update_wrap(self):
if self._width is not None:
self._wrap = 'width'
elif '\n' in self.text:
self._wrap = 'multiline'
self._layout.begin_update()
if self._wrap == None:
self._layout.multiline = False
elif self._wrap == 'width':
self._layout.multiline = True
self._layout.width = self._width
self._document.set_style(0, len(self.text), dict(wrap=True))
elif self._wrap == 'multiline':
self._layout.multiline = True
self._document.set_style(0, len(self.text), dict(wrap=False))
self._update_layout_halign()
self._layout.end_update()
def _get_width(self):
if self._wrap == 'width':
return self._layout.width
else:
return self._layout.content_width
def _set_width(self, width):
self._width = width
self._update_wrap()
width = property(_get_width, _set_width,
doc='''Width of the text.
When set, this enables word-wrapping to the specified width.
Otherwise, the width of the text as it will be rendered can be
determined.
:type: float
''')
def _get_height(self):
return self._layout.content_height
height = property(_get_height,
doc='''Height of the text.
This property is the ascent minus the descent of the font, unless
there is more than one line of word-wrapped text, in which case
the height takes into account the line leading. Read-only.
:type: float
''')
def _get_text(self):
return self._document.text
def _set_text(self, text):
self._document.text = text
self._update_wrap()
text = property(_get_text, _set_text,
doc='''Text to render.
The glyph vertices are only recalculated as needed, so multiple
changes to the text can be performed with no performance penalty.
:type: str
''')
def _get_halign(self):
return self._layout.anchor_x
def _set_halign(self, halign):
self._layout.anchor_x = halign
self._update_layout_halign()
halign = property(_get_halign, _set_halign,
doc='''Horizontal alignment of the text.
The text is positioned relative to `x` and `width` according to this
property, which must be one of the alignment constants `LEFT`,
`CENTER` or `RIGHT`.
:type: str
''')
def _get_valign(self):
return self._layout.anchor_y
def _set_valign(self, valign):
self._layout.anchor_y = valign
valign = property(_get_valign, _set_valign,
doc='''Vertical alignment of the text.
The text is positioned relative to `y` according to this property,
which must be one of the alignment constants `BOTTOM`, `BASELINE`,
`CENTER` or `TOP`.
:type: str
''')
def _get_leading(self):
return self._document.get_style('leading') or 0
def _set_leading(self, leading):
self._document.set_style(0, len(self._document.text), {
'leading': leading,
})
leading = property(_get_leading, _set_leading,
doc='''Vertical space between adjacent lines, in pixels.
:type: int
''')
def _get_line_height(self):
return self._font.ascent - self._font.descent + self.leading
def _set_line_height(self, line_height):
self.leading = line_height - (self._font.ascent - self._font.descent)
line_height = property(_get_line_height, _set_line_height,
doc='''Vertical distance between adjacent baselines, in pixels.
:type: int
''')
def draw(self):
self._layout.draw()
if not getattr(sys, 'is_epydoc', False):
if sys.platform == 'darwin':
from pyglet.font.carbon import CarbonFont
_font_class = CarbonFont
elif sys.platform in ('win32', 'cygwin'):
if pyglet.options['font'][0] == 'win32':
from pyglet.font.win32 import Win32Font
_font_class = Win32Font
elif pyglet.options['font'][0] == 'gdiplus':
from pyglet.font.win32 import GDIPlusFont
_font_class = GDIPlusFont
else:
assert False, 'Unknown font driver'
else:
from pyglet.font.freetype import FreeTypeFont
_font_class = FreeTypeFont
def load(name=None, size=None, bold=False, italic=False, dpi=None):
'''Load a font for rendering.
:Parameters:
`name` : str, or list of str
Font family, for example, "Times New Roman". If a list of names
is provided, the first one matching a known font is used. If no
font can be matched to the name(s), a default font is used. In
pyglet 1.1, the name may be omitted.
`size` : float
Size of the font, in points. The returned font may be an exact
match or the closest available. In pyglet 1.1, the size may be
omitted, and defaults to 12pt.
`bold` : bool
If True, a bold variant is returned, if one exists for the given
family and size.
`italic` : bool
If True, an italic variant is returned, if one exists for the given
family and size.
`dpi` : float
The assumed resolution of the display device, for the purposes of
determining the pixel size of the font. Defaults to 96.
:rtype: `Font`
'''
# Arbitrary default size
if size is None:
size = 12
if dpi is None:
dpi = 96
# Find first matching name
if type(name) in (tuple, list):
for n in name:
if _font_class.have_font(n):
name = n
break
else:
name = None
# Locate or create font cache
shared_object_space = gl.current_context.object_space
if not hasattr(shared_object_space, 'pyglet_font_font_cache'):
shared_object_space.pyglet_font_font_cache = \
weakref.WeakValueDictionary()
shared_object_space.pyglet_font_font_hold = []
font_cache = shared_object_space.pyglet_font_font_cache
font_hold = shared_object_space.pyglet_font_font_hold
# Look for font name in font cache
descriptor = (name, size, bold, italic, dpi)
if descriptor in font_cache:
return font_cache[descriptor]
# Not in cache, create from scratch
font = _font_class(name, size, bold=bold, italic=italic, dpi=dpi)
# Save parameters for new-style layout classes to recover
font.name = name
font.size = size
font.bold = bold
font.italic = italic
font.dpi = dpi
# Cache font in weak-ref dictionary to avoid reloading while still in use
font_cache[descriptor] = font
# Hold onto refs of last three loaded fonts to prevent them being
# collected if momentarily dropped.
del font_hold[3:]
font_hold.insert(0, font)
return font
def add_file(font):
'''Add a font to pyglet's search path.
In order to load a font that is not installed on the system, you must
call this method to tell pyglet that it exists. You can supply
either a filename or any file-like object.
The font format is platform-dependent, but is typically a TrueType font
file containing a single font face. Note that to load this file after
adding it you must specify the face name to `load`, not the filename.
:Parameters:
`font` : str or file
Filename or file-like object to load fonts from.
'''
if type(font) in (str, unicode):
font = open(font, 'rb')
if hasattr(font, 'read'):
font = font.read()
_font_class.add_font_data(font)
def add_directory(dir):
'''Add a directory of fonts to pyglet's search path.
This function simply calls `add_file` for each file with a ``.ttf``
extension in the given directory. Subdirectories are not searched.
:Parameters:
`dir` : str
Directory that contains font files.
'''
import os
for file in os.listdir(dir):
if file[-4:].lower() == '.ttf':
add_file(os.path.join(dir, file))

442
pyglet/font/base.py Normal file
View file

@ -0,0 +1,442 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Abstract classes used by pyglet.font implementations.
These classes should not be constructed directly. Instead, use the functions
in `pyglet.font` to obtain platform-specific instances. You can use these
classes as a documented interface to the concrete classes.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: base.py 2278 2008-09-23 12:18:50Z Alex.Holkner $'
import unicodedata
from pyglet.gl import *
from pyglet import image
_other_grapheme_extend = \
map(unichr, [0x09be, 0x09d7, 0x0be3, 0x0b57, 0x0bbe, 0x0bd7, 0x0cc2,
0x0cd5, 0x0cd6, 0x0d3e, 0x0d57, 0x0dcf, 0x0ddf, 0x200c,
0x200d, 0xff9e, 0xff9f]) # skip codepoints above U+10000
_logical_order_exception = \
map(unichr, range(0xe40, 0xe45) + range(0xec0, 0xec4))
_grapheme_extend = lambda c, cc: \
cc in ('Me', 'Mn') or c in _other_grapheme_extend
_CR = u'\u000d'
_LF = u'\u000a'
_control = lambda c, cc: cc in ('ZI', 'Zp', 'Cc', 'Cf') and not \
c in map(unichr, [0x000d, 0x000a, 0x200c, 0x200d])
_extend = lambda c, cc: _grapheme_extend(c, cc) or \
c in map(unichr, [0xe30, 0xe32, 0xe33, 0xe45, 0xeb0, 0xeb2, 0xeb3])
_prepend = lambda c, cc: c in _logical_order_exception
_spacing_mark = lambda c, cc: cc == 'Mc' and c not in _other_grapheme_extend
def _grapheme_break(left, right):
# GB1
if left is None:
return True
# GB2 not required, see end of get_grapheme_clusters
# GB3
if left == _CR and right == LF:
return False
left_cc = unicodedata.category(left)
# GB4
if _control(left, left_cc):
return True
right_cc = unicodedata.category(right)
# GB5
if _control(right, right_cc):
return True
# GB6, GB7, GB8 not implemented
# GB9
if _extend(right, right_cc):
return False
# GB9a
if _spacing_mark(right, right_cc):
return False
# GB9b
if _prepend(left, left_cc):
return False
# GB10
return True
def get_grapheme_clusters(text):
'''Implements Table 2 of UAX #29: Grapheme Cluster Boundaries.
Does not currently implement Hangul syllable rules.
:Parameters:
`text` : unicode
String to cluster.
:since: pyglet 1.1.2
:rtype: List of `unicode`
:return: List of Unicode grapheme clusters
'''
clusters = []
cluster = ''
left = None
for right in text:
if cluster and _grapheme_break(left, right):
clusters.append(cluster)
cluster = ''
elif cluster:
# Add a zero-width space to keep len(clusters) == len(text)
clusters.append(u'\u200b')
cluster += right
left = right
# GB2
if cluster:
clusters.append(cluster)
return clusters
class Glyph(image.TextureRegion):
'''A single glyph located within a larger texture.
Glyphs are drawn most efficiently using the higher level APIs, for example
`GlyphString`.
:Ivariables:
`advance` : int
The horizontal advance of this glyph, in pixels.
`vertices` : (int, int, int, int)
The vertices of this glyph, with (0,0) originating at the
left-side bearing at the baseline.
'''
advance = 0
vertices = (0, 0, 0, 0)
def set_bearings(self, baseline, left_side_bearing, advance):
'''Set metrics for this glyph.
:Parameters:
`baseline` : int
Distance from the bottom of the glyph to its baseline;
typically negative.
`left_side_bearing` : int
Distance to add to the left edge of the glyph.
`advance` : int
Distance to move the horizontal advance to the next glyph.
'''
self.advance = advance
self.vertices = (
left_side_bearing,
-baseline,
left_side_bearing + self.width,
-baseline + self.height)
def draw(self):
'''Debug method.
Use the higher level APIs for performance and kerning.
'''
glBindTexture(GL_TEXTURE_2D, self.owner.id)
glBegin(GL_QUADS)
self.draw_quad_vertices()
glEnd()
def draw_quad_vertices(self):
'''Debug method.
Use the higher level APIs for performance and kerning.
'''
glTexCoord3f(*self.tex_coords[:3])
glVertex2f(self.vertices[0], self.vertices[1])
glTexCoord3f(*self.tex_coords[3:6])
glVertex2f(self.vertices[2], self.vertices[1])
glTexCoord3f(*self.tex_coords[6:9])
glVertex2f(self.vertices[2], self.vertices[3])
glTexCoord3f(*self.tex_coords[9:12])
glVertex2f(self.vertices[0], self.vertices[3])
def get_kerning_pair(self, right_glyph):
'''Not implemented.
'''
return 0
class GlyphTextureAtlas(image.Texture):
'''A texture within which glyphs can be drawn.
'''
region_class = Glyph
x = 0
y = 0
line_height = 0
def apply_blend_state(self):
'''Set the OpenGL blend state for the glyphs in this texture.
'''
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_BLEND)
def fit(self, image):
'''Place `image` within this texture.
:Parameters:
`image` : `pyglet.image.AbstractImage`
Image to place within the texture.
:rtype: `Glyph`
:return: The glyph representing the image from this texture, or None
if the image doesn't fit.
'''
if self.x + image.width > self.width:
self.x = 0
self.y += self.line_height
self.line_height = 0
if self.y + image.height > self.height:
return None
self.line_height = max(self.line_height, image.height)
region = self.get_region(
self.x, self.y, image.width, image.height)
if image.width > 0:
region.blit_into(image, 0, 0, 0)
self.x += image.width + 1
return region
class GlyphRenderer(object):
'''Abstract class for creating glyph images.
'''
def __init__(self, font):
pass
def render(self, text):
raise NotImplementedError('Subclass must override')
class FontException(Exception):
'''Generic exception related to errors from the font module. Typically
these relate to invalid font data.'''
pass
class Font(object):
'''Abstract font class able to produce glyphs.
To construct a font, use `pyglet.font.load`, which will instantiate the
platform-specific font class.
Internally, this class is used by the platform classes to manage the set
of textures into which glyphs are written.
:Ivariables:
`ascent` : int
Maximum ascent above the baseline, in pixels.
`descent` : int
Maximum descent below the baseline, in pixels. Usually negative.
'''
texture_width = 256
texture_height = 256
texture_internalformat = GL_ALPHA
# These should also be set by subclass when known
ascent = 0
descent = 0
glyph_renderer_class = GlyphRenderer
texture_class = GlyphTextureAtlas
def __init__(self):
self.textures = []
self.glyphs = {}
@classmethod
def add_font_data(cls, data):
'''Add font data to the font loader.
This is a class method and affects all fonts loaded. Data must be
some byte string of data, for example, the contents of a TrueType font
file. Subclasses can override this method to add the font data into
the font registry.
There is no way to instantiate a font given the data directly, you
must use `pyglet.font.load` specifying the font name.
'''
pass
@classmethod
def have_font(cls, name):
'''Determine if a font with the given name is installed.
:Parameters:
`name` : str
Name of a font to search for
:rtype: bool
'''
return True
def create_glyph(self, image):
'''Create a glyph using the given image.
This is used internally by `Font` subclasses to add glyph data
to the font. Glyphs are packed within large textures maintained by
`Font`. This method inserts the image into a font texture and returns
a glyph reference; it is up to the subclass to add metadata to the
glyph.
Applications should not use this method directly.
:Parameters:
`image` : `pyglet.image.AbstractImage`
The image to write to the font texture.
:rtype: `Glyph`
'''
glyph = None
for texture in self.textures:
glyph = texture.fit(image)
if glyph:
break
if not glyph:
if image.width > self.texture_width or \
image.height > self.texture_height:
texture = self.texture_class.create_for_size(GL_TEXTURE_2D,
image.width * 2, image.height * 2,
self.texture_internalformat)
self.texture_width = texture.width
self.texture_height = texture.height
else:
texture = self.texture_class.create_for_size(GL_TEXTURE_2D,
self.texture_width, self.texture_height,
self.texture_internalformat)
self.textures.insert(0, texture)
glyph = texture.fit(image)
return glyph
def get_glyphs(self, text):
'''Create and return a list of Glyphs for `text`.
If any characters do not have a known glyph representation in this
font, a substitution will be made.
:Parameters:
`text` : str or unicode
Text to render.
:rtype: list of `Glyph`
'''
glyph_renderer = None
glyphs = [] # glyphs that are committed.
for c in get_grapheme_clusters(unicode(text)):
# Get the glyph for 'c'. Hide tabs (Windows and Linux render
# boxes)
if c == '\t':
c = ' '
if c not in self.glyphs:
if not glyph_renderer:
glyph_renderer = self.glyph_renderer_class(self)
self.glyphs[c] = glyph_renderer.render(c)
glyphs.append(self.glyphs[c])
return glyphs
def get_glyphs_for_width(self, text, width):
'''Return a list of glyphs for `text` that fit within the given width.
If the entire text is larger than 'width', as much as possible will be
used while breaking after a space or zero-width space character. If a
newline is enountered in text, only text up to that newline will be
used. If no break opportunities (newlines or spaces) occur within
`width`, the text up to the first break opportunity will be used (this
will exceed `width`). If there are no break opportunities, the entire
text will be used.
You can assume that each character of the text is represented by
exactly one glyph; so the amount of text "used up" can be determined
by examining the length of the returned glyph list.
:Parameters:
`text` : str or unicode
Text to render.
`width` : int
Maximum width of returned glyphs.
:rtype: list of `Glyph`
:see: `GlyphString`
'''
glyph_renderer = None
glyph_buffer = [] # next glyphs to be added, as soon as a BP is found
glyphs = [] # glyphs that are committed.
for c in text:
if c == '\n':
glyphs += glyph_buffer
break
# Get the glyph for 'c'
if c not in self.glyphs:
if not glyph_renderer:
glyph_renderer = self.glyph_renderer_class(self)
self.glyphs[c] = glyph_renderer.render(c)
glyph = self.glyphs[c]
# Add to holding buffer and measure
glyph_buffer.append(glyph)
width -= glyph.advance
# If over width and have some committed glyphs, finish.
if width <= 0 and len(glyphs) > 0:
break
# If a valid breakpoint, commit holding buffer
if c in u'\u0020\u200b':
glyphs += glyph_buffer
glyph_buffer = []
# If nothing was committed, commit everything (no breakpoints found).
if len(glyphs) == 0:
glyphs = glyph_buffer
return glyphs

438
pyglet/font/carbon.py Normal file
View file

@ -0,0 +1,438 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: $'
# TODO Tiger and later: need to set kWindowApplicationScaledAttribute for DPI
# independence?
from ctypes import *
import string
import math
from sys import byteorder
from pyglet.font import base
import pyglet.image
from pyglet.window.carbon import carbon, _oscheck
from pyglet.window.carbon import _create_cfstring
from pyglet.window.carbon.types import *
class FixedPoint(Structure):
_fields_ = [
('x', Fixed),
('y', Fixed)
]
class ATSTrapezoid(Structure):
_fields_ = [
('upperLeft', FixedPoint),
('upperRight', FixedPoint),
('lowerRight', FixedPoint),
('lowerLeft', FixedPoint)
]
# TODO: most of the ATS and CG here not used any more.
CGGlyph = c_ushort
ATSUFontID = c_uint32
RGBColor = c_short * 3
ATSURGBAlphaColor = c_float * 4
kCGImageAlphaNone = 0
kCGImageAlphaPremultipliedLast = 1
kCGTextFill = 0
kATSUInvalidFontErr = -8796
kATSFontContextUnspecified = 0
kATSFontContextGlobal = 1
kATSFontContextLocal = 2
kATSFontFilterSelectorUnspecified = 0
kATSFontFilterSelectorGeneration = 3
kATSFontFilterSelectorFontFamily = 7
kATSFontFilterSelectorFontFamilyApplierFunction = 8
kATSFontFilterSelectorFontApplierFunction = 9
kATSOptionFlagsDoNotNotify = 0x00000001 << 8
kATSOptionFlagsIterationScopeMask = 0x00000007 << 12
kATSOptionFlagsDefaultScope = 0x00000000 << 12
kATSOptionFlagsUnRestrictedScope = 0x00000001 << 12
kATSOptionFlagsRestrictedScope = 0x00000002 << 12
kATSOptionFlagsProcessSubdirectories = 0x00000001 << 6
kATSUFromTextBeginning = c_ulong(0xFFFFFFFF)
kATSUToTextEnd = c_ulong(0xFFFFFFFF)
kATSULineAscentTag = 8
kATSULineDescentTag = 9
ATSUTextMeasurement = Fixed
kATSUQDBoldfaceTag = 256
kATSUQDItalicTag = 257
kATSUFontTag = 261
kATSUSizeTag = 262
kATSUCGContextTag = 32767
kATSUColorTag = 263
kATSURGBAlphaColorTag = 288
kATSULineWidthTag = 1
kFontFullName = 4
kFontNoPlatformCode = c_ulong(-1)
kFontNoScriptCode = c_ulong(-1)
kFontNoLanguageCode = c_ulong(-1)
kATSUseDeviceOrigins = 1
kATSFontFormatUnspecified = 0
kATSFontContextLocal = 2
carbon.CGColorSpaceCreateWithName.restype = c_void_p
carbon.CGBitmapContextCreate.restype = POINTER(c_void_p)
UniCharArrayOffset = c_uint32
UniCharCount = c_uint32
kATSULayoutOperationJustification = 1
kATSULayoutOperationPostLayoutAdjustment = 0x20
kATSULayoutOperationCallbackStatusHandled = 0
kATSULayoutOperationCallbackStatusContinue = c_long(1)
kATSULayoutOperationOverrideTag = 15
kATSUDirectDataAdvanceDeltaFixedArray = 0
kATSUDirectDataDeviceDeltaSInt16Array = 2
kATSUDirectDataLayoutRecordATSLayoutRecordVersion1 = 100
ATSUDirectLayoutOperationOverrideUPP = CFUNCTYPE(c_int,
c_int, c_void_p, c_uint32, c_void_p, POINTER(c_int))
class ATSULayoutOperationOverrideSpecifier(Structure):
_fields_ = [
('operationSelector', c_uint32),
('overrideUPP', ATSUDirectLayoutOperationOverrideUPP)
]
class ATSLayoutRecord(Structure):
_pack_ = 2
_fields_ = [
('glyphID', c_uint16),
('flags', c_uint32),
('originalOffset', c_uint32),
('realPos', Fixed),
]
def fixed(value):
return c_int32(carbon.Long2Fix(c_long(int(value))))
carbon.Fix2X.restype = c_double
def fix2float(value):
return carbon.Fix2X(value)
def create_atsu_style(attributes):
# attributes is a dict of ATSUAttributeTag => ctypes value
tags, values = zip(*attributes.items())
tags = (c_int * len(tags))(*tags)
sizes = (c_uint * len(values))(*[sizeof(v) for v in values])
values = (c_void_p * len(values))(*[cast(pointer(v), c_void_p) \
for v in values])
style = c_void_p()
carbon.ATSUCreateStyle(byref(style))
carbon.ATSUSetAttributes(style, len(tags), tags, sizes, values)
return style
def set_layout_attributes(layout, attributes):
if attributes:
# attributes is a dict of ATSUAttributeTag => ctypes value
tags, values = zip(*attributes.items())
tags = (c_int * len(tags))(*tags)
sizes = (c_uint * len(values))(*[sizeof(v) for v in values])
values = (c_void_p * len(values))(*[cast(pointer(v), c_void_p) \
for v in values])
r = carbon.ATSUSetLayoutControls(layout, len(tags), tags, sizes, values)
_oscheck(r)
def str_ucs2(text):
if byteorder == 'big':
text = text.encode('utf_16_be')
else:
text = text.encode('utf_16_le') # explicit endian avoids BOM
return create_string_buffer(text + '\0')
class CarbonGlyphRenderer(base.GlyphRenderer):
_bitmap = None
_bitmap_context = None
_bitmap_rect = None
_glyph_advance = 0 # set through callback
def __init__(self, font):
super(CarbonGlyphRenderer, self).__init__(font)
self._create_bitmap_context(256, 256)
self.font = font
def __del__(self):
try:
if self._bitmap_context:
carbon.CGContextRelease(self._bitmap_context)
except:
pass
def _layout_callback(self, operation, line, ref, extra, callback_status):
records = c_void_p()
n_records = c_uint()
r = carbon.ATSUDirectGetLayoutDataArrayPtrFromLineRef(line,
kATSUDirectDataLayoutRecordATSLayoutRecordVersion1,
0,
byref(records),
byref(n_records))
_oscheck(r)
records = cast(records,
POINTER(ATSLayoutRecord * n_records.value)).contents
self._glyph_advance = fix2float(records[-1].realPos)
callback_status.contents = kATSULayoutOperationCallbackStatusContinue
return 0
def render(self, text):
# Convert text to UCS2
text_len = len(text)
text_ucs2 = str_ucs2(text)
# Create layout override handler to extract device advance value.
override_spec = ATSULayoutOperationOverrideSpecifier()
override_spec.operationSelector = \
kATSULayoutOperationPostLayoutAdjustment
override_spec.overrideUPP = \
ATSUDirectLayoutOperationOverrideUPP(self._layout_callback)
# Create ATSU text layout for this text and font
layout = c_void_p()
carbon.ATSUCreateTextLayout(byref(layout))
set_layout_attributes(layout, {
kATSUCGContextTag: self._bitmap_context,
kATSULayoutOperationOverrideTag: override_spec})
carbon.ATSUSetTextPointerLocation(layout,
text_ucs2,
kATSUFromTextBeginning,
kATSUToTextEnd,
text_len)
carbon.ATSUSetRunStyle(layout, self.font.atsu_style,
kATSUFromTextBeginning, kATSUToTextEnd)
# Turning on transient font matching screws up font layout
# predictability when strange fonts are installed
# <ah> Don't believe this. Can't get foreign/special characters
# without transient on.
carbon.ATSUSetTransientFontMatching(layout, True)
# Get bitmap dimensions required
rect = Rect()
carbon.ATSUMeasureTextImage(layout,
kATSUFromTextBeginning,
kATSUToTextEnd,
0, 0,
byref(rect))
image_width = rect.right - rect.left + 2
image_height = rect.bottom - rect.top + 2
baseline = rect.bottom + 1
lsb = rect.left
# Resize Quartz context if necessary
if (image_width > self._bitmap_rect.size.width or
image_height > self._bitmap_rect.size.height):
self._create_bitmap_context(
int(max(image_width, self._bitmap_rect.size.width)),
int(max(image_height, self._bitmap_rect.size.height)))
set_layout_attributes(layout, {
kATSUCGContextTag: self._bitmap_context})
# Draw to the bitmap
carbon.CGContextClearRect(self._bitmap_context, self._bitmap_rect)
carbon.ATSUDrawText(layout,
0,
kATSUToTextEnd,
fixed(-lsb + 1), fixed(baseline))
advance = self._glyph_advance
# Round advance to nearest int. It actually looks good with sub-pixel
# advance as well -- Helvetica at 12pt is more tightly spaced, but
# Times New Roman at 12pt is too light. With integer positioning
# overall look seems darker and perhaps more uniform. It's also more
# similar (programmatically) to Win32 and FreeType. Still, worth
# messing around with (comment out next line) if you're interested.
advance = int(round(advance))
# Fix advance for zero-width space
if text == u'\u200b':
advance = 0
# A negative pitch is required, but it is much faster to load the
# glyph upside-down and flip the tex_coords. Note region used
# to start at top of glyph image.
pitch = int(4 * self._bitmap_rect.size.width)
image = pyglet.image.ImageData(image_width,
self._bitmap_rect.size.height, 'RGBA', self._bitmap, pitch)
skip_rows = int(self._bitmap_rect.size.height - image_height)
image = image.get_region(0, skip_rows, image.width, image_height)
glyph = self.font.create_glyph(image)
glyph.set_bearings(baseline, lsb - 1, int(advance))
t = list(glyph.tex_coords)
glyph.tex_coords = t[9:12] + t[6:9] + t[3:6] + t[:3]
return glyph
def _create_bitmap_context(self, width, height):
'''Create or recreate bitmap and Quartz context.'''
if self._bitmap_context:
carbon.CGContextRelease(self._bitmap_context)
components = 4
pitch = width * components
self._bitmap = (c_ubyte * (pitch * height))()
color_space = carbon.CGColorSpaceCreateDeviceRGB()
context = carbon.CGBitmapContextCreate(self._bitmap,
width, height, 8, pitch,
color_space, kCGImageAlphaPremultipliedLast)
carbon.CGColorSpaceRelease(color_space)
# Disable RGB decimated antialiasing, use standard
# antialiasing which won't break alpha.
carbon.CGContextSetShouldSmoothFonts(context, False)
carbon.CGContextSetShouldAntialias(context, True)
self._bitmap_context = context
self._bitmap_rect = CGRect()
self._bitmap_rect.origin.x = 0
self._bitmap_rect.origin.y = 0
self._bitmap_rect.size.width = width
self._bitmap_rect.size.height = height
class CarbonFont(base.Font):
glyph_renderer_class = CarbonGlyphRenderer
def __init__(self, name, size, bold=False, italic=False, dpi=None):
super(CarbonFont, self).__init__()
if not name:
name = 'Helvetica'
if dpi is None:
dpi = 96 # pyglet 1.1; in pyglet 1.0 this was 72.
# If application is not DPI-aware, DPI is fixed at 72. Scale
# font size to emulate other DPI. This will need to be fixed if issue
# #87 is implemented.
size = size * dpi / 72.
name = name.encode('ascii', 'ignore')
font_id = ATSUFontID()
carbon.ATSUFindFontFromName(
name,
len(name),
kFontFullName,
kFontNoPlatformCode,
kFontNoScriptCode,
kFontNoLanguageCode,
byref(font_id))
attributes = {
kATSUSizeTag: fixed(size),
kATSUFontTag: font_id,
kATSURGBAlphaColorTag: ATSURGBAlphaColor(1, 1, 1, 1),
kATSUQDBoldfaceTag: c_byte(bold),
kATSUQDItalicTag: c_byte(italic)
}
self.atsu_style = create_atsu_style(attributes)
self.calculate_metrics()
@classmethod
def have_font(cls, name):
font_id = ATSUFontID()
name = name.encode('ascii', 'ignore')
r = carbon.ATSUFindFontFromName(
name,
len(name),
kFontFullName,
kFontNoPlatformCode,
kFontNoScriptCode,
kFontNoLanguageCode,
byref(font_id))
return r != kATSUInvalidFontErr
def calculate_metrics(self):
# It seems the only way to get the font's ascent and descent is to lay
# out some glyphs and measure them.
# fake ucs2 string
text = '\0a'
layout = c_void_p()
carbon.ATSUCreateTextLayout(byref(layout))
carbon.ATSUSetTextPointerLocation(layout, text,
kATSUFromTextBeginning, kATSUToTextEnd, 1)
carbon.ATSUSetRunStyle(layout, self.atsu_style,
kATSUFromTextBeginning, kATSUToTextEnd)
# determine the metrics for this font only
carbon.ATSUSetTransientFontMatching(layout, False)
value = ATSUTextMeasurement()
carbon.ATSUGetLineControl(layout, 0, kATSULineAscentTag,
sizeof(value), byref(value), None)
self.ascent = int(math.ceil(fix2float(value)))
carbon.ATSUGetLineControl(layout, 0, kATSULineDescentTag,
sizeof(value), byref(value), None)
self.descent = -int(math.ceil(fix2float(value)))
@classmethod
def add_font_data(cls, data):
container = c_void_p()
r = carbon.ATSFontActivateFromMemory(data, len(data),
kATSFontContextLocal, kATSFontFormatUnspecified, None, 0,
byref(container))
_oscheck(r)

354
pyglet/font/freetype.py Normal file
View file

@ -0,0 +1,354 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: freetype.py 2084 2008-05-27 12:42:19Z Alex.Holkner $'
import ctypes
from ctypes import *
from warnings import warn
import pyglet.lib
from pyglet.font import base
from pyglet import image
from pyglet.font.freetype_lib import *
# fontconfig library definitions
fontconfig = pyglet.lib.load_library('fontconfig')
FcResult = c_int
fontconfig.FcPatternBuild.restype = c_void_p
fontconfig.FcFontMatch.restype = c_void_p
fontconfig.FcFreeTypeCharIndex.restype = c_uint
FC_FAMILY = 'family'
FC_SIZE = 'size'
FC_SLANT = 'slant'
FC_WEIGHT = 'weight'
FC_FT_FACE = 'ftface'
FC_FILE = 'file'
FC_WEIGHT_REGULAR = 80
FC_WEIGHT_BOLD = 200
FC_SLANT_ROMAN = 0
FC_SLANT_ITALIC = 100
FT_STYLE_FLAG_ITALIC = 1
FT_STYLE_FLAG_BOLD = 2
(FT_RENDER_MODE_NORMAL,
FT_RENDER_MODE_LIGHT,
FT_RENDER_MODE_MONO,
FT_RENDER_MODE_LCD,
FT_RENDER_MODE_LCD_V) = range(5)
def FT_LOAD_TARGET_(x):
return (x & 15) << 16
FT_LOAD_TARGET_NORMAL = FT_LOAD_TARGET_(FT_RENDER_MODE_NORMAL)
FT_LOAD_TARGET_LIGHT = FT_LOAD_TARGET_(FT_RENDER_MODE_LIGHT)
FT_LOAD_TARGET_MONO = FT_LOAD_TARGET_(FT_RENDER_MODE_MONO)
FT_LOAD_TARGET_LCD = FT_LOAD_TARGET_(FT_RENDER_MODE_LCD)
FT_LOAD_TARGET_LCD_V = FT_LOAD_TARGET_(FT_RENDER_MODE_LCD_V)
(FT_PIXEL_MODE_NONE,
FT_PIXEL_MODE_MONO,
FT_PIXEL_MODE_GRAY,
FT_PIXEL_MODE_GRAY2,
FT_PIXEL_MODE_GRAY4,
FT_PIXEL_MODE_LCD,
FT_PIXEL_MODE_LCD_V) = range(7)
(FcTypeVoid,
FcTypeInteger,
FcTypeDouble,
FcTypeString,
FcTypeBool,
FcTypeMatrix,
FcTypeCharSet,
FcTypeFTFace,
FcTypeLangSet) = range(9)
FcType = c_int
(FcMatchPattern,
FcMatchFont) = range(2)
FcMatchKind = c_int
class _FcValueUnion(Union):
_fields_ = [
('s', c_char_p),
('i', c_int),
('b', c_int),
('d', c_double),
('m', c_void_p),
('c', c_void_p),
('f', c_void_p),
('p', c_void_p),
('l', c_void_p),
]
class FcValue(Structure):
_fields_ = [
('type', FcType),
('u', _FcValueUnion)
]
# End of library definitions
def f16p16_to_float(value):
return float(value) / (1 << 16)
def float_to_f16p16(value):
return int(value * (1 << 16))
def f26p6_to_float(value):
return float(value) / (1 << 6)
def float_to_f26p6(value):
return int(value * (1 << 6))
class FreeTypeGlyphRenderer(base.GlyphRenderer):
def __init__(self, font):
super(FreeTypeGlyphRenderer, self).__init__(font)
self.font = font
def render(self, text):
face = self.font.face
FT_Set_Char_Size(face, 0, self.font._face_size,
self.font._dpi, self.font._dpi)
glyph_index = fontconfig.FcFreeTypeCharIndex(byref(face), ord(text[0]))
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER)
if error != 0:
raise base.FontException(
'Could not load glyph for "%c"' % text[0], error)
glyph_slot = face.glyph.contents
width = glyph_slot.bitmap.width
height = glyph_slot.bitmap.rows
baseline = height - glyph_slot.bitmap_top
lsb = glyph_slot.bitmap_left
advance = int(f26p6_to_float(glyph_slot.advance.x))
mode = glyph_slot.bitmap.pixel_mode
pitch = glyph_slot.bitmap.pitch
if mode == FT_PIXEL_MODE_MONO:
# BCF fonts always render to 1 bit mono, regardless of render
# flags. (freetype 2.3.5)
bitmap_data = cast(glyph_slot.bitmap.buffer,
POINTER(c_ubyte * (pitch * height))).contents
data = (c_ubyte * (pitch * 8 * height))()
data_i = 0
for byte in bitmap_data:
# Data is MSB; left-most pixel in a byte has value 128.
data[data_i + 0] = (byte & 0x80) and 255 or 0
data[data_i + 1] = (byte & 0x40) and 255 or 0
data[data_i + 2] = (byte & 0x20) and 255 or 0
data[data_i + 3] = (byte & 0x10) and 255 or 0
data[data_i + 4] = (byte & 0x08) and 255 or 0
data[data_i + 5] = (byte & 0x04) and 255 or 0
data[data_i + 6] = (byte & 0x02) and 255 or 0
data[data_i + 7] = (byte & 0x01) and 255 or 0
data_i += 8
pitch <<= 3
elif mode == FT_PIXEL_MODE_GRAY:
# Usual case
data = glyph_slot.bitmap.buffer
else:
raise base.FontException('Unsupported render mode for this glyph')
# pitch should be negative, but much faster to just swap tex_coords
img = image.ImageData(width, height, 'A', data, pitch)
glyph = self.font.create_glyph(img)
glyph.set_bearings(baseline, lsb, advance)
t = list(glyph.tex_coords)
glyph.tex_coords = t[9:12] + t[6:9] + t[3:6] + t[:3]
return glyph
class FreeTypeMemoryFont(object):
def __init__(self, data):
self.buffer = (ctypes.c_byte * len(data))()
ctypes.memmove(self.buffer, data, len(data))
ft_library = ft_get_library()
self.face = FT_Face()
r = FT_New_Memory_Face(ft_library,
self.buffer, len(self.buffer), 0, self.face)
if r != 0:
raise base.FontException('Could not load font data')
self.name = self.face.contents.family_name
self.bold = self.face.contents.style_flags & FT_STYLE_FLAG_BOLD != 0
self.italic = self.face.contents.style_flags & FT_STYLE_FLAG_ITALIC != 0
# Replace Freetype's generic family name with TTF/OpenType specific
# name if we can find one; there are some instances where Freetype
# gets it wrong.
if self.face.contents.face_flags & FT_FACE_FLAG_SFNT:
name = FT_SfntName()
for i in range(FT_Get_Sfnt_Name_Count(self.face)):
result = FT_Get_Sfnt_Name(self.face, i, name)
if result != 0:
continue
if not (name.platform_id == TT_PLATFORM_MICROSOFT and
name.encoding_id == TT_MS_ID_UNICODE_CS):
continue
if name.name_id == TT_NAME_ID_FONT_FAMILY:
string = string_at(name.string, name.string_len)
self.name = string.decode('utf-16be', 'ignore')
def __del__(self):
try:
FT_Done_Face(self.face)
except:
pass
class FreeTypeFont(base.Font):
glyph_renderer_class = FreeTypeGlyphRenderer
# Map font (name, bold, italic) to FreeTypeMemoryFont
_memory_fonts = {}
def __init__(self, name, size, bold=False, italic=False, dpi=None):
super(FreeTypeFont, self).__init__()
if dpi is None:
dpi = 96 # as of pyglet 1.1; pyglet 1.0 had 72.
# Check if font name/style matches a font loaded into memory by user
lname = name and name.lower() or ''
if (lname, bold, italic) in self._memory_fonts:
font = self._memory_fonts[lname, bold, italic]
self._set_face(font.face, size, dpi)
return
# Use fontconfig to match the font (or substitute a default).
ft_library = ft_get_library()
match = self.get_fontconfig_match(name, size, bold, italic)
if not match:
raise base.FontException('Could not match font "%s"' % name)
f = FT_Face()
if fontconfig.FcPatternGetFTFace(match, FC_FT_FACE, 0, byref(f)) != 0:
value = FcValue()
result = fontconfig.FcPatternGet(match, FC_FILE, 0, byref(value))
if result != 0:
raise base.FontException('No filename or FT face for "%s"' % \
name)
result = FT_New_Face(ft_library, value.u.s, 0, byref(f))
if result:
raise base.FontException('Could not load "%s": %d' % \
(name, result))
fontconfig.FcPatternDestroy(match)
self._set_face(f, size, dpi)
def _set_face(self, face, size, dpi):
self.face = face.contents
self._face_size = float_to_f26p6(size)
self._dpi = dpi
FT_Set_Char_Size(self.face, 0, float_to_f26p6(size), dpi, dpi)
metrics = self.face.size.contents.metrics
if metrics.ascender == 0 and metrics.descender == 0:
# Workaround broken fonts with no metrics. Has been observed with
# courR12-ISO8859-1.pcf.gz: "Courier" "Regular"
#
# None of the metrics fields are filled in, so render a glyph and
# grab its height as the ascent, and make up an arbitrary
# descent.
i = fontconfig.FcFreeTypeCharIndex(byref(self.face), ord('X'))
FT_Load_Glyph(self.face, i, FT_LOAD_RENDER)
self.ascent = self.face.available_sizes.contents.height
self.descent = -self.ascent // 4 # arbitrary.
else:
self.ascent = int(f26p6_to_float(metrics.ascender))
self.descent = int(f26p6_to_float(metrics.descender))
@staticmethod
def get_fontconfig_match(name, size, bold, italic):
if bold:
bold = FC_WEIGHT_BOLD
else:
bold = FC_WEIGHT_REGULAR
if italic:
italic = FC_SLANT_ITALIC
else:
italic = FC_SLANT_ROMAN
fontconfig.FcInit()
if isinstance(name, unicode):
name = name.encode('utf8')
pattern = fontconfig.FcPatternCreate()
fontconfig.FcPatternAddDouble(pattern, FC_SIZE, c_double(size))
fontconfig.FcPatternAddInteger(pattern, FC_WEIGHT, bold)
fontconfig.FcPatternAddInteger(pattern, FC_SLANT, italic)
fontconfig.FcPatternAddString(pattern, FC_FAMILY, name)
fontconfig.FcConfigSubstitute(0, pattern, FcMatchPattern)
fontconfig.FcDefaultSubstitute(pattern)
# Look for a font that matches pattern
result = FcResult()
match = fontconfig.FcFontMatch(0, pattern, byref(result))
fontconfig.FcPatternDestroy(pattern)
return match
@classmethod
def have_font(cls, name):
value = FcValue()
match = cls.get_fontconfig_match(name, 12, False, False)
result = fontconfig.FcPatternGet(match, FC_FAMILY, 0, byref(value))
if value.u.s == name:
return True
else:
name = name.lower()
for font in cls._memory_fonts.values():
if font.name.lower() == name:
return True
return False
@classmethod
def add_font_data(cls, data):
font = FreeTypeMemoryFont(data)
cls._memory_fonts[font.name.lower(), font.bold, font.italic] = font

427
pyglet/font/freetype_lib.py Normal file
View file

@ -0,0 +1,427 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: freetype_lib.py 2084 2008-05-27 12:42:19Z Alex.Holkner $'
from ctypes import *
import pyglet.lib
_libfreetype = pyglet.lib.load_library('freetype')
_font_data = {}
def _get_function(name, argtypes, rtype):
try:
func = getattr(_libfreetype, name)
func.argtypes = argtypes
func.restype = rtype
return func
except AttributeError, e:
raise ImportError(e)
FT_Done_FreeType = _get_function('FT_Done_FreeType', [c_void_p], None)
FT_Done_Face = _get_function('FT_Done_Face', [c_void_p], None)
class FT_LibraryRec(Structure):
_fields_ = [
('dummy', c_int),
]
def __del__(self):
global _library
try:
FT_Done_FreeType(byref(self))
_library = None
except:
pass
FT_Library = POINTER(FT_LibraryRec)
class FT_Glyph_Metrics(Structure):
_fields_ = [
('width', c_long),
('height', c_long),
('horiBearingX', c_long),
('horiBearingY', c_long),
('horiAdvance', c_long),
('vertBearingX', c_long),
('vertBearingY', c_long),
('vertAdvance', c_long),
]
def dump(self):
for (name, type) in self._fields_:
print 'FT_Glyph_Metrics', name, `getattr(self, name)`
class FT_Generic(Structure):
_fields_ = [('data', c_void_p), ('finalizer', c_void_p)]
class FT_BBox(Structure):
_fields_ = [('xMin', c_long), ('yMin', c_long), ('xMax', c_long),
('yMax', c_long)]
class FT_Vector(Structure):
_fields_ = [('x', c_long), ('y', c_long)]
class FT_Bitmap(Structure):
_fields_ = [
('rows', c_int),
('width', c_int),
('pitch', c_int),
# declaring buffer as c_char_p confuses ctypes, poor dear
('buffer', POINTER(c_ubyte)),
('num_grays', c_short),
('pixel_mode', c_ubyte),
('palette_mode', c_char),
('palette', c_void_p),
]
class FT_Outline(Structure):
_fields_ = [
('n_contours', c_short), # number of contours in glyph
('n_points', c_short), # number of points in the glyph
('points', POINTER(FT_Vector)), # the outline's points
('tags', c_char_p), # the points flags
('contours', POINTER(c_short)), # the contour end points
('flags', c_int), # outline masks
]
class FT_GlyphSlotRec(Structure):
_fields_ = [
('library', FT_Library),
('face', c_void_p),
('next', c_void_p),
('reserved', c_uint),
('generic', FT_Generic),
('metrics', FT_Glyph_Metrics),
('linearHoriAdvance', c_long),
('linearVertAdvance', c_long),
('advance', FT_Vector),
('format', c_int),
('bitmap', FT_Bitmap),
('bitmap_left', c_int),
('bitmap_top', c_int),
('outline', FT_Outline),
('num_subglyphs', c_uint),
('subglyphs', c_void_p),
('control_data', c_void_p),
('control_len', c_long),
('lsb_delta', c_long),
('rsb_delta', c_long),
('other', c_void_p),
('internal', c_void_p),
]
FT_GlyphSlot = POINTER(FT_GlyphSlotRec)
class FT_Size_Metrics(Structure):
_fields_ = [
('x_ppem', c_ushort), # horizontal pixels per EM
('y_ppem', c_ushort), # vertical pixels per EM
('x_scale', c_long), # two scales used to convert font units
('y_scale', c_long), # to 26.6 frac. pixel coordinates
('ascender', c_long), # ascender in 26.6 frac. pixels
('descender', c_long), # descender in 26.6 frac. pixels
('height', c_long), # text height in 26.6 frac. pixels
('max_advance', c_long), # max horizontal advance, in 26.6 pixels
]
class FT_SizeRec(Structure):
_fields_ = [
('face', c_void_p),
('generic', FT_Generic),
('metrics', FT_Size_Metrics),
('internal', c_void_p),
]
FT_Size = POINTER(FT_SizeRec)
class FT_Bitmap_Size(Structure):
_fields_ = [
('height', c_ushort),
('width', c_ushort),
('size', c_long),
('x_ppem', c_long),
('y_ppem', c_long),
]
# face_flags values
FT_FACE_FLAG_SCALABLE = 1 << 0
FT_FACE_FLAG_FIXED_SIZES = 1 << 1
FT_FACE_FLAG_FIXED_WIDTH = 1 << 2
FT_FACE_FLAG_SFNT = 1 << 3
FT_FACE_FLAG_HORIZONTAL = 1 << 4
FT_FACE_FLAG_VERTICAL = 1 << 5
FT_FACE_FLAG_KERNING = 1 << 6
FT_FACE_FLAG_FAST_GLYPHS = 1 << 7
FT_FACE_FLAG_MULTIPLE_MASTERS = 1 << 8
FT_FACE_FLAG_GLYPH_NAMES = 1 << 9
FT_FACE_FLAG_EXTERNAL_STREAM = 1 << 10
FT_FACE_FLAG_HINTER = 1 << 11
class FT_FaceRec(Structure):
_fields_ = [
('num_faces', c_long),
('face_index', c_long),
('face_flags', c_long),
('style_flags', c_long),
('num_glyphs', c_long),
('family_name', c_char_p),
('style_name', c_char_p),
('num_fixed_sizes', c_int),
('available_sizes', POINTER(FT_Bitmap_Size)),
('num_charmaps', c_int),
('charmaps', c_void_p),
('generic', FT_Generic),
('bbox', FT_BBox),
('units_per_EM', c_ushort),
('ascender', c_short),
('descender', c_short),
('height', c_short),
('max_advance_width', c_short),
('max_advance_height', c_short),
('underline_position', c_short),
('underline_thickness', c_short),
('glyph', FT_GlyphSlot),
('size', FT_Size),
('charmap', c_void_p),
('driver', c_void_p),
('memory', c_void_p),
('stream', c_void_p),
('sizes_list_head', c_void_p),
('sizes_list_tail', c_void_p),
('autohint', FT_Generic),
('extensions', c_void_p),
('internal', c_void_p),
]
def dump(self):
for (name, type) in self._fields_:
print 'FT_FaceRec', name, `getattr(self, name)`
def has_kerning(self):
return self.face_flags & FT_FACE_FLAG_KERNING
FT_Face = POINTER(FT_FaceRec)
class Error(Exception):
def __init__(self, message, errcode):
self.message = message
self.errcode = errcode
def __str__(self):
return '%s: %s (%s)'%(self.__class__.__name__, self.message,
self._ft_errors.get(self.errcode, 'unknown error'))
_ft_errors = {
0x00: "no error" ,
0x01: "cannot open resource" ,
0x02: "unknown file format" ,
0x03: "broken file" ,
0x04: "invalid FreeType version" ,
0x05: "module version is too low" ,
0x06: "invalid argument" ,
0x07: "unimplemented feature" ,
0x08: "broken table" ,
0x09: "broken offset within table" ,
0x10: "invalid glyph index" ,
0x11: "invalid character code" ,
0x12: "unsupported glyph image format" ,
0x13: "cannot render this glyph format" ,
0x14: "invalid outline" ,
0x15: "invalid composite glyph" ,
0x16: "too many hints" ,
0x17: "invalid pixel size" ,
0x20: "invalid object handle" ,
0x21: "invalid library handle" ,
0x22: "invalid module handle" ,
0x23: "invalid face handle" ,
0x24: "invalid size handle" ,
0x25: "invalid glyph slot handle" ,
0x26: "invalid charmap handle" ,
0x27: "invalid cache manager handle" ,
0x28: "invalid stream handle" ,
0x30: "too many modules" ,
0x31: "too many extensions" ,
0x40: "out of memory" ,
0x41: "unlisted object" ,
0x51: "cannot open stream" ,
0x52: "invalid stream seek" ,
0x53: "invalid stream skip" ,
0x54: "invalid stream read" ,
0x55: "invalid stream operation" ,
0x56: "invalid frame operation" ,
0x57: "nested frame access" ,
0x58: "invalid frame read" ,
0x60: "raster uninitialized" ,
0x61: "raster corrupted" ,
0x62: "raster overflow" ,
0x63: "negative height while rastering" ,
0x70: "too many registered caches" ,
0x80: "invalid opcode" ,
0x81: "too few arguments" ,
0x82: "stack overflow" ,
0x83: "code overflow" ,
0x84: "bad argument" ,
0x85: "division by zero" ,
0x86: "invalid reference" ,
0x87: "found debug opcode" ,
0x88: "found ENDF opcode in execution stream" ,
0x89: "nested DEFS" ,
0x8A: "invalid code range" ,
0x8B: "execution context too long" ,
0x8C: "too many function definitions" ,
0x8D: "too many instruction definitions" ,
0x8E: "SFNT font table missing" ,
0x8F: "horizontal header (hhea, table missing" ,
0x90: "locations (loca, table missing" ,
0x91: "name table missing" ,
0x92: "character map (cmap, table missing" ,
0x93: "horizontal metrics (hmtx, table missing" ,
0x94: "PostScript (post, table missing" ,
0x95: "invalid horizontal metrics" ,
0x96: "invalid character map (cmap, format" ,
0x97: "invalid ppem value" ,
0x98: "invalid vertical metrics" ,
0x99: "could not find context" ,
0x9A: "invalid PostScript (post, table format" ,
0x9B: "invalid PostScript (post, table" ,
0xA0: "opcode syntax error" ,
0xA1: "argument stack underflow" ,
0xA2: "ignore" ,
0xB0: "`STARTFONT' field missing" ,
0xB1: "`FONT' field missing" ,
0xB2: "`SIZE' field missing" ,
0xB3: "`CHARS' field missing" ,
0xB4: "`STARTCHAR' field missing" ,
0xB5: "`ENCODING' field missing" ,
0xB6: "`BBX' field missing" ,
0xB7: "`BBX' too big" ,
}
FT_LOAD_RENDER = 0x4
FT_F26Dot6 = c_long
FT_Init_FreeType = _get_function('FT_Init_FreeType',
[POINTER(FT_Library)], c_int)
FT_New_Memory_Face = _get_function('FT_New_Memory_Face',
[FT_Library, POINTER(c_byte), c_long, c_long, POINTER(FT_Face)], c_int)
FT_New_Face = _get_function('FT_New_Face',
[FT_Library, c_char_p, c_long, POINTER(FT_Face)], c_int)
FT_Set_Pixel_Sizes = _get_function('FT_Set_Pixel_Sizes',
[FT_Face, c_uint, c_uint], c_int)
FT_Set_Char_Size = _get_function('FT_Set_Char_Size',
[FT_Face, FT_F26Dot6, FT_F26Dot6, c_uint, c_uint], c_int)
FT_Load_Glyph = _get_function('FT_Load_Glyph',
[FT_Face, c_uint, c_int32], c_int)
FT_Get_Char_Index = _get_function('FT_Get_Char_Index',
[FT_Face, c_ulong], c_uint)
FT_Load_Char = _get_function('FT_Load_Char',
[FT_Face, c_ulong, c_int], c_int)
FT_Get_Kerning = _get_function('FT_Get_Kerning',
[FT_Face, c_uint, c_uint, c_uint, POINTER(FT_Vector)], c_int)
# SFNT interface
class FT_SfntName(Structure):
_fields_ = [
('platform_id', c_ushort),
('encoding_id', c_ushort),
('language_id', c_ushort),
('name_id', c_ushort),
('string', POINTER(c_byte)),
('string_len', c_uint)
]
FT_Get_Sfnt_Name_Count = _get_function('FT_Get_Sfnt_Name_Count',
[FT_Face], c_uint)
FT_Get_Sfnt_Name = _get_function('FT_Get_Sfnt_Name',
[FT_Face, c_uint, POINTER(FT_SfntName)], c_int)
TT_PLATFORM_MICROSOFT = 3
TT_MS_ID_UNICODE_CS = 1
TT_NAME_ID_COPYRIGHT = 0
TT_NAME_ID_FONT_FAMILY = 1
TT_NAME_ID_FONT_SUBFAMILY = 2
TT_NAME_ID_UNIQUE_ID = 3
TT_NAME_ID_FULL_NAME = 4
TT_NAME_ID_VERSION_STRING = 5
TT_NAME_ID_PS_NAME = 6
TT_NAME_ID_TRADEMARK = 7
TT_NAME_ID_MANUFACTURER = 8
TT_NAME_ID_DESIGNER = 9
TT_NAME_ID_DESCRIPTION = 10
TT_NAME_ID_VENDOR_URL = 11
TT_NAME_ID_DESIGNER_URL = 12
TT_NAME_ID_LICENSE = 13
TT_NAME_ID_LICENSE_URL = 14
TT_NAME_ID_PREFERRED_FAMILY = 16
TT_NAME_ID_PREFERRED_SUBFAMILY= 17
TT_NAME_ID_MAC_FULL_NAME = 18
TT_NAME_ID_CID_FINDFONT_NAME = 20
_library = None
def ft_get_library():
global _library
if not _library:
_library = FT_Library()
error = FT_Init_FreeType(byref(_library))
if error:
raise FontException(
'an error occurred during library initialization', error)
return _library

635
pyglet/font/ttf.py Normal file
View file

@ -0,0 +1,635 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id: ttf.py 1579 2008-01-15 14:47:19Z Alex.Holkner $
"""
Implementation of the Truetype file format.
Typical applications will not need to use this module directly; look at
`pyglyph.font` instead.
References:
* http://developer.apple.com/fonts/TTRefMan/RM06
* http://www.microsoft.com/typography/otspec
"""
__docformat__ = 'restructuredtext'
__version__ = '$Id: ttf.py 1579 2008-01-15 14:47:19Z Alex.Holkner $'
import codecs
import os
import mmap
import struct
class TruetypeInfo:
"""Information about a single Truetype face.
The class memory-maps the font file to read the tables, so
it is vital that you call the `close` method to avoid large memory
leaks. Once closed, you cannot call any of the ``get_*`` methods.
Not all tables have been implemented yet (or likely ever will).
Currently only the name and metric tables are read; in particular
there is no glyph or hinting information.
"""
_name_id_lookup = {
'copyright': 0,
'family': 1,
'subfamily': 2,
'identifier': 3,
'name': 4,
'version': 5,
'postscript': 6,
'trademark': 7,
'manufacturer': 8,
'designer': 9,
'description': 10,
'vendor-url': 11,
'designer-url': 12,
'license': 13,
'license-url': 14,
'preferred-family': 16,
'preferred-subfamily': 17,
'compatible-name': 18,
'sample': 19,
}
_platform_id_lookup = {
'unicode': 0,
'macintosh': 1,
'iso': 2,
'microsoft': 3,
'custom': 4
}
_microsoft_encoding_lookup = {
1: 'utf_16_be',
2: 'shift_jis',
4: 'big5',
6: 'johab',
10: 'utf_16_be'
}
_macintosh_encoding_lookup = {
0: 'mac_roman'
}
def __init__(self, filename):
"""Read the given truetype file.
:Parameters:
`filename`
The name of any Windows, OS2 or Macintosh Truetype file.
The object must be closed (see `close`) after use.
An exception will be raised if the file does not exist or cannot
be read.
"""
if not filename: filename = ''
len = os.stat(filename).st_size
self._fileno = os.open(filename, os.O_RDONLY)
if hasattr(mmap, 'MAP_SHARED'):
self._data = mmap.mmap(self._fileno, len, mmap.MAP_SHARED,
mmap.PROT_READ)
else:
self._data = mmap.mmap(self._fileno, len, None, mmap.ACCESS_READ)
offsets = _read_offset_table(self._data, 0)
self._tables = {}
for table in _read_table_directory_entry.array(self._data,
offsets.size, offsets.num_tables):
self._tables[table.tag] = table
self._names = None
self._horizontal_metrics = None
self._character_advances = None
self._character_kernings = None
self._glyph_kernings = None
self._character_map = None
self._glyph_map = None
self._font_selection_flags = None
self.header = \
_read_head_table(self._data, self._tables['head'].offset)
self.horizontal_header = \
_read_horizontal_header(self._data, self._tables['hhea'].offset)
def get_font_selection_flags(self):
"""Return the font selection flags, as defined in OS/2 table"""
if not self._font_selection_flags:
OS2_table = \
_read_OS2_table(self._data, self._tables['OS/2'].offset)
self._font_selection_flags = OS2_table.fs_selection
return self._font_selection_flags
def is_bold(self):
"""Returns True iff the font describes itself as bold."""
return bool(self.get_font_selection_flags() & 0x20)
def is_italic(self):
"""Returns True iff the font describes itself as italic."""
return bool(self.get_font_selection_flags() & 0x1)
def get_names(self):
"""Returns a dictionary of names defined in the file.
The key of each item is a tuple of ``platform_id``, ``name_id``,
where each ID is the number as described in the Truetype format.
The value of each item is a tuple of
``encoding_id``, ``language_id``, ``value``, where ``value`` is
an encoded string.
"""
if self._names:
return self._names
naming_table = \
_read_naming_table(self._data, self._tables['name'].offset)
name_records = \
_read_name_record.array(self._data,
self._tables['name'].offset + naming_table.size,
naming_table.count)
storage = naming_table.string_offset + self._tables['name'].offset
self._names = {}
for record in name_records:
value = self._data[record.offset + storage:\
record.offset + storage + record.length]
key = record.platform_id, record.name_id
value = (record.encoding_id, record.language_id, value)
if not key in self._names:
self._names[key] = []
self._names[key].append(value)
return self._names
def get_name(self, name, platform=None, languages=None):
"""Returns the value of the given name in this font.
:Parameters:
`name`
Either an integer, representing the name_id desired (see
font format); or a string describing it, see below for
valid names.
`platform`
Platform for the requested name. Can be the integer ID,
or a string describing it. By default, the Microsoft
platform is searched first, then Macintosh.
`languages`
A list of language IDs to search. The first language
which defines the requested name will be used. By default,
all English dialects are searched.
If the name is not found, ``None`` is returned. If the name
is found, the value will be decoded and returned as a unicode
string. Currently only some common encodings are supported.
Valid names to request are (supply as a string)::
'copyright'
'family'
'subfamily'
'identifier'
'name'
'version'
'postscript'
'trademark'
'manufacturer'
'designer'
'description'
'vendor-url'
'designer-url'
'license'
'license-url'
'preferred-family'
'preferred-subfamily'
'compatible-name'
'sample'
Valid platforms to request are (supply as a string)::
'unicode'
'macintosh'
'iso'
'microsoft'
'custom'
"""
names = self.get_names()
if type(name) == str:
name = self._name_id_lookup[name]
if not platform:
for platform in ('microsoft','macintosh'):
value = self.get_name(name, platform, languages)
if value:
return value
if type(platform) == str:
platform = self._platform_id_lookup[platform]
if not (platform, name) in names:
return None
if platform == 3: # setup for microsoft
encodings = self._microsoft_encoding_lookup
if not languages:
# Default to english languages for microsoft
languages = (0x409,0x809,0xc09,0x1009,0x1409,0x1809)
elif platform == 1: # setup for macintosh
encodings = self.__macintosh_encoding_lookup
if not languages:
# Default to english for macintosh
languages = (0,)
for record in names[(platform, name)]:
if record[1] in languages and record[0] in encodings:
decoder = codecs.getdecoder(encodings[record[0]])
return decoder(record[2])[0]
return None
def get_horizontal_metrics(self):
"""Return all horizontal metric entries in table format."""
if not self._horizontal_metrics:
ar = _read_long_hor_metric.array(self._data,
self._tables['hmtx'].offset,
self.horizontal_header.number_of_h_metrics)
self._horizontal_metrics = ar
return self._horizontal_metrics
def get_character_advances(self):
"""Return a dictionary of character->advance.
They key of the dictionary is a unit-length unicode string,
and the value is a float giving the horizontal advance in
em.
"""
if self._character_advances:
return self._character_advances
ga = self.get_glyph_advances()
gmap = self.get_glyph_map()
self._character_advances = {}
for i in range(len(ga)):
if i in gmap and not gmap[i] in self._character_advances:
self._character_advances[gmap[i]] = ga[i]
return self._character_advances
def get_glyph_advances(self):
"""Return a dictionary of glyph->advance.
They key of the dictionary is the glyph index and the value is a float
giving the horizontal advance in em.
"""
hm = self.get_horizontal_metrics()
return [float(m.advance_width) / self.header.units_per_em for m in hm]
def get_character_kernings(self):
"""Return a dictionary of (left,right)->kerning
The key of the dictionary is a tuple of ``(left, right)``
where each element is a unit-length unicode string. The
value of the dictionary is the horizontal pairwise kerning
in em.
"""
if not self._character_kernings:
gmap = self.get_glyph_map()
kerns = self.get_glyph_kernings()
self._character_kernings = {}
for pair, value in kerns.items():
lglyph, rglyph = pair
lchar = lglyph in gmap and gmap[lglyph] or None
rchar = rglyph in gmap and gmap[rglyph] or None
if lchar and rchar:
self._character_kernings[(lchar, rchar)] = value
return self._character_kernings
def get_glyph_kernings(self):
"""Return a dictionary of (left,right)->kerning
The key of the dictionary is a tuple of ``(left, right)``
where each element is a glyph index. The value of the dictionary is
the horizontal pairwise kerning in em.
"""
if self._glyph_kernings:
return self._glyph_kernings
header = \
_read_kern_header_table(self._data, self._tables['kern'].offset)
offset = self._tables['kern'].offset + header.size
kernings = {}
for i in range(header.n_tables):
header = _read_kern_subtable_header(self._data, offset)
if header.coverage & header.horizontal_mask \
and not header.coverage & header.minimum_mask \
and not header.coverage & header.perpendicular_mask:
if header.coverage & header.format_mask == 0:
self._add_kernings_format0(kernings, offset + header.size)
offset += header.length
self._glyph_kernings = kernings
return kernings
def _add_kernings_format0(self, kernings, offset):
header = _read_kern_subtable_format0(self._data, offset)
kerning_pairs = _read_kern_subtable_format0Pair.array(self._data,
offset + header.size, header.n_pairs)
for pair in kerning_pairs:
if (pair.left, pair.right) in kernings:
kernings[(pair.left, pair.right)] += pair.value \
/ float(self.header.units_per_em)
else:
kernings[(pair.left, pair.right)] = pair.value \
/ float(self.header.units_per_em)
def get_glyph_map(self):
"""Calculate and return a reverse character map.
Returns a dictionary where the key is a glyph index and the
value is a unit-length unicode string.
"""
if self._glyph_map:
return self._glyph_map
cmap = self.get_character_map()
self._glyph_map = {}
for ch, glyph in cmap.items():
if not glyph in self._glyph_map:
self._glyph_map[glyph] = ch
return self._glyph_map
def get_character_map(self):
"""Return the character map.
Returns a dictionary where the key is a unit-length unicode
string and the value is a glyph index. Currently only
format 4 character maps are read.
"""
if self._character_map:
return self._character_map
cmap = _read_cmap_header(self._data, self._tables['cmap'].offset)
records = _read_cmap_encoding_record.array(self._data,
self._tables['cmap'].offset + cmap.size, cmap.num_tables)
self._character_map = {}
for record in records:
if record.platform_id == 3 and record.encoding_id == 1:
# Look at Windows Unicode charmaps only
offset = self._tables['cmap'].offset + record.offset
format_header = _read_cmap_format_header(self._data, offset)
if format_header.format == 4:
self._character_map = \
self._get_character_map_format4(offset)
break
return self._character_map
def _get_character_map_format4(self, offset):
# This is absolutely, without question, the *worst* file
# format ever. Whoever the fuckwit is that thought this up is
# a fuckwit.
header = _read_cmap_format4Header(self._data, offset)
seg_count = header.seg_count_x2 / 2
array_size = struct.calcsize('>%dH' % seg_count)
end_count = self._read_array('>%dH' % seg_count,
offset + header.size)
start_count = self._read_array('>%dH' % seg_count,
offset + header.size + array_size + 2)
id_delta = self._read_array('>%dh' % seg_count,
offset + header.size + array_size + 2 + array_size)
id_range_offset_address = \
offset + header.size + array_size + 2 + array_size + array_size
id_range_offset = self._read_array('>%dH' % seg_count,
id_range_offset_address)
character_map = {}
for i in range(0, seg_count):
if id_range_offset[i] != 0:
if id_range_offset[i] == 65535:
continue # Hack around a dodgy font (babelfish.ttf)
for c in range(start_count[i], end_count[i] + 1):
addr = id_range_offset[i] + 2*(c - start_count[i]) + \
id_range_offset_address + 2*i
g = struct.unpack('>H', self._data[addr:addr+2])[0]
if g != 0:
character_map[unichr(c)] = (g + id_delta[i]) % 65536
else:
for c in range(start_count[i], end_count[i] + 1):
g = (c + id_delta[i]) % 65536
if g != 0:
character_map[unichr(c)] = g
return character_map
def _read_array(self, format, offset):
size = struct.calcsize(format)
return struct.unpack(format, self._data[offset:offset+size])
def close(self):
"""Close the font file.
This is a good idea, since the entire file is memory mapped in
until this method is called. After closing cannot rely on the
``get_*`` methods.
"""
self._data.close()
os.close(self._fileno)
def _read_table(*entries):
""" Generic table constructor used for table formats listed at
end of file."""
fmt = '>'
names = []
for entry in entries:
name, type = entry.split(':')
names.append(name)
fmt += type
class _table_class:
size = struct.calcsize(fmt)
def __init__(self, data, offset):
items = struct.unpack(fmt, data[offset:offset+self.size])
self.pairs = zip(names, items)
for name, value in self.pairs:
setattr(self, name, value)
def __repr__(self):
s = '{' + ', '.join(['%s = %s' % (name, value) \
for name, value in self.pairs]) + '}'
return s
@staticmethod
def array(data, offset, count):
tables = []
for i in range(count):
tables.append(_table_class(data, offset))
offset += _table_class.size
return tables
return _table_class
# Table formats (see references)
_read_offset_table = _read_table('scalertype:I',
'num_tables:H',
'search_range:H',
'entry_selector:H',
'range_shift:H')
_read_table_directory_entry = _read_table('tag:4s',
'check_sum:I',
'offset:I',
'length:I')
_read_head_table = _read_table('version:i',
'font_revision:i',
'check_sum_adjustment:L',
'magic_number:L',
'flags:H',
'units_per_em:H',
'created:Q',
'modified:Q',
'x_min:h',
'y_min:h',
'x_max:h',
'y_max:h',
'mac_style:H',
'lowest_rec_p_pEM:H',
'font_direction_hint:h',
'index_to_loc_format:h',
'glyph_data_format:h')
_read_OS2_table = _read_table('version:H',
'x_avg_char_width:h',
'us_weight_class:H',
'us_width_class:H',
'fs_type:H',
'y_subscript_x_size:h',
'y_subscript_y_size:h',
'y_subscript_x_offset:h',
'y_subscript_y_offset:h',
'y_superscript_x_size:h',
'y_superscript_y_size:h',
'y_superscript_x_offset:h',
'y_superscript_y_offset:h',
'y_strikeout_size:h',
'y_strikeout_position:h',
's_family_class:h',
'panose1:B',
'panose2:B',
'panose3:B',
'panose4:B',
'panose5:B',
'panose6:B',
'panose7:B',
'panose8:B',
'panose9:B',
'panose10:B',
'ul_unicode_range1:L',
'ul_unicode_range2:L',
'ul_unicode_range3:L',
'ul_unicode_range4:L',
'ach_vend_id:I',
'fs_selection:H',
'us_first_char_index:H',
'us_last_char_index:H',
's_typo_ascender:h',
's_typo_descender:h',
's_typo_line_gap:h',
'us_win_ascent:H',
'us_win_descent:H',
'ul_code_page_range1:L',
'ul_code_page_range2:L',
'sx_height:h',
's_cap_height:h',
'us_default_char:H',
'us_break_char:H',
'us_max_context:H')
_read_kern_header_table = _read_table('version_num:H',
'n_tables:H')
_read_kern_subtable_header = _read_table('version:H',
'length:H',
'coverage:H')
_read_kern_subtable_header.horizontal_mask = 0x1
_read_kern_subtable_header.minimum_mask = 0x2
_read_kern_subtable_header.perpendicular_mask = 0x4
_read_kern_subtable_header.override_mask = 0x5
_read_kern_subtable_header.format_mask = 0xf0
_read_kern_subtable_format0 = _read_table('n_pairs:H',
'search_range:H',
'entry_selector:H',
'range_shift:H')
_read_kern_subtable_format0Pair = _read_table('left:H',
'right:H',
'value:h')
_read_cmap_header = _read_table('version:H',
'num_tables:H')
_read_cmap_encoding_record = _read_table('platform_id:H',
'encoding_id:H',
'offset:L')
_read_cmap_format_header = _read_table('format:H',
'length:H')
_read_cmap_format4Header = _read_table('format:H',
'length:H',
'language:H',
'seg_count_x2:H',
'search_range:H',
'entry_selector:H',
'range_shift:H')
_read_horizontal_header = _read_table('version:i',
'Advance:h',
'Descender:h',
'LineGap:h',
'advance_width_max:H',
'min_left_side_bearing:h',
'min_right_side_bearing:h',
'x_max_extent:h',
'caret_slope_rise:h',
'caret_slope_run:h',
'caret_offset:h',
'reserved1:h',
'reserved2:h',
'reserved3:h',
'reserved4:h',
'metric_data_format:h',
'number_of_h_metrics:H')
_read_long_hor_metric = _read_table('advance_width:H',
'lsb:h')
_read_naming_table = _read_table('format:H',
'count:H',
'string_offset:H')
_read_name_record = _read_table('platform_id:H',
'encoding_id:H',
'language_id:H',
'name_id:H',
'length:H',
'offset:H')

574
pyglet/font/win32.py Normal file
View file

@ -0,0 +1,574 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''
'''
# TODO Windows Vista: need to call SetProcessDPIAware? May affect GDI+ calls
# as well as font.
from ctypes import *
import ctypes
import math
import pyglet
from pyglet.font import base
import pyglet.image
from pyglet.window.win32.constants import *
from pyglet.window.win32.types import *
from pyglet.window.win32 import _gdi32 as gdi32, _user32 as user32
from pyglet.window.win32 import _kernel32 as kernel32
_debug_font = pyglet.options['debug_font']
HFONT = HANDLE
HBITMAP = HANDLE
HDC = HANDLE
HGDIOBJ = HANDLE
gdi32.CreateFontIndirectA.restype = HFONT
gdi32.CreateCompatibleBitmap.restype = HBITMAP
gdi32.CreateCompatibleDC.restype = HDC
user32.GetDC.restype = HDC
gdi32.GetStockObject.restype = HGDIOBJ
gdi32.CreateDIBSection.restype = HBITMAP
class LOGFONT(Structure):
_fields_ = [
('lfHeight', c_long),
('lfWidth', c_long),
('lfEscapement', c_long),
('lfOrientation', c_long),
('lfWeight', c_long),
('lfItalic', c_byte),
('lfUnderline', c_byte),
('lfStrikeOut', c_byte),
('lfCharSet', c_byte),
('lfOutPrecision', c_byte),
('lfClipPrecision', c_byte),
('lfQuality', c_byte),
('lfPitchAndFamily', c_byte),
('lfFaceName', (c_char * LF_FACESIZE)) # Use ASCII
]
__slots__ = [f[0] for f in _fields_]
class TEXTMETRIC(Structure):
_fields_ = [
('tmHeight', c_long),
('tmAscent', c_long),
('tmDescent', c_long),
('tmInternalLeading', c_long),
('tmExternalLeading', c_long),
('tmAveCharWidth', c_long),
('tmMaxCharWidth', c_long),
('tmWeight', c_long),
('tmOverhang', c_long),
('tmDigitizedAspectX', c_long),
('tmDigitizedAspectY', c_long),
('tmFirstChar', c_char), # Use ASCII
('tmLastChar', c_char),
('tmDefaultChar', c_char),
('tmBreakChar', c_char),
('tmItalic', c_byte),
('tmUnderlined', c_byte),
('tmStruckOut', c_byte),
('tmPitchAndFamily', c_byte),
('tmCharSet', c_byte)
]
__slots__ = [f[0] for f in _fields_]
class ABC(Structure):
_fields_ = [
('abcA', c_int),
('abcB', c_uint),
('abcC', c_int)
]
__slots__ = [f[0] for f in _fields_]
class BITMAPINFOHEADER(Structure):
_fields_ = [
('biSize', c_uint32),
('biWidth', c_int),
('biHeight', c_int),
('biPlanes', c_short),
('biBitCount', c_short),
('biCompression', c_uint32),
('biSizeImage', c_uint32),
('biXPelsPerMeter', c_long),
('biYPelsPerMeter', c_long),
('biClrUsed', c_uint32),
('biClrImportant', c_uint32)
]
__slots__ = [f[0] for f in _fields_]
class RGBQUAD(Structure):
_fields_ = [
('rgbBlue', c_byte),
('rgbGreen', c_byte),
('rgbRed', c_byte),
('rgbReserved', c_byte)
]
def __init__(self, r, g, b):
self.rgbRed = r
self.rgbGreen = g
self.rgbBlue = b
class BITMAPINFO(Structure):
_fields_ = [
('bmiHeader', BITMAPINFOHEADER),
('bmiColors', c_ulong * 3)
]
def str_ucs2(text):
if byteorder == 'big':
text = text.encode('utf_16_be')
else:
text = text.encode('utf_16_le') # explicit endian avoids BOM
return create_string_buffer(text + '\0')
_debug_dir = 'debug_font'
def _debug_filename(base, extension):
import os
if not os.path.exists(_debug_dir):
os.makedirs(_debug_dir)
name = '%s-%%d.%%s' % os.path.join(_debug_dir, base)
num = 1
while os.path.exists(name % (num, extension)):
num += 1
return name % (num, extension)
def _debug_image(image, name):
filename = _debug_filename(name, 'png')
image.save(filename)
_debug('Saved image %r to %s' % (image, filename))
_debug_logfile = None
def _debug(msg):
global _debug_logfile
if not _debug_logfile:
_debug_logfile = open(_debug_filename('log', 'txt'), 'wt')
_debug_logfile.write(msg + '\n')
class Win32GlyphRenderer(base.GlyphRenderer):
_bitmap = None
_dc = None
_bitmap_rect = None
def __init__(self, font):
super(Win32GlyphRenderer, self).__init__(font)
self.font = font
# Pessimistically round up width and height to 4 byte alignment
width = font.max_glyph_width
height = font.ascent - font.descent
width = (width | 0x3) + 1
height = (height | 0x3) + 1
self._create_bitmap(width, height)
gdi32.SelectObject(self._dc, self.font.hfont)
def _create_bitmap(self, width, height):
pass
def render(self, text):
raise NotImplementedError('abstract')
class GDIGlyphRenderer(Win32GlyphRenderer):
def __del__(self):
try:
if self._dc:
gdi32.DeleteDC(self._dc)
if self._bitmap:
gdi32.DeleteObject(self._bitmap)
except:
pass
def render(self, text):
# Attempt to get ABC widths (only for TrueType)
abc = ABC()
if gdi32.GetCharABCWidthsW(self._dc,
ord(text), ord(text), byref(abc)):
width = abc.abcB
lsb = abc.abcA
advance = abc.abcA + abc.abcB + abc.abcC
else:
width_buf = c_int()
gdi32.GetCharWidth32W(self._dc,
ord(text), ord(text), byref(width_buf))
width = width_buf.value
lsb = 0
advance = width
# Can't get glyph-specific dimensions, use whole line-height.
height = self._bitmap_height
image = self._get_image(text, width, height, lsb)
glyph = self.font.create_glyph(image)
glyph.set_bearings(-self.font.descent, lsb, advance)
if _debug_font:
_debug('%r.render(%s)' % (self, text))
_debug('abc.abcA = %r' % abc.abcA)
_debug('abc.abcB = %r' % abc.abcB)
_debug('abc.abcC = %r' % abc.abcC)
_debug('width = %r' % width)
_debug('height = %r' % height)
_debug('lsb = %r' % lsb)
_debug('advance = %r' % advance)
_debug_image(image, 'glyph_%s' % text)
_debug_image(self.font.textures[0], 'tex_%s' % text)
return glyph
def _get_image(self, text, width, height, lsb):
# There's no such thing as a greyscale bitmap format in GDI. We can
# create an 8-bit palette bitmap with 256 shades of grey, but
# unfortunately antialiasing will not work on such a bitmap. So, we
# use a 32-bit bitmap and use the red channel as OpenGL's alpha.
gdi32.SelectObject(self._dc, self._bitmap)
gdi32.SelectObject(self._dc, self.font.hfont)
gdi32.SetBkColor(self._dc, 0x0)
gdi32.SetTextColor(self._dc, 0x00ffffff)
gdi32.SetBkMode(self._dc, OPAQUE)
# Draw to DC
user32.FillRect(self._dc, byref(self._bitmap_rect), self._black)
gdi32.ExtTextOutA(self._dc, -lsb, 0, 0, c_void_p(), text,
len(text), c_void_p())
gdi32.GdiFlush()
# Create glyph object and copy bitmap data to texture
image = pyglet.image.ImageData(width, height,
'AXXX', self._bitmap_data, self._bitmap_rect.right * 4)
return image
def _create_bitmap(self, width, height):
self._black = gdi32.GetStockObject(BLACK_BRUSH)
self._white = gdi32.GetStockObject(WHITE_BRUSH)
if self._dc:
gdi32.ReleaseDC(self._dc)
if self._bitmap:
gdi32.DeleteObject(self._bitmap)
pitch = width * 4
data = POINTER(c_byte * (height * pitch))()
info = BITMAPINFO()
info.bmiHeader.biSize = sizeof(info.bmiHeader)
info.bmiHeader.biWidth = width
info.bmiHeader.biHeight = height
info.bmiHeader.biPlanes = 1
info.bmiHeader.biBitCount = 32
info.bmiHeader.biCompression = BI_RGB
self._dc = gdi32.CreateCompatibleDC(c_void_p())
self._bitmap = gdi32.CreateDIBSection(c_void_p(),
byref(info), DIB_RGB_COLORS, byref(data), c_void_p(),
0)
# Spookiness: the above line causes a "not enough storage" error,
# even though that error cannot be generated according to docs,
# and everything works fine anyway. Call SetLastError to clear it.
kernel32.SetLastError(0)
self._bitmap_data = data.contents
self._bitmap_rect = RECT()
self._bitmap_rect.left = 0
self._bitmap_rect.right = width
self._bitmap_rect.top = 0
self._bitmap_rect.bottom = height
self._bitmap_height = height
if _debug_font:
_debug('%r._create_dc(%d, %d)' % (self, width, height))
_debug('_dc = %r' % self._dc)
_debug('_bitmap = %r' % self._bitmap)
_debug('pitch = %r' % pitch)
_debug('info.bmiHeader.biSize = %r' % info.bmiHeader.biSize)
class Win32Font(base.Font):
glyph_renderer_class = GDIGlyphRenderer
def __init__(self, name, size, bold=False, italic=False, dpi=None):
super(Win32Font, self).__init__()
self.logfont = self.get_logfont(name, size, bold, italic, dpi)
self.hfont = gdi32.CreateFontIndirectA(byref(self.logfont))
# Create a dummy DC for coordinate mapping
dc = user32.GetDC(0)
metrics = TEXTMETRIC()
gdi32.SelectObject(dc, self.hfont)
gdi32.GetTextMetricsA(dc, byref(metrics))
self.ascent = metrics.tmAscent
self.descent = -metrics.tmDescent
self.max_glyph_width = metrics.tmMaxCharWidth
@staticmethod
def get_logfont(name, size, bold, italic, dpi):
# Create a dummy DC for coordinate mapping
dc = user32.GetDC(0)
if dpi is None:
dpi = 96
logpixelsy = dpi
logfont = LOGFONT()
# Conversion of point size to device pixels
logfont.lfHeight = int(-size * logpixelsy / 72)
if bold:
logfont.lfWeight = FW_BOLD
else:
logfont.lfWeight = FW_NORMAL
logfont.lfItalic = italic
logfont.lfFaceName = name
logfont.lfQuality = ANTIALIASED_QUALITY
return logfont
@classmethod
def have_font(cls, name):
# CreateFontIndirect always returns a font... have to work out
# something with EnumFontFamily... TODO
return True
@classmethod
def add_font_data(cls, data):
numfonts = c_uint32()
gdi32.AddFontMemResourceEx(data, len(data), 0, byref(numfonts))
# --- GDI+ font rendering ---
from pyglet.image.codecs.gdiplus import PixelFormat32bppARGB, gdiplus, Rect
from pyglet.image.codecs.gdiplus import ImageLockModeRead, BitmapData
DriverStringOptionsCmapLookup = 1
DriverStringOptionsRealizedAdvance = 4
TextRenderingHintAntiAlias = 4
TextRenderingHintAntiAliasGridFit = 3
StringFormatFlagsDirectionRightToLeft = 0x00000001
StringFormatFlagsDirectionVertical = 0x00000002
StringFormatFlagsNoFitBlackBox = 0x00000004
StringFormatFlagsDisplayFormatControl = 0x00000020
StringFormatFlagsNoFontFallback = 0x00000400
StringFormatFlagsMeasureTrailingSpaces = 0x00000800
StringFormatFlagsNoWrap = 0x00001000
StringFormatFlagsLineLimit = 0x00002000
StringFormatFlagsNoClip = 0x00004000
class Rectf(ctypes.Structure):
_fields_ = [
('x', ctypes.c_float),
('y', ctypes.c_float),
('width', ctypes.c_float),
('height', ctypes.c_float),
]
class GDIPlusGlyphRenderer(Win32GlyphRenderer):
def _create_bitmap(self, width, height):
self._data = (ctypes.c_byte * (4 * width * height))()
self._bitmap = ctypes.c_void_p()
self._format = PixelFormat32bppARGB
gdiplus.GdipCreateBitmapFromScan0(width, height, width * 4,
self._format, self._data, ctypes.byref(self._bitmap))
self._graphics = ctypes.c_void_p()
gdiplus.GdipGetImageGraphicsContext(self._bitmap,
ctypes.byref(self._graphics))
gdiplus.GdipSetPageUnit(self._graphics, UnitPixel)
self._dc = user32.GetDC(0)
gdi32.SelectObject(self._dc, self.font.hfont)
gdiplus.GdipSetTextRenderingHint(self._graphics,
TextRenderingHintAntiAliasGridFit)
self._brush = ctypes.c_void_p()
gdiplus.GdipCreateSolidFill(0xffffffff, ctypes.byref(self._brush))
self._matrix = ctypes.c_void_p()
gdiplus.GdipCreateMatrix(ctypes.byref(self._matrix))
self._flags = (DriverStringOptionsCmapLookup |
DriverStringOptionsRealizedAdvance)
self._rect = Rect(0, 0, width, height)
self._bitmap_height = height
def render(self, text):
ch = ctypes.create_unicode_buffer(text)
# Layout rectangle; not clipped against so not terribly important.
width = 10000
height = self._bitmap_height
rect = Rectf(0, self._bitmap_height
- self.font.ascent + self.font.descent,
width, height)
# Set up GenericTypographic with 1 character measure range
generic = ctypes.c_void_p()
gdiplus.GdipStringFormatGetGenericTypographic(ctypes.byref(generic))
format = ctypes.c_void_p()
gdiplus.GdipCloneStringFormat(generic, ctypes.byref(format))
# Measure advance
bbox = Rectf()
flags = (StringFormatFlagsMeasureTrailingSpaces |
StringFormatFlagsNoClip |
StringFormatFlagsNoFitBlackBox)
gdiplus.GdipSetStringFormatFlags(format, flags)
gdiplus.GdipMeasureString(self._graphics, ch, len(ch) - 1,
self.font._gdipfont, ctypes.byref(rect), format,
ctypes.byref(bbox), 0, 0)
lsb = 0
advance = int(math.ceil(bbox.width))
# XXX HACK HACK HACK
# Windows GDI+ is a filthy broken toy. No way to measure the bounding
# box of a string, or to obtain LSB. What a joke.
#
# For historical note, GDI cannot be used because it cannot composite
# into a bitmap with alpha.
#
# It looks like MS have abandoned GDI and GDI+ and are finally
# supporting accurate text measurement with alpha composition in .NET
# 2.0 (WinForms) via the TextRenderer class; this has no C interface
# though, so we're entirely screwed.
#
# So anyway, this hack bumps up the width if the font is italic;
# this compensates for some common fonts. It's also a stupid waste of
# texture memory.
width = advance
if self.font.italic:
width += width // 2
# XXX END HACK HACK HACK
# Draw character to bitmap
gdiplus.GdipGraphicsClear(self._graphics, 0x00000000)
gdiplus.GdipDrawString(self._graphics, ch, len(ch) - 1,
self.font._gdipfont, ctypes.byref(rect), format,
self._brush)
gdiplus.GdipFlush(self._graphics, 1)
bitmap_data = BitmapData()
gdiplus.GdipBitmapLockBits(self._bitmap,
byref(self._rect), ImageLockModeRead, self._format,
byref(bitmap_data))
# Create buffer for RawImage
buffer = create_string_buffer(
bitmap_data.Stride * bitmap_data.Height)
memmove(buffer, bitmap_data.Scan0, len(buffer))
# Unlock data
gdiplus.GdipBitmapUnlockBits(self._bitmap, byref(bitmap_data))
image = pyglet.image.ImageData(width, height,
'BGRA', buffer, -bitmap_data.Stride)
glyph = self.font.create_glyph(image)
glyph.set_bearings(-self.font.descent, lsb, advance)
return glyph
FontStyleBold = 1
FontStyleItalic = 2
UnitPixel = 2
UnitPoint = 3
class GDIPlusFont(Win32Font):
glyph_renderer_class = GDIPlusGlyphRenderer
_private_fonts = None
_default_name = 'Arial'
def __init__(self, name, size, bold=False, italic=False, dpi=None):
if not name:
name = self._default_name
super(GDIPlusFont, self).__init__(name, size, bold, italic, dpi)
family = ctypes.c_void_p()
name = ctypes.c_wchar_p(name)
# Look in private collection first:
if self._private_fonts:
gdiplus.GdipCreateFontFamilyFromName(name,
self._private_fonts, ctypes.byref(family))
# Then in system collection:
if not family:
gdiplus.GdipCreateFontFamilyFromName(name,
None, ctypes.byref(family))
# Nothing found, use default font.
if not family:
name = self._default_name
gdiplus.GdipCreateFontFamilyFromName(ctypes.c_wchar_p(name),
None, ctypes.byref(family))
if dpi is None:
unit = UnitPoint
self.dpi = 96
else:
unit = UnitPixel
size = (size * dpi) / 72
self.dpi = dpi
style = 0
if bold:
style |= FontStyleBold
if italic:
style |= FontStyleItalic
self.italic = italic # XXX needed for HACK HACK HACK
self._gdipfont = ctypes.c_void_p()
gdiplus.GdipCreateFont(family, ctypes.c_float(size),
style, unit, ctypes.byref(self._gdipfont))
@classmethod
def add_font_data(cls, data):
super(GDIPlusFont, cls).add_font_data(data)
if not cls._private_fonts:
cls._private_fonts = ctypes.c_void_p()
gdiplus.GdipNewPrivateFontCollection(
ctypes.byref(cls._private_fonts))
gdiplus.GdipPrivateAddMemoryFont(cls._private_fonts, data, len(data))

507
pyglet/gl/__init__.py Normal file
View file

@ -0,0 +1,507 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''OpenGL and GLU interface.
This package imports all OpenGL, GLU and registered OpenGL extension
functions. Functions have identical signatures to their C counterparts. For
example::
from pyglet.gl import *
# [...omitted: set up a GL context and framebuffer]
glBegin(GL_QUADS)
glVertex3f(0, 0, 0)
glVertex3f(0.1, 0.2, 0.3)
glVertex3f(0.1, 0.2, 0.3)
glEnd()
OpenGL is documented in full at the `OpenGL Reference Pages`_.
The `OpenGL Programming Guide`_ is a popular reference manual organised by
topic. The free online version documents only OpenGL 1.1. `Later editions`_
cover more recent versions of the API and can be purchased from a book store.
.. _OpenGL Reference Pages: http://www.opengl.org/documentation/red_book/
.. _OpenGL Programming Guide: http://fly.cc.fer.hr/~unreal/theredbook/
.. _Later editions: http://www.opengl.org/documentation/red_book/
The following subpackages are imported into this "mega" package already (and
so are available by importing ``pyglet.gl``):
``pyglet.gl.gl``
OpenGL
``pyglet.gl.glu``
GLU
``pyglet.gl.gl.glext_arb``
ARB registered OpenGL extension functions
``pyglet.gl.gl.glext_missing``
ARB registered OpenGL extension functions not included in the ARB C header
These subpackages are also available, but are not imported into this namespace
by default:
``pyglet.gl.glext_nv``
nVidia OpenGL extension functions
``pyglet.gl.agl``
AGL (Mac OS X OpenGL context functions)
``pyglet.gl.glx``
GLX (Linux OpenGL context functions)
``pyglet.gl.glxext_arb``
ARB registered GLX extension functions
``pyglet.gl.glxext_nv``
nvidia GLX extension functions
``pyglet.gl.wgl``
WGL (Windows OpenGL context functions)
``pyglet.gl.wglext_arb``
ARB registered WGL extension functions
``pyglet.gl.wglext_nv``
nvidia WGL extension functions
The information modules are provided for convenience, and are documented
below.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: __init__.py 2175 2008-08-15 04:29:16Z Alex.Holkner $'
from pyglet.gl.lib import GLException
from pyglet.gl.gl import *
from pyglet.gl.glu import *
from pyglet.gl.glext_arb import *
from pyglet.gl.glext_missing import *
from pyglet.gl import gl_info
import sys as _sys
_is_epydoc = hasattr(_sys, 'is_epydoc') and _sys.is_epydoc
# List of contexts currently in use, so we can create new contexts that
# share objects with. Remember to remove from this list when context is
# destroyed.
_contexts = []
#: The active OpenGL context.
#:
#: You can change the current context by calling `Context.set_current`; do not
#: modify this global.
#:
#: :type: `Context`
#:
#: :since: pyglet 1.1
current_context = None
def get_current_context():
'''Return the active OpenGL context.
You can change the current context by calling `Context.set_current`.
:deprecated: Use `current_context`
:rtype: `Context`
:return: the context to which OpenGL commands are directed, or None
if there is no selected context.
'''
return current_context
class Config(object):
'''Graphics configuration.
A GLConfig stores the preferences for OpenGL attributes such as the
number of auxilliary buffers, size of the colour and depth buffers,
double buffering, stencilling, multi- and super-sampling, and so on.
Different platforms support a different set of attributes, so these
are set with a string key and a value which is integer or boolean.
See also `pyglet.window.Screen.get_best_config` and
`pyglet.window.Screen.get_matching_configs`.
:Ivariables:
`double_buffer` : bool
Specify the presence of a back-buffer for every color buffer.
`stereo` : bool
Specify the presence of separate left and right buffer sets.
`buffer_size` : int
Total bits per sample per color buffer.
`aux_buffers` : int
The number of auxilliary color buffers.
`sample_buffers` : int
The number of multisample buffers.
`samples` : int
The number of samples per pixel, or 0 if there are no multisample
buffers.
`red_size` : int
Bits per sample per buffer devoted to the red component.
`green_size` : int
Bits per sample per buffer devoted to the green component.
`blue_size` : int
Bits per sample per buffer devoted to the blue component.
`alpha_size` : int
Bits per sample per buffer devoted to the alpha component.
`depth_size` : int
Bits per sample in the depth buffer.
`stencil_size` : int
Bits per sample in the stencil buffer.
`accum_red_size` : int
Bits per pixel devoted to the red component in the accumulation
buffer.
`accum_green_size` : int
Bits per pixel devoted to the green component in the accumulation
buffer.
`accum_blue_size` : int
Bits per pixel devoted to the blue component in the accumulation
buffer.
`accum_alpha_size` : int
Bits per pixel devoted to the alpha component in the accumulation
buffer.
'''
_attribute_names = [
'double_buffer',
'stereo',
'buffer_size',
'aux_buffers',
'sample_buffers',
'samples',
'red_size',
'green_size',
'blue_size',
'alpha_size',
'depth_size',
'stencil_size',
'accum_red_size',
'accum_green_size',
'accum_blue_size',
'accum_alpha_size',
]
def __init__(self, **kwargs):
'''Create a template config with the given attributes.
Specify attributes as keyword arguments, for example::
template = Config(double_buffer=True)
'''
for name in self._attribute_names:
if name in kwargs:
setattr(self, name, kwargs[name])
else:
setattr(self, name, None)
def get_gl_attributes(self):
'''Return a list of attributes set on this config.
:rtype: list of tuple (name, value)
:return: All attributes, with unset attributes having a value of
``None``.
'''
return [(name, getattr(self, name)) for name in self._attribute_names]
def create_context(self, share):
'''Create a GL context that satisifies this configuration.
:Parameters:
`share` : `Context`
If not None, a context with which to share objects with.
:rtype: `Context`
:return: The new context.
'''
raise ConfigException(
'This config is not complete. Use Screen.get_matching_configs')
def is_complete(self):
'''Determine if this config is complete and able to create a context.
Configs created directly are not complete, they can only serve
as templates for retrieving a supported config from the system.
For example, `pyglet.window.Screen.get_matching_configs` returns
complete configs.
:rtype: bool
:return: True if the config is complete and can create a context.
'''
return False
def __repr__(self):
import pprint
return '%s(%s)' % (self.__class__.__name__,
pprint.pformat(self.get_gl_attributes()))
class ObjectSpace(object):
def __init__(self):
# Textures and buffers scheduled for deletion the next time this
# object space is active.
self._doomed_textures = []
self._doomed_buffers = []
class Context(object):
'''OpenGL context for drawing.
Windows in pyglet each have their own GL context. This class boxes
the context in a platform-independent manner. Applications will have
no need to deal with contexts directly.
:Ivariables:
`object_space` : `ObjectSpace`
An object which is shared between all contexts that share
GL objects.
'''
#: Context share behaviour indicating that objects should not be
#: shared with existing contexts.
CONTEXT_SHARE_NONE = None
#: Context share behaviour indicating that objects are shared with
#: the most recently created context (the default).
CONTEXT_SHARE_EXISTING = 1
# Used for error checking, True if currently within a glBegin/End block.
# Ignored if error checking is disabled.
_gl_begin = False
# gl_info.GLInfo instance, filled in on first set_current
_info = None
# List of (attr, check) for each driver/device-specific workaround that is
# implemented. The `attr` attribute on this context is set to the result
# of evaluating `check(gl_info)` the first time this context is used.
_workaround_checks = [
# GDI Generic renderer on Windows does not implement
# GL_UNPACK_ROW_LENGTH correctly.
('_workaround_unpack_row_length',
lambda info: info.get_renderer() == 'GDI Generic'),
# Reportedly segfaults in text_input.py example.
('_workaround_vbo',
lambda info: info.get_renderer() == 'ATI Radeon X1600 OpenGL Engine'),
# Some ATI cards on OS X start drawing from a VBO before it's written
# to. In these cases pyglet needs to call glFinish() to flush the
# pipeline after updating a buffer but before rendering.
('_workaround_vbo_finish',
lambda info: ('ATI' in info.get_renderer() and
info.have_version(1, 5) and
_sys.platform == 'darwin')),
]
def __init__(self, context_share=None):
self.window = None
_contexts.append(self)
if context_share:
assert context_share in _contexts
self.object_space = context_share.object_space
else:
self.object_space = ObjectSpace()
def __repr__(self):
return '%s()' % self.__class__.__name__
def set_current(self):
global current_context
assert self in _contexts
current_context = self
# Implement workarounds
if not self._info:
self._info = gl_info.GLInfo()
self._info.set_active_context()
for attr, check in self._workaround_checks:
setattr(self, attr, check(self._info))
# Release textures on this context scheduled for deletion
if self.object_space._doomed_textures:
textures = self.object_space._doomed_textures
textures = (GLuint * len(textures))(*textures)
glDeleteTextures(len(textures), textures)
self.object_space._doomed_textures = []
# Release buffers on this context scheduled for deletion
if self.object_space._doomed_buffers:
buffers = self.object_space._doomed_buffers
buffers = (GLuint * len(buffers))(*buffers)
glDeleteBuffers(len(buffers), buffers)
self.object_space._doomed_buffers = []
def destroy(self):
'''Release the context.
The context will not be useable after being destroyed. Each platform
has its own convention for releasing the context and the buffer(s)
that depend on it in the correct order; this should never be called
by an application.
'''
global current_context
if current_context is self:
current_context = None
gl_info.remove_active_context()
# Switch back to shadow context.
if _shadow_window is not None:
_shadow_window.switch_to()
_contexts.remove(self)
def delete_texture(self, texture_id):
'''Safely delete a texture belonging to this context.
Usually, the texture is released immediately using
``glDeleteTextures``, however if another context that does not share
this context's object space is currently active, the deletion will
be deferred until an appropriate context is activated.
:Parameters:
`texture_id` : int
The OpenGL name of the texture to delete.
'''
if self.object_space is current_context.object_space:
id = GLuint(texture_id)
glDeleteTextures(1, id)
else:
self.object_space._doomed_textures.append(texture_id)
def delete_buffer(self, buffer_id):
'''Safely delete a buffer object belonging to this context.
This method behaves similarly to `delete_texture`, though for
``glDeleteBuffers`` instead of ``glDeleteTextures``.
:Parameters:
`buffer_id` : int
The OpenGL name of the buffer to delete.
:since: pyglet 1.1
'''
if self.object_space is current_context.object_space and False:
id = GLuint(buffer_id)
glDeleteBuffers(1, id)
else:
self.object_space._doomed_buffers.append(buffer_id)
class ContextException(Exception):
pass
class ConfigException(Exception):
pass
import pyglet as _pyglet
if _pyglet.options['debug_texture']:
_debug_texture_total = 0
_debug_texture_sizes = {}
_debug_texture = None
def _debug_texture_alloc(texture, size):
global _debug_texture_total
_debug_texture_sizes[texture] = size
_debug_texture_total += size
print '%d (+%d)' % (_debug_texture_total, size)
def _debug_texture_dealloc(texture):
global _debug_texture_total
size = _debug_texture_sizes[texture]
del _debug_texture_sizes[texture]
_debug_texture_total -= size
print '%d (-%d)' % (_debug_texture_total, size)
_glBindTexture = glBindTexture
def glBindTexture(target, texture):
global _debug_texture
_debug_texture = texture
return _glBindTexture(target, texture)
_glTexImage2D = glTexImage2D
def glTexImage2D(target, level, internalformat, width, height, border,
format, type, pixels):
try:
_debug_texture_dealloc(_debug_texture)
except KeyError:
pass
if internalformat in (1, GL_ALPHA, GL_INTENSITY, GL_LUMINANCE):
depth = 1
elif internalformat in (2, GL_RGB16, GL_RGBA16):
depth = 2
elif internalformat in (3, GL_RGB):
depth = 3
else:
depth = 4 # Pretty crap assumption
size = (width + 2 * border) * (height + 2 * border) * depth
_debug_texture_alloc(_debug_texture, size)
return _glTexImage2D(target, level, internalformat, width, height,
border, format, type, pixels)
_glDeleteTextures = glDeleteTextures
def glDeleteTextures(n, textures):
if not hasattr(textures, '__len__'):
_debug_texture_dealloc(textures.value)
else:
for i in range(n):
_debug_texture_dealloc(textures[i].value)
return _glDeleteTextures(n, textures)
def _create_shadow_window():
global _shadow_window
import pyglet
if not pyglet.options['shadow_window'] or _is_epydoc:
return
from pyglet.window import Window
_shadow_window = Window(width=1, height=1, visible=False)
_shadow_window.switch_to()
from pyglet import app
app.windows.remove(_shadow_window)
_shadow_window = None
# Import pyglet.window now if it isn't currently being imported (this creates
# the shadow window).
if (not _is_epydoc and
'pyglet.window' not in _sys.modules and
_pyglet.options['shadow_window']):
# trickery is for circular import
_pyglet.gl = _sys.modules[__name__]
import pyglet.window

452
pyglet/gl/agl.py Normal file
View file

@ -0,0 +1,452 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Wrapper for /System/Library/Frameworks/AGL.framework/Headers/agl.h
Generated by tools/gengl.py.
Do not modify this file.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: gengl.py 601 2007-02-04 05:36:59Z Alex.Holkner $'
from ctypes import *
from pyglet.gl.lib import link_AGL as _link_function
from pyglet.gl.lib import c_ptrdiff_t
if not _link_function:
raise ImportError('AGL framework is not available.')
# BEGIN GENERATED CONTENT (do not edit below this line)
# This content is generated by tools/gengl.py.
# Wrapper for /System/Library/Frameworks/AGL.framework/Headers/agl.h
AGL_VERSION_2_0 = 1 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:41
class struct_GDevice(Structure):
__slots__ = [
]
struct_GDevice._fields_ = [
('_opaque_struct', c_int)
]
GDevice = struct_GDevice # /System/Library/Frameworks/ApplicationServices.framework/Frameworks/QD.framework/Headers/Quickdraw.h:1347
GDPtr = POINTER(GDevice) # /System/Library/Frameworks/ApplicationServices.framework/Frameworks/QD.framework/Headers/Quickdraw.h:1348
GDHandle = POINTER(GDPtr) # /System/Library/Frameworks/ApplicationServices.framework/Frameworks/QD.framework/Headers/Quickdraw.h:1349
AGLDevice = GDHandle # /System/Library/Frameworks/AGL.framework/Headers/agl.h:46
class struct_OpaqueGrafPtr(Structure):
__slots__ = [
]
struct_OpaqueGrafPtr._fields_ = [
('_opaque_struct', c_int)
]
GrafPtr = POINTER(struct_OpaqueGrafPtr) # /System/Library/Frameworks/ApplicationServices.framework/Frameworks/QD.framework/Headers/Quickdraw.h:1009
CGrafPtr = GrafPtr # /System/Library/Frameworks/ApplicationServices.framework/Frameworks/QD.framework/Headers/Quickdraw.h:1392
AGLDrawable = CGrafPtr # /System/Library/Frameworks/AGL.framework/Headers/agl.h:51
class struct___AGLRendererInfoRec(Structure):
__slots__ = [
]
struct___AGLRendererInfoRec._fields_ = [
('_opaque_struct', c_int)
]
AGLRendererInfo = POINTER(struct___AGLRendererInfoRec) # /System/Library/Frameworks/AGL.framework/Headers/agl.h:56
class struct___AGLPixelFormatRec(Structure):
__slots__ = [
]
struct___AGLPixelFormatRec._fields_ = [
('_opaque_struct', c_int)
]
AGLPixelFormat = POINTER(struct___AGLPixelFormatRec) # /System/Library/Frameworks/AGL.framework/Headers/agl.h:57
class struct___AGLContextRec(Structure):
__slots__ = [
]
struct___AGLContextRec._fields_ = [
('_opaque_struct', c_int)
]
AGLContext = POINTER(struct___AGLContextRec) # /System/Library/Frameworks/AGL.framework/Headers/agl.h:58
class struct___AGLPBufferRec(Structure):
__slots__ = [
]
struct___AGLPBufferRec._fields_ = [
('_opaque_struct', c_int)
]
AGLPbuffer = POINTER(struct___AGLPBufferRec) # /System/Library/Frameworks/AGL.framework/Headers/agl.h:59
AGL_NONE = 0 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:66
AGL_ALL_RENDERERS = 1 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:67
AGL_BUFFER_SIZE = 2 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:68
AGL_LEVEL = 3 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:69
AGL_RGBA = 4 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:70
AGL_DOUBLEBUFFER = 5 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:71
AGL_STEREO = 6 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:72
AGL_AUX_BUFFERS = 7 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:73
AGL_RED_SIZE = 8 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:74
AGL_GREEN_SIZE = 9 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:75
AGL_BLUE_SIZE = 10 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:76
AGL_ALPHA_SIZE = 11 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:77
AGL_DEPTH_SIZE = 12 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:78
AGL_STENCIL_SIZE = 13 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:79
AGL_ACCUM_RED_SIZE = 14 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:80
AGL_ACCUM_GREEN_SIZE = 15 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:81
AGL_ACCUM_BLUE_SIZE = 16 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:82
AGL_ACCUM_ALPHA_SIZE = 17 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:83
AGL_PIXEL_SIZE = 50 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:88
AGL_MINIMUM_POLICY = 51 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:89
AGL_MAXIMUM_POLICY = 52 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:90
AGL_OFFSCREEN = 53 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:91
AGL_FULLSCREEN = 54 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:92
AGL_SAMPLE_BUFFERS_ARB = 55 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:93
AGL_SAMPLES_ARB = 56 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:94
AGL_AUX_DEPTH_STENCIL = 57 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:95
AGL_COLOR_FLOAT = 58 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:96
AGL_MULTISAMPLE = 59 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:97
AGL_SUPERSAMPLE = 60 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:98
AGL_SAMPLE_ALPHA = 61 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:99
AGL_RENDERER_ID = 70 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:104
AGL_SINGLE_RENDERER = 71 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:105
AGL_NO_RECOVERY = 72 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:106
AGL_ACCELERATED = 73 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:107
AGL_CLOSEST_POLICY = 74 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:108
AGL_ROBUST = 75 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:109
AGL_BACKING_STORE = 76 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:110
AGL_MP_SAFE = 78 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:111
AGL_WINDOW = 80 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:113
AGL_MULTISCREEN = 81 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:114
AGL_VIRTUAL_SCREEN = 82 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:115
AGL_COMPLIANT = 83 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:116
AGL_PBUFFER = 90 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:118
AGL_BUFFER_MODES = 100 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:135
AGL_MIN_LEVEL = 101 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:136
AGL_MAX_LEVEL = 102 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:137
AGL_COLOR_MODES = 103 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:138
AGL_ACCUM_MODES = 104 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:139
AGL_DEPTH_MODES = 105 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:140
AGL_STENCIL_MODES = 106 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:141
AGL_MAX_AUX_BUFFERS = 107 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:142
AGL_VIDEO_MEMORY = 120 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:143
AGL_TEXTURE_MEMORY = 121 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:144
AGL_RENDERER_COUNT = 128 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:145
AGL_SWAP_RECT = 200 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:150
AGL_BUFFER_RECT = 202 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:151
AGL_SWAP_LIMIT = 203 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:152
AGL_COLORMAP_TRACKING = 210 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:153
AGL_COLORMAP_ENTRY = 212 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:154
AGL_RASTERIZATION = 220 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:155
AGL_SWAP_INTERVAL = 222 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:156
AGL_STATE_VALIDATION = 230 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:157
AGL_BUFFER_NAME = 231 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:158
AGL_ORDER_CONTEXT_TO_FRONT = 232 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:159
AGL_CONTEXT_SURFACE_ID = 233 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:160
AGL_CONTEXT_DISPLAY_ID = 234 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:161
AGL_SURFACE_ORDER = 235 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:162
AGL_SURFACE_OPACITY = 236 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:163
AGL_CLIP_REGION = 254 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:164
AGL_FS_CAPTURE_SINGLE = 255 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:165
AGL_SURFACE_BACKING_SIZE = 304 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:166
AGL_ENABLE_SURFACE_BACKING_SIZE = 305 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:167
AGL_SURFACE_VOLATILE = 306 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:168
AGL_FORMAT_CACHE_SIZE = 501 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:172
AGL_CLEAR_FORMAT_CACHE = 502 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:173
AGL_RETAIN_RENDERERS = 503 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:174
AGL_MONOSCOPIC_BIT = 1 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:177
AGL_STEREOSCOPIC_BIT = 2 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:178
AGL_SINGLEBUFFER_BIT = 4 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:179
AGL_DOUBLEBUFFER_BIT = 8 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:180
AGL_0_BIT = 1 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:183
AGL_1_BIT = 2 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:184
AGL_2_BIT = 4 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:185
AGL_3_BIT = 8 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:186
AGL_4_BIT = 16 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:187
AGL_5_BIT = 32 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:188
AGL_6_BIT = 64 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:189
AGL_8_BIT = 128 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:190
AGL_10_BIT = 256 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:191
AGL_12_BIT = 512 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:192
AGL_16_BIT = 1024 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:193
AGL_24_BIT = 2048 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:194
AGL_32_BIT = 4096 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:195
AGL_48_BIT = 8192 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:196
AGL_64_BIT = 16384 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:197
AGL_96_BIT = 32768 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:198
AGL_128_BIT = 65536 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:199
AGL_RGB8_BIT = 1 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:202
AGL_RGB8_A8_BIT = 2 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:203
AGL_BGR233_BIT = 4 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:204
AGL_BGR233_A8_BIT = 8 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:205
AGL_RGB332_BIT = 16 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:206
AGL_RGB332_A8_BIT = 32 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:207
AGL_RGB444_BIT = 64 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:208
AGL_ARGB4444_BIT = 128 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:209
AGL_RGB444_A8_BIT = 256 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:210
AGL_RGB555_BIT = 512 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:211
AGL_ARGB1555_BIT = 1024 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:212
AGL_RGB555_A8_BIT = 2048 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:213
AGL_RGB565_BIT = 4096 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:214
AGL_RGB565_A8_BIT = 8192 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:215
AGL_RGB888_BIT = 16384 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:216
AGL_ARGB8888_BIT = 32768 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:217
AGL_RGB888_A8_BIT = 65536 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:218
AGL_RGB101010_BIT = 131072 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:219
AGL_ARGB2101010_BIT = 262144 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:220
AGL_RGB101010_A8_BIT = 524288 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:221
AGL_RGB121212_BIT = 1048576 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:222
AGL_ARGB12121212_BIT = 2097152 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:223
AGL_RGB161616_BIT = 4194304 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:224
AGL_ARGB16161616_BIT = 8388608 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:225
AGL_INDEX8_BIT = 536870912 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:226
AGL_INDEX16_BIT = 1073741824 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:227
AGL_RGBFLOAT64_BIT = 16777216 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:228
AGL_RGBAFLOAT64_BIT = 33554432 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:229
AGL_RGBFLOAT128_BIT = 67108864 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:230
AGL_RGBAFLOAT128_BIT = 134217728 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:231
AGL_RGBFLOAT256_BIT = 268435456 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:232
AGL_RGBAFLOAT256_BIT = 536870912 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:233
AGL_NO_ERROR = 0 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:238
AGL_BAD_ATTRIBUTE = 10000 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:240
AGL_BAD_PROPERTY = 10001 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:241
AGL_BAD_PIXELFMT = 10002 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:242
AGL_BAD_RENDINFO = 10003 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:243
AGL_BAD_CONTEXT = 10004 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:244
AGL_BAD_DRAWABLE = 10005 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:245
AGL_BAD_GDEV = 10006 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:246
AGL_BAD_STATE = 10007 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:247
AGL_BAD_VALUE = 10008 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:248
AGL_BAD_MATCH = 10009 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:249
AGL_BAD_ENUM = 10010 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:250
AGL_BAD_OFFSCREEN = 10011 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:251
AGL_BAD_FULLSCREEN = 10012 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:252
AGL_BAD_WINDOW = 10013 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:253
AGL_BAD_POINTER = 10014 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:254
AGL_BAD_MODULE = 10015 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:255
AGL_BAD_ALLOC = 10016 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:256
AGL_BAD_CONNECTION = 10017 # /System/Library/Frameworks/AGL.framework/Headers/agl.h:257
GLint = c_long # /System/Library/Frameworks/OpenGL.framework/Headers/gl.h:47
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:264
aglChoosePixelFormat = _link_function('aglChoosePixelFormat', AGLPixelFormat, [POINTER(AGLDevice), GLint, POINTER(GLint)], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:265
aglDestroyPixelFormat = _link_function('aglDestroyPixelFormat', None, [AGLPixelFormat], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:266
aglNextPixelFormat = _link_function('aglNextPixelFormat', AGLPixelFormat, [AGLPixelFormat], None)
GLboolean = c_ubyte # /System/Library/Frameworks/OpenGL.framework/Headers/gl.h:43
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:267
aglDescribePixelFormat = _link_function('aglDescribePixelFormat', GLboolean, [AGLPixelFormat, GLint, POINTER(GLint)], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:268
aglDevicesOfPixelFormat = _link_function('aglDevicesOfPixelFormat', POINTER(AGLDevice), [AGLPixelFormat, POINTER(GLint)], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:273
aglQueryRendererInfo = _link_function('aglQueryRendererInfo', AGLRendererInfo, [POINTER(AGLDevice), GLint], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:274
aglDestroyRendererInfo = _link_function('aglDestroyRendererInfo', None, [AGLRendererInfo], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:275
aglNextRendererInfo = _link_function('aglNextRendererInfo', AGLRendererInfo, [AGLRendererInfo], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:276
aglDescribeRenderer = _link_function('aglDescribeRenderer', GLboolean, [AGLRendererInfo, GLint, POINTER(GLint)], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:281
aglCreateContext = _link_function('aglCreateContext', AGLContext, [AGLPixelFormat, AGLContext], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:282
aglDestroyContext = _link_function('aglDestroyContext', GLboolean, [AGLContext], None)
GLuint = c_ulong # /System/Library/Frameworks/OpenGL.framework/Headers/gl.h:51
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:283
aglCopyContext = _link_function('aglCopyContext', GLboolean, [AGLContext, AGLContext, GLuint], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:284
aglUpdateContext = _link_function('aglUpdateContext', GLboolean, [AGLContext], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:289
aglSetCurrentContext = _link_function('aglSetCurrentContext', GLboolean, [AGLContext], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:290
aglGetCurrentContext = _link_function('aglGetCurrentContext', AGLContext, [], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:295
aglSetDrawable = _link_function('aglSetDrawable', GLboolean, [AGLContext, AGLDrawable], None)
GLsizei = c_long # /System/Library/Frameworks/OpenGL.framework/Headers/gl.h:48
GLvoid = None # /System/Library/Frameworks/OpenGL.framework/Headers/gl.h:56
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:296
aglSetOffScreen = _link_function('aglSetOffScreen', GLboolean, [AGLContext, GLsizei, GLsizei, GLsizei, POINTER(GLvoid)], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:297
aglSetFullScreen = _link_function('aglSetFullScreen', GLboolean, [AGLContext, GLsizei, GLsizei, GLsizei, GLint], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:298
aglGetDrawable = _link_function('aglGetDrawable', AGLDrawable, [AGLContext], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:303
aglSetVirtualScreen = _link_function('aglSetVirtualScreen', GLboolean, [AGLContext, GLint], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:304
aglGetVirtualScreen = _link_function('aglGetVirtualScreen', GLint, [AGLContext], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:309
aglGetVersion = _link_function('aglGetVersion', None, [POINTER(GLint), POINTER(GLint)], None)
GLenum = c_ulong # /System/Library/Frameworks/OpenGL.framework/Headers/gl.h:42
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:314
aglConfigure = _link_function('aglConfigure', GLboolean, [GLenum, GLuint], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:319
aglSwapBuffers = _link_function('aglSwapBuffers', None, [AGLContext], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:324
aglEnable = _link_function('aglEnable', GLboolean, [AGLContext, GLenum], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:325
aglDisable = _link_function('aglDisable', GLboolean, [AGLContext, GLenum], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:326
aglIsEnabled = _link_function('aglIsEnabled', GLboolean, [AGLContext, GLenum], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:327
aglSetInteger = _link_function('aglSetInteger', GLboolean, [AGLContext, GLenum, POINTER(GLint)], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:328
aglGetInteger = _link_function('aglGetInteger', GLboolean, [AGLContext, GLenum, POINTER(GLint)], None)
Style = c_ubyte # /System/Library/Frameworks/CoreServices.framework/Headers/../Frameworks/CarbonCore.framework/Headers/MacTypes.h:524
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:333
aglUseFont = _link_function('aglUseFont', GLboolean, [AGLContext, GLint, Style, GLint, GLint, GLint, GLint], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:338
aglGetError = _link_function('aglGetError', GLenum, [], None)
GLubyte = c_ubyte # /System/Library/Frameworks/OpenGL.framework/Headers/gl.h:49
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:339
aglErrorString = _link_function('aglErrorString', POINTER(GLubyte), [GLenum], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:344
aglResetLibrary = _link_function('aglResetLibrary', None, [], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:349
aglSurfaceTexture = _link_function('aglSurfaceTexture', None, [AGLContext, GLenum, GLenum, AGLContext], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:354
aglCreatePBuffer = _link_function('aglCreatePBuffer', GLboolean, [GLint, GLint, GLenum, GLenum, c_long, POINTER(AGLPbuffer)], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:355
aglDestroyPBuffer = _link_function('aglDestroyPBuffer', GLboolean, [AGLPbuffer], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:356
aglDescribePBuffer = _link_function('aglDescribePBuffer', GLboolean, [AGLPbuffer, POINTER(GLint), POINTER(GLint), POINTER(GLenum), POINTER(GLenum), POINTER(GLint)], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:357
aglTexImagePBuffer = _link_function('aglTexImagePBuffer', GLboolean, [AGLContext, AGLPbuffer, GLint], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:362
aglSetPBuffer = _link_function('aglSetPBuffer', GLboolean, [AGLContext, AGLPbuffer, GLint, GLint, GLint], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:363
aglGetPBuffer = _link_function('aglGetPBuffer', GLboolean, [AGLContext, POINTER(AGLPbuffer), POINTER(GLint), POINTER(GLint), POINTER(GLint)], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:368
aglGetCGLContext = _link_function('aglGetCGLContext', GLboolean, [AGLContext, POINTER(POINTER(None))], None)
# /System/Library/Frameworks/AGL.framework/Headers/agl.h:369
aglGetCGLPixelFormat = _link_function('aglGetCGLPixelFormat', GLboolean, [AGLPixelFormat, POINTER(POINTER(None))], None)
__all__ = ['AGL_VERSION_2_0', 'AGLDevice', 'AGLDrawable', 'AGLRendererInfo',
'AGLPixelFormat', 'AGLContext', 'AGLPbuffer', 'AGL_NONE', 'AGL_ALL_RENDERERS',
'AGL_BUFFER_SIZE', 'AGL_LEVEL', 'AGL_RGBA', 'AGL_DOUBLEBUFFER', 'AGL_STEREO',
'AGL_AUX_BUFFERS', 'AGL_RED_SIZE', 'AGL_GREEN_SIZE', 'AGL_BLUE_SIZE',
'AGL_ALPHA_SIZE', 'AGL_DEPTH_SIZE', 'AGL_STENCIL_SIZE', 'AGL_ACCUM_RED_SIZE',
'AGL_ACCUM_GREEN_SIZE', 'AGL_ACCUM_BLUE_SIZE', 'AGL_ACCUM_ALPHA_SIZE',
'AGL_PIXEL_SIZE', 'AGL_MINIMUM_POLICY', 'AGL_MAXIMUM_POLICY', 'AGL_OFFSCREEN',
'AGL_FULLSCREEN', 'AGL_SAMPLE_BUFFERS_ARB', 'AGL_SAMPLES_ARB',
'AGL_AUX_DEPTH_STENCIL', 'AGL_COLOR_FLOAT', 'AGL_MULTISAMPLE',
'AGL_SUPERSAMPLE', 'AGL_SAMPLE_ALPHA', 'AGL_RENDERER_ID',
'AGL_SINGLE_RENDERER', 'AGL_NO_RECOVERY', 'AGL_ACCELERATED',
'AGL_CLOSEST_POLICY', 'AGL_ROBUST', 'AGL_BACKING_STORE', 'AGL_MP_SAFE',
'AGL_WINDOW', 'AGL_MULTISCREEN', 'AGL_VIRTUAL_SCREEN', 'AGL_COMPLIANT',
'AGL_PBUFFER', 'AGL_BUFFER_MODES', 'AGL_MIN_LEVEL', 'AGL_MAX_LEVEL',
'AGL_COLOR_MODES', 'AGL_ACCUM_MODES', 'AGL_DEPTH_MODES', 'AGL_STENCIL_MODES',
'AGL_MAX_AUX_BUFFERS', 'AGL_VIDEO_MEMORY', 'AGL_TEXTURE_MEMORY',
'AGL_RENDERER_COUNT', 'AGL_SWAP_RECT', 'AGL_BUFFER_RECT', 'AGL_SWAP_LIMIT',
'AGL_COLORMAP_TRACKING', 'AGL_COLORMAP_ENTRY', 'AGL_RASTERIZATION',
'AGL_SWAP_INTERVAL', 'AGL_STATE_VALIDATION', 'AGL_BUFFER_NAME',
'AGL_ORDER_CONTEXT_TO_FRONT', 'AGL_CONTEXT_SURFACE_ID',
'AGL_CONTEXT_DISPLAY_ID', 'AGL_SURFACE_ORDER', 'AGL_SURFACE_OPACITY',
'AGL_CLIP_REGION', 'AGL_FS_CAPTURE_SINGLE', 'AGL_SURFACE_BACKING_SIZE',
'AGL_ENABLE_SURFACE_BACKING_SIZE', 'AGL_SURFACE_VOLATILE',
'AGL_FORMAT_CACHE_SIZE', 'AGL_CLEAR_FORMAT_CACHE', 'AGL_RETAIN_RENDERERS',
'AGL_MONOSCOPIC_BIT', 'AGL_STEREOSCOPIC_BIT', 'AGL_SINGLEBUFFER_BIT',
'AGL_DOUBLEBUFFER_BIT', 'AGL_0_BIT', 'AGL_1_BIT', 'AGL_2_BIT', 'AGL_3_BIT',
'AGL_4_BIT', 'AGL_5_BIT', 'AGL_6_BIT', 'AGL_8_BIT', 'AGL_10_BIT',
'AGL_12_BIT', 'AGL_16_BIT', 'AGL_24_BIT', 'AGL_32_BIT', 'AGL_48_BIT',
'AGL_64_BIT', 'AGL_96_BIT', 'AGL_128_BIT', 'AGL_RGB8_BIT', 'AGL_RGB8_A8_BIT',
'AGL_BGR233_BIT', 'AGL_BGR233_A8_BIT', 'AGL_RGB332_BIT', 'AGL_RGB332_A8_BIT',
'AGL_RGB444_BIT', 'AGL_ARGB4444_BIT', 'AGL_RGB444_A8_BIT', 'AGL_RGB555_BIT',
'AGL_ARGB1555_BIT', 'AGL_RGB555_A8_BIT', 'AGL_RGB565_BIT',
'AGL_RGB565_A8_BIT', 'AGL_RGB888_BIT', 'AGL_ARGB8888_BIT',
'AGL_RGB888_A8_BIT', 'AGL_RGB101010_BIT', 'AGL_ARGB2101010_BIT',
'AGL_RGB101010_A8_BIT', 'AGL_RGB121212_BIT', 'AGL_ARGB12121212_BIT',
'AGL_RGB161616_BIT', 'AGL_ARGB16161616_BIT', 'AGL_INDEX8_BIT',
'AGL_INDEX16_BIT', 'AGL_RGBFLOAT64_BIT', 'AGL_RGBAFLOAT64_BIT',
'AGL_RGBFLOAT128_BIT', 'AGL_RGBAFLOAT128_BIT', 'AGL_RGBFLOAT256_BIT',
'AGL_RGBAFLOAT256_BIT', 'AGL_NO_ERROR', 'AGL_BAD_ATTRIBUTE',
'AGL_BAD_PROPERTY', 'AGL_BAD_PIXELFMT', 'AGL_BAD_RENDINFO', 'AGL_BAD_CONTEXT',
'AGL_BAD_DRAWABLE', 'AGL_BAD_GDEV', 'AGL_BAD_STATE', 'AGL_BAD_VALUE',
'AGL_BAD_MATCH', 'AGL_BAD_ENUM', 'AGL_BAD_OFFSCREEN', 'AGL_BAD_FULLSCREEN',
'AGL_BAD_WINDOW', 'AGL_BAD_POINTER', 'AGL_BAD_MODULE', 'AGL_BAD_ALLOC',
'AGL_BAD_CONNECTION', 'aglChoosePixelFormat', 'aglDestroyPixelFormat',
'aglNextPixelFormat', 'aglDescribePixelFormat', 'aglDevicesOfPixelFormat',
'aglQueryRendererInfo', 'aglDestroyRendererInfo', 'aglNextRendererInfo',
'aglDescribeRenderer', 'aglCreateContext', 'aglDestroyContext',
'aglCopyContext', 'aglUpdateContext', 'aglSetCurrentContext',
'aglGetCurrentContext', 'aglSetDrawable', 'aglSetOffScreen',
'aglSetFullScreen', 'aglGetDrawable', 'aglSetVirtualScreen',
'aglGetVirtualScreen', 'aglGetVersion', 'aglConfigure', 'aglSwapBuffers',
'aglEnable', 'aglDisable', 'aglIsEnabled', 'aglSetInteger', 'aglGetInteger',
'aglUseFont', 'aglGetError', 'aglErrorString', 'aglResetLibrary',
'aglSurfaceTexture', 'aglCreatePBuffer', 'aglDestroyPBuffer',
'aglDescribePBuffer', 'aglTexImagePBuffer', 'aglSetPBuffer', 'aglGetPBuffer',
'aglGetCGLContext', 'aglGetCGLPixelFormat']
# END GENERATED CONTENT (do not edit above this line)

2156
pyglet/gl/gl.py Normal file

File diff suppressed because it is too large Load diff

196
pyglet/gl/gl_info.py Normal file
View file

@ -0,0 +1,196 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Information about version and extensions of current GL implementation.
Usage::
from pyglet.gl import gl_info
if gl_info.have_extension('GL_NV_register_combiners'):
# ...
If you are using more than one context, you can set up a separate GLInfo
object for each context. Call `set_active_context` after switching to the
context::
from pyglet.gl.gl_info import GLInfo
info = GLInfo()
info.set_active_context()
if info.have_version(2, 1):
# ...
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
from ctypes import *
import warnings
from pyglet.gl.gl import *
class GLInfo(object):
'''Information interface for a single GL context.
A default instance is created automatically when the first OpenGL context
is created. You can use the module functions as a convenience for
this default instance's methods.
If you are using more than one context, you must call `set_active_context`
when the context is active for this `GLInfo` instance.
'''
have_context = False
version = '0.0.0'
vendor = ''
renderer = ''
extensions = set()
_have_info = False
def set_active_context(self):
'''Store information for the currently active context.
This method is called automatically for the default context.
'''
self.have_context = True
if not self._have_info:
self.vendor = cast(glGetString(GL_VENDOR), c_char_p).value
self.renderer = cast(glGetString(GL_RENDERER), c_char_p).value
self.extensions = cast(glGetString(GL_EXTENSIONS), c_char_p).value
if self.extensions:
self.extensions = set(self.extensions.split())
self.version = cast(glGetString(GL_VERSION), c_char_p).value
self._have_info = True
def remove_active_context(self):
self.have_context = False
def have_extension(self, extension):
'''Determine if an OpenGL extension is available.
:Parameters:
`extension` : str
The name of the extension to test for, including its
``GL_`` prefix.
:return: True if the extension is provided by the driver.
:rtype: bool
'''
if not self.have_context:
warnings.warn('No GL context created yet.')
return extension in self.extensions
def get_extensions(self):
'''Get a list of available OpenGL extensions.
:return: a list of the available extensions.
:rtype: list of str
'''
if not self.have_context:
warnings.warn('No GL context created yet.')
return self.extensions
def get_version(self):
'''Get the current OpenGL version.
:return: the OpenGL version
:rtype: str
'''
if not self.have_context:
warnings.warn('No GL context created yet.')
return self.version
def have_version(self, major, minor=0, release=0):
'''Determine if a version of OpenGL is supported.
:Parameters:
`major` : int
The major revision number (typically 1 or 2).
`minor` : int
The minor revision number.
`release` : int
The release number.
:rtype: bool
:return: True if the requested or a later version is supported.
'''
if not self.have_context:
warnings.warn('No GL context created yet.')
ver = '%s.0.0' % self.version.split(' ', 1)[0]
imajor, iminor, irelease = [int(v) for v in ver.split('.', 3)[:3]]
return imajor > major or \
(imajor == major and iminor > minor) or \
(imajor == major and iminor == minor and irelease >= release)
def get_renderer(self):
'''Determine the renderer string of the OpenGL context.
:rtype: str
'''
if not self.have_context:
warnings.warn('No GL context created yet.')
return self.renderer
def get_vendor(self):
'''Determine the vendor string of the OpenGL context.
:rtype: str
'''
if not self.have_context:
warnings.warn('No GL context created yet.')
return self.vendor
# Single instance useful for apps with only a single context (or all contexts
# have same GL driver, common case).
_gl_info = GLInfo()
set_active_context = _gl_info.set_active_context
remove_active_context = _gl_info.remove_active_context
have_extension = _gl_info.have_extension
get_extensions = _gl_info.get_extensions
get_version = _gl_info.get_version
have_version = _gl_info.have_version
get_renderer = _gl_info.get_renderer
get_vendor = _gl_info.get_vendor
def have_context():
'''Determine if a default OpenGL context has been set yet.
:rtype: bool
'''
return _gl_info.have_context

9349
pyglet/gl/glext_arb.py Normal file

File diff suppressed because it is too large Load diff

127
pyglet/gl/glext_missing.py Normal file
View file

@ -0,0 +1,127 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Additional hand-coded GL extensions.
These are hand-wrapped extension tokens and functions that are in
the OpenGL Extension Registry but have not yet been added to either
the registry's glext.h or nVidia's glext.h. Remove wraps from here
when the headers are updated (and glext_arb.py or glext_nv.py are
regenerated).
When adding an extension here, include the name and URL, and any tokens and
functions appearing under "New Tokens" and "New Procedures" headings. Don't
forget to add the GL_/gl prefix.
Unnumbered extensions in the registry are not included.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: glext_missing.py 1579 2008-01-15 14:47:19Z Alex.Holkner $'
from ctypes import *
from pyglet.gl.lib import link_GL as _link_function
from pyglet.gl.lib import c_ptrdiff_t
# At time of writing, ABI glext.h was last updated 2005/06/20, so numbered
# non-ARB extensions from 312 on must be included here.
# GL_EXT_packed_depth_stencil
# http://oss.sgi.com/projects/ogl-sample/registry/EXT/packed_depth_stencil.txt
GL_DEPTH_STENCIL_EXT = 0x84F9
GL_UNSIGNED_INT_24_8_EXT = 0x84FA
GL_DEPTH24_STENCIL8_EXT = 0x88F0
GL_TEXTURE_STENCIL_SIZE_EXT = 0x88F1
# GL_EXT_texture_sRGB
# http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_sRGB.txt
GL_SRGB_EXT = 0x8C40
GL_SRGB8_EXT = 0x8C41
GL_SRGB_ALPHA_EXT = 0x8C42
GL_SRGB8_ALPHA8_EXT = 0x8C43
GL_SLUMINANCE_ALPHA_EXT = 0x8C44
GL_SLUMINANCE8_ALPHA8_EXT = 0x8C45
GL_SLUMINANCE_EXT = 0x8C46
GL_SLUMINANCE8_EXT = 0x8C47
GL_COMPRESSED_SRGB_EXT = 0x8C48
GL_COMPRESSED_SRGB_ALPHA_EXT = 0x8C49
GL_COMPRESSED_SLUMINANCE_EXT = 0x8C4A
GL_COMPRESSED_SLUMINANCE_ALPHA_EXT = 0x8C4B
GL_COMPRESSED_SRGB_S3TC_DXT1_EXT = 0x8C4C
GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT = 0x8C4D
GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT = 0x8C4E
GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = 0x8C4F
# GL_EXT_stencil_clear_tag
# http://oss.sgi.com/projects/ogl-sample/registry/EXT/stencil_clear_tag.txt
GLuint = c_uint # /usr/include/GL/gl.h:62
GLsizei = c_int # /usr/include/GL/gl.h:59
glStencilClearTagEXT = _link_function(
'glStencilClearTagEXT', None, [GLsizei, GLuint])
GL_STENCIL_TAG_BITS_EXT = 0x88F2
GL_STENCIL_CLEAR_TAG_VALUE_EXT = 0x88F3
# GL_EXT_framebuffer_blit
# http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_blit.txt
GLenum = c_uint # /usr/include/GL/gl.h:53
GLint = c_int # /usr/include/GL/gl.h:58
glBlitFramebufferEXT = _link_function(
'glBlitFramebufferEXT', None, [GLint, GLint, GLint, GLint,
GLint, GLint, GLint, GLint,
GLuint, GLenum])
GL_READ_FRAMEBUFFER_EXT = 0x8CA8
GL_DRAW_FRAMEBUFFER_EXT = 0x8CA9
GL_DRAW_FRAMEBUFFER_BINDING_EXT = 0x8CA6
GL_READ_FRAMEBUFFER_BINDING_EXT = 0x8CAA
# GL_EXT_framebuffer_multisample
# http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_multisample.txt
GL_RENDERBUFFER_SAMPLES_EXT = 0x8CAB
# GL_MESAX_texture_stack
# http://oss.sgi.com/projects/ogl-sample/registry/MESAX/texture_stack.txt
GL_TEXTURE_1D_STACK_MESAX = 0x8759
GL_TEXTURE_2D_STACK_MESAX = 0x875A
GL_PROXY_TEXTURE_1D_STACK_MESAX = 0x875B
GL_PROXY_TEXTURE_2D_STACK_MESAX = 0x875C
GL_TEXTURE_1D_STACK_BINDING_MESAX = 0x875D
GL_TEXTURE_2D_STACK_BINDING_MESAX = 0x875E

10240
pyglet/gl/glext_nv.py Normal file

File diff suppressed because it is too large Load diff

494
pyglet/gl/glu.py Normal file
View file

@ -0,0 +1,494 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Wrapper for /usr/include/GL/glu.h
Generated by tools/gengl.py.
Do not modify this file.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: glu.py 1579 2008-01-15 14:47:19Z Alex.Holkner $'
from ctypes import *
from pyglet.gl.lib import link_GLU as _link_function
from pyglet.gl.lib import c_ptrdiff_t
# BEGIN GENERATED CONTENT (do not edit below this line)
# This content is generated by tools/gengl.py.
# Wrapper for /usr/include/GL/glu.h
GLU_EXT_object_space_tess = 1 # /usr/include/GL/glu.h:58
GLU_EXT_nurbs_tessellator = 1 # /usr/include/GL/glu.h:59
GLU_FALSE = 0 # /usr/include/GL/glu.h:62
GLU_TRUE = 1 # /usr/include/GL/glu.h:63
GLU_VERSION_1_1 = 1 # /usr/include/GL/glu.h:66
GLU_VERSION_1_2 = 1 # /usr/include/GL/glu.h:67
GLU_VERSION_1_3 = 1 # /usr/include/GL/glu.h:68
GLU_VERSION = 100800 # /usr/include/GL/glu.h:71
GLU_EXTENSIONS = 100801 # /usr/include/GL/glu.h:72
GLU_INVALID_ENUM = 100900 # /usr/include/GL/glu.h:75
GLU_INVALID_VALUE = 100901 # /usr/include/GL/glu.h:76
GLU_OUT_OF_MEMORY = 100902 # /usr/include/GL/glu.h:77
GLU_INCOMPATIBLE_GL_VERSION = 100903 # /usr/include/GL/glu.h:78
GLU_INVALID_OPERATION = 100904 # /usr/include/GL/glu.h:79
GLU_OUTLINE_POLYGON = 100240 # /usr/include/GL/glu.h:83
GLU_OUTLINE_PATCH = 100241 # /usr/include/GL/glu.h:84
GLU_NURBS_ERROR = 100103 # /usr/include/GL/glu.h:87
GLU_ERROR = 100103 # /usr/include/GL/glu.h:88
GLU_NURBS_BEGIN = 100164 # /usr/include/GL/glu.h:89
GLU_NURBS_BEGIN_EXT = 100164 # /usr/include/GL/glu.h:90
GLU_NURBS_VERTEX = 100165 # /usr/include/GL/glu.h:91
GLU_NURBS_VERTEX_EXT = 100165 # /usr/include/GL/glu.h:92
GLU_NURBS_NORMAL = 100166 # /usr/include/GL/glu.h:93
GLU_NURBS_NORMAL_EXT = 100166 # /usr/include/GL/glu.h:94
GLU_NURBS_COLOR = 100167 # /usr/include/GL/glu.h:95
GLU_NURBS_COLOR_EXT = 100167 # /usr/include/GL/glu.h:96
GLU_NURBS_TEXTURE_COORD = 100168 # /usr/include/GL/glu.h:97
GLU_NURBS_TEX_COORD_EXT = 100168 # /usr/include/GL/glu.h:98
GLU_NURBS_END = 100169 # /usr/include/GL/glu.h:99
GLU_NURBS_END_EXT = 100169 # /usr/include/GL/glu.h:100
GLU_NURBS_BEGIN_DATA = 100170 # /usr/include/GL/glu.h:101
GLU_NURBS_BEGIN_DATA_EXT = 100170 # /usr/include/GL/glu.h:102
GLU_NURBS_VERTEX_DATA = 100171 # /usr/include/GL/glu.h:103
GLU_NURBS_VERTEX_DATA_EXT = 100171 # /usr/include/GL/glu.h:104
GLU_NURBS_NORMAL_DATA = 100172 # /usr/include/GL/glu.h:105
GLU_NURBS_NORMAL_DATA_EXT = 100172 # /usr/include/GL/glu.h:106
GLU_NURBS_COLOR_DATA = 100173 # /usr/include/GL/glu.h:107
GLU_NURBS_COLOR_DATA_EXT = 100173 # /usr/include/GL/glu.h:108
GLU_NURBS_TEXTURE_COORD_DATA = 100174 # /usr/include/GL/glu.h:109
GLU_NURBS_TEX_COORD_DATA_EXT = 100174 # /usr/include/GL/glu.h:110
GLU_NURBS_END_DATA = 100175 # /usr/include/GL/glu.h:111
GLU_NURBS_END_DATA_EXT = 100175 # /usr/include/GL/glu.h:112
GLU_NURBS_ERROR1 = 100251 # /usr/include/GL/glu.h:115
GLU_NURBS_ERROR2 = 100252 # /usr/include/GL/glu.h:116
GLU_NURBS_ERROR3 = 100253 # /usr/include/GL/glu.h:117
GLU_NURBS_ERROR4 = 100254 # /usr/include/GL/glu.h:118
GLU_NURBS_ERROR5 = 100255 # /usr/include/GL/glu.h:119
GLU_NURBS_ERROR6 = 100256 # /usr/include/GL/glu.h:120
GLU_NURBS_ERROR7 = 100257 # /usr/include/GL/glu.h:121
GLU_NURBS_ERROR8 = 100258 # /usr/include/GL/glu.h:122
GLU_NURBS_ERROR9 = 100259 # /usr/include/GL/glu.h:123
GLU_NURBS_ERROR10 = 100260 # /usr/include/GL/glu.h:124
GLU_NURBS_ERROR11 = 100261 # /usr/include/GL/glu.h:125
GLU_NURBS_ERROR12 = 100262 # /usr/include/GL/glu.h:126
GLU_NURBS_ERROR13 = 100263 # /usr/include/GL/glu.h:127
GLU_NURBS_ERROR14 = 100264 # /usr/include/GL/glu.h:128
GLU_NURBS_ERROR15 = 100265 # /usr/include/GL/glu.h:129
GLU_NURBS_ERROR16 = 100266 # /usr/include/GL/glu.h:130
GLU_NURBS_ERROR17 = 100267 # /usr/include/GL/glu.h:131
GLU_NURBS_ERROR18 = 100268 # /usr/include/GL/glu.h:132
GLU_NURBS_ERROR19 = 100269 # /usr/include/GL/glu.h:133
GLU_NURBS_ERROR20 = 100270 # /usr/include/GL/glu.h:134
GLU_NURBS_ERROR21 = 100271 # /usr/include/GL/glu.h:135
GLU_NURBS_ERROR22 = 100272 # /usr/include/GL/glu.h:136
GLU_NURBS_ERROR23 = 100273 # /usr/include/GL/glu.h:137
GLU_NURBS_ERROR24 = 100274 # /usr/include/GL/glu.h:138
GLU_NURBS_ERROR25 = 100275 # /usr/include/GL/glu.h:139
GLU_NURBS_ERROR26 = 100276 # /usr/include/GL/glu.h:140
GLU_NURBS_ERROR27 = 100277 # /usr/include/GL/glu.h:141
GLU_NURBS_ERROR28 = 100278 # /usr/include/GL/glu.h:142
GLU_NURBS_ERROR29 = 100279 # /usr/include/GL/glu.h:143
GLU_NURBS_ERROR30 = 100280 # /usr/include/GL/glu.h:144
GLU_NURBS_ERROR31 = 100281 # /usr/include/GL/glu.h:145
GLU_NURBS_ERROR32 = 100282 # /usr/include/GL/glu.h:146
GLU_NURBS_ERROR33 = 100283 # /usr/include/GL/glu.h:147
GLU_NURBS_ERROR34 = 100284 # /usr/include/GL/glu.h:148
GLU_NURBS_ERROR35 = 100285 # /usr/include/GL/glu.h:149
GLU_NURBS_ERROR36 = 100286 # /usr/include/GL/glu.h:150
GLU_NURBS_ERROR37 = 100287 # /usr/include/GL/glu.h:151
GLU_AUTO_LOAD_MATRIX = 100200 # /usr/include/GL/glu.h:154
GLU_CULLING = 100201 # /usr/include/GL/glu.h:155
GLU_SAMPLING_TOLERANCE = 100203 # /usr/include/GL/glu.h:156
GLU_DISPLAY_MODE = 100204 # /usr/include/GL/glu.h:157
GLU_PARAMETRIC_TOLERANCE = 100202 # /usr/include/GL/glu.h:158
GLU_SAMPLING_METHOD = 100205 # /usr/include/GL/glu.h:159
GLU_U_STEP = 100206 # /usr/include/GL/glu.h:160
GLU_V_STEP = 100207 # /usr/include/GL/glu.h:161
GLU_NURBS_MODE = 100160 # /usr/include/GL/glu.h:162
GLU_NURBS_MODE_EXT = 100160 # /usr/include/GL/glu.h:163
GLU_NURBS_TESSELLATOR = 100161 # /usr/include/GL/glu.h:164
GLU_NURBS_TESSELLATOR_EXT = 100161 # /usr/include/GL/glu.h:165
GLU_NURBS_RENDERER = 100162 # /usr/include/GL/glu.h:166
GLU_NURBS_RENDERER_EXT = 100162 # /usr/include/GL/glu.h:167
GLU_OBJECT_PARAMETRIC_ERROR = 100208 # /usr/include/GL/glu.h:170
GLU_OBJECT_PARAMETRIC_ERROR_EXT = 100208 # /usr/include/GL/glu.h:171
GLU_OBJECT_PATH_LENGTH = 100209 # /usr/include/GL/glu.h:172
GLU_OBJECT_PATH_LENGTH_EXT = 100209 # /usr/include/GL/glu.h:173
GLU_PATH_LENGTH = 100215 # /usr/include/GL/glu.h:174
GLU_PARAMETRIC_ERROR = 100216 # /usr/include/GL/glu.h:175
GLU_DOMAIN_DISTANCE = 100217 # /usr/include/GL/glu.h:176
GLU_MAP1_TRIM_2 = 100210 # /usr/include/GL/glu.h:179
GLU_MAP1_TRIM_3 = 100211 # /usr/include/GL/glu.h:180
GLU_POINT = 100010 # /usr/include/GL/glu.h:183
GLU_LINE = 100011 # /usr/include/GL/glu.h:184
GLU_FILL = 100012 # /usr/include/GL/glu.h:185
GLU_SILHOUETTE = 100013 # /usr/include/GL/glu.h:186
GLU_SMOOTH = 100000 # /usr/include/GL/glu.h:192
GLU_FLAT = 100001 # /usr/include/GL/glu.h:193
GLU_NONE = 100002 # /usr/include/GL/glu.h:194
GLU_OUTSIDE = 100020 # /usr/include/GL/glu.h:197
GLU_INSIDE = 100021 # /usr/include/GL/glu.h:198
GLU_TESS_BEGIN = 100100 # /usr/include/GL/glu.h:201
GLU_BEGIN = 100100 # /usr/include/GL/glu.h:202
GLU_TESS_VERTEX = 100101 # /usr/include/GL/glu.h:203
GLU_VERTEX = 100101 # /usr/include/GL/glu.h:204
GLU_TESS_END = 100102 # /usr/include/GL/glu.h:205
GLU_END = 100102 # /usr/include/GL/glu.h:206
GLU_TESS_ERROR = 100103 # /usr/include/GL/glu.h:207
GLU_TESS_EDGE_FLAG = 100104 # /usr/include/GL/glu.h:208
GLU_EDGE_FLAG = 100104 # /usr/include/GL/glu.h:209
GLU_TESS_COMBINE = 100105 # /usr/include/GL/glu.h:210
GLU_TESS_BEGIN_DATA = 100106 # /usr/include/GL/glu.h:211
GLU_TESS_VERTEX_DATA = 100107 # /usr/include/GL/glu.h:212
GLU_TESS_END_DATA = 100108 # /usr/include/GL/glu.h:213
GLU_TESS_ERROR_DATA = 100109 # /usr/include/GL/glu.h:214
GLU_TESS_EDGE_FLAG_DATA = 100110 # /usr/include/GL/glu.h:215
GLU_TESS_COMBINE_DATA = 100111 # /usr/include/GL/glu.h:216
GLU_CW = 100120 # /usr/include/GL/glu.h:219
GLU_CCW = 100121 # /usr/include/GL/glu.h:220
GLU_INTERIOR = 100122 # /usr/include/GL/glu.h:221
GLU_EXTERIOR = 100123 # /usr/include/GL/glu.h:222
GLU_UNKNOWN = 100124 # /usr/include/GL/glu.h:223
GLU_TESS_WINDING_RULE = 100140 # /usr/include/GL/glu.h:226
GLU_TESS_BOUNDARY_ONLY = 100141 # /usr/include/GL/glu.h:227
GLU_TESS_TOLERANCE = 100142 # /usr/include/GL/glu.h:228
GLU_TESS_ERROR1 = 100151 # /usr/include/GL/glu.h:231
GLU_TESS_ERROR2 = 100152 # /usr/include/GL/glu.h:232
GLU_TESS_ERROR3 = 100153 # /usr/include/GL/glu.h:233
GLU_TESS_ERROR4 = 100154 # /usr/include/GL/glu.h:234
GLU_TESS_ERROR5 = 100155 # /usr/include/GL/glu.h:235
GLU_TESS_ERROR6 = 100156 # /usr/include/GL/glu.h:236
GLU_TESS_ERROR7 = 100157 # /usr/include/GL/glu.h:237
GLU_TESS_ERROR8 = 100158 # /usr/include/GL/glu.h:238
GLU_TESS_MISSING_BEGIN_POLYGON = 100151 # /usr/include/GL/glu.h:239
GLU_TESS_MISSING_BEGIN_CONTOUR = 100152 # /usr/include/GL/glu.h:240
GLU_TESS_MISSING_END_POLYGON = 100153 # /usr/include/GL/glu.h:241
GLU_TESS_MISSING_END_CONTOUR = 100154 # /usr/include/GL/glu.h:242
GLU_TESS_COORD_TOO_LARGE = 100155 # /usr/include/GL/glu.h:243
GLU_TESS_NEED_COMBINE_CALLBACK = 100156 # /usr/include/GL/glu.h:244
GLU_TESS_WINDING_ODD = 100130 # /usr/include/GL/glu.h:247
GLU_TESS_WINDING_NONZERO = 100131 # /usr/include/GL/glu.h:248
GLU_TESS_WINDING_POSITIVE = 100132 # /usr/include/GL/glu.h:249
GLU_TESS_WINDING_NEGATIVE = 100133 # /usr/include/GL/glu.h:250
GLU_TESS_WINDING_ABS_GEQ_TWO = 100134 # /usr/include/GL/glu.h:251
class struct_GLUnurbs(Structure):
__slots__ = [
]
struct_GLUnurbs._fields_ = [
('_opaque_struct', c_int)
]
GLUnurbs = struct_GLUnurbs # /usr/include/GL/glu.h:261
class struct_GLUquadric(Structure):
__slots__ = [
]
struct_GLUquadric._fields_ = [
('_opaque_struct', c_int)
]
GLUquadric = struct_GLUquadric # /usr/include/GL/glu.h:262
class struct_GLUtesselator(Structure):
__slots__ = [
]
struct_GLUtesselator._fields_ = [
('_opaque_struct', c_int)
]
GLUtesselator = struct_GLUtesselator # /usr/include/GL/glu.h:263
GLUnurbsObj = GLUnurbs # /usr/include/GL/glu.h:266
GLUquadricObj = GLUquadric # /usr/include/GL/glu.h:267
GLUtesselatorObj = GLUtesselator # /usr/include/GL/glu.h:268
GLUtriangulatorObj = GLUtesselator # /usr/include/GL/glu.h:269
GLU_TESS_MAX_COORD = 9.9999999999999998e+149 # /usr/include/GL/glu.h:271
_GLUfuncptr = CFUNCTYPE(None) # /usr/include/GL/glu.h:274
# /usr/include/GL/glu.h:276
gluBeginCurve = _link_function('gluBeginCurve', None, [POINTER(GLUnurbs)], None)
# /usr/include/GL/glu.h:277
gluBeginPolygon = _link_function('gluBeginPolygon', None, [POINTER(GLUtesselator)], None)
# /usr/include/GL/glu.h:278
gluBeginSurface = _link_function('gluBeginSurface', None, [POINTER(GLUnurbs)], None)
# /usr/include/GL/glu.h:279
gluBeginTrim = _link_function('gluBeginTrim', None, [POINTER(GLUnurbs)], None)
GLint = c_int # /usr/include/GL/gl.h:58
GLenum = c_uint # /usr/include/GL/gl.h:53
GLsizei = c_int # /usr/include/GL/gl.h:59
# /usr/include/GL/glu.h:280
gluBuild1DMipmapLevels = _link_function('gluBuild1DMipmapLevels', GLint, [GLenum, GLint, GLsizei, GLenum, GLenum, GLint, GLint, GLint, POINTER(None)], None)
# /usr/include/GL/glu.h:281
gluBuild1DMipmaps = _link_function('gluBuild1DMipmaps', GLint, [GLenum, GLint, GLsizei, GLenum, GLenum, POINTER(None)], None)
# /usr/include/GL/glu.h:282
gluBuild2DMipmapLevels = _link_function('gluBuild2DMipmapLevels', GLint, [GLenum, GLint, GLsizei, GLsizei, GLenum, GLenum, GLint, GLint, GLint, POINTER(None)], None)
# /usr/include/GL/glu.h:283
gluBuild2DMipmaps = _link_function('gluBuild2DMipmaps', GLint, [GLenum, GLint, GLsizei, GLsizei, GLenum, GLenum, POINTER(None)], None)
# /usr/include/GL/glu.h:284
gluBuild3DMipmapLevels = _link_function('gluBuild3DMipmapLevels', GLint, [GLenum, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, GLint, GLint, GLint, POINTER(None)], None)
# /usr/include/GL/glu.h:285
gluBuild3DMipmaps = _link_function('gluBuild3DMipmaps', GLint, [GLenum, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, POINTER(None)], None)
GLboolean = c_ubyte # /usr/include/GL/gl.h:54
GLubyte = c_ubyte # /usr/include/GL/gl.h:60
# /usr/include/GL/glu.h:286
gluCheckExtension = _link_function('gluCheckExtension', GLboolean, [POINTER(GLubyte), POINTER(GLubyte)], None)
GLdouble = c_double # /usr/include/GL/gl.h:65
# /usr/include/GL/glu.h:287
gluCylinder = _link_function('gluCylinder', None, [POINTER(GLUquadric), GLdouble, GLdouble, GLdouble, GLint, GLint], None)
# /usr/include/GL/glu.h:288
gluDeleteNurbsRenderer = _link_function('gluDeleteNurbsRenderer', None, [POINTER(GLUnurbs)], None)
# /usr/include/GL/glu.h:289
gluDeleteQuadric = _link_function('gluDeleteQuadric', None, [POINTER(GLUquadric)], None)
# /usr/include/GL/glu.h:290
gluDeleteTess = _link_function('gluDeleteTess', None, [POINTER(GLUtesselator)], None)
# /usr/include/GL/glu.h:291
gluDisk = _link_function('gluDisk', None, [POINTER(GLUquadric), GLdouble, GLdouble, GLint, GLint], None)
# /usr/include/GL/glu.h:292
gluEndCurve = _link_function('gluEndCurve', None, [POINTER(GLUnurbs)], None)
# /usr/include/GL/glu.h:293
gluEndPolygon = _link_function('gluEndPolygon', None, [POINTER(GLUtesselator)], None)
# /usr/include/GL/glu.h:294
gluEndSurface = _link_function('gluEndSurface', None, [POINTER(GLUnurbs)], None)
# /usr/include/GL/glu.h:295
gluEndTrim = _link_function('gluEndTrim', None, [POINTER(GLUnurbs)], None)
# /usr/include/GL/glu.h:296
gluErrorString = _link_function('gluErrorString', POINTER(GLubyte), [GLenum], None)
GLfloat = c_float # /usr/include/GL/gl.h:63
# /usr/include/GL/glu.h:297
gluGetNurbsProperty = _link_function('gluGetNurbsProperty', None, [POINTER(GLUnurbs), GLenum, POINTER(GLfloat)], None)
# /usr/include/GL/glu.h:298
gluGetString = _link_function('gluGetString', POINTER(GLubyte), [GLenum], None)
# /usr/include/GL/glu.h:299
gluGetTessProperty = _link_function('gluGetTessProperty', None, [POINTER(GLUtesselator), GLenum, POINTER(GLdouble)], None)
# /usr/include/GL/glu.h:300
gluLoadSamplingMatrices = _link_function('gluLoadSamplingMatrices', None, [POINTER(GLUnurbs), POINTER(GLfloat), POINTER(GLfloat), POINTER(GLint)], None)
# /usr/include/GL/glu.h:301
gluLookAt = _link_function('gluLookAt', None, [GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble], None)
# /usr/include/GL/glu.h:302
gluNewNurbsRenderer = _link_function('gluNewNurbsRenderer', POINTER(GLUnurbs), [], None)
# /usr/include/GL/glu.h:303
gluNewQuadric = _link_function('gluNewQuadric', POINTER(GLUquadric), [], None)
# /usr/include/GL/glu.h:304
gluNewTess = _link_function('gluNewTess', POINTER(GLUtesselator), [], None)
# /usr/include/GL/glu.h:305
gluNextContour = _link_function('gluNextContour', None, [POINTER(GLUtesselator), GLenum], None)
# /usr/include/GL/glu.h:306
gluNurbsCallback = _link_function('gluNurbsCallback', None, [POINTER(GLUnurbs), GLenum, _GLUfuncptr], None)
GLvoid = None # /usr/include/GL/gl.h:67
# /usr/include/GL/glu.h:307
gluNurbsCallbackData = _link_function('gluNurbsCallbackData', None, [POINTER(GLUnurbs), POINTER(GLvoid)], None)
# /usr/include/GL/glu.h:308
gluNurbsCallbackDataEXT = _link_function('gluNurbsCallbackDataEXT', None, [POINTER(GLUnurbs), POINTER(GLvoid)], None)
# /usr/include/GL/glu.h:309
gluNurbsCurve = _link_function('gluNurbsCurve', None, [POINTER(GLUnurbs), GLint, POINTER(GLfloat), GLint, POINTER(GLfloat), GLint, GLenum], None)
# /usr/include/GL/glu.h:310
gluNurbsProperty = _link_function('gluNurbsProperty', None, [POINTER(GLUnurbs), GLenum, GLfloat], None)
# /usr/include/GL/glu.h:311
gluNurbsSurface = _link_function('gluNurbsSurface', None, [POINTER(GLUnurbs), GLint, POINTER(GLfloat), GLint, POINTER(GLfloat), GLint, GLint, POINTER(GLfloat), GLint, GLint, GLenum], None)
# /usr/include/GL/glu.h:312
gluOrtho2D = _link_function('gluOrtho2D', None, [GLdouble, GLdouble, GLdouble, GLdouble], None)
# /usr/include/GL/glu.h:313
gluPartialDisk = _link_function('gluPartialDisk', None, [POINTER(GLUquadric), GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble], None)
# /usr/include/GL/glu.h:314
gluPerspective = _link_function('gluPerspective', None, [GLdouble, GLdouble, GLdouble, GLdouble], None)
# /usr/include/GL/glu.h:315
gluPickMatrix = _link_function('gluPickMatrix', None, [GLdouble, GLdouble, GLdouble, GLdouble, POINTER(GLint)], None)
# /usr/include/GL/glu.h:316
gluProject = _link_function('gluProject', GLint, [GLdouble, GLdouble, GLdouble, POINTER(GLdouble), POINTER(GLdouble), POINTER(GLint), POINTER(GLdouble), POINTER(GLdouble), POINTER(GLdouble)], None)
# /usr/include/GL/glu.h:317
gluPwlCurve = _link_function('gluPwlCurve', None, [POINTER(GLUnurbs), GLint, POINTER(GLfloat), GLint, GLenum], None)
# /usr/include/GL/glu.h:318
gluQuadricCallback = _link_function('gluQuadricCallback', None, [POINTER(GLUquadric), GLenum, _GLUfuncptr], None)
# /usr/include/GL/glu.h:319
gluQuadricDrawStyle = _link_function('gluQuadricDrawStyle', None, [POINTER(GLUquadric), GLenum], None)
# /usr/include/GL/glu.h:320
gluQuadricNormals = _link_function('gluQuadricNormals', None, [POINTER(GLUquadric), GLenum], None)
# /usr/include/GL/glu.h:321
gluQuadricOrientation = _link_function('gluQuadricOrientation', None, [POINTER(GLUquadric), GLenum], None)
# /usr/include/GL/glu.h:322
gluQuadricTexture = _link_function('gluQuadricTexture', None, [POINTER(GLUquadric), GLboolean], None)
# /usr/include/GL/glu.h:323
gluScaleImage = _link_function('gluScaleImage', GLint, [GLenum, GLsizei, GLsizei, GLenum, POINTER(None), GLsizei, GLsizei, GLenum, POINTER(GLvoid)], None)
# /usr/include/GL/glu.h:324
gluSphere = _link_function('gluSphere', None, [POINTER(GLUquadric), GLdouble, GLint, GLint], None)
# /usr/include/GL/glu.h:325
gluTessBeginContour = _link_function('gluTessBeginContour', None, [POINTER(GLUtesselator)], None)
# /usr/include/GL/glu.h:326
gluTessBeginPolygon = _link_function('gluTessBeginPolygon', None, [POINTER(GLUtesselator), POINTER(GLvoid)], None)
# /usr/include/GL/glu.h:327
gluTessCallback = _link_function('gluTessCallback', None, [POINTER(GLUtesselator), GLenum, _GLUfuncptr], None)
# /usr/include/GL/glu.h:328
gluTessEndContour = _link_function('gluTessEndContour', None, [POINTER(GLUtesselator)], None)
# /usr/include/GL/glu.h:329
gluTessEndPolygon = _link_function('gluTessEndPolygon', None, [POINTER(GLUtesselator)], None)
# /usr/include/GL/glu.h:330
gluTessNormal = _link_function('gluTessNormal', None, [POINTER(GLUtesselator), GLdouble, GLdouble, GLdouble], None)
# /usr/include/GL/glu.h:331
gluTessProperty = _link_function('gluTessProperty', None, [POINTER(GLUtesselator), GLenum, GLdouble], None)
# /usr/include/GL/glu.h:332
gluTessVertex = _link_function('gluTessVertex', None, [POINTER(GLUtesselator), POINTER(GLdouble), POINTER(GLvoid)], None)
# /usr/include/GL/glu.h:333
gluUnProject = _link_function('gluUnProject', GLint, [GLdouble, GLdouble, GLdouble, POINTER(GLdouble), POINTER(GLdouble), POINTER(GLint), POINTER(GLdouble), POINTER(GLdouble), POINTER(GLdouble)], None)
# /usr/include/GL/glu.h:334
gluUnProject4 = _link_function('gluUnProject4', GLint, [GLdouble, GLdouble, GLdouble, GLdouble, POINTER(GLdouble), POINTER(GLdouble), POINTER(GLint), GLdouble, GLdouble, POINTER(GLdouble), POINTER(GLdouble), POINTER(GLdouble), POINTER(GLdouble)], None)
__all__ = ['GLU_EXT_object_space_tess', 'GLU_EXT_nurbs_tessellator',
'GLU_FALSE', 'GLU_TRUE', 'GLU_VERSION_1_1', 'GLU_VERSION_1_2',
'GLU_VERSION_1_3', 'GLU_VERSION', 'GLU_EXTENSIONS', 'GLU_INVALID_ENUM',
'GLU_INVALID_VALUE', 'GLU_OUT_OF_MEMORY', 'GLU_INCOMPATIBLE_GL_VERSION',
'GLU_INVALID_OPERATION', 'GLU_OUTLINE_POLYGON', 'GLU_OUTLINE_PATCH',
'GLU_NURBS_ERROR', 'GLU_ERROR', 'GLU_NURBS_BEGIN', 'GLU_NURBS_BEGIN_EXT',
'GLU_NURBS_VERTEX', 'GLU_NURBS_VERTEX_EXT', 'GLU_NURBS_NORMAL',
'GLU_NURBS_NORMAL_EXT', 'GLU_NURBS_COLOR', 'GLU_NURBS_COLOR_EXT',
'GLU_NURBS_TEXTURE_COORD', 'GLU_NURBS_TEX_COORD_EXT', 'GLU_NURBS_END',
'GLU_NURBS_END_EXT', 'GLU_NURBS_BEGIN_DATA', 'GLU_NURBS_BEGIN_DATA_EXT',
'GLU_NURBS_VERTEX_DATA', 'GLU_NURBS_VERTEX_DATA_EXT', 'GLU_NURBS_NORMAL_DATA',
'GLU_NURBS_NORMAL_DATA_EXT', 'GLU_NURBS_COLOR_DATA',
'GLU_NURBS_COLOR_DATA_EXT', 'GLU_NURBS_TEXTURE_COORD_DATA',
'GLU_NURBS_TEX_COORD_DATA_EXT', 'GLU_NURBS_END_DATA',
'GLU_NURBS_END_DATA_EXT', 'GLU_NURBS_ERROR1', 'GLU_NURBS_ERROR2',
'GLU_NURBS_ERROR3', 'GLU_NURBS_ERROR4', 'GLU_NURBS_ERROR5',
'GLU_NURBS_ERROR6', 'GLU_NURBS_ERROR7', 'GLU_NURBS_ERROR8',
'GLU_NURBS_ERROR9', 'GLU_NURBS_ERROR10', 'GLU_NURBS_ERROR11',
'GLU_NURBS_ERROR12', 'GLU_NURBS_ERROR13', 'GLU_NURBS_ERROR14',
'GLU_NURBS_ERROR15', 'GLU_NURBS_ERROR16', 'GLU_NURBS_ERROR17',
'GLU_NURBS_ERROR18', 'GLU_NURBS_ERROR19', 'GLU_NURBS_ERROR20',
'GLU_NURBS_ERROR21', 'GLU_NURBS_ERROR22', 'GLU_NURBS_ERROR23',
'GLU_NURBS_ERROR24', 'GLU_NURBS_ERROR25', 'GLU_NURBS_ERROR26',
'GLU_NURBS_ERROR27', 'GLU_NURBS_ERROR28', 'GLU_NURBS_ERROR29',
'GLU_NURBS_ERROR30', 'GLU_NURBS_ERROR31', 'GLU_NURBS_ERROR32',
'GLU_NURBS_ERROR33', 'GLU_NURBS_ERROR34', 'GLU_NURBS_ERROR35',
'GLU_NURBS_ERROR36', 'GLU_NURBS_ERROR37', 'GLU_AUTO_LOAD_MATRIX',
'GLU_CULLING', 'GLU_SAMPLING_TOLERANCE', 'GLU_DISPLAY_MODE',
'GLU_PARAMETRIC_TOLERANCE', 'GLU_SAMPLING_METHOD', 'GLU_U_STEP', 'GLU_V_STEP',
'GLU_NURBS_MODE', 'GLU_NURBS_MODE_EXT', 'GLU_NURBS_TESSELLATOR',
'GLU_NURBS_TESSELLATOR_EXT', 'GLU_NURBS_RENDERER', 'GLU_NURBS_RENDERER_EXT',
'GLU_OBJECT_PARAMETRIC_ERROR', 'GLU_OBJECT_PARAMETRIC_ERROR_EXT',
'GLU_OBJECT_PATH_LENGTH', 'GLU_OBJECT_PATH_LENGTH_EXT', 'GLU_PATH_LENGTH',
'GLU_PARAMETRIC_ERROR', 'GLU_DOMAIN_DISTANCE', 'GLU_MAP1_TRIM_2',
'GLU_MAP1_TRIM_3', 'GLU_POINT', 'GLU_LINE', 'GLU_FILL', 'GLU_SILHOUETTE',
'GLU_SMOOTH', 'GLU_FLAT', 'GLU_NONE', 'GLU_OUTSIDE', 'GLU_INSIDE',
'GLU_TESS_BEGIN', 'GLU_BEGIN', 'GLU_TESS_VERTEX', 'GLU_VERTEX',
'GLU_TESS_END', 'GLU_END', 'GLU_TESS_ERROR', 'GLU_TESS_EDGE_FLAG',
'GLU_EDGE_FLAG', 'GLU_TESS_COMBINE', 'GLU_TESS_BEGIN_DATA',
'GLU_TESS_VERTEX_DATA', 'GLU_TESS_END_DATA', 'GLU_TESS_ERROR_DATA',
'GLU_TESS_EDGE_FLAG_DATA', 'GLU_TESS_COMBINE_DATA', 'GLU_CW', 'GLU_CCW',
'GLU_INTERIOR', 'GLU_EXTERIOR', 'GLU_UNKNOWN', 'GLU_TESS_WINDING_RULE',
'GLU_TESS_BOUNDARY_ONLY', 'GLU_TESS_TOLERANCE', 'GLU_TESS_ERROR1',
'GLU_TESS_ERROR2', 'GLU_TESS_ERROR3', 'GLU_TESS_ERROR4', 'GLU_TESS_ERROR5',
'GLU_TESS_ERROR6', 'GLU_TESS_ERROR7', 'GLU_TESS_ERROR8',
'GLU_TESS_MISSING_BEGIN_POLYGON', 'GLU_TESS_MISSING_BEGIN_CONTOUR',
'GLU_TESS_MISSING_END_POLYGON', 'GLU_TESS_MISSING_END_CONTOUR',
'GLU_TESS_COORD_TOO_LARGE', 'GLU_TESS_NEED_COMBINE_CALLBACK',
'GLU_TESS_WINDING_ODD', 'GLU_TESS_WINDING_NONZERO',
'GLU_TESS_WINDING_POSITIVE', 'GLU_TESS_WINDING_NEGATIVE',
'GLU_TESS_WINDING_ABS_GEQ_TWO', 'GLUnurbs', 'GLUquadric', 'GLUtesselator',
'GLUnurbsObj', 'GLUquadricObj', 'GLUtesselatorObj', 'GLUtriangulatorObj',
'GLU_TESS_MAX_COORD', '_GLUfuncptr', 'gluBeginCurve', 'gluBeginPolygon',
'gluBeginSurface', 'gluBeginTrim', 'gluBuild1DMipmapLevels',
'gluBuild1DMipmaps', 'gluBuild2DMipmapLevels', 'gluBuild2DMipmaps',
'gluBuild3DMipmapLevels', 'gluBuild3DMipmaps', 'gluCheckExtension',
'gluCylinder', 'gluDeleteNurbsRenderer', 'gluDeleteQuadric', 'gluDeleteTess',
'gluDisk', 'gluEndCurve', 'gluEndPolygon', 'gluEndSurface', 'gluEndTrim',
'gluErrorString', 'gluGetNurbsProperty', 'gluGetString', 'gluGetTessProperty',
'gluLoadSamplingMatrices', 'gluLookAt', 'gluNewNurbsRenderer',
'gluNewQuadric', 'gluNewTess', 'gluNextContour', 'gluNurbsCallback',
'gluNurbsCallbackData', 'gluNurbsCallbackDataEXT', 'gluNurbsCurve',
'gluNurbsProperty', 'gluNurbsSurface', 'gluOrtho2D', 'gluPartialDisk',
'gluPerspective', 'gluPickMatrix', 'gluProject', 'gluPwlCurve',
'gluQuadricCallback', 'gluQuadricDrawStyle', 'gluQuadricNormals',
'gluQuadricOrientation', 'gluQuadricTexture', 'gluScaleImage', 'gluSphere',
'gluTessBeginContour', 'gluTessBeginPolygon', 'gluTessCallback',
'gluTessEndContour', 'gluTessEndPolygon', 'gluTessNormal', 'gluTessProperty',
'gluTessVertex', 'gluUnProject', 'gluUnProject4']
# END GENERATED CONTENT (do not edit above this line)

160
pyglet/gl/glu_info.py Normal file
View file

@ -0,0 +1,160 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Information about version and extensions of current GLU implementation.
Usage::
from pyglet.gl import glu_info
if glu_info.have_extension('GLU_EXT_nurbs_tessellator'):
# ...
If multiple contexts are in use you can use a separate GLUInfo object for each
context. Call `set_active_context` after switching to the desired context for
each GLUInfo::
from pyglet.gl.glu_info import GLUInfo
info = GLUInfo()
info.set_active_context()
if info.have_version(1, 3):
# ...
Note that GLUInfo only returns meaningful information if a context has been
created.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: glu_info.py 1979 2008-03-28 15:23:51Z Alex.Holkner $'
from ctypes import *
import warnings
from pyglet.gl.glu import *
class GLUInfo(object):
'''Information interface for the GLU library.
A default instance is created automatically when the first OpenGL context
is created. You can use the module functions as a convenience for
this default instance's methods.
If you are using more than one context, you must call `set_active_context`
when the context is active for this `GLUInfo` instance.
'''
have_context = False
version = '0.0.0'
extensions = []
_have_info = False
def set_active_context(self):
'''Store information for the currently active context.
This method is called automatically for the default context.
'''
self.have_context = True
if not self._have_info:
self.extensions = \
cast(gluGetString(GLU_EXTENSIONS), c_char_p).value.split()
self.version = cast(gluGetString(GLU_VERSION), c_char_p).value
self._have_info = True
def have_version(self, major, minor=0, release=0):
'''Determine if a version of GLU is supported.
:Parameters:
`major` : int
The major revision number (typically 1).
`minor` : int
The minor revision number.
`release` : int
The release number.
:rtype: bool
:return: True if the requested or a later version is supported.
'''
if not self.have_context:
warnings.warn('No GL context created yet.')
ver = '%s.0.0' % self.version.split(' ', 1)[0]
imajor, iminor, irelease = [int(v) for v in ver.split('.', 3)[:3]]
return imajor > major or \
(imajor == major and iminor > minor) or \
(imajor == major and iminor == minor and irelease >= release)
def get_version(self):
'''Get the current GLU version.
:return: the GLU version
:rtype: str
'''
if not self.have_context:
warnings.warn('No GL context created yet.')
return self.version
def have_extension(self, extension):
'''Determine if a GLU extension is available.
:Parameters:
`extension` : str
The name of the extension to test for, including its
``GLU_`` prefix.
:return: True if the extension is provided by the implementation.
:rtype: bool
'''
if not self.have_context:
warnings.warn('No GL context created yet.')
return extension in self.extensions
def get_extensions(self):
'''Get a list of available GLU extensions.
:return: a list of the available extensions.
:rtype: list of str
'''
if not self.have_context:
warnings.warn('No GL context created yet.')
return self.extensions
# Single instance useful for apps with only a single context (or all contexts
# have same GLU driver, common case).
_glu_info = GLUInfo()
set_active_context = _glu_info.set_active_context
have_version = _glu_info.have_version
get_version = _glu_info.get_version
have_extension = _glu_info.have_extension
get_extensions = _glu_info.get_extensions

587
pyglet/gl/glx.py Normal file
View file

@ -0,0 +1,587 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Wrapper for /usr/include/GL/glx.h
Do not modify generated portions of this file.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: glx.py 1579 2008-01-15 14:47:19Z Alex.Holkner $'
from ctypes import *
from pyglet.gl.lib import link_GLX as _link_function
from pyglet.gl.lib import c_ptrdiff_t, c_void
if not _link_function:
raise ImportError('libGL.so is not available.')
# BEGIN GENERATED CONTENT (do not edit below this line)
# This content is generated by tools/gengl.py.
# Wrapper for /usr/include/GL/glx.h
GLX_USE_GL = 1 # /usr/include/GL/glx.h:36
GLX_BUFFER_SIZE = 2 # /usr/include/GL/glx.h:37
GLX_LEVEL = 3 # /usr/include/GL/glx.h:38
GLX_RGBA = 4 # /usr/include/GL/glx.h:39
GLX_DOUBLEBUFFER = 5 # /usr/include/GL/glx.h:40
GLX_STEREO = 6 # /usr/include/GL/glx.h:41
GLX_AUX_BUFFERS = 7 # /usr/include/GL/glx.h:42
GLX_RED_SIZE = 8 # /usr/include/GL/glx.h:43
GLX_GREEN_SIZE = 9 # /usr/include/GL/glx.h:44
GLX_BLUE_SIZE = 10 # /usr/include/GL/glx.h:45
GLX_ALPHA_SIZE = 11 # /usr/include/GL/glx.h:46
GLX_DEPTH_SIZE = 12 # /usr/include/GL/glx.h:47
GLX_STENCIL_SIZE = 13 # /usr/include/GL/glx.h:48
GLX_ACCUM_RED_SIZE = 14 # /usr/include/GL/glx.h:49
GLX_ACCUM_GREEN_SIZE = 15 # /usr/include/GL/glx.h:50
GLX_ACCUM_BLUE_SIZE = 16 # /usr/include/GL/glx.h:51
GLX_ACCUM_ALPHA_SIZE = 17 # /usr/include/GL/glx.h:52
GLX_BAD_SCREEN = 1 # /usr/include/GL/glx.h:58
GLX_BAD_ATTRIBUTE = 2 # /usr/include/GL/glx.h:59
GLX_NO_EXTENSION = 3 # /usr/include/GL/glx.h:60
GLX_BAD_VISUAL = 4 # /usr/include/GL/glx.h:61
GLX_BAD_CONTEXT = 5 # /usr/include/GL/glx.h:62
GLX_BAD_VALUE = 6 # /usr/include/GL/glx.h:63
GLX_BAD_ENUM = 7 # /usr/include/GL/glx.h:64
GLX_VENDOR = 1 # /usr/include/GL/glx.h:69
GLX_VERSION = 2 # /usr/include/GL/glx.h:70
GLX_EXTENSIONS = 3 # /usr/include/GL/glx.h:71
# VERSION_1_3 (/usr/include/GL/glx.h:73)
GLX_WINDOW_BIT = 1 # /usr/include/GL/glx.h:74
GLX_PIXMAP_BIT = 2 # /usr/include/GL/glx.h:75
GLX_PBUFFER_BIT = 4 # /usr/include/GL/glx.h:76
GLX_RGBA_BIT = 1 # /usr/include/GL/glx.h:77
GLX_COLOR_INDEX_BIT = 2 # /usr/include/GL/glx.h:78
GLX_PBUFFER_CLOBBER_MASK = 134217728 # /usr/include/GL/glx.h:79
GLX_FRONT_LEFT_BUFFER_BIT = 1 # /usr/include/GL/glx.h:80
GLX_FRONT_RIGHT_BUFFER_BIT = 2 # /usr/include/GL/glx.h:81
GLX_BACK_LEFT_BUFFER_BIT = 4 # /usr/include/GL/glx.h:82
GLX_BACK_RIGHT_BUFFER_BIT = 8 # /usr/include/GL/glx.h:83
GLX_AUX_BUFFERS_BIT = 16 # /usr/include/GL/glx.h:84
GLX_DEPTH_BUFFER_BIT = 32 # /usr/include/GL/glx.h:85
GLX_STENCIL_BUFFER_BIT = 64 # /usr/include/GL/glx.h:86
GLX_ACCUM_BUFFER_BIT = 128 # /usr/include/GL/glx.h:87
GLX_CONFIG_CAVEAT = 32 # /usr/include/GL/glx.h:88
GLX_X_VISUAL_TYPE = 34 # /usr/include/GL/glx.h:89
GLX_TRANSPARENT_TYPE = 35 # /usr/include/GL/glx.h:90
GLX_TRANSPARENT_INDEX_VALUE = 36 # /usr/include/GL/glx.h:91
GLX_TRANSPARENT_RED_VALUE = 37 # /usr/include/GL/glx.h:92
GLX_TRANSPARENT_GREEN_VALUE = 38 # /usr/include/GL/glx.h:93
GLX_TRANSPARENT_BLUE_VALUE = 39 # /usr/include/GL/glx.h:94
GLX_TRANSPARENT_ALPHA_VALUE = 40 # /usr/include/GL/glx.h:95
GLX_DONT_CARE = 4294967295 # /usr/include/GL/glx.h:96
GLX_NONE = 32768 # /usr/include/GL/glx.h:97
GLX_SLOW_CONFIG = 32769 # /usr/include/GL/glx.h:98
GLX_TRUE_COLOR = 32770 # /usr/include/GL/glx.h:99
GLX_DIRECT_COLOR = 32771 # /usr/include/GL/glx.h:100
GLX_PSEUDO_COLOR = 32772 # /usr/include/GL/glx.h:101
GLX_STATIC_COLOR = 32773 # /usr/include/GL/glx.h:102
GLX_GRAY_SCALE = 32774 # /usr/include/GL/glx.h:103
GLX_STATIC_GRAY = 32775 # /usr/include/GL/glx.h:104
GLX_TRANSPARENT_RGB = 32776 # /usr/include/GL/glx.h:105
GLX_TRANSPARENT_INDEX = 32777 # /usr/include/GL/glx.h:106
GLX_VISUAL_ID = 32779 # /usr/include/GL/glx.h:107
GLX_SCREEN = 32780 # /usr/include/GL/glx.h:108
GLX_NON_CONFORMANT_CONFIG = 32781 # /usr/include/GL/glx.h:109
GLX_DRAWABLE_TYPE = 32784 # /usr/include/GL/glx.h:110
GLX_RENDER_TYPE = 32785 # /usr/include/GL/glx.h:111
GLX_X_RENDERABLE = 32786 # /usr/include/GL/glx.h:112
GLX_FBCONFIG_ID = 32787 # /usr/include/GL/glx.h:113
GLX_RGBA_TYPE = 32788 # /usr/include/GL/glx.h:114
GLX_COLOR_INDEX_TYPE = 32789 # /usr/include/GL/glx.h:115
GLX_MAX_PBUFFER_WIDTH = 32790 # /usr/include/GL/glx.h:116
GLX_MAX_PBUFFER_HEIGHT = 32791 # /usr/include/GL/glx.h:117
GLX_MAX_PBUFFER_PIXELS = 32792 # /usr/include/GL/glx.h:118
GLX_PRESERVED_CONTENTS = 32795 # /usr/include/GL/glx.h:119
GLX_LARGEST_PBUFFER = 32796 # /usr/include/GL/glx.h:120
GLX_WIDTH = 32797 # /usr/include/GL/glx.h:121
GLX_HEIGHT = 32798 # /usr/include/GL/glx.h:122
GLX_EVENT_MASK = 32799 # /usr/include/GL/glx.h:123
GLX_DAMAGED = 32800 # /usr/include/GL/glx.h:124
GLX_SAVED = 32801 # /usr/include/GL/glx.h:125
GLX_WINDOW = 32802 # /usr/include/GL/glx.h:126
GLX_PBUFFER = 32803 # /usr/include/GL/glx.h:127
GLX_PBUFFER_HEIGHT = 32832 # /usr/include/GL/glx.h:128
GLX_PBUFFER_WIDTH = 32833 # /usr/include/GL/glx.h:129
# VERSION_1_4 (/usr/include/GL/glx.h:132)
GLX_SAMPLE_BUFFERS = 100000 # /usr/include/GL/glx.h:133
GLX_SAMPLES = 100001 # /usr/include/GL/glx.h:134
# ARB_get_proc_address (/usr/include/GL/glx.h:137)
__GLXextFuncPtr = CFUNCTYPE(None) # /usr/include/GL/glx.h:138
XID = c_ulong # /usr/include/X11/X.h:71
GLXContextID = XID # /usr/include/GL/glx.h:144
GLXPixmap = XID # /usr/include/GL/glx.h:145
GLXDrawable = XID # /usr/include/GL/glx.h:146
GLXPbuffer = XID # /usr/include/GL/glx.h:147
GLXPbufferSGIX = XID # /usr/include/GL/glx.h:148
GLXWindow = XID # /usr/include/GL/glx.h:149
GLXFBConfigID = XID # /usr/include/GL/glx.h:150
class struct___GLXcontextRec(Structure):
__slots__ = [
]
struct___GLXcontextRec._fields_ = [
('_opaque_struct', c_int)
]
GLXContext = POINTER(struct___GLXcontextRec) # /usr/include/GL/glx.h:155
class struct___GLXFBConfigRec(Structure):
__slots__ = [
]
struct___GLXFBConfigRec._fields_ = [
('_opaque_struct', c_int)
]
GLXFBConfig = POINTER(struct___GLXFBConfigRec) # /usr/include/GL/glx.h:160
class struct_anon_94(Structure):
__slots__ = [
'visual',
'visualid',
'screen',
'depth',
'class',
'red_mask',
'green_mask',
'blue_mask',
'colormap_size',
'bits_per_rgb',
]
class struct_anon_11(Structure):
__slots__ = [
'ext_data',
'visualid',
'class',
'red_mask',
'green_mask',
'blue_mask',
'bits_per_rgb',
'map_entries',
]
class struct__XExtData(Structure):
__slots__ = [
'number',
'next',
'free_private',
'private_data',
]
XPointer = c_char_p # /usr/include/X11/Xlib.h:108
struct__XExtData._fields_ = [
('number', c_int),
('next', POINTER(struct__XExtData)),
('free_private', POINTER(CFUNCTYPE(c_int, POINTER(struct__XExtData)))),
('private_data', XPointer),
]
XExtData = struct__XExtData # /usr/include/X11/Xlib.h:187
VisualID = c_ulong # /usr/include/X11/X.h:81
struct_anon_11._fields_ = [
('ext_data', POINTER(XExtData)),
('visualid', VisualID),
('class', c_int),
('red_mask', c_ulong),
('green_mask', c_ulong),
('blue_mask', c_ulong),
('bits_per_rgb', c_int),
('map_entries', c_int),
]
Visual = struct_anon_11 # /usr/include/X11/Xlib.h:270
struct_anon_94._fields_ = [
('visual', POINTER(Visual)),
('visualid', VisualID),
('screen', c_int),
('depth', c_int),
('class', c_int),
('red_mask', c_ulong),
('green_mask', c_ulong),
('blue_mask', c_ulong),
('colormap_size', c_int),
('bits_per_rgb', c_int),
]
XVisualInfo = struct_anon_94 # /usr/include/X11/Xutil.h:296
class struct__XDisplay(Structure):
__slots__ = [
]
struct__XDisplay._fields_ = [
('_opaque_struct', c_int)
]
Display = struct__XDisplay # /usr/include/X11/Xlib.h:519
# /usr/include/GL/glx.h:168
glXChooseVisual = _link_function('glXChooseVisual', POINTER(XVisualInfo), [POINTER(Display), c_int, POINTER(c_int)], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:171
glXCopyContext = _link_function('glXCopyContext', None, [POINTER(Display), GLXContext, GLXContext, c_ulong], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:174
glXCreateContext = _link_function('glXCreateContext', GLXContext, [POINTER(Display), POINTER(XVisualInfo), GLXContext, c_int], 'ARB_get_proc_address')
Pixmap = XID # /usr/include/X11/X.h:107
# /usr/include/GL/glx.h:177
glXCreateGLXPixmap = _link_function('glXCreateGLXPixmap', GLXPixmap, [POINTER(Display), POINTER(XVisualInfo), Pixmap], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:180
glXDestroyContext = _link_function('glXDestroyContext', None, [POINTER(Display), GLXContext], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:182
glXDestroyGLXPixmap = _link_function('glXDestroyGLXPixmap', None, [POINTER(Display), GLXPixmap], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:184
glXGetConfig = _link_function('glXGetConfig', c_int, [POINTER(Display), POINTER(XVisualInfo), c_int, POINTER(c_int)], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:187
glXGetCurrentContext = _link_function('glXGetCurrentContext', GLXContext, [], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:189
glXGetCurrentDrawable = _link_function('glXGetCurrentDrawable', GLXDrawable, [], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:191
glXIsDirect = _link_function('glXIsDirect', c_int, [POINTER(Display), GLXContext], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:193
glXMakeCurrent = _link_function('glXMakeCurrent', c_int, [POINTER(Display), GLXDrawable, GLXContext], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:196
glXQueryExtension = _link_function('glXQueryExtension', c_int, [POINTER(Display), POINTER(c_int), POINTER(c_int)], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:198
glXQueryVersion = _link_function('glXQueryVersion', c_int, [POINTER(Display), POINTER(c_int), POINTER(c_int)], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:200
glXSwapBuffers = _link_function('glXSwapBuffers', None, [POINTER(Display), GLXDrawable], 'ARB_get_proc_address')
Font = XID # /usr/include/X11/X.h:105
# /usr/include/GL/glx.h:202
glXUseXFont = _link_function('glXUseXFont', None, [Font, c_int, c_int, c_int], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:204
glXWaitGL = _link_function('glXWaitGL', None, [], 'ARB_get_proc_address')
# /usr/include/GL/glx.h:206
glXWaitX = _link_function('glXWaitX', None, [], 'ARB_get_proc_address')
# VERSION_1_1 (/usr/include/GL/glx.h:209)
GLX_VERSION_1_1 = 1 # /usr/include/GL/glx.h:210
# /usr/include/GL/glx.h:214
glXGetClientString = _link_function('glXGetClientString', c_char_p, [POINTER(Display), c_int], 'VERSION_1_1')
# /usr/include/GL/glx.h:216
glXQueryServerString = _link_function('glXQueryServerString', c_char_p, [POINTER(Display), c_int, c_int], 'VERSION_1_1')
# /usr/include/GL/glx.h:218
glXQueryExtensionsString = _link_function('glXQueryExtensionsString', c_char_p, [POINTER(Display), c_int], 'VERSION_1_1')
# VERSION_1_2 (/usr/include/GL/glx.h:222)
GLX_VERSION_1_2 = 1 # /usr/include/GL/glx.h:223
# /usr/include/GL/glx.h:227
glXGetCurrentDisplay = _link_function('glXGetCurrentDisplay', POINTER(Display), [], 'VERSION_1_2')
# VERSION_1_3 (/usr/include/GL/glx.h:230)
GLX_VERSION_1_3 = 1 # /usr/include/GL/glx.h:231
# /usr/include/GL/glx.h:235
glXChooseFBConfig = _link_function('glXChooseFBConfig', POINTER(GLXFBConfig), [POINTER(Display), c_int, POINTER(c_int), POINTER(c_int)], 'VERSION_1_3')
# /usr/include/GL/glx.h:238
glXCreateNewContext = _link_function('glXCreateNewContext', GLXContext, [POINTER(Display), GLXFBConfig, c_int, GLXContext, c_int], 'VERSION_1_3')
# /usr/include/GL/glx.h:242
glXCreatePbuffer = _link_function('glXCreatePbuffer', GLXPbuffer, [POINTER(Display), GLXFBConfig, POINTER(c_int)], 'VERSION_1_3')
# /usr/include/GL/glx.h:245
glXCreatePixmap = _link_function('glXCreatePixmap', GLXPixmap, [POINTER(Display), GLXFBConfig, Pixmap, POINTER(c_int)], 'VERSION_1_3')
Window = XID # /usr/include/X11/X.h:101
# /usr/include/GL/glx.h:248
glXCreateWindow = _link_function('glXCreateWindow', GLXWindow, [POINTER(Display), GLXFBConfig, Window, POINTER(c_int)], 'VERSION_1_3')
# /usr/include/GL/glx.h:251
glXDestroyPbuffer = _link_function('glXDestroyPbuffer', None, [POINTER(Display), GLXPbuffer], 'VERSION_1_3')
# /usr/include/GL/glx.h:253
glXDestroyPixmap = _link_function('glXDestroyPixmap', None, [POINTER(Display), GLXPixmap], 'VERSION_1_3')
# /usr/include/GL/glx.h:255
glXDestroyWindow = _link_function('glXDestroyWindow', None, [POINTER(Display), GLXWindow], 'VERSION_1_3')
# /usr/include/GL/glx.h:257
glXGetCurrentReadDrawable = _link_function('glXGetCurrentReadDrawable', GLXDrawable, [], 'VERSION_1_3')
# /usr/include/GL/glx.h:259
glXGetFBConfigAttrib = _link_function('glXGetFBConfigAttrib', c_int, [POINTER(Display), GLXFBConfig, c_int, POINTER(c_int)], 'VERSION_1_3')
# /usr/include/GL/glx.h:262
glXGetFBConfigs = _link_function('glXGetFBConfigs', POINTER(GLXFBConfig), [POINTER(Display), c_int, POINTER(c_int)], 'VERSION_1_3')
# /usr/include/GL/glx.h:264
glXGetSelectedEvent = _link_function('glXGetSelectedEvent', None, [POINTER(Display), GLXDrawable, POINTER(c_ulong)], 'VERSION_1_3')
# /usr/include/GL/glx.h:267
glXGetVisualFromFBConfig = _link_function('glXGetVisualFromFBConfig', POINTER(XVisualInfo), [POINTER(Display), GLXFBConfig], 'VERSION_1_3')
# /usr/include/GL/glx.h:269
glXMakeContextCurrent = _link_function('glXMakeContextCurrent', c_int, [POINTER(Display), GLXDrawable, GLXDrawable, GLXContext], 'VERSION_1_3')
# /usr/include/GL/glx.h:272
glXQueryContext = _link_function('glXQueryContext', c_int, [POINTER(Display), GLXContext, c_int, POINTER(c_int)], 'VERSION_1_3')
# /usr/include/GL/glx.h:275
glXQueryDrawable = _link_function('glXQueryDrawable', None, [POINTER(Display), GLXDrawable, c_int, POINTER(c_uint)], 'VERSION_1_3')
# /usr/include/GL/glx.h:278
glXSelectEvent = _link_function('glXSelectEvent', None, [POINTER(Display), GLXDrawable, c_ulong], 'VERSION_1_3')
PFNGLXGETFBCONFIGSPROC = CFUNCTYPE(POINTER(GLXFBConfig), POINTER(Display), c_int, POINTER(c_int)) # /usr/include/GL/glx.h:281
PFNGLXCHOOSEFBCONFIGPROC = CFUNCTYPE(POINTER(GLXFBConfig), POINTER(Display), c_int, POINTER(c_int), POINTER(c_int)) # /usr/include/GL/glx.h:282
PFNGLXGETFBCONFIGATTRIBPROC = CFUNCTYPE(c_int, POINTER(Display), GLXFBConfig, c_int, POINTER(c_int)) # /usr/include/GL/glx.h:283
PFNGLXGETVISUALFROMFBCONFIGPROC = CFUNCTYPE(POINTER(XVisualInfo), POINTER(Display), GLXFBConfig) # /usr/include/GL/glx.h:284
PFNGLXCREATEWINDOWPROC = CFUNCTYPE(GLXWindow, POINTER(Display), GLXFBConfig, Window, POINTER(c_int)) # /usr/include/GL/glx.h:285
PFNGLXDESTROYWINDOWPROC = CFUNCTYPE(None, POINTER(Display), GLXWindow) # /usr/include/GL/glx.h:286
PFNGLXCREATEPIXMAPPROC = CFUNCTYPE(GLXPixmap, POINTER(Display), GLXFBConfig, Pixmap, POINTER(c_int)) # /usr/include/GL/glx.h:287
PFNGLXDESTROYPIXMAPPROC = CFUNCTYPE(None, POINTER(Display), GLXPixmap) # /usr/include/GL/glx.h:288
PFNGLXCREATEPBUFFERPROC = CFUNCTYPE(GLXPbuffer, POINTER(Display), GLXFBConfig, POINTER(c_int)) # /usr/include/GL/glx.h:289
PFNGLXDESTROYPBUFFERPROC = CFUNCTYPE(None, POINTER(Display), GLXPbuffer) # /usr/include/GL/glx.h:290
PFNGLXQUERYDRAWABLEPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, c_int, POINTER(c_uint)) # /usr/include/GL/glx.h:291
PFNGLXCREATENEWCONTEXTPROC = CFUNCTYPE(GLXContext, POINTER(Display), GLXFBConfig, c_int, GLXContext, c_int) # /usr/include/GL/glx.h:292
PFNGLXMAKECONTEXTCURRENTPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, GLXDrawable, GLXContext) # /usr/include/GL/glx.h:293
PFNGLXGETCURRENTREADDRAWABLEPROC = CFUNCTYPE(GLXDrawable) # /usr/include/GL/glx.h:294
PFNGLXGETCURRENTDISPLAYPROC = CFUNCTYPE(POINTER(Display)) # /usr/include/GL/glx.h:295
PFNGLXQUERYCONTEXTPROC = CFUNCTYPE(c_int, POINTER(Display), GLXContext, c_int, POINTER(c_int)) # /usr/include/GL/glx.h:296
PFNGLXSELECTEVENTPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, c_ulong) # /usr/include/GL/glx.h:297
PFNGLXGETSELECTEDEVENTPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, POINTER(c_ulong)) # /usr/include/GL/glx.h:298
# VERSION_1_4 (/usr/include/GL/glx.h:302)
GLX_VERSION_1_4 = 1 # /usr/include/GL/glx.h:303
GLubyte = c_ubyte # /usr/include/GL/gl.h:60
# /usr/include/GL/glx.h:307
glXGetProcAddress = _link_function('glXGetProcAddress', __GLXextFuncPtr, [POINTER(GLubyte)], 'VERSION_1_4')
PFNGLXGETPROCADDRESSPROC = CFUNCTYPE(__GLXextFuncPtr, POINTER(GLubyte)) # /usr/include/GL/glx.h:308
# ARB_get_proc_address (/usr/include/GL/glx.h:318)
GLX_ARB_get_proc_address = 1 # /usr/include/GL/glx.h:319
# /usr/include/GL/glx.h:321
glXGetProcAddressARB = _link_function('glXGetProcAddressARB', POINTER(CFUNCTYPE(None)), [POINTER(GLubyte)], 'ARB_get_proc_address')
PFNGLXGETPROCADDRESSARBPROC = CFUNCTYPE(__GLXextFuncPtr, POINTER(GLubyte)) # /usr/include/GL/glx.h:322
class struct_anon_96(Structure):
__slots__ = [
'event_type',
'draw_type',
'serial',
'send_event',
'display',
'drawable',
'buffer_mask',
'aux_buffer',
'x',
'y',
'width',
'height',
'count',
]
struct_anon_96._fields_ = [
('event_type', c_int),
('draw_type', c_int),
('serial', c_ulong),
('send_event', c_int),
('display', POINTER(Display)),
('drawable', GLXDrawable),
('buffer_mask', c_uint),
('aux_buffer', c_uint),
('x', c_int),
('y', c_int),
('width', c_int),
('height', c_int),
('count', c_int),
]
GLXPbufferClobberEvent = struct_anon_96 # /usr/include/GL/glx.h:343
class struct___GLXEvent(Union):
__slots__ = [
'glxpbufferclobber',
'pad',
]
struct___GLXEvent._fields_ = [
('glxpbufferclobber', GLXPbufferClobberEvent),
('pad', c_long * 24),
]
GLXEvent = struct___GLXEvent # /usr/include/GL/glx.h:348
# GLXEXT_LEGACY (/usr/include/GL/glx.h:350)
# VERSION_1_3 (/usr/include/GL/glxext.h:59)
# VERSION_1_4 (/usr/include/GL/glxext.h:118)
# ARB_get_proc_address (/usr/include/GL/glxext.h:123)
# ARB_multisample (/usr/include/GL/glxext.h:126)
# ARB_fbconfig_float (/usr/include/GL/glxext.h:131)
# SGIS_multisample (/usr/include/GL/glxext.h:136)
# EXT_visual_info (/usr/include/GL/glxext.h:141)
# SGI_swap_control (/usr/include/GL/glxext.h:160)
# SGI_video_sync (/usr/include/GL/glxext.h:163)
# SGI_make_current_read (/usr/include/GL/glxext.h:166)
# SGIX_video_source (/usr/include/GL/glxext.h:169)
# EXT_visual_rating (/usr/include/GL/glxext.h:172)
# EXT_import_context (/usr/include/GL/glxext.h:179)
# SGIX_fbconfig (/usr/include/GL/glxext.h:185)
# SGIX_pbuffer (/usr/include/GL/glxext.h:199)
# SGI_cushion (/usr/include/GL/glxext.h:227)
# SGIX_video_resize (/usr/include/GL/glxext.h:230)
# SGIX_dmbuffer (/usr/include/GL/glxext.h:235)
# SGIX_swap_group (/usr/include/GL/glxext.h:239)
# SGIX_swap_barrier (/usr/include/GL/glxext.h:242)
# SGIS_blended_overlay (/usr/include/GL/glxext.h:245)
# SGIS_shared_multisample (/usr/include/GL/glxext.h:249)
# SUN_get_transparent_index (/usr/include/GL/glxext.h:254)
# 3DFX_multisample (/usr/include/GL/glxext.h:257)
# MESA_copy_sub_buffer (/usr/include/GL/glxext.h:262)
# MESA_pixmap_colormap (/usr/include/GL/glxext.h:265)
# MESA_release_buffers (/usr/include/GL/glxext.h:268)
# MESA_set_3dfx_mode (/usr/include/GL/glxext.h:271)
# SGIX_visual_select_group (/usr/include/GL/glxext.h:276)
# OML_swap_method (/usr/include/GL/glxext.h:280)
# OML_sync_control (/usr/include/GL/glxext.h:287)
# NV_float_buffer (/usr/include/GL/glxext.h:290)
# SGIX_hyperpipe (/usr/include/GL/glxext.h:294)
# MESA_agp_offset (/usr/include/GL/glxext.h:307)
# ARB_get_proc_address (/usr/include/GL/glxext.h:313)
# SGIX_video_source (/usr/include/GL/glxext.h:317)
# SGIX_fbconfig (/usr/include/GL/glxext.h:321)
# SGIX_pbuffer (/usr/include/GL/glxext.h:326)
# VERSION_1_3 (/usr/include/GL/glxext.h:358)
# VERSION_1_4 (/usr/include/GL/glxext.h:400)
# ARB_get_proc_address (/usr/include/GL/glxext.h:408)
# ARB_multisample (/usr/include/GL/glxext.h:416)
# ARB_fbconfig_float (/usr/include/GL/glxext.h:420)
# SGIS_multisample (/usr/include/GL/glxext.h:424)
# EXT_visual_info (/usr/include/GL/glxext.h:428)
# SGI_swap_control (/usr/include/GL/glxext.h:432)
# SGI_video_sync (/usr/include/GL/glxext.h:440)
# SGI_make_current_read (/usr/include/GL/glxext.h:450)
# SGIX_video_source (/usr/include/GL/glxext.h:460)
# EXT_visual_rating (/usr/include/GL/glxext.h:472)
# EXT_import_context (/usr/include/GL/glxext.h:476)
# SGIX_fbconfig (/usr/include/GL/glxext.h:492)
# SGIX_pbuffer (/usr/include/GL/glxext.h:510)
# SGI_cushion (/usr/include/GL/glxext.h:526)
# SGIX_video_resize (/usr/include/GL/glxext.h:534)
# SGIX_dmbuffer (/usr/include/GL/glxext.h:550)
# SGIX_swap_group (/usr/include/GL/glxext.h:560)
# SGIX_swap_barrier (/usr/include/GL/glxext.h:568)
# SUN_get_transparent_index (/usr/include/GL/glxext.h:578)
# MESA_copy_sub_buffer (/usr/include/GL/glxext.h:586)
# MESA_pixmap_colormap (/usr/include/GL/glxext.h:594)
# MESA_release_buffers (/usr/include/GL/glxext.h:602)
# MESA_set_3dfx_mode (/usr/include/GL/glxext.h:610)
# SGIX_visual_select_group (/usr/include/GL/glxext.h:618)
# OML_swap_method (/usr/include/GL/glxext.h:622)
# OML_sync_control (/usr/include/GL/glxext.h:626)
# NV_float_buffer (/usr/include/GL/glxext.h:642)
# SGIX_hyperpipe (/usr/include/GL/glxext.h:646)
# MESA_agp_offset (/usr/include/GL/glxext.h:693)
__all__ = ['GLX_USE_GL', 'GLX_BUFFER_SIZE', 'GLX_LEVEL', 'GLX_RGBA',
'GLX_DOUBLEBUFFER', 'GLX_STEREO', 'GLX_AUX_BUFFERS', 'GLX_RED_SIZE',
'GLX_GREEN_SIZE', 'GLX_BLUE_SIZE', 'GLX_ALPHA_SIZE', 'GLX_DEPTH_SIZE',
'GLX_STENCIL_SIZE', 'GLX_ACCUM_RED_SIZE', 'GLX_ACCUM_GREEN_SIZE',
'GLX_ACCUM_BLUE_SIZE', 'GLX_ACCUM_ALPHA_SIZE', 'GLX_BAD_SCREEN',
'GLX_BAD_ATTRIBUTE', 'GLX_NO_EXTENSION', 'GLX_BAD_VISUAL', 'GLX_BAD_CONTEXT',
'GLX_BAD_VALUE', 'GLX_BAD_ENUM', 'GLX_VENDOR', 'GLX_VERSION',
'GLX_EXTENSIONS', 'GLX_WINDOW_BIT', 'GLX_PIXMAP_BIT', 'GLX_PBUFFER_BIT',
'GLX_RGBA_BIT', 'GLX_COLOR_INDEX_BIT', 'GLX_PBUFFER_CLOBBER_MASK',
'GLX_FRONT_LEFT_BUFFER_BIT', 'GLX_FRONT_RIGHT_BUFFER_BIT',
'GLX_BACK_LEFT_BUFFER_BIT', 'GLX_BACK_RIGHT_BUFFER_BIT',
'GLX_AUX_BUFFERS_BIT', 'GLX_DEPTH_BUFFER_BIT', 'GLX_STENCIL_BUFFER_BIT',
'GLX_ACCUM_BUFFER_BIT', 'GLX_CONFIG_CAVEAT', 'GLX_X_VISUAL_TYPE',
'GLX_TRANSPARENT_TYPE', 'GLX_TRANSPARENT_INDEX_VALUE',
'GLX_TRANSPARENT_RED_VALUE', 'GLX_TRANSPARENT_GREEN_VALUE',
'GLX_TRANSPARENT_BLUE_VALUE', 'GLX_TRANSPARENT_ALPHA_VALUE', 'GLX_DONT_CARE',
'GLX_NONE', 'GLX_SLOW_CONFIG', 'GLX_TRUE_COLOR', 'GLX_DIRECT_COLOR',
'GLX_PSEUDO_COLOR', 'GLX_STATIC_COLOR', 'GLX_GRAY_SCALE', 'GLX_STATIC_GRAY',
'GLX_TRANSPARENT_RGB', 'GLX_TRANSPARENT_INDEX', 'GLX_VISUAL_ID', 'GLX_SCREEN',
'GLX_NON_CONFORMANT_CONFIG', 'GLX_DRAWABLE_TYPE', 'GLX_RENDER_TYPE',
'GLX_X_RENDERABLE', 'GLX_FBCONFIG_ID', 'GLX_RGBA_TYPE',
'GLX_COLOR_INDEX_TYPE', 'GLX_MAX_PBUFFER_WIDTH', 'GLX_MAX_PBUFFER_HEIGHT',
'GLX_MAX_PBUFFER_PIXELS', 'GLX_PRESERVED_CONTENTS', 'GLX_LARGEST_PBUFFER',
'GLX_WIDTH', 'GLX_HEIGHT', 'GLX_EVENT_MASK', 'GLX_DAMAGED', 'GLX_SAVED',
'GLX_WINDOW', 'GLX_PBUFFER', 'GLX_PBUFFER_HEIGHT', 'GLX_PBUFFER_WIDTH',
'GLX_SAMPLE_BUFFERS', 'GLX_SAMPLES', '__GLXextFuncPtr', 'GLXContextID',
'GLXPixmap', 'GLXDrawable', 'GLXPbuffer', 'GLXPbufferSGIX', 'GLXWindow',
'GLXFBConfigID', 'GLXContext', 'GLXFBConfig', 'glXChooseVisual',
'glXCopyContext', 'glXCreateContext', 'glXCreateGLXPixmap',
'glXDestroyContext', 'glXDestroyGLXPixmap', 'glXGetConfig',
'glXGetCurrentContext', 'glXGetCurrentDrawable', 'glXIsDirect',
'glXMakeCurrent', 'glXQueryExtension', 'glXQueryVersion', 'glXSwapBuffers',
'glXUseXFont', 'glXWaitGL', 'glXWaitX', 'GLX_VERSION_1_1',
'glXGetClientString', 'glXQueryServerString', 'glXQueryExtensionsString',
'GLX_VERSION_1_2', 'glXGetCurrentDisplay', 'GLX_VERSION_1_3',
'glXChooseFBConfig', 'glXCreateNewContext', 'glXCreatePbuffer',
'glXCreatePixmap', 'glXCreateWindow', 'glXDestroyPbuffer', 'glXDestroyPixmap',
'glXDestroyWindow', 'glXGetCurrentReadDrawable', 'glXGetFBConfigAttrib',
'glXGetFBConfigs', 'glXGetSelectedEvent', 'glXGetVisualFromFBConfig',
'glXMakeContextCurrent', 'glXQueryContext', 'glXQueryDrawable',
'glXSelectEvent', 'PFNGLXGETFBCONFIGSPROC', 'PFNGLXCHOOSEFBCONFIGPROC',
'PFNGLXGETFBCONFIGATTRIBPROC', 'PFNGLXGETVISUALFROMFBCONFIGPROC',
'PFNGLXCREATEWINDOWPROC', 'PFNGLXDESTROYWINDOWPROC', 'PFNGLXCREATEPIXMAPPROC',
'PFNGLXDESTROYPIXMAPPROC', 'PFNGLXCREATEPBUFFERPROC',
'PFNGLXDESTROYPBUFFERPROC', 'PFNGLXQUERYDRAWABLEPROC',
'PFNGLXCREATENEWCONTEXTPROC', 'PFNGLXMAKECONTEXTCURRENTPROC',
'PFNGLXGETCURRENTREADDRAWABLEPROC', 'PFNGLXGETCURRENTDISPLAYPROC',
'PFNGLXQUERYCONTEXTPROC', 'PFNGLXSELECTEVENTPROC',
'PFNGLXGETSELECTEDEVENTPROC', 'GLX_VERSION_1_4', 'glXGetProcAddress',
'PFNGLXGETPROCADDRESSPROC', 'GLX_ARB_get_proc_address',
'glXGetProcAddressARB', 'PFNGLXGETPROCADDRESSARBPROC',
'GLXPbufferClobberEvent', 'GLXEvent']
# END GENERATED CONTENT (do not edit above this line)
# From glxproto.h
GLXBadContext = 0
GLXBadContextState = 1
GLXBadDrawable = 2
GLXBadPixmap = 3
GLXBadContextTag = 4
GLXBadCurrentWindow = 5
GLXBadRenderRequest = 6
GLXBadLargeRequest = 7
GLXUnsupportedPrivateRequest = 8
GLXBadFBConfig = 9
GLXBadPbuffer = 10
GLXBadCurrentDrawable = 11
GLXBadWindow = 12
__all__ += ['GLXBadContext', 'GLXBadContextState', 'GLXBadDrawable',
'GLXBadPixmap', 'GLXBadContextTag', 'GLXBadCurrentWindow',
'GLXBadRenderRequest', 'GLXBadLargeRequest', 'GLXUnsupportedPrivateRequest',
'GLXBadFBConfig', 'GLXBadPbuffer', 'GLXBadCurrentDrawable', 'GLXBadWindow']

143
pyglet/gl/glx_info.py Normal file
View file

@ -0,0 +1,143 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Information about version and extensions of current GLX implementation.
Usage::
from pyglet.gl import glx_info
if glx_info.have_extension('GLX_NV_float_buffer'):
# ...
Or, if using more than one display::
from pyglet.gl.glx_info import GLXInfo
info = GLXInfo(window._display)
if info.get_server_vendor() == 'ATI':
# ...
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: glx_info.py 1579 2008-01-15 14:47:19Z Alex.Holkner $'
from ctypes import *
from pyglet.gl.glx import *
from pyglet.gl.glx import Display
class GLXInfoException(Exception):
pass
class GLXInfo(object):
def __init__(self, display=None):
self.display = display
def set_display(self, display):
self.display = cast(pointer(display), POINTER(Display))
def check_display(self):
if not self.display:
raise GLXInfoException('No X11 display has been set yet.')
def have_version(self, major, minor=0):
self.check_display()
if not glXQueryExtension(self.display, None, None):
raise GLXInfoException('pyglet requires an X server with GLX')
server_version = self.get_server_version().split()[0]
client_version = self.get_client_version().split()[0]
server = [int(i) for i in server_version.split('.')]
client = [int(i) for i in client_version.split('.')]
return (tuple(server) >= (major, minor) and
tuple(client) >= (major, minor))
def get_server_vendor(self):
self.check_display()
return glXQueryServerString(self.display, 0, GLX_VENDOR)
def get_server_version(self):
# glXQueryServerString was introduced in GLX 1.1, so we need to use the
# 1.0 function here which queries the server implementation for its
# version.
self.check_display()
major = c_int()
minor = c_int()
if not glXQueryVersion(self.display, byref(major), byref(minor)):
raise GLXInfoException('Could not determine GLX server version')
return '%s.%s'%(major.value, minor.value)
def get_server_extensions(self):
self.check_display()
return glXQueryServerString(self.display, 0, GLX_EXTENSIONS).split()
def get_client_vendor(self):
self.check_display()
return glXGetClientString(self.display, GLX_VENDOR)
def get_client_version(self):
self.check_display()
return glXGetClientString(self.display, GLX_VERSION)
def get_client_extensions(self):
self.check_display()
return glXGetClientString(self.display, GLX_EXTENSIONS).split()
def get_extensions(self):
self.check_display()
return glXQueryExtensionsString(self.display, 0).split()
def have_extension(self, extension):
self.check_display()
if not self.have_version(1, 1):
return False
return extension in self.get_extensions()
# Single instance suitable for apps that use only a single display.
_glx_info = GLXInfo()
set_display = _glx_info.set_display
check_display = _glx_info.check_display
have_version = _glx_info.have_version
get_server_vendor = _glx_info.get_server_vendor
get_server_version = _glx_info.get_server_version
get_server_extensions = _glx_info.get_server_extensions
get_client_vendor = _glx_info.get_client_vendor
get_client_version = _glx_info.get_client_version
get_client_extensions = _glx_info.get_client_extensions
get_extensions = _glx_info.get_extensions
have_extension = _glx_info.have_extension

756
pyglet/gl/glxext_arb.py Normal file
View file

@ -0,0 +1,756 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Wrapper for http://oss.sgi.com/projects/ogl-sample/ABI/glxext.h
Generated by tools/gengl.py.
Do not modify this file.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: glxext_arb.py 1579 2008-01-15 14:47:19Z Alex.Holkner $'
import ctypes
from ctypes import *
from pyglet.gl.lib import link_GLX as _link_function
from pyglet.gl.lib import c_ptrdiff_t
if not hasattr(ctypes, 'c_int64'):
# XXX TODO completely wrong, but at least can import.
# Can c_longlong still be used?
c_int64 = c_long
c_uint64 = c_ulong
# BEGIN GENERATED CONTENT (do not edit below this line)
# This content is generated by tools/gengl.py.
# Wrapper for http://oss.sgi.com/projects/ogl-sample/ABI/glxext.h
# VERSION_1_3 (/usr/include/GL/glx.h:73)
# VERSION_1_4 (/usr/include/GL/glx.h:132)
# ARB_get_proc_address (/usr/include/GL/glx.h:137)
# VERSION_1_1 (/usr/include/GL/glx.h:209)
# VERSION_1_2 (/usr/include/GL/glx.h:222)
# VERSION_1_3 (/usr/include/GL/glx.h:230)
# VERSION_1_4 (/usr/include/GL/glx.h:302)
# ARB_get_proc_address (/usr/include/GL/glx.h:318)
# GLXEXT_LEGACY (/usr/include/GL/glx.h:350)
GLAPI = 0 # GL/glxext.h:49
GLX_GLXEXT_VERSION = 11 # GL/glxext.h:57
# VERSION_1_3 (GL/glxext.h:59)
# VERSION_1_4 (GL/glxext.h:118)
# ARB_get_proc_address (GL/glxext.h:123)
# ARB_multisample (GL/glxext.h:126)
GLX_SAMPLE_BUFFERS_ARB = 100000 # GL/glxext.h:127
GLX_SAMPLES_ARB = 100001 # GL/glxext.h:128
# ARB_fbconfig_float (GL/glxext.h:131)
GLX_RGBA_FLOAT_TYPE_ARB = 8377 # GL/glxext.h:132
GLX_RGBA_FLOAT_BIT_ARB = 4 # GL/glxext.h:133
# SGIS_multisample (GL/glxext.h:136)
GLX_SAMPLE_BUFFERS_SGIS = 100000 # GL/glxext.h:137
GLX_SAMPLES_SGIS = 100001 # GL/glxext.h:138
# EXT_visual_info (GL/glxext.h:141)
GLX_X_VISUAL_TYPE_EXT = 34 # GL/glxext.h:142
GLX_TRANSPARENT_TYPE_EXT = 35 # GL/glxext.h:143
GLX_TRANSPARENT_INDEX_VALUE_EXT = 36 # GL/glxext.h:144
GLX_TRANSPARENT_RED_VALUE_EXT = 37 # GL/glxext.h:145
GLX_TRANSPARENT_GREEN_VALUE_EXT = 38 # GL/glxext.h:146
GLX_TRANSPARENT_BLUE_VALUE_EXT = 39 # GL/glxext.h:147
GLX_TRANSPARENT_ALPHA_VALUE_EXT = 40 # GL/glxext.h:148
GLX_NONE_EXT = 32768 # GL/glxext.h:149
GLX_TRUE_COLOR_EXT = 32770 # GL/glxext.h:150
GLX_DIRECT_COLOR_EXT = 32771 # GL/glxext.h:151
GLX_PSEUDO_COLOR_EXT = 32772 # GL/glxext.h:152
GLX_STATIC_COLOR_EXT = 32773 # GL/glxext.h:153
GLX_GRAY_SCALE_EXT = 32774 # GL/glxext.h:154
GLX_STATIC_GRAY_EXT = 32775 # GL/glxext.h:155
GLX_TRANSPARENT_RGB_EXT = 32776 # GL/glxext.h:156
GLX_TRANSPARENT_INDEX_EXT = 32777 # GL/glxext.h:157
# SGI_swap_control (GL/glxext.h:160)
# SGI_video_sync (GL/glxext.h:163)
# SGI_make_current_read (GL/glxext.h:166)
# SGIX_video_source (GL/glxext.h:169)
# EXT_visual_rating (GL/glxext.h:172)
GLX_VISUAL_CAVEAT_EXT = 32 # GL/glxext.h:173
GLX_SLOW_VISUAL_EXT = 32769 # GL/glxext.h:174
GLX_NON_CONFORMANT_VISUAL_EXT = 32781 # GL/glxext.h:175
# EXT_import_context (GL/glxext.h:179)
GLX_SHARE_CONTEXT_EXT = 32778 # GL/glxext.h:180
GLX_VISUAL_ID_EXT = 32779 # GL/glxext.h:181
GLX_SCREEN_EXT = 32780 # GL/glxext.h:182
# SGIX_fbconfig (GL/glxext.h:185)
GLX_WINDOW_BIT_SGIX = 1 # GL/glxext.h:186
GLX_PIXMAP_BIT_SGIX = 2 # GL/glxext.h:187
GLX_RGBA_BIT_SGIX = 1 # GL/glxext.h:188
GLX_COLOR_INDEX_BIT_SGIX = 2 # GL/glxext.h:189
GLX_DRAWABLE_TYPE_SGIX = 32784 # GL/glxext.h:190
GLX_RENDER_TYPE_SGIX = 32785 # GL/glxext.h:191
GLX_X_RENDERABLE_SGIX = 32786 # GL/glxext.h:192
GLX_FBCONFIG_ID_SGIX = 32787 # GL/glxext.h:193
GLX_RGBA_TYPE_SGIX = 32788 # GL/glxext.h:194
GLX_COLOR_INDEX_TYPE_SGIX = 32789 # GL/glxext.h:195
# SGIX_pbuffer (GL/glxext.h:199)
GLX_PBUFFER_BIT_SGIX = 4 # GL/glxext.h:200
GLX_BUFFER_CLOBBER_MASK_SGIX = 134217728 # GL/glxext.h:201
GLX_FRONT_LEFT_BUFFER_BIT_SGIX = 1 # GL/glxext.h:202
GLX_FRONT_RIGHT_BUFFER_BIT_SGIX = 2 # GL/glxext.h:203
GLX_BACK_LEFT_BUFFER_BIT_SGIX = 4 # GL/glxext.h:204
GLX_BACK_RIGHT_BUFFER_BIT_SGIX = 8 # GL/glxext.h:205
GLX_AUX_BUFFERS_BIT_SGIX = 16 # GL/glxext.h:206
GLX_DEPTH_BUFFER_BIT_SGIX = 32 # GL/glxext.h:207
GLX_STENCIL_BUFFER_BIT_SGIX = 64 # GL/glxext.h:208
GLX_ACCUM_BUFFER_BIT_SGIX = 128 # GL/glxext.h:209
GLX_SAMPLE_BUFFERS_BIT_SGIX = 256 # GL/glxext.h:210
GLX_MAX_PBUFFER_WIDTH_SGIX = 32790 # GL/glxext.h:211
GLX_MAX_PBUFFER_HEIGHT_SGIX = 32791 # GL/glxext.h:212
GLX_MAX_PBUFFER_PIXELS_SGIX = 32792 # GL/glxext.h:213
GLX_OPTIMAL_PBUFFER_WIDTH_SGIX = 32793 # GL/glxext.h:214
GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX = 32794 # GL/glxext.h:215
GLX_PRESERVED_CONTENTS_SGIX = 32795 # GL/glxext.h:216
GLX_LARGEST_PBUFFER_SGIX = 32796 # GL/glxext.h:217
GLX_WIDTH_SGIX = 32797 # GL/glxext.h:218
GLX_HEIGHT_SGIX = 32798 # GL/glxext.h:219
GLX_EVENT_MASK_SGIX = 32799 # GL/glxext.h:220
GLX_DAMAGED_SGIX = 32800 # GL/glxext.h:221
GLX_SAVED_SGIX = 32801 # GL/glxext.h:222
GLX_WINDOW_SGIX = 32802 # GL/glxext.h:223
GLX_PBUFFER_SGIX = 32803 # GL/glxext.h:224
# SGI_cushion (GL/glxext.h:227)
# SGIX_video_resize (GL/glxext.h:230)
GLX_SYNC_FRAME_SGIX = 0 # GL/glxext.h:231
GLX_SYNC_SWAP_SGIX = 1 # GL/glxext.h:232
# SGIX_dmbuffer (GL/glxext.h:235)
GLX_DIGITAL_MEDIA_PBUFFER_SGIX = 32804 # GL/glxext.h:236
# SGIX_swap_group (GL/glxext.h:239)
# SGIX_swap_barrier (GL/glxext.h:242)
# SGIS_blended_overlay (GL/glxext.h:245)
GLX_BLENDED_RGBA_SGIS = 32805 # GL/glxext.h:246
# SGIS_shared_multisample (GL/glxext.h:249)
GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS = 32806 # GL/glxext.h:250
GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS = 32807 # GL/glxext.h:251
# SUN_get_transparent_index (GL/glxext.h:254)
# 3DFX_multisample (GL/glxext.h:257)
GLX_SAMPLE_BUFFERS_3DFX = 32848 # GL/glxext.h:258
GLX_SAMPLES_3DFX = 32849 # GL/glxext.h:259
# MESA_copy_sub_buffer (GL/glxext.h:262)
# MESA_pixmap_colormap (GL/glxext.h:265)
# MESA_release_buffers (GL/glxext.h:268)
# MESA_set_3dfx_mode (GL/glxext.h:271)
GLX_3DFX_WINDOW_MODE_MESA = 1 # GL/glxext.h:272
GLX_3DFX_FULLSCREEN_MODE_MESA = 2 # GL/glxext.h:273
# SGIX_visual_select_group (GL/glxext.h:276)
GLX_VISUAL_SELECT_GROUP_SGIX = 32808 # GL/glxext.h:277
# OML_swap_method (GL/glxext.h:280)
GLX_SWAP_METHOD_OML = 32864 # GL/glxext.h:281
GLX_SWAP_EXCHANGE_OML = 32865 # GL/glxext.h:282
GLX_SWAP_COPY_OML = 32866 # GL/glxext.h:283
GLX_SWAP_UNDEFINED_OML = 32867 # GL/glxext.h:284
# OML_sync_control (GL/glxext.h:287)
# NV_float_buffer (GL/glxext.h:290)
GLX_FLOAT_COMPONENTS_NV = 8368 # GL/glxext.h:291
# SGIX_hyperpipe (GL/glxext.h:294)
GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX = 80 # GL/glxext.h:295
GLX_BAD_HYPERPIPE_CONFIG_SGIX = 91 # GL/glxext.h:296
GLX_BAD_HYPERPIPE_SGIX = 92 # GL/glxext.h:297
GLX_HYPERPIPE_DISPLAY_PIPE_SGIX = 1 # GL/glxext.h:298
GLX_HYPERPIPE_RENDER_PIPE_SGIX = 2 # GL/glxext.h:299
GLX_PIPE_RECT_SGIX = 1 # GL/glxext.h:300
GLX_PIPE_RECT_LIMITS_SGIX = 2 # GL/glxext.h:301
GLX_HYPERPIPE_STEREO_SGIX = 3 # GL/glxext.h:302
GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX = 4 # GL/glxext.h:303
GLX_HYPERPIPE_ID_SGIX = 32816 # GL/glxext.h:304
# MESA_agp_offset (GL/glxext.h:307)
# ARB_get_proc_address (GL/glxext.h:313)
# SGIX_video_source (GL/glxext.h:317)
XID = c_ulong # /usr/include/X11/X.h:71
GLXVideoSourceSGIX = XID # GL/glxext.h:318
# SGIX_fbconfig (GL/glxext.h:321)
GLXFBConfigIDSGIX = XID # GL/glxext.h:322
class struct___GLXFBConfigRec(Structure):
__slots__ = [
]
struct___GLXFBConfigRec._fields_ = [
('_opaque_struct', c_int)
]
GLXFBConfigSGIX = POINTER(struct___GLXFBConfigRec) # GL/glxext.h:323
# SGIX_pbuffer (GL/glxext.h:326)
class struct_anon_199(Structure):
__slots__ = [
'type',
'serial',
'send_event',
'display',
'drawable',
'event_type',
'draw_type',
'mask',
'x',
'y',
'width',
'height',
'count',
]
class struct__XDisplay(Structure):
__slots__ = [
]
struct__XDisplay._fields_ = [
('_opaque_struct', c_int)
]
Display = struct__XDisplay # /usr/include/X11/Xlib.h:519
GLXDrawable = XID # /usr/include/GL/glx.h:146
struct_anon_199._fields_ = [
('type', c_int),
('serial', c_ulong),
('send_event', c_int),
('display', POINTER(Display)),
('drawable', GLXDrawable),
('event_type', c_int),
('draw_type', c_int),
('mask', c_uint),
('x', c_int),
('y', c_int),
('width', c_int),
('height', c_int),
('count', c_int),
]
GLXBufferClobberEventSGIX = struct_anon_199 # GL/glxext.h:340
# VERSION_1_3 (GL/glxext.h:358)
# VERSION_1_4 (GL/glxext.h:400)
# ARB_get_proc_address (GL/glxext.h:408)
# ARB_multisample (GL/glxext.h:416)
GLX_ARB_multisample = 1 # GL/glxext.h:417
# ARB_fbconfig_float (GL/glxext.h:420)
GLX_ARB_fbconfig_float = 1 # GL/glxext.h:421
# SGIS_multisample (GL/glxext.h:424)
GLX_SGIS_multisample = 1 # GL/glxext.h:425
# EXT_visual_info (GL/glxext.h:428)
GLX_EXT_visual_info = 1 # GL/glxext.h:429
# SGI_swap_control (GL/glxext.h:432)
GLX_SGI_swap_control = 1 # GL/glxext.h:433
# GL/glxext.h:435
glXSwapIntervalSGI = _link_function('glXSwapIntervalSGI', c_int, [c_int], 'SGI_swap_control')
PFNGLXSWAPINTERVALSGIPROC = CFUNCTYPE(c_int, c_int) # GL/glxext.h:437
# SGI_video_sync (GL/glxext.h:440)
GLX_SGI_video_sync = 1 # GL/glxext.h:441
# GL/glxext.h:443
glXGetVideoSyncSGI = _link_function('glXGetVideoSyncSGI', c_int, [POINTER(c_uint)], 'SGI_video_sync')
# GL/glxext.h:444
glXWaitVideoSyncSGI = _link_function('glXWaitVideoSyncSGI', c_int, [c_int, c_int, POINTER(c_uint)], 'SGI_video_sync')
PFNGLXGETVIDEOSYNCSGIPROC = CFUNCTYPE(c_int, POINTER(c_uint)) # GL/glxext.h:446
PFNGLXWAITVIDEOSYNCSGIPROC = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_uint)) # GL/glxext.h:447
# SGI_make_current_read (GL/glxext.h:450)
GLX_SGI_make_current_read = 1 # GL/glxext.h:451
class struct___GLXcontextRec(Structure):
__slots__ = [
]
struct___GLXcontextRec._fields_ = [
('_opaque_struct', c_int)
]
GLXContext = POINTER(struct___GLXcontextRec) # /usr/include/GL/glx.h:155
# GL/glxext.h:453
glXMakeCurrentReadSGI = _link_function('glXMakeCurrentReadSGI', c_int, [POINTER(Display), GLXDrawable, GLXDrawable, GLXContext], 'SGI_make_current_read')
# GL/glxext.h:454
glXGetCurrentReadDrawableSGI = _link_function('glXGetCurrentReadDrawableSGI', GLXDrawable, [], 'SGI_make_current_read')
PFNGLXMAKECURRENTREADSGIPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, GLXDrawable, GLXContext) # GL/glxext.h:456
PFNGLXGETCURRENTREADDRAWABLESGIPROC = CFUNCTYPE(GLXDrawable) # GL/glxext.h:457
# SGIX_video_source (GL/glxext.h:460)
GLX_SGIX_video_source = 1 # GL/glxext.h:461
# EXT_visual_rating (GL/glxext.h:472)
GLX_EXT_visual_rating = 1 # GL/glxext.h:473
# EXT_import_context (GL/glxext.h:476)
GLX_EXT_import_context = 1 # GL/glxext.h:477
# GL/glxext.h:479
glXGetCurrentDisplayEXT = _link_function('glXGetCurrentDisplayEXT', POINTER(Display), [], 'EXT_import_context')
# GL/glxext.h:480
glXQueryContextInfoEXT = _link_function('glXQueryContextInfoEXT', c_int, [POINTER(Display), GLXContext, c_int, POINTER(c_int)], 'EXT_import_context')
GLXContextID = XID # /usr/include/GL/glx.h:144
# GL/glxext.h:481
glXGetContextIDEXT = _link_function('glXGetContextIDEXT', GLXContextID, [GLXContext], 'EXT_import_context')
# GL/glxext.h:482
glXImportContextEXT = _link_function('glXImportContextEXT', GLXContext, [POINTER(Display), GLXContextID], 'EXT_import_context')
# GL/glxext.h:483
glXFreeContextEXT = _link_function('glXFreeContextEXT', None, [POINTER(Display), GLXContext], 'EXT_import_context')
PFNGLXGETCURRENTDISPLAYEXTPROC = CFUNCTYPE(POINTER(Display)) # GL/glxext.h:485
PFNGLXQUERYCONTEXTINFOEXTPROC = CFUNCTYPE(c_int, POINTER(Display), GLXContext, c_int, POINTER(c_int)) # GL/glxext.h:486
PFNGLXGETCONTEXTIDEXTPROC = CFUNCTYPE(GLXContextID, GLXContext) # GL/glxext.h:487
PFNGLXIMPORTCONTEXTEXTPROC = CFUNCTYPE(GLXContext, POINTER(Display), GLXContextID) # GL/glxext.h:488
PFNGLXFREECONTEXTEXTPROC = CFUNCTYPE(None, POINTER(Display), GLXContext) # GL/glxext.h:489
# SGIX_fbconfig (GL/glxext.h:492)
GLX_SGIX_fbconfig = 1 # GL/glxext.h:493
# GL/glxext.h:495
glXGetFBConfigAttribSGIX = _link_function('glXGetFBConfigAttribSGIX', c_int, [POINTER(Display), GLXFBConfigSGIX, c_int, POINTER(c_int)], 'SGIX_fbconfig')
# GL/glxext.h:496
glXChooseFBConfigSGIX = _link_function('glXChooseFBConfigSGIX', POINTER(GLXFBConfigSGIX), [POINTER(Display), c_int, POINTER(c_int), POINTER(c_int)], 'SGIX_fbconfig')
GLXPixmap = XID # /usr/include/GL/glx.h:145
Pixmap = XID # /usr/include/X11/X.h:107
# GL/glxext.h:497
glXCreateGLXPixmapWithConfigSGIX = _link_function('glXCreateGLXPixmapWithConfigSGIX', GLXPixmap, [POINTER(Display), GLXFBConfigSGIX, Pixmap], 'SGIX_fbconfig')
# GL/glxext.h:498
glXCreateContextWithConfigSGIX = _link_function('glXCreateContextWithConfigSGIX', GLXContext, [POINTER(Display), GLXFBConfigSGIX, c_int, GLXContext, c_int], 'SGIX_fbconfig')
class struct_anon_196(Structure):
__slots__ = [
'visual',
'visualid',
'screen',
'depth',
'class',
'red_mask',
'green_mask',
'blue_mask',
'colormap_size',
'bits_per_rgb',
]
class struct_anon_113(Structure):
__slots__ = [
'ext_data',
'visualid',
'class',
'red_mask',
'green_mask',
'blue_mask',
'bits_per_rgb',
'map_entries',
]
class struct__XExtData(Structure):
__slots__ = [
'number',
'next',
'free_private',
'private_data',
]
XPointer = c_char_p # /usr/include/X11/Xlib.h:108
struct__XExtData._fields_ = [
('number', c_int),
('next', POINTER(struct__XExtData)),
('free_private', POINTER(CFUNCTYPE(c_int, POINTER(struct__XExtData)))),
('private_data', XPointer),
]
XExtData = struct__XExtData # /usr/include/X11/Xlib.h:187
VisualID = c_ulong # /usr/include/X11/X.h:81
struct_anon_113._fields_ = [
('ext_data', POINTER(XExtData)),
('visualid', VisualID),
('class', c_int),
('red_mask', c_ulong),
('green_mask', c_ulong),
('blue_mask', c_ulong),
('bits_per_rgb', c_int),
('map_entries', c_int),
]
Visual = struct_anon_113 # /usr/include/X11/Xlib.h:270
struct_anon_196._fields_ = [
('visual', POINTER(Visual)),
('visualid', VisualID),
('screen', c_int),
('depth', c_int),
('class', c_int),
('red_mask', c_ulong),
('green_mask', c_ulong),
('blue_mask', c_ulong),
('colormap_size', c_int),
('bits_per_rgb', c_int),
]
XVisualInfo = struct_anon_196 # /usr/include/X11/Xutil.h:296
# GL/glxext.h:499
glXGetVisualFromFBConfigSGIX = _link_function('glXGetVisualFromFBConfigSGIX', POINTER(XVisualInfo), [POINTER(Display), GLXFBConfigSGIX], 'SGIX_fbconfig')
# GL/glxext.h:500
glXGetFBConfigFromVisualSGIX = _link_function('glXGetFBConfigFromVisualSGIX', GLXFBConfigSGIX, [POINTER(Display), POINTER(XVisualInfo)], 'SGIX_fbconfig')
PFNGLXGETFBCONFIGATTRIBSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), GLXFBConfigSGIX, c_int, POINTER(c_int)) # GL/glxext.h:502
PFNGLXCHOOSEFBCONFIGSGIXPROC = CFUNCTYPE(POINTER(GLXFBConfigSGIX), POINTER(Display), c_int, POINTER(c_int), POINTER(c_int)) # GL/glxext.h:503
PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC = CFUNCTYPE(GLXPixmap, POINTER(Display), GLXFBConfigSGIX, Pixmap) # GL/glxext.h:504
PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC = CFUNCTYPE(GLXContext, POINTER(Display), GLXFBConfigSGIX, c_int, GLXContext, c_int) # GL/glxext.h:505
PFNGLXGETVISUALFROMFBCONFIGSGIXPROC = CFUNCTYPE(POINTER(XVisualInfo), POINTER(Display), GLXFBConfigSGIX) # GL/glxext.h:506
PFNGLXGETFBCONFIGFROMVISUALSGIXPROC = CFUNCTYPE(GLXFBConfigSGIX, POINTER(Display), POINTER(XVisualInfo)) # GL/glxext.h:507
# SGIX_pbuffer (GL/glxext.h:510)
GLX_SGIX_pbuffer = 1 # GL/glxext.h:511
GLXPbufferSGIX = XID # /usr/include/GL/glx.h:148
# GL/glxext.h:513
glXCreateGLXPbufferSGIX = _link_function('glXCreateGLXPbufferSGIX', GLXPbufferSGIX, [POINTER(Display), GLXFBConfigSGIX, c_uint, c_uint, POINTER(c_int)], 'SGIX_pbuffer')
# GL/glxext.h:514
glXDestroyGLXPbufferSGIX = _link_function('glXDestroyGLXPbufferSGIX', None, [POINTER(Display), GLXPbufferSGIX], 'SGIX_pbuffer')
# GL/glxext.h:515
glXQueryGLXPbufferSGIX = _link_function('glXQueryGLXPbufferSGIX', c_int, [POINTER(Display), GLXPbufferSGIX, c_int, POINTER(c_uint)], 'SGIX_pbuffer')
# GL/glxext.h:516
glXSelectEventSGIX = _link_function('glXSelectEventSGIX', None, [POINTER(Display), GLXDrawable, c_ulong], 'SGIX_pbuffer')
# GL/glxext.h:517
glXGetSelectedEventSGIX = _link_function('glXGetSelectedEventSGIX', None, [POINTER(Display), GLXDrawable, POINTER(c_ulong)], 'SGIX_pbuffer')
PFNGLXCREATEGLXPBUFFERSGIXPROC = CFUNCTYPE(GLXPbufferSGIX, POINTER(Display), GLXFBConfigSGIX, c_uint, c_uint, POINTER(c_int)) # GL/glxext.h:519
PFNGLXDESTROYGLXPBUFFERSGIXPROC = CFUNCTYPE(None, POINTER(Display), GLXPbufferSGIX) # GL/glxext.h:520
PFNGLXQUERYGLXPBUFFERSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), GLXPbufferSGIX, c_int, POINTER(c_uint)) # GL/glxext.h:521
PFNGLXSELECTEVENTSGIXPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, c_ulong) # GL/glxext.h:522
PFNGLXGETSELECTEDEVENTSGIXPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, POINTER(c_ulong)) # GL/glxext.h:523
# SGI_cushion (GL/glxext.h:526)
GLX_SGI_cushion = 1 # GL/glxext.h:527
Window = XID # /usr/include/X11/X.h:101
# GL/glxext.h:529
glXCushionSGI = _link_function('glXCushionSGI', None, [POINTER(Display), Window, c_float], 'SGI_cushion')
PFNGLXCUSHIONSGIPROC = CFUNCTYPE(None, POINTER(Display), Window, c_float) # GL/glxext.h:531
# SGIX_video_resize (GL/glxext.h:534)
GLX_SGIX_video_resize = 1 # GL/glxext.h:535
# GL/glxext.h:537
glXBindChannelToWindowSGIX = _link_function('glXBindChannelToWindowSGIX', c_int, [POINTER(Display), c_int, c_int, Window], 'SGIX_video_resize')
# GL/glxext.h:538
glXChannelRectSGIX = _link_function('glXChannelRectSGIX', c_int, [POINTER(Display), c_int, c_int, c_int, c_int, c_int, c_int], 'SGIX_video_resize')
# GL/glxext.h:539
glXQueryChannelRectSGIX = _link_function('glXQueryChannelRectSGIX', c_int, [POINTER(Display), c_int, c_int, POINTER(c_int), POINTER(c_int), POINTER(c_int), POINTER(c_int)], 'SGIX_video_resize')
# GL/glxext.h:540
glXQueryChannelDeltasSGIX = _link_function('glXQueryChannelDeltasSGIX', c_int, [POINTER(Display), c_int, c_int, POINTER(c_int), POINTER(c_int), POINTER(c_int), POINTER(c_int)], 'SGIX_video_resize')
GLenum = c_uint # /usr/include/GL/gl.h:53
# GL/glxext.h:541
glXChannelRectSyncSGIX = _link_function('glXChannelRectSyncSGIX', c_int, [POINTER(Display), c_int, c_int, GLenum], 'SGIX_video_resize')
PFNGLXBINDCHANNELTOWINDOWSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, Window) # GL/glxext.h:543
PFNGLXCHANNELRECTSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, c_int, c_int, c_int, c_int) # GL/glxext.h:544
PFNGLXQUERYCHANNELRECTSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, POINTER(c_int), POINTER(c_int), POINTER(c_int), POINTER(c_int)) # GL/glxext.h:545
PFNGLXQUERYCHANNELDELTASSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, POINTER(c_int), POINTER(c_int), POINTER(c_int), POINTER(c_int)) # GL/glxext.h:546
PFNGLXCHANNELRECTSYNCSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, GLenum) # GL/glxext.h:547
# SGIX_dmbuffer (GL/glxext.h:550)
GLX_SGIX_dmbuffer = 1 # GL/glxext.h:551
# SGIX_swap_group (GL/glxext.h:560)
GLX_SGIX_swap_group = 1 # GL/glxext.h:561
# GL/glxext.h:563
glXJoinSwapGroupSGIX = _link_function('glXJoinSwapGroupSGIX', None, [POINTER(Display), GLXDrawable, GLXDrawable], 'SGIX_swap_group')
PFNGLXJOINSWAPGROUPSGIXPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, GLXDrawable) # GL/glxext.h:565
# SGIX_swap_barrier (GL/glxext.h:568)
GLX_SGIX_swap_barrier = 1 # GL/glxext.h:569
# GL/glxext.h:571
glXBindSwapBarrierSGIX = _link_function('glXBindSwapBarrierSGIX', None, [POINTER(Display), GLXDrawable, c_int], 'SGIX_swap_barrier')
# GL/glxext.h:572
glXQueryMaxSwapBarriersSGIX = _link_function('glXQueryMaxSwapBarriersSGIX', c_int, [POINTER(Display), c_int, POINTER(c_int)], 'SGIX_swap_barrier')
PFNGLXBINDSWAPBARRIERSGIXPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, c_int) # GL/glxext.h:574
PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, POINTER(c_int)) # GL/glxext.h:575
# SUN_get_transparent_index (GL/glxext.h:578)
GLX_SUN_get_transparent_index = 1 # GL/glxext.h:579
# GL/glxext.h:581
glXGetTransparentIndexSUN = _link_function('glXGetTransparentIndexSUN', c_int, [POINTER(Display), Window, Window, POINTER(c_long)], 'SUN_get_transparent_index')
PFNGLXGETTRANSPARENTINDEXSUNPROC = CFUNCTYPE(c_int, POINTER(Display), Window, Window, POINTER(c_long)) # GL/glxext.h:583
# MESA_copy_sub_buffer (GL/glxext.h:586)
GLX_MESA_copy_sub_buffer = 1 # GL/glxext.h:587
# GL/glxext.h:589
glXCopySubBufferMESA = _link_function('glXCopySubBufferMESA', None, [POINTER(Display), GLXDrawable, c_int, c_int, c_int, c_int], 'MESA_copy_sub_buffer')
PFNGLXCOPYSUBBUFFERMESAPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, c_int, c_int, c_int, c_int) # GL/glxext.h:591
# MESA_pixmap_colormap (GL/glxext.h:594)
GLX_MESA_pixmap_colormap = 1 # GL/glxext.h:595
Colormap = XID # /usr/include/X11/X.h:109
# GL/glxext.h:597
glXCreateGLXPixmapMESA = _link_function('glXCreateGLXPixmapMESA', GLXPixmap, [POINTER(Display), POINTER(XVisualInfo), Pixmap, Colormap], 'MESA_pixmap_colormap')
PFNGLXCREATEGLXPIXMAPMESAPROC = CFUNCTYPE(GLXPixmap, POINTER(Display), POINTER(XVisualInfo), Pixmap, Colormap) # GL/glxext.h:599
# MESA_release_buffers (GL/glxext.h:602)
GLX_MESA_release_buffers = 1 # GL/glxext.h:603
# GL/glxext.h:605
glXReleaseBuffersMESA = _link_function('glXReleaseBuffersMESA', c_int, [POINTER(Display), GLXDrawable], 'MESA_release_buffers')
PFNGLXRELEASEBUFFERSMESAPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable) # GL/glxext.h:607
# MESA_set_3dfx_mode (GL/glxext.h:610)
GLX_MESA_set_3dfx_mode = 1 # GL/glxext.h:611
# GL/glxext.h:613
glXSet3DfxModeMESA = _link_function('glXSet3DfxModeMESA', c_int, [c_int], 'MESA_set_3dfx_mode')
PFNGLXSET3DFXMODEMESAPROC = CFUNCTYPE(c_int, c_int) # GL/glxext.h:615
# SGIX_visual_select_group (GL/glxext.h:618)
GLX_SGIX_visual_select_group = 1 # GL/glxext.h:619
# OML_swap_method (GL/glxext.h:622)
GLX_OML_swap_method = 1 # GL/glxext.h:623
# OML_sync_control (GL/glxext.h:626)
GLX_OML_sync_control = 1 # GL/glxext.h:627
# GL/glxext.h:629
glXGetSyncValuesOML = _link_function('glXGetSyncValuesOML', c_int, [POINTER(Display), GLXDrawable, POINTER(c_int64), POINTER(c_int64), POINTER(c_int64)], 'OML_sync_control')
# GL/glxext.h:630
glXGetMscRateOML = _link_function('glXGetMscRateOML', c_int, [POINTER(Display), GLXDrawable, POINTER(c_int32), POINTER(c_int32)], 'OML_sync_control')
# GL/glxext.h:631
glXSwapBuffersMscOML = _link_function('glXSwapBuffersMscOML', c_int64, [POINTER(Display), GLXDrawable, c_int64, c_int64, c_int64], 'OML_sync_control')
# GL/glxext.h:632
glXWaitForMscOML = _link_function('glXWaitForMscOML', c_int, [POINTER(Display), GLXDrawable, c_int64, c_int64, c_int64, POINTER(c_int64), POINTER(c_int64), POINTER(c_int64)], 'OML_sync_control')
# GL/glxext.h:633
glXWaitForSbcOML = _link_function('glXWaitForSbcOML', c_int, [POINTER(Display), GLXDrawable, c_int64, POINTER(c_int64), POINTER(c_int64), POINTER(c_int64)], 'OML_sync_control')
PFNGLXGETSYNCVALUESOMLPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, POINTER(c_int64), POINTER(c_int64), POINTER(c_int64)) # GL/glxext.h:635
PFNGLXGETMSCRATEOMLPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, POINTER(c_int32), POINTER(c_int32)) # GL/glxext.h:636
PFNGLXSWAPBUFFERSMSCOMLPROC = CFUNCTYPE(c_int64, POINTER(Display), GLXDrawable, c_int64, c_int64, c_int64) # GL/glxext.h:637
PFNGLXWAITFORMSCOMLPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, c_int64, c_int64, c_int64, POINTER(c_int64), POINTER(c_int64), POINTER(c_int64)) # GL/glxext.h:638
PFNGLXWAITFORSBCOMLPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, c_int64, POINTER(c_int64), POINTER(c_int64), POINTER(c_int64)) # GL/glxext.h:639
# NV_float_buffer (GL/glxext.h:642)
GLX_NV_float_buffer = 1 # GL/glxext.h:643
# SGIX_hyperpipe (GL/glxext.h:646)
GLX_SGIX_hyperpipe = 1 # GL/glxext.h:647
class struct_anon_201(Structure):
__slots__ = [
'pipeName',
'networkId',
]
struct_anon_201._fields_ = [
('pipeName', c_char * 80),
('networkId', c_int),
]
GLXHyperpipeNetworkSGIX = struct_anon_201 # GL/glxext.h:652
class struct_anon_202(Structure):
__slots__ = [
'pipeName',
'channel',
'participationType',
'timeSlice',
]
struct_anon_202._fields_ = [
('pipeName', c_char * 80),
('channel', c_int),
('participationType', c_uint),
('timeSlice', c_int),
]
GLXHyperpipeConfigSGIX = struct_anon_202 # GL/glxext.h:660
class struct_anon_203(Structure):
__slots__ = [
'pipeName',
'srcXOrigin',
'srcYOrigin',
'srcWidth',
'srcHeight',
'destXOrigin',
'destYOrigin',
'destWidth',
'destHeight',
]
struct_anon_203._fields_ = [
('pipeName', c_char * 80),
('srcXOrigin', c_int),
('srcYOrigin', c_int),
('srcWidth', c_int),
('srcHeight', c_int),
('destXOrigin', c_int),
('destYOrigin', c_int),
('destWidth', c_int),
('destHeight', c_int),
]
GLXPipeRect = struct_anon_203 # GL/glxext.h:666
class struct_anon_204(Structure):
__slots__ = [
'pipeName',
'XOrigin',
'YOrigin',
'maxHeight',
'maxWidth',
]
struct_anon_204._fields_ = [
('pipeName', c_char * 80),
('XOrigin', c_int),
('YOrigin', c_int),
('maxHeight', c_int),
('maxWidth', c_int),
]
GLXPipeRectLimits = struct_anon_204 # GL/glxext.h:671
# GL/glxext.h:674
glXQueryHyperpipeNetworkSGIX = _link_function('glXQueryHyperpipeNetworkSGIX', POINTER(GLXHyperpipeNetworkSGIX), [POINTER(Display), POINTER(c_int)], 'SGIX_hyperpipe')
# GL/glxext.h:675
glXHyperpipeConfigSGIX = _link_function('glXHyperpipeConfigSGIX', c_int, [POINTER(Display), c_int, c_int, POINTER(GLXHyperpipeConfigSGIX), POINTER(c_int)], 'SGIX_hyperpipe')
# GL/glxext.h:676
glXQueryHyperpipeConfigSGIX = _link_function('glXQueryHyperpipeConfigSGIX', POINTER(GLXHyperpipeConfigSGIX), [POINTER(Display), c_int, POINTER(c_int)], 'SGIX_hyperpipe')
# GL/glxext.h:677
glXDestroyHyperpipeConfigSGIX = _link_function('glXDestroyHyperpipeConfigSGIX', c_int, [POINTER(Display), c_int], 'SGIX_hyperpipe')
# GL/glxext.h:678
glXBindHyperpipeSGIX = _link_function('glXBindHyperpipeSGIX', c_int, [POINTER(Display), c_int], 'SGIX_hyperpipe')
# GL/glxext.h:679
glXQueryHyperpipeBestAttribSGIX = _link_function('glXQueryHyperpipeBestAttribSGIX', c_int, [POINTER(Display), c_int, c_int, c_int, POINTER(None), POINTER(None)], 'SGIX_hyperpipe')
# GL/glxext.h:680
glXHyperpipeAttribSGIX = _link_function('glXHyperpipeAttribSGIX', c_int, [POINTER(Display), c_int, c_int, c_int, POINTER(None)], 'SGIX_hyperpipe')
# GL/glxext.h:681
glXQueryHyperpipeAttribSGIX = _link_function('glXQueryHyperpipeAttribSGIX', c_int, [POINTER(Display), c_int, c_int, c_int, POINTER(None)], 'SGIX_hyperpipe')
PFNGLXQUERYHYPERPIPENETWORKSGIXPROC = CFUNCTYPE(POINTER(GLXHyperpipeNetworkSGIX), POINTER(Display), POINTER(c_int)) # GL/glxext.h:683
PFNGLXHYPERPIPECONFIGSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, POINTER(GLXHyperpipeConfigSGIX), POINTER(c_int)) # GL/glxext.h:684
PFNGLXQUERYHYPERPIPECONFIGSGIXPROC = CFUNCTYPE(POINTER(GLXHyperpipeConfigSGIX), POINTER(Display), c_int, POINTER(c_int)) # GL/glxext.h:685
PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int) # GL/glxext.h:686
PFNGLXBINDHYPERPIPESGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int) # GL/glxext.h:687
PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, c_int, POINTER(None), POINTER(None)) # GL/glxext.h:688
PFNGLXHYPERPIPEATTRIBSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, c_int, POINTER(None)) # GL/glxext.h:689
PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, c_int, POINTER(None)) # GL/glxext.h:690
# MESA_agp_offset (GL/glxext.h:693)
GLX_MESA_agp_offset = 1 # GL/glxext.h:694
# GL/glxext.h:696
glXGetAGPOffsetMESA = _link_function('glXGetAGPOffsetMESA', c_uint, [POINTER(None)], 'MESA_agp_offset')
PFNGLXGETAGPOFFSETMESAPROC = CFUNCTYPE(c_uint, POINTER(None)) # GL/glxext.h:698
__all__ = ['GLAPI', 'GLX_GLXEXT_VERSION', 'GLX_SAMPLE_BUFFERS_ARB',
'GLX_SAMPLES_ARB', 'GLX_RGBA_FLOAT_TYPE_ARB', 'GLX_RGBA_FLOAT_BIT_ARB',
'GLX_SAMPLE_BUFFERS_SGIS', 'GLX_SAMPLES_SGIS', 'GLX_X_VISUAL_TYPE_EXT',
'GLX_TRANSPARENT_TYPE_EXT', 'GLX_TRANSPARENT_INDEX_VALUE_EXT',
'GLX_TRANSPARENT_RED_VALUE_EXT', 'GLX_TRANSPARENT_GREEN_VALUE_EXT',
'GLX_TRANSPARENT_BLUE_VALUE_EXT', 'GLX_TRANSPARENT_ALPHA_VALUE_EXT',
'GLX_NONE_EXT', 'GLX_TRUE_COLOR_EXT', 'GLX_DIRECT_COLOR_EXT',
'GLX_PSEUDO_COLOR_EXT', 'GLX_STATIC_COLOR_EXT', 'GLX_GRAY_SCALE_EXT',
'GLX_STATIC_GRAY_EXT', 'GLX_TRANSPARENT_RGB_EXT', 'GLX_TRANSPARENT_INDEX_EXT',
'GLX_VISUAL_CAVEAT_EXT', 'GLX_SLOW_VISUAL_EXT',
'GLX_NON_CONFORMANT_VISUAL_EXT', 'GLX_SHARE_CONTEXT_EXT', 'GLX_VISUAL_ID_EXT',
'GLX_SCREEN_EXT', 'GLX_WINDOW_BIT_SGIX', 'GLX_PIXMAP_BIT_SGIX',
'GLX_RGBA_BIT_SGIX', 'GLX_COLOR_INDEX_BIT_SGIX', 'GLX_DRAWABLE_TYPE_SGIX',
'GLX_RENDER_TYPE_SGIX', 'GLX_X_RENDERABLE_SGIX', 'GLX_FBCONFIG_ID_SGIX',
'GLX_RGBA_TYPE_SGIX', 'GLX_COLOR_INDEX_TYPE_SGIX', 'GLX_PBUFFER_BIT_SGIX',
'GLX_BUFFER_CLOBBER_MASK_SGIX', 'GLX_FRONT_LEFT_BUFFER_BIT_SGIX',
'GLX_FRONT_RIGHT_BUFFER_BIT_SGIX', 'GLX_BACK_LEFT_BUFFER_BIT_SGIX',
'GLX_BACK_RIGHT_BUFFER_BIT_SGIX', 'GLX_AUX_BUFFERS_BIT_SGIX',
'GLX_DEPTH_BUFFER_BIT_SGIX', 'GLX_STENCIL_BUFFER_BIT_SGIX',
'GLX_ACCUM_BUFFER_BIT_SGIX', 'GLX_SAMPLE_BUFFERS_BIT_SGIX',
'GLX_MAX_PBUFFER_WIDTH_SGIX', 'GLX_MAX_PBUFFER_HEIGHT_SGIX',
'GLX_MAX_PBUFFER_PIXELS_SGIX', 'GLX_OPTIMAL_PBUFFER_WIDTH_SGIX',
'GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX', 'GLX_PRESERVED_CONTENTS_SGIX',
'GLX_LARGEST_PBUFFER_SGIX', 'GLX_WIDTH_SGIX', 'GLX_HEIGHT_SGIX',
'GLX_EVENT_MASK_SGIX', 'GLX_DAMAGED_SGIX', 'GLX_SAVED_SGIX',
'GLX_WINDOW_SGIX', 'GLX_PBUFFER_SGIX', 'GLX_SYNC_FRAME_SGIX',
'GLX_SYNC_SWAP_SGIX', 'GLX_DIGITAL_MEDIA_PBUFFER_SGIX',
'GLX_BLENDED_RGBA_SGIS', 'GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS',
'GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS', 'GLX_SAMPLE_BUFFERS_3DFX',
'GLX_SAMPLES_3DFX', 'GLX_3DFX_WINDOW_MODE_MESA',
'GLX_3DFX_FULLSCREEN_MODE_MESA', 'GLX_VISUAL_SELECT_GROUP_SGIX',
'GLX_SWAP_METHOD_OML', 'GLX_SWAP_EXCHANGE_OML', 'GLX_SWAP_COPY_OML',
'GLX_SWAP_UNDEFINED_OML', 'GLX_FLOAT_COMPONENTS_NV',
'GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX', 'GLX_BAD_HYPERPIPE_CONFIG_SGIX',
'GLX_BAD_HYPERPIPE_SGIX', 'GLX_HYPERPIPE_DISPLAY_PIPE_SGIX',
'GLX_HYPERPIPE_RENDER_PIPE_SGIX', 'GLX_PIPE_RECT_SGIX',
'GLX_PIPE_RECT_LIMITS_SGIX', 'GLX_HYPERPIPE_STEREO_SGIX',
'GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX', 'GLX_HYPERPIPE_ID_SGIX',
'GLXVideoSourceSGIX', 'GLXFBConfigIDSGIX', 'GLXFBConfigSGIX',
'GLXBufferClobberEventSGIX', 'GLX_ARB_multisample', 'GLX_ARB_fbconfig_float',
'GLX_SGIS_multisample', 'GLX_EXT_visual_info', 'GLX_SGI_swap_control',
'glXSwapIntervalSGI', 'PFNGLXSWAPINTERVALSGIPROC', 'GLX_SGI_video_sync',
'glXGetVideoSyncSGI', 'glXWaitVideoSyncSGI', 'PFNGLXGETVIDEOSYNCSGIPROC',
'PFNGLXWAITVIDEOSYNCSGIPROC', 'GLX_SGI_make_current_read',
'glXMakeCurrentReadSGI', 'glXGetCurrentReadDrawableSGI',
'PFNGLXMAKECURRENTREADSGIPROC', 'PFNGLXGETCURRENTREADDRAWABLESGIPROC',
'GLX_SGIX_video_source', 'GLX_EXT_visual_rating', 'GLX_EXT_import_context',
'glXGetCurrentDisplayEXT', 'glXQueryContextInfoEXT', 'glXGetContextIDEXT',
'glXImportContextEXT', 'glXFreeContextEXT', 'PFNGLXGETCURRENTDISPLAYEXTPROC',
'PFNGLXQUERYCONTEXTINFOEXTPROC', 'PFNGLXGETCONTEXTIDEXTPROC',
'PFNGLXIMPORTCONTEXTEXTPROC', 'PFNGLXFREECONTEXTEXTPROC', 'GLX_SGIX_fbconfig',
'glXGetFBConfigAttribSGIX', 'glXChooseFBConfigSGIX',
'glXCreateGLXPixmapWithConfigSGIX', 'glXCreateContextWithConfigSGIX',
'glXGetVisualFromFBConfigSGIX', 'glXGetFBConfigFromVisualSGIX',
'PFNGLXGETFBCONFIGATTRIBSGIXPROC', 'PFNGLXCHOOSEFBCONFIGSGIXPROC',
'PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC',
'PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC',
'PFNGLXGETVISUALFROMFBCONFIGSGIXPROC', 'PFNGLXGETFBCONFIGFROMVISUALSGIXPROC',
'GLX_SGIX_pbuffer', 'glXCreateGLXPbufferSGIX', 'glXDestroyGLXPbufferSGIX',
'glXQueryGLXPbufferSGIX', 'glXSelectEventSGIX', 'glXGetSelectedEventSGIX',
'PFNGLXCREATEGLXPBUFFERSGIXPROC', 'PFNGLXDESTROYGLXPBUFFERSGIXPROC',
'PFNGLXQUERYGLXPBUFFERSGIXPROC', 'PFNGLXSELECTEVENTSGIXPROC',
'PFNGLXGETSELECTEDEVENTSGIXPROC', 'GLX_SGI_cushion', 'glXCushionSGI',
'PFNGLXCUSHIONSGIPROC', 'GLX_SGIX_video_resize', 'glXBindChannelToWindowSGIX',
'glXChannelRectSGIX', 'glXQueryChannelRectSGIX', 'glXQueryChannelDeltasSGIX',
'glXChannelRectSyncSGIX', 'PFNGLXBINDCHANNELTOWINDOWSGIXPROC',
'PFNGLXCHANNELRECTSGIXPROC', 'PFNGLXQUERYCHANNELRECTSGIXPROC',
'PFNGLXQUERYCHANNELDELTASSGIXPROC', 'PFNGLXCHANNELRECTSYNCSGIXPROC',
'GLX_SGIX_dmbuffer', 'GLX_SGIX_swap_group', 'glXJoinSwapGroupSGIX',
'PFNGLXJOINSWAPGROUPSGIXPROC', 'GLX_SGIX_swap_barrier',
'glXBindSwapBarrierSGIX', 'glXQueryMaxSwapBarriersSGIX',
'PFNGLXBINDSWAPBARRIERSGIXPROC', 'PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC',
'GLX_SUN_get_transparent_index', 'glXGetTransparentIndexSUN',
'PFNGLXGETTRANSPARENTINDEXSUNPROC', 'GLX_MESA_copy_sub_buffer',
'glXCopySubBufferMESA', 'PFNGLXCOPYSUBBUFFERMESAPROC',
'GLX_MESA_pixmap_colormap', 'glXCreateGLXPixmapMESA',
'PFNGLXCREATEGLXPIXMAPMESAPROC', 'GLX_MESA_release_buffers',
'glXReleaseBuffersMESA', 'PFNGLXRELEASEBUFFERSMESAPROC',
'GLX_MESA_set_3dfx_mode', 'glXSet3DfxModeMESA', 'PFNGLXSET3DFXMODEMESAPROC',
'GLX_SGIX_visual_select_group', 'GLX_OML_swap_method', 'GLX_OML_sync_control',
'glXGetSyncValuesOML', 'glXGetMscRateOML', 'glXSwapBuffersMscOML',
'glXWaitForMscOML', 'glXWaitForSbcOML', 'PFNGLXGETSYNCVALUESOMLPROC',
'PFNGLXGETMSCRATEOMLPROC', 'PFNGLXSWAPBUFFERSMSCOMLPROC',
'PFNGLXWAITFORMSCOMLPROC', 'PFNGLXWAITFORSBCOMLPROC', 'GLX_NV_float_buffer',
'GLX_SGIX_hyperpipe', 'GLXHyperpipeNetworkSGIX', 'GLXHyperpipeConfigSGIX',
'GLXPipeRect', 'GLXPipeRectLimits', 'glXQueryHyperpipeNetworkSGIX',
'glXHyperpipeConfigSGIX', 'glXQueryHyperpipeConfigSGIX',
'glXDestroyHyperpipeConfigSGIX', 'glXBindHyperpipeSGIX',
'glXQueryHyperpipeBestAttribSGIX', 'glXHyperpipeAttribSGIX',
'glXQueryHyperpipeAttribSGIX', 'PFNGLXQUERYHYPERPIPENETWORKSGIXPROC',
'PFNGLXHYPERPIPECONFIGSGIXPROC', 'PFNGLXQUERYHYPERPIPECONFIGSGIXPROC',
'PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC', 'PFNGLXBINDHYPERPIPESGIXPROC',
'PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC', 'PFNGLXHYPERPIPEATTRIBSGIXPROC',
'PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC', 'GLX_MESA_agp_offset',
'glXGetAGPOffsetMESA', 'PFNGLXGETAGPOFFSETMESAPROC']
# END GENERATED CONTENT (do not edit above this line)

45
pyglet/gl/glxext_mesa.py Normal file
View file

@ -0,0 +1,45 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''This file is currently hand-coded; I don't have a MESA header file to build
off.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: glxext_mesa.py 1579 2008-01-15 14:47:19Z Alex.Holkner $'
import ctypes
from ctypes import *
from pyglet.gl.lib import link_GLX as _link_function
glXSwapIntervalMESA = _link_function('glXSwapIntervalMESA', c_int, [c_int], 'MESA_swap_control')

901
pyglet/gl/glxext_nv.py Normal file
View file

@ -0,0 +1,901 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Wrapper for http://developer.download.nvidia.com/opengl/includes/glxext.h
Generated by tools/gengl.py.
Do not modify this file.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: glxext_nv.py 1579 2008-01-15 14:47:19Z Alex.Holkner $'
from ctypes import *
from pyglet.gl.lib import link_GLX as _link_function
from pyglet.gl.lib import c_ptrdiff_t
# BEGIN GENERATED CONTENT (do not edit below this line)
# This content is generated by tools/gengl.py.
# Wrapper for http://developer.download.nvidia.com/opengl/includes/glxext.h
# VERSION_1_3 (/usr/include/GL/glx.h:73)
# VERSION_1_4 (/usr/include/GL/glx.h:132)
# ARB_get_proc_address (/usr/include/GL/glx.h:137)
# VERSION_1_1 (/usr/include/GL/glx.h:209)
# VERSION_1_2 (/usr/include/GL/glx.h:222)
# VERSION_1_3 (/usr/include/GL/glx.h:230)
# VERSION_1_4 (/usr/include/GL/glx.h:302)
# ARB_get_proc_address (/usr/include/GL/glx.h:318)
# GLXEXT_LEGACY (/usr/include/GL/glx.h:350)
GLAPI = 0 # GL/glxext.h:49
GLX_GLXEXT_VERSION = 10 # GL/glxext.h:57
# ARB_get_proc_address (GL/glxext.h:59)
# ARB_multisample (GL/glxext.h:62)
GLX_SAMPLE_BUFFERS_ARB = 100000 # GL/glxext.h:63
GLX_SAMPLES_ARB = 100001 # GL/glxext.h:64
# ARB_fbconfig_float (GL/glxext.h:67)
GLX_RGBA_FLOAT_TYPE_ARB = 8377 # GL/glxext.h:68
GLX_RGBA_FLOAT_BIT_ARB = 4 # GL/glxext.h:69
# SGIS_multisample (GL/glxext.h:72)
GLX_SAMPLE_BUFFERS_SGIS = 100000 # GL/glxext.h:73
GLX_SAMPLES_SGIS = 100001 # GL/glxext.h:74
# EXT_visual_info (GL/glxext.h:77)
GLX_X_VISUAL_TYPE_EXT = 34 # GL/glxext.h:78
GLX_TRANSPARENT_TYPE_EXT = 35 # GL/glxext.h:79
GLX_TRANSPARENT_INDEX_VALUE_EXT = 36 # GL/glxext.h:80
GLX_TRANSPARENT_RED_VALUE_EXT = 37 # GL/glxext.h:81
GLX_TRANSPARENT_GREEN_VALUE_EXT = 38 # GL/glxext.h:82
GLX_TRANSPARENT_BLUE_VALUE_EXT = 39 # GL/glxext.h:83
GLX_TRANSPARENT_ALPHA_VALUE_EXT = 40 # GL/glxext.h:84
GLX_NONE_EXT = 32768 # GL/glxext.h:85
GLX_TRUE_COLOR_EXT = 32770 # GL/glxext.h:86
GLX_DIRECT_COLOR_EXT = 32771 # GL/glxext.h:87
GLX_PSEUDO_COLOR_EXT = 32772 # GL/glxext.h:88
GLX_STATIC_COLOR_EXT = 32773 # GL/glxext.h:89
GLX_GRAY_SCALE_EXT = 32774 # GL/glxext.h:90
GLX_STATIC_GRAY_EXT = 32775 # GL/glxext.h:91
GLX_TRANSPARENT_RGB_EXT = 32776 # GL/glxext.h:92
GLX_TRANSPARENT_INDEX_EXT = 32777 # GL/glxext.h:93
# SGI_swap_control (GL/glxext.h:96)
# SGI_video_sync (GL/glxext.h:99)
# SGI_make_current_read (GL/glxext.h:102)
# SGIX_video_source (GL/glxext.h:105)
# EXT_visual_rating (GL/glxext.h:108)
GLX_VISUAL_CAVEAT_EXT = 32 # GL/glxext.h:109
GLX_SLOW_VISUAL_EXT = 32769 # GL/glxext.h:110
GLX_NON_CONFORMANT_VISUAL_EXT = 32781 # GL/glxext.h:111
# EXT_import_context (GL/glxext.h:115)
GLX_SHARE_CONTEXT_EXT = 32778 # GL/glxext.h:116
GLX_VISUAL_ID_EXT = 32779 # GL/glxext.h:117
GLX_SCREEN_EXT = 32780 # GL/glxext.h:118
# SGIX_fbconfig (GL/glxext.h:121)
GLX_WINDOW_BIT_SGIX = 1 # GL/glxext.h:122
GLX_PIXMAP_BIT_SGIX = 2 # GL/glxext.h:123
GLX_RGBA_BIT_SGIX = 1 # GL/glxext.h:124
GLX_COLOR_INDEX_BIT_SGIX = 2 # GL/glxext.h:125
GLX_DRAWABLE_TYPE_SGIX = 32784 # GL/glxext.h:126
GLX_RENDER_TYPE_SGIX = 32785 # GL/glxext.h:127
GLX_X_RENDERABLE_SGIX = 32786 # GL/glxext.h:128
GLX_FBCONFIG_ID_SGIX = 32787 # GL/glxext.h:129
GLX_RGBA_TYPE_SGIX = 32788 # GL/glxext.h:130
GLX_COLOR_INDEX_TYPE_SGIX = 32789 # GL/glxext.h:131
# SGIX_pbuffer (GL/glxext.h:135)
GLX_PBUFFER_BIT_SGIX = 4 # GL/glxext.h:136
GLX_BUFFER_CLOBBER_MASK_SGIX = 134217728 # GL/glxext.h:137
GLX_FRONT_LEFT_BUFFER_BIT_SGIX = 1 # GL/glxext.h:138
GLX_FRONT_RIGHT_BUFFER_BIT_SGIX = 2 # GL/glxext.h:139
GLX_BACK_LEFT_BUFFER_BIT_SGIX = 4 # GL/glxext.h:140
GLX_BACK_RIGHT_BUFFER_BIT_SGIX = 8 # GL/glxext.h:141
GLX_AUX_BUFFERS_BIT_SGIX = 16 # GL/glxext.h:142
GLX_DEPTH_BUFFER_BIT_SGIX = 32 # GL/glxext.h:143
GLX_STENCIL_BUFFER_BIT_SGIX = 64 # GL/glxext.h:144
GLX_ACCUM_BUFFER_BIT_SGIX = 128 # GL/glxext.h:145
GLX_SAMPLE_BUFFERS_BIT_SGIX = 256 # GL/glxext.h:146
GLX_MAX_PBUFFER_WIDTH_SGIX = 32790 # GL/glxext.h:147
GLX_MAX_PBUFFER_HEIGHT_SGIX = 32791 # GL/glxext.h:148
GLX_MAX_PBUFFER_PIXELS_SGIX = 32792 # GL/glxext.h:149
GLX_OPTIMAL_PBUFFER_WIDTH_SGIX = 32793 # GL/glxext.h:150
GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX = 32794 # GL/glxext.h:151
GLX_PRESERVED_CONTENTS_SGIX = 32795 # GL/glxext.h:152
GLX_LARGEST_PBUFFER_SGIX = 32796 # GL/glxext.h:153
GLX_WIDTH_SGIX = 32797 # GL/glxext.h:154
GLX_HEIGHT_SGIX = 32798 # GL/glxext.h:155
GLX_EVENT_MASK_SGIX = 32799 # GL/glxext.h:156
GLX_DAMAGED_SGIX = 32800 # GL/glxext.h:157
GLX_SAVED_SGIX = 32801 # GL/glxext.h:158
GLX_WINDOW_SGIX = 32802 # GL/glxext.h:159
GLX_PBUFFER_SGIX = 32803 # GL/glxext.h:160
# SGI_cushion (GL/glxext.h:163)
# SGIX_video_resize (GL/glxext.h:166)
GLX_SYNC_FRAME_SGIX = 0 # GL/glxext.h:167
GLX_SYNC_SWAP_SGIX = 1 # GL/glxext.h:168
# SGIX_dmbuffer (GL/glxext.h:171)
GLX_DIGITAL_MEDIA_PBUFFER_SGIX = 32804 # GL/glxext.h:172
# SGIX_swap_group (GL/glxext.h:175)
# SGIX_swap_barrier (GL/glxext.h:178)
# SGIS_blended_overlay (GL/glxext.h:181)
GLX_BLENDED_RGBA_SGIS = 32805 # GL/glxext.h:182
# SGIS_shared_multisample (GL/glxext.h:185)
GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS = 32806 # GL/glxext.h:186
GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS = 32807 # GL/glxext.h:187
# SUN_get_transparent_index (GL/glxext.h:190)
# 3DFX_multisample (GL/glxext.h:193)
GLX_SAMPLE_BUFFERS_3DFX = 32848 # GL/glxext.h:194
GLX_SAMPLES_3DFX = 32849 # GL/glxext.h:195
# MESA_copy_sub_buffer (GL/glxext.h:198)
# MESA_pixmap_colormap (GL/glxext.h:201)
# MESA_release_buffers (GL/glxext.h:204)
# MESA_set_3dfx_mode (GL/glxext.h:207)
GLX_3DFX_WINDOW_MODE_MESA = 1 # GL/glxext.h:208
GLX_3DFX_FULLSCREEN_MODE_MESA = 2 # GL/glxext.h:209
# SGIX_visual_select_group (GL/glxext.h:212)
GLX_VISUAL_SELECT_GROUP_SGIX = 32808 # GL/glxext.h:213
# OML_swap_method (GL/glxext.h:216)
GLX_SWAP_METHOD_OML = 32864 # GL/glxext.h:217
GLX_SWAP_EXCHANGE_OML = 32865 # GL/glxext.h:218
GLX_SWAP_COPY_OML = 32866 # GL/glxext.h:219
GLX_SWAP_UNDEFINED_OML = 32867 # GL/glxext.h:220
# OML_sync_control (GL/glxext.h:223)
# NV_float_buffer (GL/glxext.h:226)
GLX_FLOAT_COMPONENTS_NV = 8368 # GL/glxext.h:227
# SGIX_hyperpipe (GL/glxext.h:230)
GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX = 80 # GL/glxext.h:231
GLX_BAD_HYPERPIPE_CONFIG_SGIX = 91 # GL/glxext.h:232
GLX_BAD_HYPERPIPE_SGIX = 92 # GL/glxext.h:233
GLX_HYPERPIPE_DISPLAY_PIPE_SGIX = 1 # GL/glxext.h:234
GLX_HYPERPIPE_RENDER_PIPE_SGIX = 2 # GL/glxext.h:235
GLX_PIPE_RECT_SGIX = 1 # GL/glxext.h:236
GLX_PIPE_RECT_LIMITS_SGIX = 2 # GL/glxext.h:237
GLX_HYPERPIPE_STEREO_SGIX = 3 # GL/glxext.h:238
GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX = 4 # GL/glxext.h:239
GLX_HYPERPIPE_ID_SGIX = 32816 # GL/glxext.h:240
# MESA_agp_offset (GL/glxext.h:243)
# ARB_get_proc_address (GL/glxext.h:249)
# SGIX_video_source (GL/glxext.h:256)
XID = c_ulong # /usr/include/X11/X.h:71
GLXVideoSourceSGIX = XID # GL/glxext.h:257
# SGIX_fbconfig (GL/glxext.h:260)
GLXFBConfigIDSGIX = XID # GL/glxext.h:261
class struct___GLXFBConfigRec(Structure):
__slots__ = [
]
struct___GLXFBConfigRec._fields_ = [
('_opaque_struct', c_int)
]
GLXFBConfigSGIX = POINTER(struct___GLXFBConfigRec) # GL/glxext.h:262
# SGIX_pbuffer (GL/glxext.h:265)
class struct_anon_301(Structure):
__slots__ = [
'type',
'serial',
'send_event',
'display',
'drawable',
'event_type',
'draw_type',
'mask',
'x',
'y',
'width',
'height',
'count',
]
class struct__XDisplay(Structure):
__slots__ = [
]
struct__XDisplay._fields_ = [
('_opaque_struct', c_int)
]
Display = struct__XDisplay # /usr/include/X11/Xlib.h:519
GLXDrawable = XID # /usr/include/GL/glx.h:146
struct_anon_301._fields_ = [
('type', c_int),
('serial', c_ulong),
('send_event', c_int),
('display', POINTER(Display)),
('drawable', GLXDrawable),
('event_type', c_int),
('draw_type', c_int),
('mask', c_uint),
('x', c_int),
('y', c_int),
('width', c_int),
('height', c_int),
('count', c_int),
]
GLXBufferClobberEventSGIX = struct_anon_301 # GL/glxext.h:279
# NV_swap_group (GL/glxext.h:282)
# NV_video_out (GL/glxext.h:285)
GLXVideoDeviceNV = c_uint # GL/glxext.h:290
GLX_VIDEO_OUT_COLOR_NV = 8387 # GL/glxext.h:293
GLX_VIDEO_OUT_ALPHA_NV = 8388 # GL/glxext.h:294
GLX_VIDEO_OUT_DEPTH_NV = 8389 # GL/glxext.h:295
GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV = 8390 # GL/glxext.h:296
GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV = 8391 # GL/glxext.h:297
GLX_VIDEO_OUT_FRAME_NV = 8392 # GL/glxext.h:300
GLX_VIDEO_OUT_FIELD_1_NV = 8393 # GL/glxext.h:301
GLX_VIDEO_OUT_FIELD_2_NV = 8394 # GL/glxext.h:302
# EXT_texture_from_pixmap (GL/glxext.h:305)
GLX_BIND_TO_TEXTURE_RGB_EXT = 8400 # GL/glxext.h:307
GLX_BIND_TO_TEXTURE_RGBA_EXT = 8401 # GL/glxext.h:308
GLX_BIND_TO_MIPMAP_TEXTURE_EXT = 8402 # GL/glxext.h:309
GLX_BIND_TO_TEXTURE_TARGETS_EXT = 8403 # GL/glxext.h:310
GLX_Y_INVERTED_EXT = 8404 # GL/glxext.h:311
GLX_TEXTURE_FORMAT_EXT = 8405 # GL/glxext.h:314
GLX_TEXTURE_TARGET_EXT = 8406 # GL/glxext.h:315
GLX_MIPMAP_TEXTURE_EXT = 8407 # GL/glxext.h:316
GLX_TEXTURE_FORMAT_NONE_EXT = 8408 # GL/glxext.h:319
GLX_TEXTURE_FORMAT_RGB_EXT = 8409 # GL/glxext.h:320
GLX_TEXTURE_FORMAT_RGBA_EXT = 8410 # GL/glxext.h:321
GLX_TEXTURE_1D_BIT_EXT = 1 # GL/glxext.h:324
GLX_TEXTURE_2D_BIT_EXT = 2 # GL/glxext.h:325
GLX_TEXTURE_RECTANGLE_BIT_EXT = 4 # GL/glxext.h:326
GLX_TEXTURE_1D_EXT = 8411 # GL/glxext.h:329
GLX_TEXTURE_2D_EXT = 8412 # GL/glxext.h:330
GLX_TEXTURE_RECTANGLE_EXT = 8413 # GL/glxext.h:331
GLX_FRONT_LEFT_EXT = 8414 # GL/glxext.h:337
GLX_FRONT_RIGHT_EXT = 8415 # GL/glxext.h:338
GLX_BACK_LEFT_EXT = 8416 # GL/glxext.h:339
GLX_BACK_RIGHT_EXT = 8417 # GL/glxext.h:340
GLX_FRONT_EXT = 8414 # GL/glxext.h:341
GLX_BACK_EXT = 8416 # GL/glxext.h:342
GLX_AUX0_EXT = 8418 # GL/glxext.h:343
GLX_AUX1_EXT = 8419 # GL/glxext.h:344
GLX_AUX2_EXT = 8420 # GL/glxext.h:345
GLX_AUX3_EXT = 8421 # GL/glxext.h:346
GLX_AUX4_EXT = 8422 # GL/glxext.h:347
GLX_AUX5_EXT = 8423 # GL/glxext.h:348
GLX_AUX6_EXT = 8424 # GL/glxext.h:349
GLX_AUX7_EXT = 8425 # GL/glxext.h:350
GLX_AUX8_EXT = 8426 # GL/glxext.h:351
GLX_AUX9_EXT = 8427 # GL/glxext.h:352
# ARB_get_proc_address (GL/glxext.h:373)
# ARB_multisample (GL/glxext.h:377)
GLX_ARB_multisample = 1 # GL/glxext.h:378
# ARB_fbconfig_float (GL/glxext.h:381)
GLX_ARB_fbconfig_float = 1 # GL/glxext.h:382
# SGIS_multisample (GL/glxext.h:385)
GLX_SGIS_multisample = 1 # GL/glxext.h:386
# EXT_visual_info (GL/glxext.h:389)
GLX_EXT_visual_info = 1 # GL/glxext.h:390
# SGI_swap_control (GL/glxext.h:393)
GLX_SGI_swap_control = 1 # GL/glxext.h:394
# GL/glxext.h:396
glXSwapIntervalSGI = _link_function('glXSwapIntervalSGI', c_int, [c_int], 'SGI_swap_control')
PFNGLXSWAPINTERVALSGIPROC = CFUNCTYPE(c_int, c_int) # GL/glxext.h:398
# SGI_video_sync (GL/glxext.h:401)
GLX_SGI_video_sync = 1 # GL/glxext.h:402
# GL/glxext.h:404
glXGetVideoSyncSGI = _link_function('glXGetVideoSyncSGI', c_int, [POINTER(c_uint)], 'SGI_video_sync')
# GL/glxext.h:405
glXWaitVideoSyncSGI = _link_function('glXWaitVideoSyncSGI', c_int, [c_int, c_int, POINTER(c_uint)], 'SGI_video_sync')
# GL/glxext.h:406
glXGetRefreshRateSGI = _link_function('glXGetRefreshRateSGI', c_int, [POINTER(c_uint)], 'SGI_video_sync')
PFNGLXGETVIDEOSYNCSGIPROC = CFUNCTYPE(c_int, POINTER(c_uint)) # GL/glxext.h:408
PFNGLXWAITVIDEOSYNCSGIPROC = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_uint)) # GL/glxext.h:409
PFNGLXGETREFRESHRATESGIPROC = CFUNCTYPE(c_int, POINTER(c_uint)) # GL/glxext.h:410
# SGI_make_current_read (GL/glxext.h:413)
GLX_SGI_make_current_read = 1 # GL/glxext.h:414
class struct___GLXcontextRec(Structure):
__slots__ = [
]
struct___GLXcontextRec._fields_ = [
('_opaque_struct', c_int)
]
GLXContext = POINTER(struct___GLXcontextRec) # /usr/include/GL/glx.h:155
# GL/glxext.h:416
glXMakeCurrentReadSGI = _link_function('glXMakeCurrentReadSGI', c_int, [POINTER(Display), GLXDrawable, GLXDrawable, GLXContext], 'SGI_make_current_read')
# GL/glxext.h:417
glXGetCurrentReadDrawableSGI = _link_function('glXGetCurrentReadDrawableSGI', GLXDrawable, [], 'SGI_make_current_read')
PFNGLXMAKECURRENTREADSGIPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, GLXDrawable, GLXContext) # GL/glxext.h:419
PFNGLXGETCURRENTREADDRAWABLESGIPROC = CFUNCTYPE(GLXDrawable) # GL/glxext.h:420
# SGIX_video_source (GL/glxext.h:423)
GLX_SGIX_video_source = 1 # GL/glxext.h:424
# EXT_visual_rating (GL/glxext.h:435)
GLX_EXT_visual_rating = 1 # GL/glxext.h:436
# EXT_import_context (GL/glxext.h:439)
GLX_EXT_import_context = 1 # GL/glxext.h:440
# GL/glxext.h:442
glXGetCurrentDisplayEXT = _link_function('glXGetCurrentDisplayEXT', POINTER(Display), [], 'EXT_import_context')
# GL/glxext.h:443
glXQueryContextInfoEXT = _link_function('glXQueryContextInfoEXT', c_int, [POINTER(Display), GLXContext, c_int, POINTER(c_int)], 'EXT_import_context')
GLXContextID = XID # /usr/include/GL/glx.h:144
# GL/glxext.h:444
glXGetContextIDEXT = _link_function('glXGetContextIDEXT', GLXContextID, [GLXContext], 'EXT_import_context')
# GL/glxext.h:445
glXImportContextEXT = _link_function('glXImportContextEXT', GLXContext, [POINTER(Display), GLXContextID], 'EXT_import_context')
# GL/glxext.h:446
glXFreeContextEXT = _link_function('glXFreeContextEXT', None, [POINTER(Display), GLXContext], 'EXT_import_context')
PFNGLXGETCURRENTDISPLAYEXTPROC = CFUNCTYPE(POINTER(Display)) # GL/glxext.h:448
PFNGLXQUERYCONTEXTINFOEXTPROC = CFUNCTYPE(c_int, POINTER(Display), GLXContext, c_int, POINTER(c_int)) # GL/glxext.h:449
PFNGLXGETCONTEXTIDEXTPROC = CFUNCTYPE(GLXContextID, GLXContext) # GL/glxext.h:450
PFNGLXIMPORTCONTEXTEXTPROC = CFUNCTYPE(GLXContext, POINTER(Display), GLXContextID) # GL/glxext.h:451
PFNGLXFREECONTEXTEXTPROC = CFUNCTYPE(None, POINTER(Display), GLXContext) # GL/glxext.h:452
# SGIX_fbconfig (GL/glxext.h:455)
GLX_SGIX_fbconfig = 1 # GL/glxext.h:456
# GL/glxext.h:458
glXGetFBConfigAttribSGIX = _link_function('glXGetFBConfigAttribSGIX', c_int, [POINTER(Display), GLXFBConfigSGIX, c_int, POINTER(c_int)], 'SGIX_fbconfig')
# GL/glxext.h:459
glXChooseFBConfigSGIX = _link_function('glXChooseFBConfigSGIX', POINTER(GLXFBConfigSGIX), [POINTER(Display), c_int, POINTER(c_int), POINTER(c_int)], 'SGIX_fbconfig')
GLXPixmap = XID # /usr/include/GL/glx.h:145
Pixmap = XID # /usr/include/X11/X.h:107
# GL/glxext.h:460
glXCreateGLXPixmapWithConfigSGIX = _link_function('glXCreateGLXPixmapWithConfigSGIX', GLXPixmap, [POINTER(Display), GLXFBConfigSGIX, Pixmap], 'SGIX_fbconfig')
# GL/glxext.h:461
glXCreateContextWithConfigSGIX = _link_function('glXCreateContextWithConfigSGIX', GLXContext, [POINTER(Display), GLXFBConfigSGIX, c_int, GLXContext, c_int], 'SGIX_fbconfig')
class struct_anon_298(Structure):
__slots__ = [
'visual',
'visualid',
'screen',
'depth',
'class',
'red_mask',
'green_mask',
'blue_mask',
'colormap_size',
'bits_per_rgb',
]
class struct_anon_215(Structure):
__slots__ = [
'ext_data',
'visualid',
'class',
'red_mask',
'green_mask',
'blue_mask',
'bits_per_rgb',
'map_entries',
]
class struct__XExtData(Structure):
__slots__ = [
'number',
'next',
'free_private',
'private_data',
]
XPointer = c_char_p # /usr/include/X11/Xlib.h:108
struct__XExtData._fields_ = [
('number', c_int),
('next', POINTER(struct__XExtData)),
('free_private', POINTER(CFUNCTYPE(c_int, POINTER(struct__XExtData)))),
('private_data', XPointer),
]
XExtData = struct__XExtData # /usr/include/X11/Xlib.h:187
VisualID = c_ulong # /usr/include/X11/X.h:81
struct_anon_215._fields_ = [
('ext_data', POINTER(XExtData)),
('visualid', VisualID),
('class', c_int),
('red_mask', c_ulong),
('green_mask', c_ulong),
('blue_mask', c_ulong),
('bits_per_rgb', c_int),
('map_entries', c_int),
]
Visual = struct_anon_215 # /usr/include/X11/Xlib.h:270
struct_anon_298._fields_ = [
('visual', POINTER(Visual)),
('visualid', VisualID),
('screen', c_int),
('depth', c_int),
('class', c_int),
('red_mask', c_ulong),
('green_mask', c_ulong),
('blue_mask', c_ulong),
('colormap_size', c_int),
('bits_per_rgb', c_int),
]
XVisualInfo = struct_anon_298 # /usr/include/X11/Xutil.h:296
# GL/glxext.h:462
glXGetVisualFromFBConfigSGIX = _link_function('glXGetVisualFromFBConfigSGIX', POINTER(XVisualInfo), [POINTER(Display), GLXFBConfigSGIX], 'SGIX_fbconfig')
# GL/glxext.h:463
glXGetFBConfigFromVisualSGIX = _link_function('glXGetFBConfigFromVisualSGIX', GLXFBConfigSGIX, [POINTER(Display), POINTER(XVisualInfo)], 'SGIX_fbconfig')
PFNGLXGETFBCONFIGATTRIBSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), GLXFBConfigSGIX, c_int, POINTER(c_int)) # GL/glxext.h:465
PFNGLXCHOOSEFBCONFIGSGIXPROC = CFUNCTYPE(POINTER(GLXFBConfigSGIX), POINTER(Display), c_int, POINTER(c_int), POINTER(c_int)) # GL/glxext.h:466
PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC = CFUNCTYPE(GLXPixmap, POINTER(Display), GLXFBConfigSGIX, Pixmap) # GL/glxext.h:467
PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC = CFUNCTYPE(GLXContext, POINTER(Display), GLXFBConfigSGIX, c_int, GLXContext, c_int) # GL/glxext.h:468
PFNGLXGETVISUALFROMFBCONFIGSGIXPROC = CFUNCTYPE(POINTER(XVisualInfo), POINTER(Display), GLXFBConfigSGIX) # GL/glxext.h:469
PFNGLXGETFBCONFIGFROMVISUALSGIXPROC = CFUNCTYPE(GLXFBConfigSGIX, POINTER(Display), POINTER(XVisualInfo)) # GL/glxext.h:470
# SGIX_pbuffer (GL/glxext.h:473)
GLX_SGIX_pbuffer = 1 # GL/glxext.h:474
GLXPbufferSGIX = XID # /usr/include/GL/glx.h:148
# GL/glxext.h:476
glXCreateGLXPbufferSGIX = _link_function('glXCreateGLXPbufferSGIX', GLXPbufferSGIX, [POINTER(Display), GLXFBConfigSGIX, c_uint, c_uint, POINTER(c_int)], 'SGIX_pbuffer')
# GL/glxext.h:477
glXDestroyGLXPbufferSGIX = _link_function('glXDestroyGLXPbufferSGIX', None, [POINTER(Display), GLXPbufferSGIX], 'SGIX_pbuffer')
# GL/glxext.h:478
glXQueryGLXPbufferSGIX = _link_function('glXQueryGLXPbufferSGIX', c_int, [POINTER(Display), GLXPbufferSGIX, c_int, POINTER(c_uint)], 'SGIX_pbuffer')
# GL/glxext.h:479
glXSelectEventSGIX = _link_function('glXSelectEventSGIX', None, [POINTER(Display), GLXDrawable, c_ulong], 'SGIX_pbuffer')
# GL/glxext.h:480
glXGetSelectedEventSGIX = _link_function('glXGetSelectedEventSGIX', None, [POINTER(Display), GLXDrawable, POINTER(c_ulong)], 'SGIX_pbuffer')
PFNGLXCREATEGLXPBUFFERSGIXPROC = CFUNCTYPE(GLXPbufferSGIX, POINTER(Display), GLXFBConfigSGIX, c_uint, c_uint, POINTER(c_int)) # GL/glxext.h:482
PFNGLXDESTROYGLXPBUFFERSGIXPROC = CFUNCTYPE(None, POINTER(Display), GLXPbufferSGIX) # GL/glxext.h:483
PFNGLXQUERYGLXPBUFFERSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), GLXPbufferSGIX, c_int, POINTER(c_uint)) # GL/glxext.h:484
PFNGLXSELECTEVENTSGIXPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, c_ulong) # GL/glxext.h:485
PFNGLXGETSELECTEDEVENTSGIXPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, POINTER(c_ulong)) # GL/glxext.h:486
# SGI_cushion (GL/glxext.h:489)
GLX_SGI_cushion = 1 # GL/glxext.h:490
Window = XID # /usr/include/X11/X.h:101
# GL/glxext.h:492
glXCushionSGI = _link_function('glXCushionSGI', None, [POINTER(Display), Window, c_float], 'SGI_cushion')
PFNGLXCUSHIONSGIPROC = CFUNCTYPE(None, POINTER(Display), Window, c_float) # GL/glxext.h:494
# SGIX_video_resize (GL/glxext.h:497)
GLX_SGIX_video_resize = 1 # GL/glxext.h:498
# GL/glxext.h:500
glXBindChannelToWindowSGIX = _link_function('glXBindChannelToWindowSGIX', c_int, [POINTER(Display), c_int, c_int, Window], 'SGIX_video_resize')
# GL/glxext.h:501
glXChannelRectSGIX = _link_function('glXChannelRectSGIX', c_int, [POINTER(Display), c_int, c_int, c_int, c_int, c_int, c_int], 'SGIX_video_resize')
# GL/glxext.h:502
glXQueryChannelRectSGIX = _link_function('glXQueryChannelRectSGIX', c_int, [POINTER(Display), c_int, c_int, POINTER(c_int), POINTER(c_int), POINTER(c_int), POINTER(c_int)], 'SGIX_video_resize')
# GL/glxext.h:503
glXQueryChannelDeltasSGIX = _link_function('glXQueryChannelDeltasSGIX', c_int, [POINTER(Display), c_int, c_int, POINTER(c_int), POINTER(c_int), POINTER(c_int), POINTER(c_int)], 'SGIX_video_resize')
GLenum = c_uint # /usr/include/GL/gl.h:53
# GL/glxext.h:504
glXChannelRectSyncSGIX = _link_function('glXChannelRectSyncSGIX', c_int, [POINTER(Display), c_int, c_int, GLenum], 'SGIX_video_resize')
PFNGLXBINDCHANNELTOWINDOWSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, Window) # GL/glxext.h:506
PFNGLXCHANNELRECTSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, c_int, c_int, c_int, c_int) # GL/glxext.h:507
PFNGLXQUERYCHANNELRECTSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, POINTER(c_int), POINTER(c_int), POINTER(c_int), POINTER(c_int)) # GL/glxext.h:508
PFNGLXQUERYCHANNELDELTASSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, POINTER(c_int), POINTER(c_int), POINTER(c_int), POINTER(c_int)) # GL/glxext.h:509
PFNGLXCHANNELRECTSYNCSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, GLenum) # GL/glxext.h:510
# SGIX_dmbuffer (GL/glxext.h:513)
GLX_SGIX_dmbuffer = 1 # GL/glxext.h:514
# SGIX_swap_group (GL/glxext.h:523)
GLX_SGIX_swap_group = 1 # GL/glxext.h:524
# GL/glxext.h:526
glXJoinSwapGroupSGIX = _link_function('glXJoinSwapGroupSGIX', None, [POINTER(Display), GLXDrawable, GLXDrawable], 'SGIX_swap_group')
PFNGLXJOINSWAPGROUPSGIXPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, GLXDrawable) # GL/glxext.h:528
# SGIX_swap_barrier (GL/glxext.h:531)
GLX_SGIX_swap_barrier = 1 # GL/glxext.h:532
# GL/glxext.h:534
glXBindSwapBarrierSGIX = _link_function('glXBindSwapBarrierSGIX', None, [POINTER(Display), GLXDrawable, c_int], 'SGIX_swap_barrier')
# GL/glxext.h:535
glXQueryMaxSwapBarriersSGIX = _link_function('glXQueryMaxSwapBarriersSGIX', c_int, [POINTER(Display), c_int, POINTER(c_int)], 'SGIX_swap_barrier')
PFNGLXBINDSWAPBARRIERSGIXPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, c_int) # GL/glxext.h:537
PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, POINTER(c_int)) # GL/glxext.h:538
# SUN_get_transparent_index (GL/glxext.h:541)
GLX_SUN_get_transparent_index = 1 # GL/glxext.h:542
# GL/glxext.h:544
glXGetTransparentIndexSUN = _link_function('glXGetTransparentIndexSUN', c_int, [POINTER(Display), Window, Window, POINTER(c_long)], 'SUN_get_transparent_index')
PFNGLXGETTRANSPARENTINDEXSUNPROC = CFUNCTYPE(c_int, POINTER(Display), Window, Window, POINTER(c_long)) # GL/glxext.h:546
# MESA_copy_sub_buffer (GL/glxext.h:549)
GLX_MESA_copy_sub_buffer = 1 # GL/glxext.h:550
# GL/glxext.h:552
glXCopySubBufferMESA = _link_function('glXCopySubBufferMESA', None, [POINTER(Display), GLXDrawable, c_int, c_int, c_int, c_int], 'MESA_copy_sub_buffer')
PFNGLXCOPYSUBBUFFERMESAPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, c_int, c_int, c_int, c_int) # GL/glxext.h:554
# MESA_pixmap_colormap (GL/glxext.h:557)
GLX_MESA_pixmap_colormap = 1 # GL/glxext.h:558
Colormap = XID # /usr/include/X11/X.h:109
# GL/glxext.h:560
glXCreateGLXPixmapMESA = _link_function('glXCreateGLXPixmapMESA', GLXPixmap, [POINTER(Display), POINTER(XVisualInfo), Pixmap, Colormap], 'MESA_pixmap_colormap')
PFNGLXCREATEGLXPIXMAPMESAPROC = CFUNCTYPE(GLXPixmap, POINTER(Display), POINTER(XVisualInfo), Pixmap, Colormap) # GL/glxext.h:562
# MESA_release_buffers (GL/glxext.h:565)
GLX_MESA_release_buffers = 1 # GL/glxext.h:566
# GL/glxext.h:568
glXReleaseBuffersMESA = _link_function('glXReleaseBuffersMESA', c_int, [POINTER(Display), GLXDrawable], 'MESA_release_buffers')
PFNGLXRELEASEBUFFERSMESAPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable) # GL/glxext.h:570
# MESA_set_3dfx_mode (GL/glxext.h:573)
GLX_MESA_set_3dfx_mode = 1 # GL/glxext.h:574
# GL/glxext.h:576
glXSet3DfxModeMESA = _link_function('glXSet3DfxModeMESA', c_int, [c_int], 'MESA_set_3dfx_mode')
PFNGLXSET3DFXMODEMESAPROC = CFUNCTYPE(c_int, c_int) # GL/glxext.h:578
# SGIX_visual_select_group (GL/glxext.h:581)
GLX_SGIX_visual_select_group = 1 # GL/glxext.h:582
# OML_swap_method (GL/glxext.h:585)
GLX_OML_swap_method = 1 # GL/glxext.h:586
# OML_sync_control (GL/glxext.h:589)
GLX_OML_sync_control = 1 # GL/glxext.h:590
# GL/glxext.h:592
glXGetSyncValuesOML = _link_function('glXGetSyncValuesOML', c_int, [POINTER(Display), GLXDrawable, POINTER(c_int64), POINTER(c_int64), POINTER(c_int64)], 'OML_sync_control')
# GL/glxext.h:593
glXGetMscRateOML = _link_function('glXGetMscRateOML', c_int, [POINTER(Display), GLXDrawable, POINTER(c_int32), POINTER(c_int32)], 'OML_sync_control')
# GL/glxext.h:594
glXSwapBuffersMscOML = _link_function('glXSwapBuffersMscOML', c_int64, [POINTER(Display), GLXDrawable, c_int64, c_int64, c_int64], 'OML_sync_control')
# GL/glxext.h:595
glXWaitForMscOML = _link_function('glXWaitForMscOML', c_int, [POINTER(Display), GLXDrawable, c_int64, c_int64, c_int64, POINTER(c_int64), POINTER(c_int64), POINTER(c_int64)], 'OML_sync_control')
# GL/glxext.h:596
glXWaitForSbcOML = _link_function('glXWaitForSbcOML', c_int, [POINTER(Display), GLXDrawable, c_int64, POINTER(c_int64), POINTER(c_int64), POINTER(c_int64)], 'OML_sync_control')
PFNGLXGETSYNCVALUESOMLPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, POINTER(c_int64), POINTER(c_int64), POINTER(c_int64)) # GL/glxext.h:598
PFNGLXGETMSCRATEOMLPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, POINTER(c_int32), POINTER(c_int32)) # GL/glxext.h:599
PFNGLXSWAPBUFFERSMSCOMLPROC = CFUNCTYPE(c_int64, POINTER(Display), GLXDrawable, c_int64, c_int64, c_int64) # GL/glxext.h:600
PFNGLXWAITFORMSCOMLPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, c_int64, c_int64, c_int64, POINTER(c_int64), POINTER(c_int64), POINTER(c_int64)) # GL/glxext.h:601
PFNGLXWAITFORSBCOMLPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, c_int64, POINTER(c_int64), POINTER(c_int64), POINTER(c_int64)) # GL/glxext.h:602
# NV_float_buffer (GL/glxext.h:605)
GLX_NV_float_buffer = 1 # GL/glxext.h:606
# SGIX_hyperpipe (GL/glxext.h:609)
GLX_SGIX_hyperpipe = 1 # GL/glxext.h:610
class struct_anon_302(Structure):
__slots__ = [
'pipeName',
'networkId',
]
struct_anon_302._fields_ = [
('pipeName', c_char * 80),
('networkId', c_int),
]
GLXHyperpipeNetworkSGIX = struct_anon_302 # GL/glxext.h:615
class struct_anon_303(Structure):
__slots__ = [
'pipeName',
'channel',
'participationType',
'timeSlice',
]
struct_anon_303._fields_ = [
('pipeName', c_char * 80),
('channel', c_int),
('participationType', c_uint),
('timeSlice', c_int),
]
GLXHyperpipeConfigSGIX = struct_anon_303 # GL/glxext.h:623
class struct_anon_304(Structure):
__slots__ = [
'pipeName',
'srcXOrigin',
'srcYOrigin',
'srcWidth',
'srcHeight',
'destXOrigin',
'destYOrigin',
'destWidth',
'destHeight',
]
struct_anon_304._fields_ = [
('pipeName', c_char * 80),
('srcXOrigin', c_int),
('srcYOrigin', c_int),
('srcWidth', c_int),
('srcHeight', c_int),
('destXOrigin', c_int),
('destYOrigin', c_int),
('destWidth', c_int),
('destHeight', c_int),
]
GLXPipeRect = struct_anon_304 # GL/glxext.h:629
class struct_anon_305(Structure):
__slots__ = [
'pipeName',
'XOrigin',
'YOrigin',
'maxHeight',
'maxWidth',
]
struct_anon_305._fields_ = [
('pipeName', c_char * 80),
('XOrigin', c_int),
('YOrigin', c_int),
('maxHeight', c_int),
('maxWidth', c_int),
]
GLXPipeRectLimits = struct_anon_305 # GL/glxext.h:634
# GL/glxext.h:637
glXQueryHyperpipeNetworkSGIX = _link_function('glXQueryHyperpipeNetworkSGIX', POINTER(GLXHyperpipeNetworkSGIX), [POINTER(Display), POINTER(c_int)], 'SGIX_hyperpipe')
# GL/glxext.h:638
glXHyperpipeConfigSGIX = _link_function('glXHyperpipeConfigSGIX', c_int, [POINTER(Display), c_int, c_int, POINTER(GLXHyperpipeConfigSGIX), POINTER(c_int)], 'SGIX_hyperpipe')
# GL/glxext.h:639
glXQueryHyperpipeConfigSGIX = _link_function('glXQueryHyperpipeConfigSGIX', POINTER(GLXHyperpipeConfigSGIX), [POINTER(Display), c_int, POINTER(c_int)], 'SGIX_hyperpipe')
# GL/glxext.h:640
glXDestroyHyperpipeConfigSGIX = _link_function('glXDestroyHyperpipeConfigSGIX', c_int, [POINTER(Display), c_int], 'SGIX_hyperpipe')
# GL/glxext.h:641
glXBindHyperpipeSGIX = _link_function('glXBindHyperpipeSGIX', c_int, [POINTER(Display), c_int], 'SGIX_hyperpipe')
# GL/glxext.h:642
glXQueryHyperpipeBestAttribSGIX = _link_function('glXQueryHyperpipeBestAttribSGIX', c_int, [POINTER(Display), c_int, c_int, c_int, POINTER(None), POINTER(None)], 'SGIX_hyperpipe')
# GL/glxext.h:643
glXHyperpipeAttribSGIX = _link_function('glXHyperpipeAttribSGIX', c_int, [POINTER(Display), c_int, c_int, c_int, POINTER(None)], 'SGIX_hyperpipe')
# GL/glxext.h:644
glXQueryHyperpipeAttribSGIX = _link_function('glXQueryHyperpipeAttribSGIX', c_int, [POINTER(Display), c_int, c_int, c_int, POINTER(None)], 'SGIX_hyperpipe')
PFNGLXQUERYHYPERPIPENETWORKSGIXPROC = CFUNCTYPE(POINTER(GLXHyperpipeNetworkSGIX), POINTER(Display), POINTER(c_int)) # GL/glxext.h:646
PFNGLXHYPERPIPECONFIGSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, POINTER(GLXHyperpipeConfigSGIX), POINTER(c_int)) # GL/glxext.h:647
PFNGLXQUERYHYPERPIPECONFIGSGIXPROC = CFUNCTYPE(POINTER(GLXHyperpipeConfigSGIX), POINTER(Display), c_int, POINTER(c_int)) # GL/glxext.h:648
PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int) # GL/glxext.h:649
PFNGLXBINDHYPERPIPESGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int) # GL/glxext.h:650
PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, c_int, POINTER(None), POINTER(None)) # GL/glxext.h:651
PFNGLXHYPERPIPEATTRIBSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, c_int, POINTER(None)) # GL/glxext.h:652
PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, c_int, POINTER(None)) # GL/glxext.h:653
# MESA_agp_offset (GL/glxext.h:656)
GLX_MESA_agp_offset = 1 # GL/glxext.h:657
# GL/glxext.h:659
glXGetAGPOffsetMESA = _link_function('glXGetAGPOffsetMESA', c_uint, [POINTER(None)], 'MESA_agp_offset')
PFNGLXGETAGPOFFSETMESAPROC = CFUNCTYPE(c_uint, POINTER(None)) # GL/glxext.h:661
# NV_vertex_array_range (GL/glxext.h:667)
GLX_NV_vertex_array_range = 1 # GL/glxext.h:668
GLsizei = c_int # /usr/include/GL/gl.h:59
GLfloat = c_float # /usr/include/GL/gl.h:63
# GL/glxext.h:670
glXAllocateMemoryNV = _link_function('glXAllocateMemoryNV', POINTER(c_void), [GLsizei, GLfloat, GLfloat, GLfloat], 'NV_vertex_array_range')
GLvoid = None # /usr/include/GL/gl.h:67
# GL/glxext.h:673
glXFreeMemoryNV = _link_function('glXFreeMemoryNV', None, [POINTER(GLvoid)], 'NV_vertex_array_range')
PFNGLXALLOCATEMEMORYNVPROC = CFUNCTYPE(POINTER(c_void), GLsizei, GLfloat, GLfloat, GLfloat) # GL/glxext.h:675
PFNGLXFREEMEMORYNVPROC = CFUNCTYPE(None, POINTER(GLvoid)) # GL/glxext.h:680
# NV_swap_group (GL/glxext.h:683)
GLX_NV_swap_group = 1 # GL/glxext.h:684
GLuint = c_uint # /usr/include/GL/gl.h:62
# GL/glxext.h:686
glXJoinSwapGroupNV = _link_function('glXJoinSwapGroupNV', c_int, [POINTER(Display), GLXDrawable, GLuint], 'NV_swap_group')
# GL/glxext.h:689
glXBindSwapBarrierNV = _link_function('glXBindSwapBarrierNV', c_int, [POINTER(Display), GLuint, GLuint], 'NV_swap_group')
# GL/glxext.h:691
glXQuerySwapGroupNV = _link_function('glXQuerySwapGroupNV', c_int, [POINTER(Display), GLXDrawable, POINTER(GLuint), POINTER(GLuint)], 'NV_swap_group')
# GL/glxext.h:694
glXQueryMaxSwapGroupsNV = _link_function('glXQueryMaxSwapGroupsNV', c_int, [POINTER(Display), c_int, POINTER(GLuint), POINTER(GLuint)], 'NV_swap_group')
# GL/glxext.h:697
glXQueryFrameCountNV = _link_function('glXQueryFrameCountNV', c_int, [POINTER(Display), c_int, POINTER(GLuint)], 'NV_swap_group')
# GL/glxext.h:699
glXResetFrameCountNV = _link_function('glXResetFrameCountNV', c_int, [POINTER(Display), c_int], 'NV_swap_group')
PFNGLXJOINSWAPGROUPNVPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, GLuint) # GL/glxext.h:701
PFNGLXBINDSWAPBARRIERNVPROC = CFUNCTYPE(c_int, POINTER(Display), GLuint, GLuint) # GL/glxext.h:705
PFNGLXQUERYSWAPGROUPNVPROC = CFUNCTYPE(c_int, POINTER(Display), GLXDrawable, POINTER(GLuint), POINTER(GLuint)) # GL/glxext.h:709
PFNGLXQUERYMAXSWAPGROUPSNVPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, POINTER(GLuint), POINTER(GLuint)) # GL/glxext.h:714
PFNGLXQUERYFRAMECOUNTNVPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, POINTER(GLuint)) # GL/glxext.h:719
PFNGLXRESETFRAMECOUNTNVPROC = CFUNCTYPE(c_int, POINTER(Display), c_int) # GL/glxext.h:723
# NV_video_out (GL/glxext.h:726)
GLX_NV_video_out = 1 # GL/glxext.h:727
# GL/glxext.h:729
glXGetVideoDeviceNV = _link_function('glXGetVideoDeviceNV', c_int, [POINTER(Display), c_int, c_int, POINTER(GLXVideoDeviceNV)], 'NV_video_out')
# GL/glxext.h:732
glXReleaseVideoDeviceNV = _link_function('glXReleaseVideoDeviceNV', c_int, [POINTER(Display), c_int, GLXVideoDeviceNV], 'NV_video_out')
GLXPbuffer = XID # /usr/include/GL/glx.h:147
# GL/glxext.h:735
glXBindVideoImageNV = _link_function('glXBindVideoImageNV', c_int, [POINTER(Display), GLXVideoDeviceNV, GLXPbuffer, c_int], 'NV_video_out')
# GL/glxext.h:738
glXReleaseVideoImageNV = _link_function('glXReleaseVideoImageNV', c_int, [POINTER(Display), GLXPbuffer], 'NV_video_out')
GLboolean = c_ubyte # /usr/include/GL/gl.h:54
# GL/glxext.h:740
glXSendPbufferToVideoNV = _link_function('glXSendPbufferToVideoNV', c_int, [POINTER(Display), GLXPbuffer, c_int, POINTER(c_ulong), GLboolean], 'NV_video_out')
# GL/glxext.h:745
glXGetVideoInfoNV = _link_function('glXGetVideoInfoNV', c_int, [POINTER(Display), c_int, GLXVideoDeviceNV, POINTER(c_ulong), POINTER(c_ulong)], 'NV_video_out')
PFNGLXGETVIDEODEVICENVPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, c_int, POINTER(GLXVideoDeviceNV)) # GL/glxext.h:750
PFNGLXRELEASEVIDEODEVICENVPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, GLXVideoDeviceNV) # GL/glxext.h:755
PFNGLXBINDVIDEOIMAGENVPROC = CFUNCTYPE(c_int, POINTER(Display), GLXVideoDeviceNV, GLXPbuffer, c_int) # GL/glxext.h:759
PFNGLXRELEASEVIDEOIMAGENVPROC = CFUNCTYPE(c_int, POINTER(Display), GLXPbuffer) # GL/glxext.h:764
PFNGLXSENDPBUFFERTOVIDEONVPROC = CFUNCTYPE(c_int, POINTER(Display), GLXPbuffer, c_int, POINTER(c_ulong), GLboolean) # GL/glxext.h:767
PFNGLXGETVIDEOINFONVPROC = CFUNCTYPE(c_int, POINTER(Display), c_int, GLXVideoDeviceNV, POINTER(c_ulong), POINTER(c_ulong)) # GL/glxext.h:773
# EXT_texture_from_pixmap (GL/glxext.h:779)
# GL/glxext.h:782
glXBindTexImageEXT = _link_function('glXBindTexImageEXT', None, [POINTER(Display), GLXDrawable, c_int, POINTER(c_int)], 'EXT_texture_from_pixmap')
# GL/glxext.h:784
glXReleaseTextImageEXT = _link_function('glXReleaseTextImageEXT', None, [POINTER(Display), GLXDrawable, c_int], 'EXT_texture_from_pixmap')
PFNGLXBINDTEXIMAGEEXTPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, c_int, POINTER(c_int)) # GL/glxext.h:787
PFNGLXRELEASETEXIMAGEEXTPROC = CFUNCTYPE(None, POINTER(Display), GLXDrawable, c_int) # GL/glxext.h:791
__all__ = ['GLAPI', 'GLX_GLXEXT_VERSION', 'GLX_SAMPLE_BUFFERS_ARB',
'GLX_SAMPLES_ARB', 'GLX_RGBA_FLOAT_TYPE_ARB', 'GLX_RGBA_FLOAT_BIT_ARB',
'GLX_SAMPLE_BUFFERS_SGIS', 'GLX_SAMPLES_SGIS', 'GLX_X_VISUAL_TYPE_EXT',
'GLX_TRANSPARENT_TYPE_EXT', 'GLX_TRANSPARENT_INDEX_VALUE_EXT',
'GLX_TRANSPARENT_RED_VALUE_EXT', 'GLX_TRANSPARENT_GREEN_VALUE_EXT',
'GLX_TRANSPARENT_BLUE_VALUE_EXT', 'GLX_TRANSPARENT_ALPHA_VALUE_EXT',
'GLX_NONE_EXT', 'GLX_TRUE_COLOR_EXT', 'GLX_DIRECT_COLOR_EXT',
'GLX_PSEUDO_COLOR_EXT', 'GLX_STATIC_COLOR_EXT', 'GLX_GRAY_SCALE_EXT',
'GLX_STATIC_GRAY_EXT', 'GLX_TRANSPARENT_RGB_EXT', 'GLX_TRANSPARENT_INDEX_EXT',
'GLX_VISUAL_CAVEAT_EXT', 'GLX_SLOW_VISUAL_EXT',
'GLX_NON_CONFORMANT_VISUAL_EXT', 'GLX_SHARE_CONTEXT_EXT', 'GLX_VISUAL_ID_EXT',
'GLX_SCREEN_EXT', 'GLX_WINDOW_BIT_SGIX', 'GLX_PIXMAP_BIT_SGIX',
'GLX_RGBA_BIT_SGIX', 'GLX_COLOR_INDEX_BIT_SGIX', 'GLX_DRAWABLE_TYPE_SGIX',
'GLX_RENDER_TYPE_SGIX', 'GLX_X_RENDERABLE_SGIX', 'GLX_FBCONFIG_ID_SGIX',
'GLX_RGBA_TYPE_SGIX', 'GLX_COLOR_INDEX_TYPE_SGIX', 'GLX_PBUFFER_BIT_SGIX',
'GLX_BUFFER_CLOBBER_MASK_SGIX', 'GLX_FRONT_LEFT_BUFFER_BIT_SGIX',
'GLX_FRONT_RIGHT_BUFFER_BIT_SGIX', 'GLX_BACK_LEFT_BUFFER_BIT_SGIX',
'GLX_BACK_RIGHT_BUFFER_BIT_SGIX', 'GLX_AUX_BUFFERS_BIT_SGIX',
'GLX_DEPTH_BUFFER_BIT_SGIX', 'GLX_STENCIL_BUFFER_BIT_SGIX',
'GLX_ACCUM_BUFFER_BIT_SGIX', 'GLX_SAMPLE_BUFFERS_BIT_SGIX',
'GLX_MAX_PBUFFER_WIDTH_SGIX', 'GLX_MAX_PBUFFER_HEIGHT_SGIX',
'GLX_MAX_PBUFFER_PIXELS_SGIX', 'GLX_OPTIMAL_PBUFFER_WIDTH_SGIX',
'GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX', 'GLX_PRESERVED_CONTENTS_SGIX',
'GLX_LARGEST_PBUFFER_SGIX', 'GLX_WIDTH_SGIX', 'GLX_HEIGHT_SGIX',
'GLX_EVENT_MASK_SGIX', 'GLX_DAMAGED_SGIX', 'GLX_SAVED_SGIX',
'GLX_WINDOW_SGIX', 'GLX_PBUFFER_SGIX', 'GLX_SYNC_FRAME_SGIX',
'GLX_SYNC_SWAP_SGIX', 'GLX_DIGITAL_MEDIA_PBUFFER_SGIX',
'GLX_BLENDED_RGBA_SGIS', 'GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS',
'GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS', 'GLX_SAMPLE_BUFFERS_3DFX',
'GLX_SAMPLES_3DFX', 'GLX_3DFX_WINDOW_MODE_MESA',
'GLX_3DFX_FULLSCREEN_MODE_MESA', 'GLX_VISUAL_SELECT_GROUP_SGIX',
'GLX_SWAP_METHOD_OML', 'GLX_SWAP_EXCHANGE_OML', 'GLX_SWAP_COPY_OML',
'GLX_SWAP_UNDEFINED_OML', 'GLX_FLOAT_COMPONENTS_NV',
'GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX', 'GLX_BAD_HYPERPIPE_CONFIG_SGIX',
'GLX_BAD_HYPERPIPE_SGIX', 'GLX_HYPERPIPE_DISPLAY_PIPE_SGIX',
'GLX_HYPERPIPE_RENDER_PIPE_SGIX', 'GLX_PIPE_RECT_SGIX',
'GLX_PIPE_RECT_LIMITS_SGIX', 'GLX_HYPERPIPE_STEREO_SGIX',
'GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX', 'GLX_HYPERPIPE_ID_SGIX',
'GLXVideoSourceSGIX', 'GLXFBConfigIDSGIX', 'GLXFBConfigSGIX',
'GLXBufferClobberEventSGIX', 'GLXVideoDeviceNV', 'GLX_VIDEO_OUT_COLOR_NV',
'GLX_VIDEO_OUT_ALPHA_NV', 'GLX_VIDEO_OUT_DEPTH_NV',
'GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV', 'GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV',
'GLX_VIDEO_OUT_FRAME_NV', 'GLX_VIDEO_OUT_FIELD_1_NV',
'GLX_VIDEO_OUT_FIELD_2_NV', 'GLX_BIND_TO_TEXTURE_RGB_EXT',
'GLX_BIND_TO_TEXTURE_RGBA_EXT', 'GLX_BIND_TO_MIPMAP_TEXTURE_EXT',
'GLX_BIND_TO_TEXTURE_TARGETS_EXT', 'GLX_Y_INVERTED_EXT',
'GLX_TEXTURE_FORMAT_EXT', 'GLX_TEXTURE_TARGET_EXT', 'GLX_MIPMAP_TEXTURE_EXT',
'GLX_TEXTURE_FORMAT_NONE_EXT', 'GLX_TEXTURE_FORMAT_RGB_EXT',
'GLX_TEXTURE_FORMAT_RGBA_EXT', 'GLX_TEXTURE_1D_BIT_EXT',
'GLX_TEXTURE_2D_BIT_EXT', 'GLX_TEXTURE_RECTANGLE_BIT_EXT',
'GLX_TEXTURE_1D_EXT', 'GLX_TEXTURE_2D_EXT', 'GLX_TEXTURE_RECTANGLE_EXT',
'GLX_FRONT_LEFT_EXT', 'GLX_FRONT_RIGHT_EXT', 'GLX_BACK_LEFT_EXT',
'GLX_BACK_RIGHT_EXT', 'GLX_FRONT_EXT', 'GLX_BACK_EXT', 'GLX_AUX0_EXT',
'GLX_AUX1_EXT', 'GLX_AUX2_EXT', 'GLX_AUX3_EXT', 'GLX_AUX4_EXT',
'GLX_AUX5_EXT', 'GLX_AUX6_EXT', 'GLX_AUX7_EXT', 'GLX_AUX8_EXT',
'GLX_AUX9_EXT', 'GLX_ARB_multisample', 'GLX_ARB_fbconfig_float',
'GLX_SGIS_multisample', 'GLX_EXT_visual_info', 'GLX_SGI_swap_control',
'glXSwapIntervalSGI', 'PFNGLXSWAPINTERVALSGIPROC', 'GLX_SGI_video_sync',
'glXGetVideoSyncSGI', 'glXWaitVideoSyncSGI', 'glXGetRefreshRateSGI',
'PFNGLXGETVIDEOSYNCSGIPROC', 'PFNGLXWAITVIDEOSYNCSGIPROC',
'PFNGLXGETREFRESHRATESGIPROC', 'GLX_SGI_make_current_read',
'glXMakeCurrentReadSGI', 'glXGetCurrentReadDrawableSGI',
'PFNGLXMAKECURRENTREADSGIPROC', 'PFNGLXGETCURRENTREADDRAWABLESGIPROC',
'GLX_SGIX_video_source', 'GLX_EXT_visual_rating', 'GLX_EXT_import_context',
'glXGetCurrentDisplayEXT', 'glXQueryContextInfoEXT', 'glXGetContextIDEXT',
'glXImportContextEXT', 'glXFreeContextEXT', 'PFNGLXGETCURRENTDISPLAYEXTPROC',
'PFNGLXQUERYCONTEXTINFOEXTPROC', 'PFNGLXGETCONTEXTIDEXTPROC',
'PFNGLXIMPORTCONTEXTEXTPROC', 'PFNGLXFREECONTEXTEXTPROC', 'GLX_SGIX_fbconfig',
'glXGetFBConfigAttribSGIX', 'glXChooseFBConfigSGIX',
'glXCreateGLXPixmapWithConfigSGIX', 'glXCreateContextWithConfigSGIX',
'glXGetVisualFromFBConfigSGIX', 'glXGetFBConfigFromVisualSGIX',
'PFNGLXGETFBCONFIGATTRIBSGIXPROC', 'PFNGLXCHOOSEFBCONFIGSGIXPROC',
'PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC',
'PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC',
'PFNGLXGETVISUALFROMFBCONFIGSGIXPROC', 'PFNGLXGETFBCONFIGFROMVISUALSGIXPROC',
'GLX_SGIX_pbuffer', 'glXCreateGLXPbufferSGIX', 'glXDestroyGLXPbufferSGIX',
'glXQueryGLXPbufferSGIX', 'glXSelectEventSGIX', 'glXGetSelectedEventSGIX',
'PFNGLXCREATEGLXPBUFFERSGIXPROC', 'PFNGLXDESTROYGLXPBUFFERSGIXPROC',
'PFNGLXQUERYGLXPBUFFERSGIXPROC', 'PFNGLXSELECTEVENTSGIXPROC',
'PFNGLXGETSELECTEDEVENTSGIXPROC', 'GLX_SGI_cushion', 'glXCushionSGI',
'PFNGLXCUSHIONSGIPROC', 'GLX_SGIX_video_resize', 'glXBindChannelToWindowSGIX',
'glXChannelRectSGIX', 'glXQueryChannelRectSGIX', 'glXQueryChannelDeltasSGIX',
'glXChannelRectSyncSGIX', 'PFNGLXBINDCHANNELTOWINDOWSGIXPROC',
'PFNGLXCHANNELRECTSGIXPROC', 'PFNGLXQUERYCHANNELRECTSGIXPROC',
'PFNGLXQUERYCHANNELDELTASSGIXPROC', 'PFNGLXCHANNELRECTSYNCSGIXPROC',
'GLX_SGIX_dmbuffer', 'GLX_SGIX_swap_group', 'glXJoinSwapGroupSGIX',
'PFNGLXJOINSWAPGROUPSGIXPROC', 'GLX_SGIX_swap_barrier',
'glXBindSwapBarrierSGIX', 'glXQueryMaxSwapBarriersSGIX',
'PFNGLXBINDSWAPBARRIERSGIXPROC', 'PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC',
'GLX_SUN_get_transparent_index', 'glXGetTransparentIndexSUN',
'PFNGLXGETTRANSPARENTINDEXSUNPROC', 'GLX_MESA_copy_sub_buffer',
'glXCopySubBufferMESA', 'PFNGLXCOPYSUBBUFFERMESAPROC',
'GLX_MESA_pixmap_colormap', 'glXCreateGLXPixmapMESA',
'PFNGLXCREATEGLXPIXMAPMESAPROC', 'GLX_MESA_release_buffers',
'glXReleaseBuffersMESA', 'PFNGLXRELEASEBUFFERSMESAPROC',
'GLX_MESA_set_3dfx_mode', 'glXSet3DfxModeMESA', 'PFNGLXSET3DFXMODEMESAPROC',
'GLX_SGIX_visual_select_group', 'GLX_OML_swap_method', 'GLX_OML_sync_control',
'glXGetSyncValuesOML', 'glXGetMscRateOML', 'glXSwapBuffersMscOML',
'glXWaitForMscOML', 'glXWaitForSbcOML', 'PFNGLXGETSYNCVALUESOMLPROC',
'PFNGLXGETMSCRATEOMLPROC', 'PFNGLXSWAPBUFFERSMSCOMLPROC',
'PFNGLXWAITFORMSCOMLPROC', 'PFNGLXWAITFORSBCOMLPROC', 'GLX_NV_float_buffer',
'GLX_SGIX_hyperpipe', 'GLXHyperpipeNetworkSGIX', 'GLXHyperpipeConfigSGIX',
'GLXPipeRect', 'GLXPipeRectLimits', 'glXQueryHyperpipeNetworkSGIX',
'glXHyperpipeConfigSGIX', 'glXQueryHyperpipeConfigSGIX',
'glXDestroyHyperpipeConfigSGIX', 'glXBindHyperpipeSGIX',
'glXQueryHyperpipeBestAttribSGIX', 'glXHyperpipeAttribSGIX',
'glXQueryHyperpipeAttribSGIX', 'PFNGLXQUERYHYPERPIPENETWORKSGIXPROC',
'PFNGLXHYPERPIPECONFIGSGIXPROC', 'PFNGLXQUERYHYPERPIPECONFIGSGIXPROC',
'PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC', 'PFNGLXBINDHYPERPIPESGIXPROC',
'PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC', 'PFNGLXHYPERPIPEATTRIBSGIXPROC',
'PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC', 'GLX_MESA_agp_offset',
'glXGetAGPOffsetMESA', 'PFNGLXGETAGPOFFSETMESAPROC',
'GLX_NV_vertex_array_range', 'glXAllocateMemoryNV', 'glXFreeMemoryNV',
'PFNGLXALLOCATEMEMORYNVPROC', 'PFNGLXFREEMEMORYNVPROC', 'GLX_NV_swap_group',
'glXJoinSwapGroupNV', 'glXBindSwapBarrierNV', 'glXQuerySwapGroupNV',
'glXQueryMaxSwapGroupsNV', 'glXQueryFrameCountNV', 'glXResetFrameCountNV',
'PFNGLXJOINSWAPGROUPNVPROC', 'PFNGLXBINDSWAPBARRIERNVPROC',
'PFNGLXQUERYSWAPGROUPNVPROC', 'PFNGLXQUERYMAXSWAPGROUPSNVPROC',
'PFNGLXQUERYFRAMECOUNTNVPROC', 'PFNGLXRESETFRAMECOUNTNVPROC',
'GLX_NV_video_out', 'glXGetVideoDeviceNV', 'glXReleaseVideoDeviceNV',
'glXBindVideoImageNV', 'glXReleaseVideoImageNV', 'glXSendPbufferToVideoNV',
'glXGetVideoInfoNV', 'PFNGLXGETVIDEODEVICENVPROC',
'PFNGLXRELEASEVIDEODEVICENVPROC', 'PFNGLXBINDVIDEOIMAGENVPROC',
'PFNGLXRELEASEVIDEOIMAGENVPROC', 'PFNGLXSENDPBUFFERTOVIDEONVPROC',
'PFNGLXGETVIDEOINFONVPROC', 'glXBindTexImageEXT', 'glXReleaseTextImageEXT',
'PFNGLXBINDTEXIMAGEEXTPROC', 'PFNGLXRELEASETEXIMAGEEXTPROC']
# END GENERATED CONTENT (do not edit above this line)

144
pyglet/gl/lib.py Normal file
View file

@ -0,0 +1,144 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: lib.py 1978 2008-03-28 15:11:48Z Alex.Holkner $'
import sys
import ctypes
import pyglet
__all__ = ['link_GL', 'link_GLU', 'link_AGL', 'link_GLX', 'link_WGL']
_debug_gl = pyglet.options['debug_gl']
_debug_gl_trace = pyglet.options['debug_gl_trace']
_debug_gl_trace_args = pyglet.options['debug_gl_trace_args']
class MissingFunctionException(Exception):
def __init__(self, name, requires=None, suggestions=None):
msg = '%s is not exported by the available OpenGL driver.' % name
if requires:
msg += ' %s is required for this functionality.' % requires
if suggestions:
msg += ' Consider alternative(s) %s.' % ', '.join(suggestions)
Exception.__init__(self, msg)
def missing_function(name, requires=None, suggestions=None):
def MissingFunction(*args, **kwargs):
raise MissingFunctionException(name, requires, suggestions)
return MissingFunction
_int_types = (ctypes.c_int16, ctypes.c_int32)
if hasattr(ctypes, 'c_int64'):
# Some builds of ctypes apparently do not have c_int64
# defined; it's a pretty good bet that these builds do not
# have 64-bit pointers.
_int_types += (ctypes.c_int64,)
for t in _int_types:
if ctypes.sizeof(t) == ctypes.sizeof(ctypes.c_size_t):
c_ptrdiff_t = t
class c_void(ctypes.Structure):
# c_void_p is a buggy return type, converting to int, so
# POINTER(None) == c_void_p is actually written as
# POINTER(c_void), so it can be treated as a real pointer.
_fields_ = [('dummy', ctypes.c_int)]
class GLException(Exception):
pass
def errcheck(result, func, arguments):
if _debug_gl_trace:
try:
name = func.__name__
except AttributeError:
name = repr(func)
if _debug_gl_trace_args:
trace_args = ', '.join([repr(arg)[:20] for arg in arguments])
print '%s(%s)' % (name, trace_args)
else:
print name
from pyglet import gl
context = gl.current_context
if not context:
raise GLException('No GL context; create a Window first')
if not context._gl_begin:
error = gl.glGetError()
if error:
msg = ctypes.cast(gl.gluErrorString(error), ctypes.c_char_p).value
raise GLException(msg)
return result
def errcheck_glbegin(result, func, arguments):
from pyglet import gl
context = gl.current_context
if not context:
raise GLException('No GL context; create a Window first')
context._gl_begin = True
return result
def errcheck_glend(result, func, arguments):
from pyglet import gl
context = gl.current_context
if not context:
raise GLException('No GL context; create a Window first')
context._gl_begin = False
return errcheck(result, func, arguments)
def decorate_function(func, name):
if _debug_gl:
if name == 'glBegin':
func.errcheck = errcheck_glbegin
elif name == 'glEnd':
func.errcheck = errcheck_glend
elif name not in ('glGetError', 'gluErrorString') and \
name[:3] not in ('glX', 'agl', 'wgl'):
func.errcheck = errcheck
link_AGL = None
link_GLX = None
link_WGL = None
if sys.platform in ('win32', 'cygwin'):
from pyglet.gl.lib_wgl import link_GL, link_GLU, link_WGL
elif sys.platform == 'darwin':
from pyglet.gl.lib_agl import link_GL, link_GLU, link_AGL
else:
from pyglet.gl.lib_glx import link_GL, link_GLU, link_GLX

74
pyglet/gl/lib_agl.py Normal file
View file

@ -0,0 +1,74 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: $'
from ctypes import *
import pyglet.lib
from pyglet.gl.lib import missing_function, decorate_function
__all__ = ['link_GL', 'link_GLU', 'link_AGL']
gl_lib = pyglet.lib.load_library(
framework='/System/Library/Frameworks/OpenGL.framework')
agl_lib = pyglet.lib.load_library(
framework='/System/Library/Frameworks/AGL.framework')
def link_GL(name, restype, argtypes, requires=None, suggestions=None):
try:
func = getattr(gl_lib, name)
func.restype = restype
func.argtypes = argtypes
decorate_function(func, name)
return func
except AttributeError, e:
return missing_function(name, requires, suggestions)
link_GLU = link_GL
def link_AGL(name, restype, argtypes, requires=None, suggestions=None):
try:
func = getattr(agl_lib, name)
func.restype = restype
func.argtypes = argtypes
decorate_function(func, name)
return func
except AttributeError, e:
return missing_function(name, requires, suggestions)

92
pyglet/gl/lib_glx.py Normal file
View file

@ -0,0 +1,92 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: lib_glx.py 1579 2008-01-15 14:47:19Z Alex.Holkner $'
from ctypes import *
import pyglet.lib
from pyglet.gl.lib import missing_function, decorate_function
__all__ = ['link_GL', 'link_GLU', 'link_GLX']
gl_lib = pyglet.lib.load_library('GL')
glu_lib = pyglet.lib.load_library('GLU')
# Look for glXGetProcAddressARB extension, use it as fallback (for
# ATI fglrx and DRI drivers).
try:
glXGetProcAddressARB = getattr(gl_lib, 'glXGetProcAddressARB')
glXGetProcAddressARB.restype = POINTER(CFUNCTYPE(None))
glXGetProcAddressARB.argtypes = [POINTER(c_ubyte)]
_have_getprocaddress = True
except AttributeError:
_have_get_procaddress = False
def link_GL(name, restype, argtypes, requires=None, suggestions=None):
try:
func = getattr(gl_lib, name)
func.restype = restype
func.argtypes = argtypes
decorate_function(func, name)
return func
except AttributeError, e:
if _have_getprocaddress:
# Fallback if implemented but not in ABI
bname = cast(pointer(create_string_buffer(name)), POINTER(c_ubyte))
addr = glXGetProcAddressARB(bname)
if addr:
ftype = CFUNCTYPE(*((restype,) + tuple(argtypes)))
func = cast(addr, ftype)
decorate_function(func, name)
return func
return missing_function(name, requires, suggestions)
link_GLX = link_GL
def link_GLU(name, restype, argtypes, requires=None, suggestions=None):
try:
func = getattr(glu_lib, name)
func.restype = restype
func.argtypes = argtypes
decorate_function(func, name)
return func
except AttributeError, e:
return missing_function(name, requires, suggestions)

153
pyglet/gl/lib_wgl.py Normal file
View file

@ -0,0 +1,153 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: lib_glx.py 597 2007-02-03 16:13:07Z Alex.Holkner $'
import ctypes
from ctypes import *
import pyglet
from pyglet.gl.lib import missing_function, decorate_function
__all__ = ['link_GL', 'link_GLU', 'link_WGL']
_debug_trace = pyglet.options['debug_trace']
gl_lib = ctypes.windll.opengl32
glu_lib = ctypes.windll.glu32
wgl_lib = gl_lib
if _debug_trace:
from pyglet.lib import _TraceLibrary
gl_lib = _TraceLibrary(gl_lib)
glu_lib = _TraceLibrary(glu_lib)
wgl_lib = _TraceLibrary(wgl_lib)
try:
wglGetProcAddress = wgl_lib.wglGetProcAddress
wglGetProcAddress.restype = CFUNCTYPE(POINTER(c_int))
wglGetProcAddress.argtypes = [c_char_p]
_have_get_proc_address = True
except AttributeError:
_have_get_proc_address = False
class WGLFunctionProxy(object):
__slots__ = ['name', 'requires', 'suggestions', 'ftype', 'func']
def __init__(self, name, ftype, requires, suggestions):
assert _have_get_proc_address
self.name = name
self.ftype = ftype
self.requires = requires
self.suggestions = suggestions
self.func = None
def __call__(self, *args, **kwargs):
if self.func:
return self.func(*args, **kwargs)
from pyglet.gl import current_context
if not current_context:
raise Exception(
'Call to function "%s" before GL context created' % self.name)
address = wglGetProcAddress(self.name)
if cast(address, POINTER(c_int)): # check cast because address is func
self.func = cast(address, self.ftype)
decorate_function(self.func, self.name)
else:
self.func = missing_function(
self.name, self.requires, self.suggestions)
result = self.func(*args, **kwargs)
return result
def link_GL(name, restype, argtypes, requires=None, suggestions=None):
try:
func = getattr(gl_lib, name)
func.restype = restype
func.argtypes = argtypes
decorate_function(func, name)
return func
except AttributeError, e:
# Not in opengl32.dll. Try and get a pointer from WGL.
try:
fargs = (restype,) + tuple(argtypes)
ftype = ctypes.WINFUNCTYPE(*fargs)
if _have_get_proc_address:
from pyglet.gl import gl_info
if gl_info.have_context():
address = wglGetProcAddress(name)
if address:
func = cast(address, ftype)
decorate_function(func, name)
return func
else:
# Insert proxy until we have a context
return WGLFunctionProxy(name, ftype, requires, suggestions)
except:
pass
return missing_function(name, requires, suggestions)
def link_GLU(name, restype, argtypes, requires=None, suggestions=None):
try:
func = getattr(glu_lib, name)
func.restype = restype
func.argtypes = argtypes
decorate_function(func, name)
return func
except AttributeError, e:
# Not in glu32.dll. Try and get a pointer from WGL.
try:
fargs = (restype,) + tuple(argtypes)
ftype = ctypes.WINFUNCTYPE(*fargs)
if _have_get_proc_address:
from pyglet.gl import gl_info
if gl_info.have_context():
address = wglGetProcAddress(name)
if address:
func = cast(address, ftype)
decorate_function(func, name)
return func
else:
# Insert proxy until we have a context
return WGLFunctionProxy(name, ftype, requires, suggestions)
except:
pass
return missing_function(name, requires, suggestions)
link_WGL = link_GL

374
pyglet/gl/wgl.py Executable file
View file

@ -0,0 +1,374 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Wrapper for C:\cygwin\home\Alex\pyglet\tools\wgl.h
Generated by tools/gengl.py.
Do not modify this file.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: gengl.py 601 2007-02-04 05:36:59Z Alex.Holkner $'
from ctypes import *
from pyglet.gl.lib import link_WGL as _link_function
from pyglet.gl.lib import c_ptrdiff_t
if not _link_function:
raise ImportError('opengl32.dll is not available.')
# BEGIN GENERATED CONTENT (do not edit below this line)
# This content is generated by tools/gengl.py.
# Wrapper for C:\cygwin\home\Alex\pyglet\tools\wgl.h
CONST = 0 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:14
GLenum = c_uint # C:\cygwin\home\Alex\pyglet\tools\wgl.h:17
GLboolean = c_ubyte # C:\cygwin\home\Alex\pyglet\tools\wgl.h:18
GLbitfield = c_uint # C:\cygwin\home\Alex\pyglet\tools\wgl.h:19
GLbyte = c_char # C:\cygwin\home\Alex\pyglet\tools\wgl.h:20
GLshort = c_short # C:\cygwin\home\Alex\pyglet\tools\wgl.h:21
GLint = c_int # C:\cygwin\home\Alex\pyglet\tools\wgl.h:22
GLsizei = c_int # C:\cygwin\home\Alex\pyglet\tools\wgl.h:23
GLubyte = c_ubyte # C:\cygwin\home\Alex\pyglet\tools\wgl.h:24
GLushort = c_ushort # C:\cygwin\home\Alex\pyglet\tools\wgl.h:25
GLuint = c_uint # C:\cygwin\home\Alex\pyglet\tools\wgl.h:26
GLfloat = c_float # C:\cygwin\home\Alex\pyglet\tools\wgl.h:27
GLclampf = c_float # C:\cygwin\home\Alex\pyglet\tools\wgl.h:28
GLdouble = c_double # C:\cygwin\home\Alex\pyglet\tools\wgl.h:29
GLclampd = c_double # C:\cygwin\home\Alex\pyglet\tools\wgl.h:30
GLvoid = None # C:\cygwin\home\Alex\pyglet\tools\wgl.h:31
INT8 = c_char # C:\cygwin\home\Alex\pyglet\tools\wgl.h:33
PINT8 = c_char_p # C:\cygwin\home\Alex\pyglet\tools\wgl.h:33
INT16 = c_short # C:\cygwin\home\Alex\pyglet\tools\wgl.h:34
PINT16 = POINTER(c_short) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:34
INT32 = c_int # C:\cygwin\home\Alex\pyglet\tools\wgl.h:35
PINT32 = POINTER(c_int) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:35
UINT8 = c_ubyte # C:\cygwin\home\Alex\pyglet\tools\wgl.h:36
PUINT8 = POINTER(c_ubyte) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:36
UINT16 = c_ushort # C:\cygwin\home\Alex\pyglet\tools\wgl.h:37
PUINT16 = POINTER(c_ushort) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:37
UINT32 = c_uint # C:\cygwin\home\Alex\pyglet\tools\wgl.h:38
PUINT32 = POINTER(c_uint) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:38
LONG32 = c_int # C:\cygwin\home\Alex\pyglet\tools\wgl.h:39
PLONG32 = POINTER(c_int) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:39
ULONG32 = c_uint # C:\cygwin\home\Alex\pyglet\tools\wgl.h:40
PULONG32 = POINTER(c_uint) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:40
DWORD32 = c_uint # C:\cygwin\home\Alex\pyglet\tools\wgl.h:41
PDWORD32 = POINTER(c_uint) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:41
INT64 = c_longlong # C:\cygwin\home\Alex\pyglet\tools\wgl.h:42
PINT64 = POINTER(c_longlong) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:42
UINT64 = c_ulonglong # C:\cygwin\home\Alex\pyglet\tools\wgl.h:43
PUINT64 = POINTER(c_ulonglong) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:43
VOID = None # C:\cygwin\home\Alex\pyglet\tools\wgl.h:45
LPVOID = POINTER(None) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:45
LPCSTR = c_char_p # C:\cygwin\home\Alex\pyglet\tools\wgl.h:46
CHAR = c_char # C:\cygwin\home\Alex\pyglet\tools\wgl.h:47
BYTE = c_ubyte # C:\cygwin\home\Alex\pyglet\tools\wgl.h:48
WORD = c_ushort # C:\cygwin\home\Alex\pyglet\tools\wgl.h:49
USHORT = c_ushort # C:\cygwin\home\Alex\pyglet\tools\wgl.h:49
UINT = c_uint # C:\cygwin\home\Alex\pyglet\tools\wgl.h:50
INT = c_int # C:\cygwin\home\Alex\pyglet\tools\wgl.h:51
INT_PTR = POINTER(c_int) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:51
BOOL = c_long # C:\cygwin\home\Alex\pyglet\tools\wgl.h:52
LONG = c_long # C:\cygwin\home\Alex\pyglet\tools\wgl.h:53
DWORD = c_ulong # C:\cygwin\home\Alex\pyglet\tools\wgl.h:54
FLOAT = c_float # C:\cygwin\home\Alex\pyglet\tools\wgl.h:55
COLORREF = DWORD # C:\cygwin\home\Alex\pyglet\tools\wgl.h:56
LPCOLORREF = POINTER(DWORD) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:56
HANDLE = POINTER(None) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:58
HGLRC = HANDLE # C:\cygwin\home\Alex\pyglet\tools\wgl.h:60
HDC = HANDLE # C:\cygwin\home\Alex\pyglet\tools\wgl.h:61
PROC = CFUNCTYPE(INT_PTR) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:63
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:65
wglCopyContext = _link_function('wglCopyContext', BOOL, [HGLRC, HGLRC, UINT], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:66
wglCreateContext = _link_function('wglCreateContext', HGLRC, [HDC], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:67
wglCreateLayerContext = _link_function('wglCreateLayerContext', HGLRC, [HDC, c_int], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:68
wglDeleteContext = _link_function('wglDeleteContext', BOOL, [HGLRC], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:69
wglGetCurrentContext = _link_function('wglGetCurrentContext', HGLRC, [], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:70
wglGetCurrentDC = _link_function('wglGetCurrentDC', HDC, [], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:71
wglGetProcAddress = _link_function('wglGetProcAddress', PROC, [LPCSTR], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:72
wglMakeCurrent = _link_function('wglMakeCurrent', BOOL, [HDC, HGLRC], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:73
wglShareLists = _link_function('wglShareLists', BOOL, [HGLRC, HGLRC], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:74
wglUseFontBitmapsA = _link_function('wglUseFontBitmapsA', BOOL, [HDC, DWORD, DWORD, DWORD], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:75
wglUseFontBitmapsW = _link_function('wglUseFontBitmapsW', BOOL, [HDC, DWORD, DWORD, DWORD], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:76
SwapBuffers = _link_function('SwapBuffers', BOOL, [HDC], None)
class struct__POINTFLOAT(Structure):
__slots__ = [
'x',
'y',
]
struct__POINTFLOAT._fields_ = [
('x', FLOAT),
('y', FLOAT),
]
POINTFLOAT = struct__POINTFLOAT # C:\cygwin\home\Alex\pyglet\tools\wgl.h:81
PPOINTFLOAT = POINTER(struct__POINTFLOAT) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:81
class struct__GLYPHMETRICSFLOAT(Structure):
__slots__ = [
'gmfBlackBoxX',
'gmfBlackBoxY',
'gmfptGlyphOrigin',
'gmfCellIncX',
'gmfCellIncY',
]
struct__GLYPHMETRICSFLOAT._fields_ = [
('gmfBlackBoxX', FLOAT),
('gmfBlackBoxY', FLOAT),
('gmfptGlyphOrigin', POINTFLOAT),
('gmfCellIncX', FLOAT),
('gmfCellIncY', FLOAT),
]
GLYPHMETRICSFLOAT = struct__GLYPHMETRICSFLOAT # C:\cygwin\home\Alex\pyglet\tools\wgl.h:89
PGLYPHMETRICSFLOAT = POINTER(struct__GLYPHMETRICSFLOAT) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:89
LPGLYPHMETRICSFLOAT = POINTER(struct__GLYPHMETRICSFLOAT) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:89
WGL_FONT_LINES = 0 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:91
WGL_FONT_POLYGONS = 1 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:92
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:93
wglUseFontOutlinesA = _link_function('wglUseFontOutlinesA', BOOL, [HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, c_int, LPGLYPHMETRICSFLOAT], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:95
wglUseFontOutlinesW = _link_function('wglUseFontOutlinesW', BOOL, [HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, c_int, LPGLYPHMETRICSFLOAT], None)
class struct_tagLAYERPLANEDESCRIPTOR(Structure):
__slots__ = [
'nSize',
'nVersion',
'dwFlags',
'iPixelType',
'cColorBits',
'cRedBits',
'cRedShift',
'cGreenBits',
'cGreenShift',
'cBlueBits',
'cBlueShift',
'cAlphaBits',
'cAlphaShift',
'cAccumBits',
'cAccumRedBits',
'cAccumGreenBits',
'cAccumBlueBits',
'cAccumAlphaBits',
'cDepthBits',
'cStencilBits',
'cAuxBuffers',
'iLayerPlane',
'bReserved',
'crTransparent',
]
struct_tagLAYERPLANEDESCRIPTOR._fields_ = [
('nSize', WORD),
('nVersion', WORD),
('dwFlags', DWORD),
('iPixelType', BYTE),
('cColorBits', BYTE),
('cRedBits', BYTE),
('cRedShift', BYTE),
('cGreenBits', BYTE),
('cGreenShift', BYTE),
('cBlueBits', BYTE),
('cBlueShift', BYTE),
('cAlphaBits', BYTE),
('cAlphaShift', BYTE),
('cAccumBits', BYTE),
('cAccumRedBits', BYTE),
('cAccumGreenBits', BYTE),
('cAccumBlueBits', BYTE),
('cAccumAlphaBits', BYTE),
('cDepthBits', BYTE),
('cStencilBits', BYTE),
('cAuxBuffers', BYTE),
('iLayerPlane', BYTE),
('bReserved', BYTE),
('crTransparent', COLORREF),
]
LAYERPLANEDESCRIPTOR = struct_tagLAYERPLANEDESCRIPTOR # C:\cygwin\home\Alex\pyglet\tools\wgl.h:125
PLAYERPLANEDESCRIPTOR = POINTER(struct_tagLAYERPLANEDESCRIPTOR) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:125
LPLAYERPLANEDESCRIPTOR = POINTER(struct_tagLAYERPLANEDESCRIPTOR) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:125
LPD_DOUBLEBUFFER = 1 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:128
LPD_STEREO = 2 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:129
LPD_SUPPORT_GDI = 16 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:130
LPD_SUPPORT_OPENGL = 32 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:131
LPD_SHARE_DEPTH = 64 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:132
LPD_SHARE_STENCIL = 128 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:133
LPD_SHARE_ACCUM = 256 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:134
LPD_SWAP_EXCHANGE = 512 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:135
LPD_SWAP_COPY = 1024 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:136
LPD_TRANSPARENT = 4096 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:137
LPD_TYPE_RGBA = 0 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:139
LPD_TYPE_COLORINDEX = 1 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:140
WGL_SWAP_MAIN_PLANE = 1 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:143
WGL_SWAP_OVERLAY1 = 2 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:144
WGL_SWAP_OVERLAY2 = 4 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:145
WGL_SWAP_OVERLAY3 = 8 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:146
WGL_SWAP_OVERLAY4 = 16 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:147
WGL_SWAP_OVERLAY5 = 32 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:148
WGL_SWAP_OVERLAY6 = 64 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:149
WGL_SWAP_OVERLAY7 = 128 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:150
WGL_SWAP_OVERLAY8 = 256 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:151
WGL_SWAP_OVERLAY9 = 512 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:152
WGL_SWAP_OVERLAY10 = 1024 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:153
WGL_SWAP_OVERLAY11 = 2048 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:154
WGL_SWAP_OVERLAY12 = 4096 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:155
WGL_SWAP_OVERLAY13 = 8192 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:156
WGL_SWAP_OVERLAY14 = 16384 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:157
WGL_SWAP_OVERLAY15 = 32768 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:158
WGL_SWAP_UNDERLAY1 = 65536 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:159
WGL_SWAP_UNDERLAY2 = 131072 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:160
WGL_SWAP_UNDERLAY3 = 262144 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:161
WGL_SWAP_UNDERLAY4 = 524288 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:162
WGL_SWAP_UNDERLAY5 = 1048576 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:163
WGL_SWAP_UNDERLAY6 = 2097152 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:164
WGL_SWAP_UNDERLAY7 = 4194304 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:165
WGL_SWAP_UNDERLAY8 = 8388608 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:166
WGL_SWAP_UNDERLAY9 = 16777216 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:167
WGL_SWAP_UNDERLAY10 = 33554432 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:168
WGL_SWAP_UNDERLAY11 = 67108864 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:169
WGL_SWAP_UNDERLAY12 = 134217728 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:170
WGL_SWAP_UNDERLAY13 = 268435456 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:171
WGL_SWAP_UNDERLAY14 = 536870912 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:172
WGL_SWAP_UNDERLAY15 = 1073741824 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:173
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:175
wglDescribeLayerPlane = _link_function('wglDescribeLayerPlane', BOOL, [HDC, c_int, c_int, UINT, LPLAYERPLANEDESCRIPTOR], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:177
wglSetLayerPaletteEntries = _link_function('wglSetLayerPaletteEntries', c_int, [HDC, c_int, c_int, c_int, POINTER(COLORREF)], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:179
wglGetLayerPaletteEntries = _link_function('wglGetLayerPaletteEntries', c_int, [HDC, c_int, c_int, c_int, POINTER(COLORREF)], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:181
wglRealizeLayerPalette = _link_function('wglRealizeLayerPalette', BOOL, [HDC, c_int, BOOL], None)
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:182
wglSwapLayerBuffers = _link_function('wglSwapLayerBuffers', BOOL, [HDC, UINT], None)
class struct__WGLSWAP(Structure):
__slots__ = [
'hdc',
'uiFlags',
]
struct__WGLSWAP._fields_ = [
('hdc', HDC),
('uiFlags', UINT),
]
WGLSWAP = struct__WGLSWAP # C:\cygwin\home\Alex\pyglet\tools\wgl.h:188
PWGLSWAP = POINTER(struct__WGLSWAP) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:188
LPWGLSWAP = POINTER(struct__WGLSWAP) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:188
WGL_SWAPMULTIPLE_MAX = 16 # C:\cygwin\home\Alex\pyglet\tools\wgl.h:190
# C:\cygwin\home\Alex\pyglet\tools\wgl.h:192
wglSwapMultipleBuffers = _link_function('wglSwapMultipleBuffers', DWORD, [UINT, POINTER(WGLSWAP)], None)
class struct_tagRECT(Structure):
__slots__ = [
'left',
'top',
'right',
'bottom',
]
struct_tagRECT._fields_ = [
('left', LONG),
('top', LONG),
('right', LONG),
('bottom', LONG),
]
RECT = struct_tagRECT # C:\cygwin\home\Alex\pyglet\tools\wgl.h:200
PRECT = POINTER(struct_tagRECT) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:200
NPRECT = POINTER(struct_tagRECT) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:200
LPRECT = POINTER(struct_tagRECT) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:200
__all__ = ['CONST', 'GLenum', 'GLboolean', 'GLbitfield', 'GLbyte', 'GLshort',
'GLint', 'GLsizei', 'GLubyte', 'GLushort', 'GLuint', 'GLfloat', 'GLclampf',
'GLdouble', 'GLclampd', 'GLvoid', 'INT8', 'PINT8', 'INT16', 'PINT16', 'INT32',
'PINT32', 'UINT8', 'PUINT8', 'UINT16', 'PUINT16', 'UINT32', 'PUINT32',
'LONG32', 'PLONG32', 'ULONG32', 'PULONG32', 'DWORD32', 'PDWORD32', 'INT64',
'PINT64', 'UINT64', 'PUINT64', 'VOID', 'LPVOID', 'LPCSTR', 'CHAR', 'BYTE',
'WORD', 'USHORT', 'UINT', 'INT', 'INT_PTR', 'BOOL', 'LONG', 'DWORD', 'FLOAT',
'COLORREF', 'LPCOLORREF', 'HANDLE', 'HGLRC', 'HDC', 'PROC', 'wglCopyContext',
'wglCreateContext', 'wglCreateLayerContext', 'wglDeleteContext',
'wglGetCurrentContext', 'wglGetCurrentDC', 'wglGetProcAddress',
'wglMakeCurrent', 'wglShareLists', 'wglUseFontBitmapsA', 'wglUseFontBitmapsW',
'SwapBuffers', 'POINTFLOAT', 'PPOINTFLOAT', 'GLYPHMETRICSFLOAT',
'PGLYPHMETRICSFLOAT', 'LPGLYPHMETRICSFLOAT', 'WGL_FONT_LINES',
'WGL_FONT_POLYGONS', 'wglUseFontOutlinesA', 'wglUseFontOutlinesW',
'LAYERPLANEDESCRIPTOR', 'PLAYERPLANEDESCRIPTOR', 'LPLAYERPLANEDESCRIPTOR',
'LPD_DOUBLEBUFFER', 'LPD_STEREO', 'LPD_SUPPORT_GDI', 'LPD_SUPPORT_OPENGL',
'LPD_SHARE_DEPTH', 'LPD_SHARE_STENCIL', 'LPD_SHARE_ACCUM',
'LPD_SWAP_EXCHANGE', 'LPD_SWAP_COPY', 'LPD_TRANSPARENT', 'LPD_TYPE_RGBA',
'LPD_TYPE_COLORINDEX', 'WGL_SWAP_MAIN_PLANE', 'WGL_SWAP_OVERLAY1',
'WGL_SWAP_OVERLAY2', 'WGL_SWAP_OVERLAY3', 'WGL_SWAP_OVERLAY4',
'WGL_SWAP_OVERLAY5', 'WGL_SWAP_OVERLAY6', 'WGL_SWAP_OVERLAY7',
'WGL_SWAP_OVERLAY8', 'WGL_SWAP_OVERLAY9', 'WGL_SWAP_OVERLAY10',
'WGL_SWAP_OVERLAY11', 'WGL_SWAP_OVERLAY12', 'WGL_SWAP_OVERLAY13',
'WGL_SWAP_OVERLAY14', 'WGL_SWAP_OVERLAY15', 'WGL_SWAP_UNDERLAY1',
'WGL_SWAP_UNDERLAY2', 'WGL_SWAP_UNDERLAY3', 'WGL_SWAP_UNDERLAY4',
'WGL_SWAP_UNDERLAY5', 'WGL_SWAP_UNDERLAY6', 'WGL_SWAP_UNDERLAY7',
'WGL_SWAP_UNDERLAY8', 'WGL_SWAP_UNDERLAY9', 'WGL_SWAP_UNDERLAY10',
'WGL_SWAP_UNDERLAY11', 'WGL_SWAP_UNDERLAY12', 'WGL_SWAP_UNDERLAY13',
'WGL_SWAP_UNDERLAY14', 'WGL_SWAP_UNDERLAY15', 'wglDescribeLayerPlane',
'wglSetLayerPaletteEntries', 'wglGetLayerPaletteEntries',
'wglRealizeLayerPalette', 'wglSwapLayerBuffers', 'WGLSWAP', 'PWGLSWAP',
'LPWGLSWAP', 'WGL_SWAPMULTIPLE_MAX', 'wglSwapMultipleBuffers', 'RECT',
'PRECT', 'NPRECT', 'LPRECT']
# END GENERATED CONTENT (do not edit above this line)

71
pyglet/gl/wgl_info.py Normal file
View file

@ -0,0 +1,71 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Cached information about version and extensions of current WGL
implementation.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: glx_info.py 615 2007-02-07 13:17:05Z Alex.Holkner $'
from ctypes import *
import warnings
from pyglet.gl.lib import MissingFunctionException
from pyglet.gl.gl import *
from pyglet.gl import gl_info
from pyglet.gl.wgl import *
from pyglet.gl.wglext_arb import *
class WGLInfoException(Exception):
pass
class WGLInfo(object):
def get_extensions(self):
if not gl_info.have_context():
warnings.warn("Can't query WGL until a context is created.")
return []
try:
return wglGetExtensionsStringEXT().split()
except MissingFunctionException:
return cast(glGetString(GL_EXTENSIONS), c_char_p).value.split()
def have_extension(self, extension):
return extension in self.get_extensions()
_wgl_info = WGLInfo()
get_extensions = _wgl_info.get_extensions
have_extension = _wgl_info.have_extension

811
pyglet/gl/wglext_arb.py Normal file
View file

@ -0,0 +1,811 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Wrapper for http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h
Generated by tools/gengl.py.
Do not modify this file.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: gengl.py 601 2007-02-04 05:36:59Z Alex.Holkner $'
from ctypes import *
from pyglet.gl.lib import link_WGL as _link_function
from pyglet.gl.lib import c_ptrdiff_t, c_void
# BEGIN GENERATED CONTENT (do not edit below this line)
# This content is generated by tools/gengl.py.
# Wrapper for http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h
# H (C:\cygwin\home\Alex\pyglet\tools\wgl.h:7)
# H (C:\cygwin\home\Alex\pyglet\tools\wgl.h:7)
WIN32_LEAN_AND_MEAN = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:40
GLAPI = 0 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:51
WGL_WGLEXT_VERSION = 6 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:59
# ARB_buffer_region (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:61)
WGL_FRONT_COLOR_BUFFER_BIT_ARB = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:62
WGL_BACK_COLOR_BUFFER_BIT_ARB = 2 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:63
WGL_DEPTH_BUFFER_BIT_ARB = 4 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:64
WGL_STENCIL_BUFFER_BIT_ARB = 8 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:65
# ARB_multisample (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:68)
WGL_SAMPLE_BUFFERS_ARB = 8257 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:69
WGL_SAMPLES_ARB = 8258 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:70
# ARB_extensions_string (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:73)
# ARB_pixel_format (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:76)
WGL_NUMBER_PIXEL_FORMATS_ARB = 8192 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:77
WGL_DRAW_TO_WINDOW_ARB = 8193 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:78
WGL_DRAW_TO_BITMAP_ARB = 8194 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:79
WGL_ACCELERATION_ARB = 8195 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:80
WGL_NEED_PALETTE_ARB = 8196 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:81
WGL_NEED_SYSTEM_PALETTE_ARB = 8197 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:82
WGL_SWAP_LAYER_BUFFERS_ARB = 8198 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:83
WGL_SWAP_METHOD_ARB = 8199 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:84
WGL_NUMBER_OVERLAYS_ARB = 8200 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:85
WGL_NUMBER_UNDERLAYS_ARB = 8201 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:86
WGL_TRANSPARENT_ARB = 8202 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:87
WGL_TRANSPARENT_RED_VALUE_ARB = 8247 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:88
WGL_TRANSPARENT_GREEN_VALUE_ARB = 8248 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:89
WGL_TRANSPARENT_BLUE_VALUE_ARB = 8249 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:90
WGL_TRANSPARENT_ALPHA_VALUE_ARB = 8250 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:91
WGL_TRANSPARENT_INDEX_VALUE_ARB = 8251 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:92
WGL_SHARE_DEPTH_ARB = 8204 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:93
WGL_SHARE_STENCIL_ARB = 8205 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:94
WGL_SHARE_ACCUM_ARB = 512 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:95
WGL_SUPPORT_GDI_ARB = 512 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:96
WGL_SUPPORT_OPENGL_ARB = 8208 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:97
WGL_DOUBLE_BUFFER_ARB = 8209 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:98
WGL_STEREO_ARB = 8210 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:99
WGL_PIXEL_TYPE_ARB = 8211 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:100
WGL_COLOR_BITS_ARB = 8212 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:101
WGL_RED_BITS_ARB = 8213 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:102
WGL_RED_SHIFT_ARB = 8214 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:103
WGL_GREEN_BITS_ARB = 8215 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:104
WGL_GREEN_SHIFT_ARB = 8216 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:105
WGL_BLUE_BITS_ARB = 8217 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:106
WGL_BLUE_SHIFT_ARB = 8218 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:107
WGL_ALPHA_BITS_ARB = 8219 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:108
WGL_ALPHA_SHIFT_ARB = 8220 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:109
WGL_ACCUM_BITS_ARB = 8221 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:110
WGL_ACCUM_RED_BITS_ARB = 513 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:111
WGL_ACCUM_GREEN_BITS_ARB = 513 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:112
WGL_ACCUM_BLUE_BITS_ARB = 8224 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:113
WGL_ACCUM_ALPHA_BITS_ARB = 8225 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:114
WGL_DEPTH_BITS_ARB = 8226 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:115
WGL_STENCIL_BITS_ARB = 8227 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:116
WGL_AUX_BUFFERS_ARB = 8228 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:117
WGL_NO_ACCELERATION_ARB = 8229 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:118
WGL_GENERIC_ACCELERATION_ARB = 8230 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:119
WGL_FULL_ACCELERATION_ARB = 8231 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:120
WGL_SWAP_EXCHANGE_ARB = 8232 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:121
WGL_SWAP_COPY_ARB = 8233 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:122
WGL_SWAP_UNDEFINED_ARB = 8234 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:123
WGL_TYPE_RGBA_ARB = 8235 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:124
WGL_TYPE_COLORINDEX_ARB = 8236 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:125
# ARB_make_current_read (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:128)
ERROR_INVALID_PIXEL_TYPE_ARB = 8259 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:129
ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB = 8276 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:130
# ARB_pbuffer (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:133)
WGL_DRAW_TO_PBUFFER_ARB = 8237 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:134
WGL_MAX_PBUFFER_PIXELS_ARB = 514 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:135
WGL_MAX_PBUFFER_WIDTH_ARB = 514 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:136
WGL_MAX_PBUFFER_HEIGHT_ARB = 8240 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:137
WGL_PBUFFER_LARGEST_ARB = 8243 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:138
WGL_PBUFFER_WIDTH_ARB = 8244 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:139
WGL_PBUFFER_HEIGHT_ARB = 8245 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:140
WGL_PBUFFER_LOST_ARB = 8246 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:141
# ARB_render_texture (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:144)
WGL_BIND_TO_TEXTURE_RGB_ARB = 8304 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:145
WGL_BIND_TO_TEXTURE_RGBA_ARB = 8305 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:146
WGL_TEXTURE_FORMAT_ARB = 8306 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:147
WGL_TEXTURE_TARGET_ARB = 8307 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:148
WGL_MIPMAP_TEXTURE_ARB = 8308 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:149
WGL_TEXTURE_RGB_ARB = 8309 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:150
WGL_TEXTURE_RGBA_ARB = 8310 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:151
WGL_NO_TEXTURE_ARB = 8311 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:152
WGL_TEXTURE_CUBE_MAP_ARB = 8312 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:153
WGL_TEXTURE_1D_ARB = 8313 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:154
WGL_TEXTURE_2D_ARB = 8314 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:155
WGL_MIPMAP_LEVEL_ARB = 8315 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:156
WGL_CUBE_MAP_FACE_ARB = 8316 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:157
WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = 8317 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:158
WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = 519 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:159
WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = 519 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:160
WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = 8320 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:161
WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = 8321 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:162
WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = 8322 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:163
WGL_FRONT_LEFT_ARB = 8323 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:164
WGL_FRONT_RIGHT_ARB = 8324 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:165
WGL_BACK_LEFT_ARB = 8325 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:166
WGL_BACK_RIGHT_ARB = 8326 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:167
WGL_AUX0_ARB = 8327 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:168
WGL_AUX1_ARB = 8328 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:169
WGL_AUX2_ARB = 8329 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:170
WGL_AUX3_ARB = 8330 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:171
WGL_AUX4_ARB = 8331 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:172
WGL_AUX5_ARB = 8332 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:173
WGL_AUX6_ARB = 8333 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:174
WGL_AUX7_ARB = 520 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:175
WGL_AUX8_ARB = 520 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:176
WGL_AUX9_ARB = 8336 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:177
# ARB_pixel_format_float (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:180)
WGL_TYPE_RGBA_FLOAT_ARB = 8608 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:181
# EXT_make_current_read (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:184)
ERROR_INVALID_PIXEL_TYPE_EXT = 8259 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:185
# EXT_pixel_format (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:188)
WGL_NUMBER_PIXEL_FORMATS_EXT = 8192 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:189
WGL_DRAW_TO_WINDOW_EXT = 8193 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:190
WGL_DRAW_TO_BITMAP_EXT = 8194 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:191
WGL_ACCELERATION_EXT = 8195 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:192
WGL_NEED_PALETTE_EXT = 8196 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:193
WGL_NEED_SYSTEM_PALETTE_EXT = 8197 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:194
WGL_SWAP_LAYER_BUFFERS_EXT = 8198 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:195
WGL_SWAP_METHOD_EXT = 8199 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:196
WGL_NUMBER_OVERLAYS_EXT = 8200 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:197
WGL_NUMBER_UNDERLAYS_EXT = 8201 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:198
WGL_TRANSPARENT_EXT = 8202 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:199
WGL_TRANSPARENT_VALUE_EXT = 8203 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:200
WGL_SHARE_DEPTH_EXT = 8204 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:201
WGL_SHARE_STENCIL_EXT = 8205 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:202
WGL_SHARE_ACCUM_EXT = 512 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:203
WGL_SUPPORT_GDI_EXT = 512 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:204
WGL_SUPPORT_OPENGL_EXT = 8208 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:205
WGL_DOUBLE_BUFFER_EXT = 8209 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:206
WGL_STEREO_EXT = 8210 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:207
WGL_PIXEL_TYPE_EXT = 8211 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:208
WGL_COLOR_BITS_EXT = 8212 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:209
WGL_RED_BITS_EXT = 8213 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:210
WGL_RED_SHIFT_EXT = 8214 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:211
WGL_GREEN_BITS_EXT = 8215 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:212
WGL_GREEN_SHIFT_EXT = 8216 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:213
WGL_BLUE_BITS_EXT = 8217 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:214
WGL_BLUE_SHIFT_EXT = 8218 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:215
WGL_ALPHA_BITS_EXT = 8219 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:216
WGL_ALPHA_SHIFT_EXT = 8220 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:217
WGL_ACCUM_BITS_EXT = 8221 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:218
WGL_ACCUM_RED_BITS_EXT = 513 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:219
WGL_ACCUM_GREEN_BITS_EXT = 513 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:220
WGL_ACCUM_BLUE_BITS_EXT = 8224 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:221
WGL_ACCUM_ALPHA_BITS_EXT = 8225 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:222
WGL_DEPTH_BITS_EXT = 8226 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:223
WGL_STENCIL_BITS_EXT = 8227 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:224
WGL_AUX_BUFFERS_EXT = 8228 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:225
WGL_NO_ACCELERATION_EXT = 8229 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:226
WGL_GENERIC_ACCELERATION_EXT = 8230 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:227
WGL_FULL_ACCELERATION_EXT = 8231 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:228
WGL_SWAP_EXCHANGE_EXT = 8232 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:229
WGL_SWAP_COPY_EXT = 8233 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:230
WGL_SWAP_UNDEFINED_EXT = 8234 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:231
WGL_TYPE_RGBA_EXT = 8235 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:232
WGL_TYPE_COLORINDEX_EXT = 8236 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:233
# EXT_pbuffer (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:236)
WGL_DRAW_TO_PBUFFER_EXT = 8237 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:237
WGL_MAX_PBUFFER_PIXELS_EXT = 514 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:238
WGL_MAX_PBUFFER_WIDTH_EXT = 514 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:239
WGL_MAX_PBUFFER_HEIGHT_EXT = 8240 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:240
WGL_OPTIMAL_PBUFFER_WIDTH_EXT = 8241 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:241
WGL_OPTIMAL_PBUFFER_HEIGHT_EXT = 8242 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:242
WGL_PBUFFER_LARGEST_EXT = 8243 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:243
WGL_PBUFFER_WIDTH_EXT = 8244 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:244
WGL_PBUFFER_HEIGHT_EXT = 8245 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:245
# EXT_depth_float (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:248)
WGL_DEPTH_FLOAT_EXT = 8256 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:249
# 3DFX_multisample (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:252)
WGL_SAMPLE_BUFFERS_3DFX = 8288 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:253
WGL_SAMPLES_3DFX = 8289 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:254
# EXT_multisample (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:257)
WGL_SAMPLE_BUFFERS_EXT = 8257 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:258
WGL_SAMPLES_EXT = 8258 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:259
# I3D_digital_video_control (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:262)
WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D = 8272 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:263
WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D = 8273 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:264
WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D = 8274 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:265
WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D = 8275 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:266
# I3D_gamma (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:269)
WGL_GAMMA_TABLE_SIZE_I3D = 516 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:270
WGL_GAMMA_EXCLUDE_DESKTOP_I3D = 516 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:271
# I3D_genlock (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:274)
WGL_GENLOCK_SOURCE_MULTIVIEW_I3D = 8260 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:275
WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D = 8261 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:276
WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D = 8262 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:277
WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D = 8263 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:278
WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D = 8264 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:279
WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D = 8265 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:280
WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D = 8266 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:281
WGL_GENLOCK_SOURCE_EDGE_RISING_I3D = 8267 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:282
WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D = 8268 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:283
# I3D_image_buffer (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:286)
WGL_IMAGE_BUFFER_MIN_ACCESS_I3D = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:287
WGL_IMAGE_BUFFER_LOCK_I3D = 2 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:288
# I3D_swap_frame_lock (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:291)
# NV_render_depth_texture (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:294)
WGL_BIND_TO_TEXTURE_DEPTH_NV = 8355 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:295
WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV = 8356 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:296
WGL_DEPTH_TEXTURE_FORMAT_NV = 8357 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:297
WGL_TEXTURE_DEPTH_COMPONENT_NV = 8358 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:298
WGL_DEPTH_COMPONENT_NV = 8359 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:299
# NV_render_texture_rectangle (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:302)
WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV = 8352 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:303
WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV = 8353 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:304
WGL_TEXTURE_RECTANGLE_NV = 8354 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:305
# ATI_pixel_format_float (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:308)
WGL_TYPE_RGBA_FLOAT_ATI = 8608 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:309
# NV_float_buffer (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:312)
WGL_FLOAT_COMPONENTS_NV = 8368 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:313
WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV = 8369 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:314
WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV = 8370 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:315
WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV = 8371 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:316
WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV = 8372 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:317
WGL_TEXTURE_FLOAT_R_NV = 8373 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:318
WGL_TEXTURE_FLOAT_RG_NV = 8374 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:319
WGL_TEXTURE_FLOAT_RGB_NV = 8375 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:320
WGL_TEXTURE_FLOAT_RGBA_NV = 8376 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:321
# ARB_pbuffer (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:327)
HANDLE = POINTER(None) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:58
HPBUFFERARB = HANDLE # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:328
# EXT_pbuffer (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:330)
HPBUFFEREXT = HANDLE # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:331
# ARB_buffer_region (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:334)
WGL_ARB_buffer_region = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:335
HDC = HANDLE # C:\cygwin\home\Alex\pyglet\tools\wgl.h:61
UINT = c_uint # C:\cygwin\home\Alex\pyglet\tools\wgl.h:50
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:337
wglCreateBufferRegionARB = _link_function('wglCreateBufferRegionARB', HANDLE, [HDC, c_int, UINT], 'ARB_buffer_region')
VOID = None # C:\cygwin\home\Alex\pyglet\tools\wgl.h:45
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:338
wglDeleteBufferRegionARB = _link_function('wglDeleteBufferRegionARB', VOID, [HANDLE], 'ARB_buffer_region')
BOOL = c_long # C:\cygwin\home\Alex\pyglet\tools\wgl.h:52
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:339
wglSaveBufferRegionARB = _link_function('wglSaveBufferRegionARB', BOOL, [HANDLE, c_int, c_int, c_int, c_int], 'ARB_buffer_region')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:340
wglRestoreBufferRegionARB = _link_function('wglRestoreBufferRegionARB', BOOL, [HANDLE, c_int, c_int, c_int, c_int, c_int, c_int], 'ARB_buffer_region')
PFNWGLCREATEBUFFERREGIONARBPROC = CFUNCTYPE(HANDLE, HDC, c_int, UINT) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:342
PFNWGLDELETEBUFFERREGIONARBPROC = CFUNCTYPE(VOID, HANDLE) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:343
PFNWGLSAVEBUFFERREGIONARBPROC = CFUNCTYPE(BOOL, HANDLE, c_int, c_int, c_int, c_int) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:344
PFNWGLRESTOREBUFFERREGIONARBPROC = CFUNCTYPE(BOOL, HANDLE, c_int, c_int, c_int, c_int, c_int, c_int) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:345
# ARB_multisample (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:348)
WGL_ARB_multisample = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:349
# ARB_extensions_string (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:352)
WGL_ARB_extensions_string = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:353
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:355
wglGetExtensionsStringARB = _link_function('wglGetExtensionsStringARB', c_char_p, [HDC], 'ARB_extensions_string')
PFNWGLGETEXTENSIONSSTRINGARBPROC = CFUNCTYPE(c_char_p, HDC) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:357
# ARB_pixel_format (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:360)
WGL_ARB_pixel_format = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:361
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:363
wglGetPixelFormatAttribivARB = _link_function('wglGetPixelFormatAttribivARB', BOOL, [HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(c_int)], 'ARB_pixel_format')
FLOAT = c_float # C:\cygwin\home\Alex\pyglet\tools\wgl.h:55
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:364
wglGetPixelFormatAttribfvARB = _link_function('wglGetPixelFormatAttribfvARB', BOOL, [HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(FLOAT)], 'ARB_pixel_format')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:365
wglChoosePixelFormatARB = _link_function('wglChoosePixelFormatARB', BOOL, [HDC, POINTER(c_int), POINTER(FLOAT), UINT, POINTER(c_int), POINTER(UINT)], 'ARB_pixel_format')
PFNWGLGETPIXELFORMATATTRIBIVARBPROC = CFUNCTYPE(BOOL, HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(c_int)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:367
PFNWGLGETPIXELFORMATATTRIBFVARBPROC = CFUNCTYPE(BOOL, HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(FLOAT)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:368
PFNWGLCHOOSEPIXELFORMATARBPROC = CFUNCTYPE(BOOL, HDC, POINTER(c_int), POINTER(FLOAT), UINT, POINTER(c_int), POINTER(UINT)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:369
# ARB_make_current_read (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:372)
WGL_ARB_make_current_read = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:373
HGLRC = HANDLE # C:\cygwin\home\Alex\pyglet\tools\wgl.h:60
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:375
wglMakeContextCurrentARB = _link_function('wglMakeContextCurrentARB', BOOL, [HDC, HDC, HGLRC], 'ARB_make_current_read')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:376
wglGetCurrentReadDCARB = _link_function('wglGetCurrentReadDCARB', HDC, [], 'ARB_make_current_read')
PFNWGLMAKECONTEXTCURRENTARBPROC = CFUNCTYPE(BOOL, HDC, HDC, HGLRC) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:378
PFNWGLGETCURRENTREADDCARBPROC = CFUNCTYPE(HDC) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:379
# ARB_pbuffer (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:382)
WGL_ARB_pbuffer = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:383
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:385
wglCreatePbufferARB = _link_function('wglCreatePbufferARB', HPBUFFERARB, [HDC, c_int, c_int, c_int, POINTER(c_int)], 'ARB_pbuffer')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:386
wglGetPbufferDCARB = _link_function('wglGetPbufferDCARB', HDC, [HPBUFFERARB], 'ARB_pbuffer')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:387
wglReleasePbufferDCARB = _link_function('wglReleasePbufferDCARB', c_int, [HPBUFFERARB, HDC], 'ARB_pbuffer')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:388
wglDestroyPbufferARB = _link_function('wglDestroyPbufferARB', BOOL, [HPBUFFERARB], 'ARB_pbuffer')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:389
wglQueryPbufferARB = _link_function('wglQueryPbufferARB', BOOL, [HPBUFFERARB, c_int, POINTER(c_int)], 'ARB_pbuffer')
PFNWGLCREATEPBUFFERARBPROC = CFUNCTYPE(HPBUFFERARB, HDC, c_int, c_int, c_int, POINTER(c_int)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:391
PFNWGLGETPBUFFERDCARBPROC = CFUNCTYPE(HDC, HPBUFFERARB) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:392
PFNWGLRELEASEPBUFFERDCARBPROC = CFUNCTYPE(c_int, HPBUFFERARB, HDC) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:393
PFNWGLDESTROYPBUFFERARBPROC = CFUNCTYPE(BOOL, HPBUFFERARB) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:394
PFNWGLQUERYPBUFFERARBPROC = CFUNCTYPE(BOOL, HPBUFFERARB, c_int, POINTER(c_int)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:395
# ARB_render_texture (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:398)
WGL_ARB_render_texture = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:399
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:401
wglBindTexImageARB = _link_function('wglBindTexImageARB', BOOL, [HPBUFFERARB, c_int], 'ARB_render_texture')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:402
wglReleaseTexImageARB = _link_function('wglReleaseTexImageARB', BOOL, [HPBUFFERARB, c_int], 'ARB_render_texture')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:403
wglSetPbufferAttribARB = _link_function('wglSetPbufferAttribARB', BOOL, [HPBUFFERARB, POINTER(c_int)], 'ARB_render_texture')
PFNWGLBINDTEXIMAGEARBPROC = CFUNCTYPE(BOOL, HPBUFFERARB, c_int) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:405
PFNWGLRELEASETEXIMAGEARBPROC = CFUNCTYPE(BOOL, HPBUFFERARB, c_int) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:406
PFNWGLSETPBUFFERATTRIBARBPROC = CFUNCTYPE(BOOL, HPBUFFERARB, POINTER(c_int)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:407
# ARB_pixel_format_float (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:410)
WGL_ARB_pixel_format_float = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:411
# EXT_display_color_table (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:414)
WGL_EXT_display_color_table = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:415
GLboolean = c_ubyte # C:\cygwin\home\Alex\pyglet\tools\wgl.h:18
GLushort = c_ushort # C:\cygwin\home\Alex\pyglet\tools\wgl.h:25
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:417
wglCreateDisplayColorTableEXT = _link_function('wglCreateDisplayColorTableEXT', GLboolean, [GLushort], 'EXT_display_color_table')
GLuint = c_uint # C:\cygwin\home\Alex\pyglet\tools\wgl.h:26
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:418
wglLoadDisplayColorTableEXT = _link_function('wglLoadDisplayColorTableEXT', GLboolean, [POINTER(GLushort), GLuint], 'EXT_display_color_table')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:419
wglBindDisplayColorTableEXT = _link_function('wglBindDisplayColorTableEXT', GLboolean, [GLushort], 'EXT_display_color_table')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:420
wglDestroyDisplayColorTableEXT = _link_function('wglDestroyDisplayColorTableEXT', VOID, [GLushort], 'EXT_display_color_table')
PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC = CFUNCTYPE(GLboolean, GLushort) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:422
PFNWGLLOADDISPLAYCOLORTABLEEXTPROC = CFUNCTYPE(GLboolean, POINTER(GLushort), GLuint) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:423
PFNWGLBINDDISPLAYCOLORTABLEEXTPROC = CFUNCTYPE(GLboolean, GLushort) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:424
PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC = CFUNCTYPE(VOID, GLushort) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:425
# EXT_extensions_string (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:428)
WGL_EXT_extensions_string = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:429
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:431
wglGetExtensionsStringEXT = _link_function('wglGetExtensionsStringEXT', c_char_p, [], 'EXT_extensions_string')
PFNWGLGETEXTENSIONSSTRINGEXTPROC = CFUNCTYPE(c_char_p) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:433
# EXT_make_current_read (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:436)
WGL_EXT_make_current_read = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:437
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:439
wglMakeContextCurrentEXT = _link_function('wglMakeContextCurrentEXT', BOOL, [HDC, HDC, HGLRC], 'EXT_make_current_read')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:440
wglGetCurrentReadDCEXT = _link_function('wglGetCurrentReadDCEXT', HDC, [], 'EXT_make_current_read')
PFNWGLMAKECONTEXTCURRENTEXTPROC = CFUNCTYPE(BOOL, HDC, HDC, HGLRC) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:442
PFNWGLGETCURRENTREADDCEXTPROC = CFUNCTYPE(HDC) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:443
# EXT_pbuffer (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:446)
WGL_EXT_pbuffer = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:447
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:449
wglCreatePbufferEXT = _link_function('wglCreatePbufferEXT', HPBUFFEREXT, [HDC, c_int, c_int, c_int, POINTER(c_int)], 'EXT_pbuffer')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:450
wglGetPbufferDCEXT = _link_function('wglGetPbufferDCEXT', HDC, [HPBUFFEREXT], 'EXT_pbuffer')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:451
wglReleasePbufferDCEXT = _link_function('wglReleasePbufferDCEXT', c_int, [HPBUFFEREXT, HDC], 'EXT_pbuffer')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:452
wglDestroyPbufferEXT = _link_function('wglDestroyPbufferEXT', BOOL, [HPBUFFEREXT], 'EXT_pbuffer')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:453
wglQueryPbufferEXT = _link_function('wglQueryPbufferEXT', BOOL, [HPBUFFEREXT, c_int, POINTER(c_int)], 'EXT_pbuffer')
PFNWGLCREATEPBUFFEREXTPROC = CFUNCTYPE(HPBUFFEREXT, HDC, c_int, c_int, c_int, POINTER(c_int)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:455
PFNWGLGETPBUFFERDCEXTPROC = CFUNCTYPE(HDC, HPBUFFEREXT) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:456
PFNWGLRELEASEPBUFFERDCEXTPROC = CFUNCTYPE(c_int, HPBUFFEREXT, HDC) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:457
PFNWGLDESTROYPBUFFEREXTPROC = CFUNCTYPE(BOOL, HPBUFFEREXT) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:458
PFNWGLQUERYPBUFFEREXTPROC = CFUNCTYPE(BOOL, HPBUFFEREXT, c_int, POINTER(c_int)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:459
# EXT_pixel_format (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:462)
WGL_EXT_pixel_format = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:463
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:465
wglGetPixelFormatAttribivEXT = _link_function('wglGetPixelFormatAttribivEXT', BOOL, [HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(c_int)], 'EXT_pixel_format')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:466
wglGetPixelFormatAttribfvEXT = _link_function('wglGetPixelFormatAttribfvEXT', BOOL, [HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(FLOAT)], 'EXT_pixel_format')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:467
wglChoosePixelFormatEXT = _link_function('wglChoosePixelFormatEXT', BOOL, [HDC, POINTER(c_int), POINTER(FLOAT), UINT, POINTER(c_int), POINTER(UINT)], 'EXT_pixel_format')
PFNWGLGETPIXELFORMATATTRIBIVEXTPROC = CFUNCTYPE(BOOL, HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(c_int)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:469
PFNWGLGETPIXELFORMATATTRIBFVEXTPROC = CFUNCTYPE(BOOL, HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(FLOAT)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:470
PFNWGLCHOOSEPIXELFORMATEXTPROC = CFUNCTYPE(BOOL, HDC, POINTER(c_int), POINTER(FLOAT), UINT, POINTER(c_int), POINTER(UINT)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:471
# EXT_swap_control (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:474)
WGL_EXT_swap_control = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:475
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:477
wglSwapIntervalEXT = _link_function('wglSwapIntervalEXT', BOOL, [c_int], 'EXT_swap_control')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:478
wglGetSwapIntervalEXT = _link_function('wglGetSwapIntervalEXT', c_int, [], 'EXT_swap_control')
PFNWGLSWAPINTERVALEXTPROC = CFUNCTYPE(BOOL, c_int) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:480
PFNWGLGETSWAPINTERVALEXTPROC = CFUNCTYPE(c_int) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:481
# EXT_depth_float (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:484)
WGL_EXT_depth_float = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:485
# NV_vertex_array_range (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:488)
WGL_NV_vertex_array_range = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:489
GLsizei = c_int # C:\cygwin\home\Alex\pyglet\tools\wgl.h:23
GLfloat = c_float # C:\cygwin\home\Alex\pyglet\tools\wgl.h:27
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:491
wglAllocateMemoryNV = _link_function('wglAllocateMemoryNV', POINTER(c_void), [GLsizei, GLfloat, GLfloat, GLfloat], 'NV_vertex_array_range')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:492
wglFreeMemoryNV = _link_function('wglFreeMemoryNV', None, [POINTER(None)], 'NV_vertex_array_range')
PFNWGLALLOCATEMEMORYNVPROC = CFUNCTYPE(POINTER(c_void), GLsizei, GLfloat, GLfloat, GLfloat) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:494
PFNWGLFREEMEMORYNVPROC = CFUNCTYPE(None, POINTER(None)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:495
# 3DFX_multisample (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:498)
WGL_3DFX_multisample = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:499
# EXT_multisample (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:502)
WGL_EXT_multisample = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:503
# OML_sync_control (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:506)
WGL_OML_sync_control = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:507
INT64 = c_longlong # C:\cygwin\home\Alex\pyglet\tools\wgl.h:42
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:509
wglGetSyncValuesOML = _link_function('wglGetSyncValuesOML', BOOL, [HDC, POINTER(INT64), POINTER(INT64), POINTER(INT64)], 'OML_sync_control')
INT32 = c_int # C:\cygwin\home\Alex\pyglet\tools\wgl.h:35
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:510
wglGetMscRateOML = _link_function('wglGetMscRateOML', BOOL, [HDC, POINTER(INT32), POINTER(INT32)], 'OML_sync_control')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:511
wglSwapBuffersMscOML = _link_function('wglSwapBuffersMscOML', INT64, [HDC, INT64, INT64, INT64], 'OML_sync_control')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:512
wglSwapLayerBuffersMscOML = _link_function('wglSwapLayerBuffersMscOML', INT64, [HDC, c_int, INT64, INT64, INT64], 'OML_sync_control')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:513
wglWaitForMscOML = _link_function('wglWaitForMscOML', BOOL, [HDC, INT64, INT64, INT64, POINTER(INT64), POINTER(INT64), POINTER(INT64)], 'OML_sync_control')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:514
wglWaitForSbcOML = _link_function('wglWaitForSbcOML', BOOL, [HDC, INT64, POINTER(INT64), POINTER(INT64), POINTER(INT64)], 'OML_sync_control')
PFNWGLGETSYNCVALUESOMLPROC = CFUNCTYPE(BOOL, HDC, POINTER(INT64), POINTER(INT64), POINTER(INT64)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:516
PFNWGLGETMSCRATEOMLPROC = CFUNCTYPE(BOOL, HDC, POINTER(INT32), POINTER(INT32)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:517
PFNWGLSWAPBUFFERSMSCOMLPROC = CFUNCTYPE(INT64, HDC, INT64, INT64, INT64) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:518
PFNWGLSWAPLAYERBUFFERSMSCOMLPROC = CFUNCTYPE(INT64, HDC, c_int, INT64, INT64, INT64) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:519
PFNWGLWAITFORMSCOMLPROC = CFUNCTYPE(BOOL, HDC, INT64, INT64, INT64, POINTER(INT64), POINTER(INT64), POINTER(INT64)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:520
PFNWGLWAITFORSBCOMLPROC = CFUNCTYPE(BOOL, HDC, INT64, POINTER(INT64), POINTER(INT64), POINTER(INT64)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:521
# I3D_digital_video_control (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:524)
WGL_I3D_digital_video_control = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:525
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:527
wglGetDigitalVideoParametersI3D = _link_function('wglGetDigitalVideoParametersI3D', BOOL, [HDC, c_int, POINTER(c_int)], 'I3D_digital_video_control')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:528
wglSetDigitalVideoParametersI3D = _link_function('wglSetDigitalVideoParametersI3D', BOOL, [HDC, c_int, POINTER(c_int)], 'I3D_digital_video_control')
PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC = CFUNCTYPE(BOOL, HDC, c_int, POINTER(c_int)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:530
PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC = CFUNCTYPE(BOOL, HDC, c_int, POINTER(c_int)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:531
# I3D_gamma (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:534)
WGL_I3D_gamma = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:535
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:537
wglGetGammaTableParametersI3D = _link_function('wglGetGammaTableParametersI3D', BOOL, [HDC, c_int, POINTER(c_int)], 'I3D_gamma')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:538
wglSetGammaTableParametersI3D = _link_function('wglSetGammaTableParametersI3D', BOOL, [HDC, c_int, POINTER(c_int)], 'I3D_gamma')
USHORT = c_ushort # C:\cygwin\home\Alex\pyglet\tools\wgl.h:49
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:539
wglGetGammaTableI3D = _link_function('wglGetGammaTableI3D', BOOL, [HDC, c_int, POINTER(USHORT), POINTER(USHORT), POINTER(USHORT)], 'I3D_gamma')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:540
wglSetGammaTableI3D = _link_function('wglSetGammaTableI3D', BOOL, [HDC, c_int, POINTER(USHORT), POINTER(USHORT), POINTER(USHORT)], 'I3D_gamma')
PFNWGLGETGAMMATABLEPARAMETERSI3DPROC = CFUNCTYPE(BOOL, HDC, c_int, POINTER(c_int)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:542
PFNWGLSETGAMMATABLEPARAMETERSI3DPROC = CFUNCTYPE(BOOL, HDC, c_int, POINTER(c_int)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:543
PFNWGLGETGAMMATABLEI3DPROC = CFUNCTYPE(BOOL, HDC, c_int, POINTER(USHORT), POINTER(USHORT), POINTER(USHORT)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:544
PFNWGLSETGAMMATABLEI3DPROC = CFUNCTYPE(BOOL, HDC, c_int, POINTER(USHORT), POINTER(USHORT), POINTER(USHORT)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:545
# I3D_genlock (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:548)
WGL_I3D_genlock = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:549
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:551
wglEnableGenlockI3D = _link_function('wglEnableGenlockI3D', BOOL, [HDC], 'I3D_genlock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:552
wglDisableGenlockI3D = _link_function('wglDisableGenlockI3D', BOOL, [HDC], 'I3D_genlock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:553
wglIsEnabledGenlockI3D = _link_function('wglIsEnabledGenlockI3D', BOOL, [HDC, POINTER(BOOL)], 'I3D_genlock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:554
wglGenlockSourceI3D = _link_function('wglGenlockSourceI3D', BOOL, [HDC, UINT], 'I3D_genlock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:555
wglGetGenlockSourceI3D = _link_function('wglGetGenlockSourceI3D', BOOL, [HDC, POINTER(UINT)], 'I3D_genlock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:556
wglGenlockSourceEdgeI3D = _link_function('wglGenlockSourceEdgeI3D', BOOL, [HDC, UINT], 'I3D_genlock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:557
wglGetGenlockSourceEdgeI3D = _link_function('wglGetGenlockSourceEdgeI3D', BOOL, [HDC, POINTER(UINT)], 'I3D_genlock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:558
wglGenlockSampleRateI3D = _link_function('wglGenlockSampleRateI3D', BOOL, [HDC, UINT], 'I3D_genlock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:559
wglGetGenlockSampleRateI3D = _link_function('wglGetGenlockSampleRateI3D', BOOL, [HDC, POINTER(UINT)], 'I3D_genlock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:560
wglGenlockSourceDelayI3D = _link_function('wglGenlockSourceDelayI3D', BOOL, [HDC, UINT], 'I3D_genlock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:561
wglGetGenlockSourceDelayI3D = _link_function('wglGetGenlockSourceDelayI3D', BOOL, [HDC, POINTER(UINT)], 'I3D_genlock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:562
wglQueryGenlockMaxSourceDelayI3D = _link_function('wglQueryGenlockMaxSourceDelayI3D', BOOL, [HDC, POINTER(UINT), POINTER(UINT)], 'I3D_genlock')
PFNWGLENABLEGENLOCKI3DPROC = CFUNCTYPE(BOOL, HDC) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:564
PFNWGLDISABLEGENLOCKI3DPROC = CFUNCTYPE(BOOL, HDC) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:565
PFNWGLISENABLEDGENLOCKI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(BOOL)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:566
PFNWGLGENLOCKSOURCEI3DPROC = CFUNCTYPE(BOOL, HDC, UINT) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:567
PFNWGLGETGENLOCKSOURCEI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(UINT)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:568
PFNWGLGENLOCKSOURCEEDGEI3DPROC = CFUNCTYPE(BOOL, HDC, UINT) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:569
PFNWGLGETGENLOCKSOURCEEDGEI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(UINT)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:570
PFNWGLGENLOCKSAMPLERATEI3DPROC = CFUNCTYPE(BOOL, HDC, UINT) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:571
PFNWGLGETGENLOCKSAMPLERATEI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(UINT)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:572
PFNWGLGENLOCKSOURCEDELAYI3DPROC = CFUNCTYPE(BOOL, HDC, UINT) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:573
PFNWGLGETGENLOCKSOURCEDELAYI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(UINT)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:574
PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(UINT), POINTER(UINT)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:575
# I3D_image_buffer (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:578)
WGL_I3D_image_buffer = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:579
LPVOID = POINTER(None) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:45
DWORD = c_ulong # C:\cygwin\home\Alex\pyglet\tools\wgl.h:54
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:581
wglCreateImageBufferI3D = _link_function('wglCreateImageBufferI3D', LPVOID, [HDC, DWORD, UINT], 'I3D_image_buffer')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:582
wglDestroyImageBufferI3D = _link_function('wglDestroyImageBufferI3D', BOOL, [HDC, LPVOID], 'I3D_image_buffer')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:583
wglAssociateImageBufferEventsI3D = _link_function('wglAssociateImageBufferEventsI3D', BOOL, [HDC, POINTER(HANDLE), POINTER(LPVOID), POINTER(DWORD), UINT], 'I3D_image_buffer')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:584
wglReleaseImageBufferEventsI3D = _link_function('wglReleaseImageBufferEventsI3D', BOOL, [HDC, POINTER(LPVOID), UINT], 'I3D_image_buffer')
PFNWGLCREATEIMAGEBUFFERI3DPROC = CFUNCTYPE(LPVOID, HDC, DWORD, UINT) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:586
PFNWGLDESTROYIMAGEBUFFERI3DPROC = CFUNCTYPE(BOOL, HDC, LPVOID) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:587
PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(HANDLE), POINTER(LPVOID), POINTER(DWORD), UINT) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:588
PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(LPVOID), UINT) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:589
# I3D_swap_frame_lock (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:592)
WGL_I3D_swap_frame_lock = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:593
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:595
wglEnableFrameLockI3D = _link_function('wglEnableFrameLockI3D', BOOL, [], 'I3D_swap_frame_lock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:596
wglDisableFrameLockI3D = _link_function('wglDisableFrameLockI3D', BOOL, [], 'I3D_swap_frame_lock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:597
wglIsEnabledFrameLockI3D = _link_function('wglIsEnabledFrameLockI3D', BOOL, [POINTER(BOOL)], 'I3D_swap_frame_lock')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:598
wglQueryFrameLockMasterI3D = _link_function('wglQueryFrameLockMasterI3D', BOOL, [POINTER(BOOL)], 'I3D_swap_frame_lock')
PFNWGLENABLEFRAMELOCKI3DPROC = CFUNCTYPE(BOOL) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:600
PFNWGLDISABLEFRAMELOCKI3DPROC = CFUNCTYPE(BOOL) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:601
PFNWGLISENABLEDFRAMELOCKI3DPROC = CFUNCTYPE(BOOL, POINTER(BOOL)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:602
PFNWGLQUERYFRAMELOCKMASTERI3DPROC = CFUNCTYPE(BOOL, POINTER(BOOL)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:603
# I3D_swap_frame_usage (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:606)
WGL_I3D_swap_frame_usage = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:607
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:609
wglGetFrameUsageI3D = _link_function('wglGetFrameUsageI3D', BOOL, [POINTER(c_float)], 'I3D_swap_frame_usage')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:610
wglBeginFrameTrackingI3D = _link_function('wglBeginFrameTrackingI3D', BOOL, [], 'I3D_swap_frame_usage')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:611
wglEndFrameTrackingI3D = _link_function('wglEndFrameTrackingI3D', BOOL, [], 'I3D_swap_frame_usage')
# http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:612
wglQueryFrameTrackingI3D = _link_function('wglQueryFrameTrackingI3D', BOOL, [POINTER(DWORD), POINTER(DWORD), POINTER(c_float)], 'I3D_swap_frame_usage')
PFNWGLGETFRAMEUSAGEI3DPROC = CFUNCTYPE(BOOL, POINTER(c_float)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:614
PFNWGLBEGINFRAMETRACKINGI3DPROC = CFUNCTYPE(BOOL) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:615
PFNWGLENDFRAMETRACKINGI3DPROC = CFUNCTYPE(BOOL) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:616
PFNWGLQUERYFRAMETRACKINGI3DPROC = CFUNCTYPE(BOOL, POINTER(DWORD), POINTER(DWORD), POINTER(c_float)) # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:617
# ATI_pixel_format_float (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:620)
WGL_ATI_pixel_format_float = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:621
# NV_float_buffer (http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:624)
WGL_NV_float_buffer = 1 # http://oss.sgi.com/projects/ogl-sample/ABI/wglext.h:625
__all__ = ['WIN32_LEAN_AND_MEAN', 'GLAPI', 'WGL_WGLEXT_VERSION',
'WGL_FRONT_COLOR_BUFFER_BIT_ARB', 'WGL_BACK_COLOR_BUFFER_BIT_ARB',
'WGL_DEPTH_BUFFER_BIT_ARB', 'WGL_STENCIL_BUFFER_BIT_ARB',
'WGL_SAMPLE_BUFFERS_ARB', 'WGL_SAMPLES_ARB', 'WGL_NUMBER_PIXEL_FORMATS_ARB',
'WGL_DRAW_TO_WINDOW_ARB', 'WGL_DRAW_TO_BITMAP_ARB', 'WGL_ACCELERATION_ARB',
'WGL_NEED_PALETTE_ARB', 'WGL_NEED_SYSTEM_PALETTE_ARB',
'WGL_SWAP_LAYER_BUFFERS_ARB', 'WGL_SWAP_METHOD_ARB',
'WGL_NUMBER_OVERLAYS_ARB', 'WGL_NUMBER_UNDERLAYS_ARB', 'WGL_TRANSPARENT_ARB',
'WGL_TRANSPARENT_RED_VALUE_ARB', 'WGL_TRANSPARENT_GREEN_VALUE_ARB',
'WGL_TRANSPARENT_BLUE_VALUE_ARB', 'WGL_TRANSPARENT_ALPHA_VALUE_ARB',
'WGL_TRANSPARENT_INDEX_VALUE_ARB', 'WGL_SHARE_DEPTH_ARB',
'WGL_SHARE_STENCIL_ARB', 'WGL_SHARE_ACCUM_ARB', 'WGL_SUPPORT_GDI_ARB',
'WGL_SUPPORT_OPENGL_ARB', 'WGL_DOUBLE_BUFFER_ARB', 'WGL_STEREO_ARB',
'WGL_PIXEL_TYPE_ARB', 'WGL_COLOR_BITS_ARB', 'WGL_RED_BITS_ARB',
'WGL_RED_SHIFT_ARB', 'WGL_GREEN_BITS_ARB', 'WGL_GREEN_SHIFT_ARB',
'WGL_BLUE_BITS_ARB', 'WGL_BLUE_SHIFT_ARB', 'WGL_ALPHA_BITS_ARB',
'WGL_ALPHA_SHIFT_ARB', 'WGL_ACCUM_BITS_ARB', 'WGL_ACCUM_RED_BITS_ARB',
'WGL_ACCUM_GREEN_BITS_ARB', 'WGL_ACCUM_BLUE_BITS_ARB',
'WGL_ACCUM_ALPHA_BITS_ARB', 'WGL_DEPTH_BITS_ARB', 'WGL_STENCIL_BITS_ARB',
'WGL_AUX_BUFFERS_ARB', 'WGL_NO_ACCELERATION_ARB',
'WGL_GENERIC_ACCELERATION_ARB', 'WGL_FULL_ACCELERATION_ARB',
'WGL_SWAP_EXCHANGE_ARB', 'WGL_SWAP_COPY_ARB', 'WGL_SWAP_UNDEFINED_ARB',
'WGL_TYPE_RGBA_ARB', 'WGL_TYPE_COLORINDEX_ARB',
'ERROR_INVALID_PIXEL_TYPE_ARB', 'ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB',
'WGL_DRAW_TO_PBUFFER_ARB', 'WGL_MAX_PBUFFER_PIXELS_ARB',
'WGL_MAX_PBUFFER_WIDTH_ARB', 'WGL_MAX_PBUFFER_HEIGHT_ARB',
'WGL_PBUFFER_LARGEST_ARB', 'WGL_PBUFFER_WIDTH_ARB', 'WGL_PBUFFER_HEIGHT_ARB',
'WGL_PBUFFER_LOST_ARB', 'WGL_BIND_TO_TEXTURE_RGB_ARB',
'WGL_BIND_TO_TEXTURE_RGBA_ARB', 'WGL_TEXTURE_FORMAT_ARB',
'WGL_TEXTURE_TARGET_ARB', 'WGL_MIPMAP_TEXTURE_ARB', 'WGL_TEXTURE_RGB_ARB',
'WGL_TEXTURE_RGBA_ARB', 'WGL_NO_TEXTURE_ARB', 'WGL_TEXTURE_CUBE_MAP_ARB',
'WGL_TEXTURE_1D_ARB', 'WGL_TEXTURE_2D_ARB', 'WGL_MIPMAP_LEVEL_ARB',
'WGL_CUBE_MAP_FACE_ARB', 'WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB',
'WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB', 'WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB',
'WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB', 'WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB',
'WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB', 'WGL_FRONT_LEFT_ARB',
'WGL_FRONT_RIGHT_ARB', 'WGL_BACK_LEFT_ARB', 'WGL_BACK_RIGHT_ARB',
'WGL_AUX0_ARB', 'WGL_AUX1_ARB', 'WGL_AUX2_ARB', 'WGL_AUX3_ARB',
'WGL_AUX4_ARB', 'WGL_AUX5_ARB', 'WGL_AUX6_ARB', 'WGL_AUX7_ARB',
'WGL_AUX8_ARB', 'WGL_AUX9_ARB', 'WGL_TYPE_RGBA_FLOAT_ARB',
'ERROR_INVALID_PIXEL_TYPE_EXT', 'WGL_NUMBER_PIXEL_FORMATS_EXT',
'WGL_DRAW_TO_WINDOW_EXT', 'WGL_DRAW_TO_BITMAP_EXT', 'WGL_ACCELERATION_EXT',
'WGL_NEED_PALETTE_EXT', 'WGL_NEED_SYSTEM_PALETTE_EXT',
'WGL_SWAP_LAYER_BUFFERS_EXT', 'WGL_SWAP_METHOD_EXT',
'WGL_NUMBER_OVERLAYS_EXT', 'WGL_NUMBER_UNDERLAYS_EXT', 'WGL_TRANSPARENT_EXT',
'WGL_TRANSPARENT_VALUE_EXT', 'WGL_SHARE_DEPTH_EXT', 'WGL_SHARE_STENCIL_EXT',
'WGL_SHARE_ACCUM_EXT', 'WGL_SUPPORT_GDI_EXT', 'WGL_SUPPORT_OPENGL_EXT',
'WGL_DOUBLE_BUFFER_EXT', 'WGL_STEREO_EXT', 'WGL_PIXEL_TYPE_EXT',
'WGL_COLOR_BITS_EXT', 'WGL_RED_BITS_EXT', 'WGL_RED_SHIFT_EXT',
'WGL_GREEN_BITS_EXT', 'WGL_GREEN_SHIFT_EXT', 'WGL_BLUE_BITS_EXT',
'WGL_BLUE_SHIFT_EXT', 'WGL_ALPHA_BITS_EXT', 'WGL_ALPHA_SHIFT_EXT',
'WGL_ACCUM_BITS_EXT', 'WGL_ACCUM_RED_BITS_EXT', 'WGL_ACCUM_GREEN_BITS_EXT',
'WGL_ACCUM_BLUE_BITS_EXT', 'WGL_ACCUM_ALPHA_BITS_EXT', 'WGL_DEPTH_BITS_EXT',
'WGL_STENCIL_BITS_EXT', 'WGL_AUX_BUFFERS_EXT', 'WGL_NO_ACCELERATION_EXT',
'WGL_GENERIC_ACCELERATION_EXT', 'WGL_FULL_ACCELERATION_EXT',
'WGL_SWAP_EXCHANGE_EXT', 'WGL_SWAP_COPY_EXT', 'WGL_SWAP_UNDEFINED_EXT',
'WGL_TYPE_RGBA_EXT', 'WGL_TYPE_COLORINDEX_EXT', 'WGL_DRAW_TO_PBUFFER_EXT',
'WGL_MAX_PBUFFER_PIXELS_EXT', 'WGL_MAX_PBUFFER_WIDTH_EXT',
'WGL_MAX_PBUFFER_HEIGHT_EXT', 'WGL_OPTIMAL_PBUFFER_WIDTH_EXT',
'WGL_OPTIMAL_PBUFFER_HEIGHT_EXT', 'WGL_PBUFFER_LARGEST_EXT',
'WGL_PBUFFER_WIDTH_EXT', 'WGL_PBUFFER_HEIGHT_EXT', 'WGL_DEPTH_FLOAT_EXT',
'WGL_SAMPLE_BUFFERS_3DFX', 'WGL_SAMPLES_3DFX', 'WGL_SAMPLE_BUFFERS_EXT',
'WGL_SAMPLES_EXT', 'WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D',
'WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D',
'WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D',
'WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D', 'WGL_GAMMA_TABLE_SIZE_I3D',
'WGL_GAMMA_EXCLUDE_DESKTOP_I3D', 'WGL_GENLOCK_SOURCE_MULTIVIEW_I3D',
'WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D', 'WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D',
'WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D', 'WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D',
'WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D', 'WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D',
'WGL_GENLOCK_SOURCE_EDGE_RISING_I3D', 'WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D',
'WGL_IMAGE_BUFFER_MIN_ACCESS_I3D', 'WGL_IMAGE_BUFFER_LOCK_I3D',
'WGL_BIND_TO_TEXTURE_DEPTH_NV', 'WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV',
'WGL_DEPTH_TEXTURE_FORMAT_NV', 'WGL_TEXTURE_DEPTH_COMPONENT_NV',
'WGL_DEPTH_COMPONENT_NV', 'WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV',
'WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV', 'WGL_TEXTURE_RECTANGLE_NV',
'WGL_TYPE_RGBA_FLOAT_ATI', 'WGL_FLOAT_COMPONENTS_NV',
'WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV',
'WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV',
'WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV',
'WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV', 'WGL_TEXTURE_FLOAT_R_NV',
'WGL_TEXTURE_FLOAT_RG_NV', 'WGL_TEXTURE_FLOAT_RGB_NV',
'WGL_TEXTURE_FLOAT_RGBA_NV', 'HPBUFFERARB', 'HPBUFFEREXT',
'WGL_ARB_buffer_region', 'wglCreateBufferRegionARB',
'wglDeleteBufferRegionARB', 'wglSaveBufferRegionARB',
'wglRestoreBufferRegionARB', 'PFNWGLCREATEBUFFERREGIONARBPROC',
'PFNWGLDELETEBUFFERREGIONARBPROC', 'PFNWGLSAVEBUFFERREGIONARBPROC',
'PFNWGLRESTOREBUFFERREGIONARBPROC', 'WGL_ARB_multisample',
'WGL_ARB_extensions_string', 'wglGetExtensionsStringARB',
'PFNWGLGETEXTENSIONSSTRINGARBPROC', 'WGL_ARB_pixel_format',
'wglGetPixelFormatAttribivARB', 'wglGetPixelFormatAttribfvARB',
'wglChoosePixelFormatARB', 'PFNWGLGETPIXELFORMATATTRIBIVARBPROC',
'PFNWGLGETPIXELFORMATATTRIBFVARBPROC', 'PFNWGLCHOOSEPIXELFORMATARBPROC',
'WGL_ARB_make_current_read', 'wglMakeContextCurrentARB',
'wglGetCurrentReadDCARB', 'PFNWGLMAKECONTEXTCURRENTARBPROC',
'PFNWGLGETCURRENTREADDCARBPROC', 'WGL_ARB_pbuffer', 'wglCreatePbufferARB',
'wglGetPbufferDCARB', 'wglReleasePbufferDCARB', 'wglDestroyPbufferARB',
'wglQueryPbufferARB', 'PFNWGLCREATEPBUFFERARBPROC',
'PFNWGLGETPBUFFERDCARBPROC', 'PFNWGLRELEASEPBUFFERDCARBPROC',
'PFNWGLDESTROYPBUFFERARBPROC', 'PFNWGLQUERYPBUFFERARBPROC',
'WGL_ARB_render_texture', 'wglBindTexImageARB', 'wglReleaseTexImageARB',
'wglSetPbufferAttribARB', 'PFNWGLBINDTEXIMAGEARBPROC',
'PFNWGLRELEASETEXIMAGEARBPROC', 'PFNWGLSETPBUFFERATTRIBARBPROC',
'WGL_ARB_pixel_format_float', 'WGL_EXT_display_color_table',
'wglCreateDisplayColorTableEXT', 'wglLoadDisplayColorTableEXT',
'wglBindDisplayColorTableEXT', 'wglDestroyDisplayColorTableEXT',
'PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC', 'PFNWGLLOADDISPLAYCOLORTABLEEXTPROC',
'PFNWGLBINDDISPLAYCOLORTABLEEXTPROC', 'PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC',
'WGL_EXT_extensions_string', 'wglGetExtensionsStringEXT',
'PFNWGLGETEXTENSIONSSTRINGEXTPROC', 'WGL_EXT_make_current_read',
'wglMakeContextCurrentEXT', 'wglGetCurrentReadDCEXT',
'PFNWGLMAKECONTEXTCURRENTEXTPROC', 'PFNWGLGETCURRENTREADDCEXTPROC',
'WGL_EXT_pbuffer', 'wglCreatePbufferEXT', 'wglGetPbufferDCEXT',
'wglReleasePbufferDCEXT', 'wglDestroyPbufferEXT', 'wglQueryPbufferEXT',
'PFNWGLCREATEPBUFFEREXTPROC', 'PFNWGLGETPBUFFERDCEXTPROC',
'PFNWGLRELEASEPBUFFERDCEXTPROC', 'PFNWGLDESTROYPBUFFEREXTPROC',
'PFNWGLQUERYPBUFFEREXTPROC', 'WGL_EXT_pixel_format',
'wglGetPixelFormatAttribivEXT', 'wglGetPixelFormatAttribfvEXT',
'wglChoosePixelFormatEXT', 'PFNWGLGETPIXELFORMATATTRIBIVEXTPROC',
'PFNWGLGETPIXELFORMATATTRIBFVEXTPROC', 'PFNWGLCHOOSEPIXELFORMATEXTPROC',
'WGL_EXT_swap_control', 'wglSwapIntervalEXT', 'wglGetSwapIntervalEXT',
'PFNWGLSWAPINTERVALEXTPROC', 'PFNWGLGETSWAPINTERVALEXTPROC',
'WGL_EXT_depth_float', 'WGL_NV_vertex_array_range', 'wglAllocateMemoryNV',
'wglFreeMemoryNV', 'PFNWGLALLOCATEMEMORYNVPROC', 'PFNWGLFREEMEMORYNVPROC',
'WGL_3DFX_multisample', 'WGL_EXT_multisample', 'WGL_OML_sync_control',
'wglGetSyncValuesOML', 'wglGetMscRateOML', 'wglSwapBuffersMscOML',
'wglSwapLayerBuffersMscOML', 'wglWaitForMscOML', 'wglWaitForSbcOML',
'PFNWGLGETSYNCVALUESOMLPROC', 'PFNWGLGETMSCRATEOMLPROC',
'PFNWGLSWAPBUFFERSMSCOMLPROC', 'PFNWGLSWAPLAYERBUFFERSMSCOMLPROC',
'PFNWGLWAITFORMSCOMLPROC', 'PFNWGLWAITFORSBCOMLPROC',
'WGL_I3D_digital_video_control', 'wglGetDigitalVideoParametersI3D',
'wglSetDigitalVideoParametersI3D', 'PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC',
'PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC', 'WGL_I3D_gamma',
'wglGetGammaTableParametersI3D', 'wglSetGammaTableParametersI3D',
'wglGetGammaTableI3D', 'wglSetGammaTableI3D',
'PFNWGLGETGAMMATABLEPARAMETERSI3DPROC',
'PFNWGLSETGAMMATABLEPARAMETERSI3DPROC', 'PFNWGLGETGAMMATABLEI3DPROC',
'PFNWGLSETGAMMATABLEI3DPROC', 'WGL_I3D_genlock', 'wglEnableGenlockI3D',
'wglDisableGenlockI3D', 'wglIsEnabledGenlockI3D', 'wglGenlockSourceI3D',
'wglGetGenlockSourceI3D', 'wglGenlockSourceEdgeI3D',
'wglGetGenlockSourceEdgeI3D', 'wglGenlockSampleRateI3D',
'wglGetGenlockSampleRateI3D', 'wglGenlockSourceDelayI3D',
'wglGetGenlockSourceDelayI3D', 'wglQueryGenlockMaxSourceDelayI3D',
'PFNWGLENABLEGENLOCKI3DPROC', 'PFNWGLDISABLEGENLOCKI3DPROC',
'PFNWGLISENABLEDGENLOCKI3DPROC', 'PFNWGLGENLOCKSOURCEI3DPROC',
'PFNWGLGETGENLOCKSOURCEI3DPROC', 'PFNWGLGENLOCKSOURCEEDGEI3DPROC',
'PFNWGLGETGENLOCKSOURCEEDGEI3DPROC', 'PFNWGLGENLOCKSAMPLERATEI3DPROC',
'PFNWGLGETGENLOCKSAMPLERATEI3DPROC', 'PFNWGLGENLOCKSOURCEDELAYI3DPROC',
'PFNWGLGETGENLOCKSOURCEDELAYI3DPROC',
'PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC', 'WGL_I3D_image_buffer',
'wglCreateImageBufferI3D', 'wglDestroyImageBufferI3D',
'wglAssociateImageBufferEventsI3D', 'wglReleaseImageBufferEventsI3D',
'PFNWGLCREATEIMAGEBUFFERI3DPROC', 'PFNWGLDESTROYIMAGEBUFFERI3DPROC',
'PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC',
'PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC', 'WGL_I3D_swap_frame_lock',
'wglEnableFrameLockI3D', 'wglDisableFrameLockI3D', 'wglIsEnabledFrameLockI3D',
'wglQueryFrameLockMasterI3D', 'PFNWGLENABLEFRAMELOCKI3DPROC',
'PFNWGLDISABLEFRAMELOCKI3DPROC', 'PFNWGLISENABLEDFRAMELOCKI3DPROC',
'PFNWGLQUERYFRAMELOCKMASTERI3DPROC', 'WGL_I3D_swap_frame_usage',
'wglGetFrameUsageI3D', 'wglBeginFrameTrackingI3D', 'wglEndFrameTrackingI3D',
'wglQueryFrameTrackingI3D', 'PFNWGLGETFRAMEUSAGEI3DPROC',
'PFNWGLBEGINFRAMETRACKINGI3DPROC', 'PFNWGLENDFRAMETRACKINGI3DPROC',
'PFNWGLQUERYFRAMETRACKINGI3DPROC', 'WGL_ATI_pixel_format_float',
'WGL_NV_float_buffer']
# END GENERATED CONTENT (do not edit above this line)

909
pyglet/gl/wglext_nv.py Normal file
View file

@ -0,0 +1,909 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Wrapper for http://developer.download.nvidia.com/opengl/includes/wglext.h
Generated by tools/gengl.py.
Do not modify this file.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: gengl.py 601 2007-02-04 05:36:59Z Alex.Holkner $'
from ctypes import *
from pyglet.gl.lib import link_WGL as _link_function
from pyglet.gl.lib import c_ptrdiff_t, c_void
# BEGIN GENERATED CONTENT (do not edit below this line)
# This content is generated by tools/gengl.py.
# Wrapper for http://developer.download.nvidia.com/opengl/includes/wglext.h
# H (C:\cygwin\home\Alex\pyglet\tools\wgl.h:7)
# H (C:\cygwin\home\Alex\pyglet\tools\wgl.h:7)
WIN32_LEAN_AND_MEAN = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:40
GLAPI = 0 # http://developer.download.nvidia.com/opengl/includes/wglext.h:51
WGL_WGLEXT_VERSION = 6 # http://developer.download.nvidia.com/opengl/includes/wglext.h:60
# ARB_buffer_region (http://developer.download.nvidia.com/opengl/includes/wglext.h:62)
WGL_FRONT_COLOR_BUFFER_BIT_ARB = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:63
WGL_BACK_COLOR_BUFFER_BIT_ARB = 2 # http://developer.download.nvidia.com/opengl/includes/wglext.h:64
WGL_DEPTH_BUFFER_BIT_ARB = 4 # http://developer.download.nvidia.com/opengl/includes/wglext.h:65
WGL_STENCIL_BUFFER_BIT_ARB = 8 # http://developer.download.nvidia.com/opengl/includes/wglext.h:66
# ARB_multisample (http://developer.download.nvidia.com/opengl/includes/wglext.h:69)
WGL_SAMPLE_BUFFERS_ARB = 8257 # http://developer.download.nvidia.com/opengl/includes/wglext.h:70
WGL_SAMPLES_ARB = 8258 # http://developer.download.nvidia.com/opengl/includes/wglext.h:71
# ARB_extensions_string (http://developer.download.nvidia.com/opengl/includes/wglext.h:74)
# ARB_pixel_format (http://developer.download.nvidia.com/opengl/includes/wglext.h:77)
WGL_NUMBER_PIXEL_FORMATS_ARB = 8192 # http://developer.download.nvidia.com/opengl/includes/wglext.h:78
WGL_DRAW_TO_WINDOW_ARB = 8193 # http://developer.download.nvidia.com/opengl/includes/wglext.h:79
WGL_DRAW_TO_BITMAP_ARB = 8194 # http://developer.download.nvidia.com/opengl/includes/wglext.h:80
WGL_ACCELERATION_ARB = 8195 # http://developer.download.nvidia.com/opengl/includes/wglext.h:81
WGL_NEED_PALETTE_ARB = 8196 # http://developer.download.nvidia.com/opengl/includes/wglext.h:82
WGL_NEED_SYSTEM_PALETTE_ARB = 8197 # http://developer.download.nvidia.com/opengl/includes/wglext.h:83
WGL_SWAP_LAYER_BUFFERS_ARB = 8198 # http://developer.download.nvidia.com/opengl/includes/wglext.h:84
WGL_SWAP_METHOD_ARB = 8199 # http://developer.download.nvidia.com/opengl/includes/wglext.h:85
WGL_NUMBER_OVERLAYS_ARB = 8200 # http://developer.download.nvidia.com/opengl/includes/wglext.h:86
WGL_NUMBER_UNDERLAYS_ARB = 8201 # http://developer.download.nvidia.com/opengl/includes/wglext.h:87
WGL_TRANSPARENT_ARB = 8202 # http://developer.download.nvidia.com/opengl/includes/wglext.h:88
WGL_TRANSPARENT_RED_VALUE_ARB = 8247 # http://developer.download.nvidia.com/opengl/includes/wglext.h:89
WGL_TRANSPARENT_GREEN_VALUE_ARB = 8248 # http://developer.download.nvidia.com/opengl/includes/wglext.h:90
WGL_TRANSPARENT_BLUE_VALUE_ARB = 8249 # http://developer.download.nvidia.com/opengl/includes/wglext.h:91
WGL_TRANSPARENT_ALPHA_VALUE_ARB = 8250 # http://developer.download.nvidia.com/opengl/includes/wglext.h:92
WGL_TRANSPARENT_INDEX_VALUE_ARB = 8251 # http://developer.download.nvidia.com/opengl/includes/wglext.h:93
WGL_SHARE_DEPTH_ARB = 8204 # http://developer.download.nvidia.com/opengl/includes/wglext.h:94
WGL_SHARE_STENCIL_ARB = 8205 # http://developer.download.nvidia.com/opengl/includes/wglext.h:95
WGL_SHARE_ACCUM_ARB = 512 # http://developer.download.nvidia.com/opengl/includes/wglext.h:96
WGL_SUPPORT_GDI_ARB = 512 # http://developer.download.nvidia.com/opengl/includes/wglext.h:97
WGL_SUPPORT_OPENGL_ARB = 8208 # http://developer.download.nvidia.com/opengl/includes/wglext.h:98
WGL_DOUBLE_BUFFER_ARB = 8209 # http://developer.download.nvidia.com/opengl/includes/wglext.h:99
WGL_STEREO_ARB = 8210 # http://developer.download.nvidia.com/opengl/includes/wglext.h:100
WGL_PIXEL_TYPE_ARB = 8211 # http://developer.download.nvidia.com/opengl/includes/wglext.h:101
WGL_COLOR_BITS_ARB = 8212 # http://developer.download.nvidia.com/opengl/includes/wglext.h:102
WGL_RED_BITS_ARB = 8213 # http://developer.download.nvidia.com/opengl/includes/wglext.h:103
WGL_RED_SHIFT_ARB = 8214 # http://developer.download.nvidia.com/opengl/includes/wglext.h:104
WGL_GREEN_BITS_ARB = 8215 # http://developer.download.nvidia.com/opengl/includes/wglext.h:105
WGL_GREEN_SHIFT_ARB = 8216 # http://developer.download.nvidia.com/opengl/includes/wglext.h:106
WGL_BLUE_BITS_ARB = 8217 # http://developer.download.nvidia.com/opengl/includes/wglext.h:107
WGL_BLUE_SHIFT_ARB = 8218 # http://developer.download.nvidia.com/opengl/includes/wglext.h:108
WGL_ALPHA_BITS_ARB = 8219 # http://developer.download.nvidia.com/opengl/includes/wglext.h:109
WGL_ALPHA_SHIFT_ARB = 8220 # http://developer.download.nvidia.com/opengl/includes/wglext.h:110
WGL_ACCUM_BITS_ARB = 8221 # http://developer.download.nvidia.com/opengl/includes/wglext.h:111
WGL_ACCUM_RED_BITS_ARB = 513 # http://developer.download.nvidia.com/opengl/includes/wglext.h:112
WGL_ACCUM_GREEN_BITS_ARB = 513 # http://developer.download.nvidia.com/opengl/includes/wglext.h:113
WGL_ACCUM_BLUE_BITS_ARB = 8224 # http://developer.download.nvidia.com/opengl/includes/wglext.h:114
WGL_ACCUM_ALPHA_BITS_ARB = 8225 # http://developer.download.nvidia.com/opengl/includes/wglext.h:115
WGL_DEPTH_BITS_ARB = 8226 # http://developer.download.nvidia.com/opengl/includes/wglext.h:116
WGL_STENCIL_BITS_ARB = 8227 # http://developer.download.nvidia.com/opengl/includes/wglext.h:117
WGL_AUX_BUFFERS_ARB = 8228 # http://developer.download.nvidia.com/opengl/includes/wglext.h:118
WGL_NO_ACCELERATION_ARB = 8229 # http://developer.download.nvidia.com/opengl/includes/wglext.h:119
WGL_GENERIC_ACCELERATION_ARB = 8230 # http://developer.download.nvidia.com/opengl/includes/wglext.h:120
WGL_FULL_ACCELERATION_ARB = 8231 # http://developer.download.nvidia.com/opengl/includes/wglext.h:121
WGL_SWAP_EXCHANGE_ARB = 8232 # http://developer.download.nvidia.com/opengl/includes/wglext.h:122
WGL_SWAP_COPY_ARB = 8233 # http://developer.download.nvidia.com/opengl/includes/wglext.h:123
WGL_SWAP_UNDEFINED_ARB = 8234 # http://developer.download.nvidia.com/opengl/includes/wglext.h:124
WGL_TYPE_RGBA_ARB = 8235 # http://developer.download.nvidia.com/opengl/includes/wglext.h:125
WGL_TYPE_COLORINDEX_ARB = 8236 # http://developer.download.nvidia.com/opengl/includes/wglext.h:126
# ARB_make_current_read (http://developer.download.nvidia.com/opengl/includes/wglext.h:129)
ERROR_INVALID_PIXEL_TYPE_ARB = 8259 # http://developer.download.nvidia.com/opengl/includes/wglext.h:130
ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB = 8276 # http://developer.download.nvidia.com/opengl/includes/wglext.h:131
# ARB_pbuffer (http://developer.download.nvidia.com/opengl/includes/wglext.h:134)
WGL_DRAW_TO_PBUFFER_ARB = 8237 # http://developer.download.nvidia.com/opengl/includes/wglext.h:135
WGL_MAX_PBUFFER_PIXELS_ARB = 514 # http://developer.download.nvidia.com/opengl/includes/wglext.h:136
WGL_MAX_PBUFFER_WIDTH_ARB = 514 # http://developer.download.nvidia.com/opengl/includes/wglext.h:137
WGL_MAX_PBUFFER_HEIGHT_ARB = 8240 # http://developer.download.nvidia.com/opengl/includes/wglext.h:138
WGL_PBUFFER_LARGEST_ARB = 8243 # http://developer.download.nvidia.com/opengl/includes/wglext.h:139
WGL_PBUFFER_WIDTH_ARB = 8244 # http://developer.download.nvidia.com/opengl/includes/wglext.h:140
WGL_PBUFFER_HEIGHT_ARB = 8245 # http://developer.download.nvidia.com/opengl/includes/wglext.h:141
WGL_PBUFFER_LOST_ARB = 8246 # http://developer.download.nvidia.com/opengl/includes/wglext.h:142
# ARB_render_texture (http://developer.download.nvidia.com/opengl/includes/wglext.h:145)
WGL_BIND_TO_TEXTURE_RGB_ARB = 8304 # http://developer.download.nvidia.com/opengl/includes/wglext.h:146
WGL_BIND_TO_TEXTURE_RGBA_ARB = 8305 # http://developer.download.nvidia.com/opengl/includes/wglext.h:147
WGL_TEXTURE_FORMAT_ARB = 8306 # http://developer.download.nvidia.com/opengl/includes/wglext.h:148
WGL_TEXTURE_TARGET_ARB = 8307 # http://developer.download.nvidia.com/opengl/includes/wglext.h:149
WGL_MIPMAP_TEXTURE_ARB = 8308 # http://developer.download.nvidia.com/opengl/includes/wglext.h:150
WGL_TEXTURE_RGB_ARB = 8309 # http://developer.download.nvidia.com/opengl/includes/wglext.h:151
WGL_TEXTURE_RGBA_ARB = 8310 # http://developer.download.nvidia.com/opengl/includes/wglext.h:152
WGL_NO_TEXTURE_ARB = 8311 # http://developer.download.nvidia.com/opengl/includes/wglext.h:153
WGL_TEXTURE_CUBE_MAP_ARB = 8312 # http://developer.download.nvidia.com/opengl/includes/wglext.h:154
WGL_TEXTURE_1D_ARB = 8313 # http://developer.download.nvidia.com/opengl/includes/wglext.h:155
WGL_TEXTURE_2D_ARB = 8314 # http://developer.download.nvidia.com/opengl/includes/wglext.h:156
WGL_MIPMAP_LEVEL_ARB = 8315 # http://developer.download.nvidia.com/opengl/includes/wglext.h:157
WGL_CUBE_MAP_FACE_ARB = 8316 # http://developer.download.nvidia.com/opengl/includes/wglext.h:158
WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = 8317 # http://developer.download.nvidia.com/opengl/includes/wglext.h:159
WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = 519 # http://developer.download.nvidia.com/opengl/includes/wglext.h:160
WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = 519 # http://developer.download.nvidia.com/opengl/includes/wglext.h:161
WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = 8320 # http://developer.download.nvidia.com/opengl/includes/wglext.h:162
WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = 8321 # http://developer.download.nvidia.com/opengl/includes/wglext.h:163
WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = 8322 # http://developer.download.nvidia.com/opengl/includes/wglext.h:164
WGL_FRONT_LEFT_ARB = 8323 # http://developer.download.nvidia.com/opengl/includes/wglext.h:165
WGL_FRONT_RIGHT_ARB = 8324 # http://developer.download.nvidia.com/opengl/includes/wglext.h:166
WGL_BACK_LEFT_ARB = 8325 # http://developer.download.nvidia.com/opengl/includes/wglext.h:167
WGL_BACK_RIGHT_ARB = 8326 # http://developer.download.nvidia.com/opengl/includes/wglext.h:168
WGL_AUX0_ARB = 8327 # http://developer.download.nvidia.com/opengl/includes/wglext.h:169
WGL_AUX1_ARB = 8328 # http://developer.download.nvidia.com/opengl/includes/wglext.h:170
WGL_AUX2_ARB = 8329 # http://developer.download.nvidia.com/opengl/includes/wglext.h:171
WGL_AUX3_ARB = 8330 # http://developer.download.nvidia.com/opengl/includes/wglext.h:172
WGL_AUX4_ARB = 8331 # http://developer.download.nvidia.com/opengl/includes/wglext.h:173
WGL_AUX5_ARB = 8332 # http://developer.download.nvidia.com/opengl/includes/wglext.h:174
WGL_AUX6_ARB = 8333 # http://developer.download.nvidia.com/opengl/includes/wglext.h:175
WGL_AUX7_ARB = 520 # http://developer.download.nvidia.com/opengl/includes/wglext.h:176
WGL_AUX8_ARB = 520 # http://developer.download.nvidia.com/opengl/includes/wglext.h:177
WGL_AUX9_ARB = 8336 # http://developer.download.nvidia.com/opengl/includes/wglext.h:178
# ARB_pixel_format_float (http://developer.download.nvidia.com/opengl/includes/wglext.h:181)
WGL_TYPE_RGBA_FLOAT_ARB = 8608 # http://developer.download.nvidia.com/opengl/includes/wglext.h:182
# EXT_make_current_read (http://developer.download.nvidia.com/opengl/includes/wglext.h:185)
ERROR_INVALID_PIXEL_TYPE_EXT = 8259 # http://developer.download.nvidia.com/opengl/includes/wglext.h:186
# EXT_pixel_format (http://developer.download.nvidia.com/opengl/includes/wglext.h:189)
WGL_NUMBER_PIXEL_FORMATS_EXT = 8192 # http://developer.download.nvidia.com/opengl/includes/wglext.h:190
WGL_DRAW_TO_WINDOW_EXT = 8193 # http://developer.download.nvidia.com/opengl/includes/wglext.h:191
WGL_DRAW_TO_BITMAP_EXT = 8194 # http://developer.download.nvidia.com/opengl/includes/wglext.h:192
WGL_ACCELERATION_EXT = 8195 # http://developer.download.nvidia.com/opengl/includes/wglext.h:193
WGL_NEED_PALETTE_EXT = 8196 # http://developer.download.nvidia.com/opengl/includes/wglext.h:194
WGL_NEED_SYSTEM_PALETTE_EXT = 8197 # http://developer.download.nvidia.com/opengl/includes/wglext.h:195
WGL_SWAP_LAYER_BUFFERS_EXT = 8198 # http://developer.download.nvidia.com/opengl/includes/wglext.h:196
WGL_SWAP_METHOD_EXT = 8199 # http://developer.download.nvidia.com/opengl/includes/wglext.h:197
WGL_NUMBER_OVERLAYS_EXT = 8200 # http://developer.download.nvidia.com/opengl/includes/wglext.h:198
WGL_NUMBER_UNDERLAYS_EXT = 8201 # http://developer.download.nvidia.com/opengl/includes/wglext.h:199
WGL_TRANSPARENT_EXT = 8202 # http://developer.download.nvidia.com/opengl/includes/wglext.h:200
WGL_TRANSPARENT_VALUE_EXT = 8203 # http://developer.download.nvidia.com/opengl/includes/wglext.h:201
WGL_SHARE_DEPTH_EXT = 8204 # http://developer.download.nvidia.com/opengl/includes/wglext.h:202
WGL_SHARE_STENCIL_EXT = 8205 # http://developer.download.nvidia.com/opengl/includes/wglext.h:203
WGL_SHARE_ACCUM_EXT = 512 # http://developer.download.nvidia.com/opengl/includes/wglext.h:204
WGL_SUPPORT_GDI_EXT = 512 # http://developer.download.nvidia.com/opengl/includes/wglext.h:205
WGL_SUPPORT_OPENGL_EXT = 8208 # http://developer.download.nvidia.com/opengl/includes/wglext.h:206
WGL_DOUBLE_BUFFER_EXT = 8209 # http://developer.download.nvidia.com/opengl/includes/wglext.h:207
WGL_STEREO_EXT = 8210 # http://developer.download.nvidia.com/opengl/includes/wglext.h:208
WGL_PIXEL_TYPE_EXT = 8211 # http://developer.download.nvidia.com/opengl/includes/wglext.h:209
WGL_COLOR_BITS_EXT = 8212 # http://developer.download.nvidia.com/opengl/includes/wglext.h:210
WGL_RED_BITS_EXT = 8213 # http://developer.download.nvidia.com/opengl/includes/wglext.h:211
WGL_RED_SHIFT_EXT = 8214 # http://developer.download.nvidia.com/opengl/includes/wglext.h:212
WGL_GREEN_BITS_EXT = 8215 # http://developer.download.nvidia.com/opengl/includes/wglext.h:213
WGL_GREEN_SHIFT_EXT = 8216 # http://developer.download.nvidia.com/opengl/includes/wglext.h:214
WGL_BLUE_BITS_EXT = 8217 # http://developer.download.nvidia.com/opengl/includes/wglext.h:215
WGL_BLUE_SHIFT_EXT = 8218 # http://developer.download.nvidia.com/opengl/includes/wglext.h:216
WGL_ALPHA_BITS_EXT = 8219 # http://developer.download.nvidia.com/opengl/includes/wglext.h:217
WGL_ALPHA_SHIFT_EXT = 8220 # http://developer.download.nvidia.com/opengl/includes/wglext.h:218
WGL_ACCUM_BITS_EXT = 8221 # http://developer.download.nvidia.com/opengl/includes/wglext.h:219
WGL_ACCUM_RED_BITS_EXT = 513 # http://developer.download.nvidia.com/opengl/includes/wglext.h:220
WGL_ACCUM_GREEN_BITS_EXT = 513 # http://developer.download.nvidia.com/opengl/includes/wglext.h:221
WGL_ACCUM_BLUE_BITS_EXT = 8224 # http://developer.download.nvidia.com/opengl/includes/wglext.h:222
WGL_ACCUM_ALPHA_BITS_EXT = 8225 # http://developer.download.nvidia.com/opengl/includes/wglext.h:223
WGL_DEPTH_BITS_EXT = 8226 # http://developer.download.nvidia.com/opengl/includes/wglext.h:224
WGL_STENCIL_BITS_EXT = 8227 # http://developer.download.nvidia.com/opengl/includes/wglext.h:225
WGL_AUX_BUFFERS_EXT = 8228 # http://developer.download.nvidia.com/opengl/includes/wglext.h:226
WGL_NO_ACCELERATION_EXT = 8229 # http://developer.download.nvidia.com/opengl/includes/wglext.h:227
WGL_GENERIC_ACCELERATION_EXT = 8230 # http://developer.download.nvidia.com/opengl/includes/wglext.h:228
WGL_FULL_ACCELERATION_EXT = 8231 # http://developer.download.nvidia.com/opengl/includes/wglext.h:229
WGL_SWAP_EXCHANGE_EXT = 8232 # http://developer.download.nvidia.com/opengl/includes/wglext.h:230
WGL_SWAP_COPY_EXT = 8233 # http://developer.download.nvidia.com/opengl/includes/wglext.h:231
WGL_SWAP_UNDEFINED_EXT = 8234 # http://developer.download.nvidia.com/opengl/includes/wglext.h:232
WGL_TYPE_RGBA_EXT = 8235 # http://developer.download.nvidia.com/opengl/includes/wglext.h:233
WGL_TYPE_COLORINDEX_EXT = 8236 # http://developer.download.nvidia.com/opengl/includes/wglext.h:234
# EXT_pbuffer (http://developer.download.nvidia.com/opengl/includes/wglext.h:237)
WGL_DRAW_TO_PBUFFER_EXT = 8237 # http://developer.download.nvidia.com/opengl/includes/wglext.h:238
WGL_MAX_PBUFFER_PIXELS_EXT = 514 # http://developer.download.nvidia.com/opengl/includes/wglext.h:239
WGL_MAX_PBUFFER_WIDTH_EXT = 514 # http://developer.download.nvidia.com/opengl/includes/wglext.h:240
WGL_MAX_PBUFFER_HEIGHT_EXT = 8240 # http://developer.download.nvidia.com/opengl/includes/wglext.h:241
WGL_OPTIMAL_PBUFFER_WIDTH_EXT = 8241 # http://developer.download.nvidia.com/opengl/includes/wglext.h:242
WGL_OPTIMAL_PBUFFER_HEIGHT_EXT = 8242 # http://developer.download.nvidia.com/opengl/includes/wglext.h:243
WGL_PBUFFER_LARGEST_EXT = 8243 # http://developer.download.nvidia.com/opengl/includes/wglext.h:244
WGL_PBUFFER_WIDTH_EXT = 8244 # http://developer.download.nvidia.com/opengl/includes/wglext.h:245
WGL_PBUFFER_HEIGHT_EXT = 8245 # http://developer.download.nvidia.com/opengl/includes/wglext.h:246
# EXT_depth_float (http://developer.download.nvidia.com/opengl/includes/wglext.h:249)
WGL_DEPTH_FLOAT_EXT = 8256 # http://developer.download.nvidia.com/opengl/includes/wglext.h:250
# 3DFX_multisample (http://developer.download.nvidia.com/opengl/includes/wglext.h:253)
WGL_SAMPLE_BUFFERS_3DFX = 8288 # http://developer.download.nvidia.com/opengl/includes/wglext.h:254
WGL_SAMPLES_3DFX = 8289 # http://developer.download.nvidia.com/opengl/includes/wglext.h:255
# EXT_multisample (http://developer.download.nvidia.com/opengl/includes/wglext.h:258)
WGL_SAMPLE_BUFFERS_EXT = 8257 # http://developer.download.nvidia.com/opengl/includes/wglext.h:259
WGL_SAMPLES_EXT = 8258 # http://developer.download.nvidia.com/opengl/includes/wglext.h:260
# I3D_digital_video_control (http://developer.download.nvidia.com/opengl/includes/wglext.h:263)
WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D = 8272 # http://developer.download.nvidia.com/opengl/includes/wglext.h:264
WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D = 8273 # http://developer.download.nvidia.com/opengl/includes/wglext.h:265
WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D = 8274 # http://developer.download.nvidia.com/opengl/includes/wglext.h:266
WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D = 8275 # http://developer.download.nvidia.com/opengl/includes/wglext.h:267
# I3D_gamma (http://developer.download.nvidia.com/opengl/includes/wglext.h:270)
WGL_GAMMA_TABLE_SIZE_I3D = 516 # http://developer.download.nvidia.com/opengl/includes/wglext.h:271
WGL_GAMMA_EXCLUDE_DESKTOP_I3D = 516 # http://developer.download.nvidia.com/opengl/includes/wglext.h:272
# I3D_genlock (http://developer.download.nvidia.com/opengl/includes/wglext.h:275)
WGL_GENLOCK_SOURCE_MULTIVIEW_I3D = 8260 # http://developer.download.nvidia.com/opengl/includes/wglext.h:276
WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D = 8261 # http://developer.download.nvidia.com/opengl/includes/wglext.h:277
WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D = 8262 # http://developer.download.nvidia.com/opengl/includes/wglext.h:278
WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D = 8263 # http://developer.download.nvidia.com/opengl/includes/wglext.h:279
WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D = 8264 # http://developer.download.nvidia.com/opengl/includes/wglext.h:280
WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D = 8265 # http://developer.download.nvidia.com/opengl/includes/wglext.h:281
WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D = 8266 # http://developer.download.nvidia.com/opengl/includes/wglext.h:282
WGL_GENLOCK_SOURCE_EDGE_RISING_I3D = 8267 # http://developer.download.nvidia.com/opengl/includes/wglext.h:283
WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D = 8268 # http://developer.download.nvidia.com/opengl/includes/wglext.h:284
# I3D_image_buffer (http://developer.download.nvidia.com/opengl/includes/wglext.h:287)
WGL_IMAGE_BUFFER_MIN_ACCESS_I3D = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:288
WGL_IMAGE_BUFFER_LOCK_I3D = 2 # http://developer.download.nvidia.com/opengl/includes/wglext.h:289
# I3D_swap_frame_lock (http://developer.download.nvidia.com/opengl/includes/wglext.h:292)
# NV_render_depth_texture (http://developer.download.nvidia.com/opengl/includes/wglext.h:295)
WGL_BIND_TO_TEXTURE_DEPTH_NV = 8355 # http://developer.download.nvidia.com/opengl/includes/wglext.h:296
WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV = 8356 # http://developer.download.nvidia.com/opengl/includes/wglext.h:297
WGL_DEPTH_TEXTURE_FORMAT_NV = 8357 # http://developer.download.nvidia.com/opengl/includes/wglext.h:298
WGL_TEXTURE_DEPTH_COMPONENT_NV = 8358 # http://developer.download.nvidia.com/opengl/includes/wglext.h:299
WGL_DEPTH_COMPONENT_NV = 8359 # http://developer.download.nvidia.com/opengl/includes/wglext.h:300
# NV_render_texture_rectangle (http://developer.download.nvidia.com/opengl/includes/wglext.h:303)
WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV = 8352 # http://developer.download.nvidia.com/opengl/includes/wglext.h:304
WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV = 8353 # http://developer.download.nvidia.com/opengl/includes/wglext.h:305
WGL_TEXTURE_RECTANGLE_NV = 8354 # http://developer.download.nvidia.com/opengl/includes/wglext.h:306
# ATI_pixel_format_float (http://developer.download.nvidia.com/opengl/includes/wglext.h:309)
WGL_TYPE_RGBA_FLOAT_ATI = 8608 # http://developer.download.nvidia.com/opengl/includes/wglext.h:310
WGL_RGBA_FLOAT_MODE_ATI = 34848 # http://developer.download.nvidia.com/opengl/includes/wglext.h:311
WGL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI = 34869 # http://developer.download.nvidia.com/opengl/includes/wglext.h:312
# NV_float_buffer (http://developer.download.nvidia.com/opengl/includes/wglext.h:315)
WGL_FLOAT_COMPONENTS_NV = 8368 # http://developer.download.nvidia.com/opengl/includes/wglext.h:316
WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV = 8369 # http://developer.download.nvidia.com/opengl/includes/wglext.h:317
WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV = 8370 # http://developer.download.nvidia.com/opengl/includes/wglext.h:318
WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV = 8371 # http://developer.download.nvidia.com/opengl/includes/wglext.h:319
WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV = 8372 # http://developer.download.nvidia.com/opengl/includes/wglext.h:320
WGL_TEXTURE_FLOAT_R_NV = 8373 # http://developer.download.nvidia.com/opengl/includes/wglext.h:321
WGL_TEXTURE_FLOAT_RG_NV = 8374 # http://developer.download.nvidia.com/opengl/includes/wglext.h:322
WGL_TEXTURE_FLOAT_RGB_NV = 8375 # http://developer.download.nvidia.com/opengl/includes/wglext.h:323
WGL_TEXTURE_FLOAT_RGBA_NV = 8376 # http://developer.download.nvidia.com/opengl/includes/wglext.h:324
# NV_swap_group (http://developer.download.nvidia.com/opengl/includes/wglext.h:327)
# NV_gpu_affinity (http://developer.download.nvidia.com/opengl/includes/wglext.h:330)
WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV = 8400 # http://developer.download.nvidia.com/opengl/includes/wglext.h:331
WGL_ERROR_MISSING_AFFINITY_MASK_NV = 8401 # http://developer.download.nvidia.com/opengl/includes/wglext.h:332
# ARB_pbuffer (http://developer.download.nvidia.com/opengl/includes/wglext.h:338)
HANDLE = POINTER(None) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:58
HPBUFFERARB = HANDLE # http://developer.download.nvidia.com/opengl/includes/wglext.h:339
# EXT_pbuffer (http://developer.download.nvidia.com/opengl/includes/wglext.h:341)
HPBUFFEREXT = HANDLE # http://developer.download.nvidia.com/opengl/includes/wglext.h:342
# NV_gpu_affinity (http://developer.download.nvidia.com/opengl/includes/wglext.h:345)
HGPUNV = HANDLE # http://developer.download.nvidia.com/opengl/includes/wglext.h:346
class struct__GPU_DEVICE(Structure):
__slots__ = [
'cb',
'DeviceName',
'DeviceString',
'Flags',
'rcVirtualScreen',
]
DWORD = c_ulong # C:\cygwin\home\Alex\pyglet\tools\wgl.h:54
CHAR = c_char # C:\cygwin\home\Alex\pyglet\tools\wgl.h:47
class struct_tagRECT(Structure):
__slots__ = [
'left',
'top',
'right',
'bottom',
]
LONG = c_long # C:\cygwin\home\Alex\pyglet\tools\wgl.h:53
struct_tagRECT._fields_ = [
('left', LONG),
('top', LONG),
('right', LONG),
('bottom', LONG),
]
RECT = struct_tagRECT # C:\cygwin\home\Alex\pyglet\tools\wgl.h:200
struct__GPU_DEVICE._fields_ = [
('cb', DWORD),
('DeviceName', CHAR * 32),
('DeviceString', CHAR * 128),
('Flags', DWORD),
('rcVirtualScreen', RECT),
]
GPU_DEVICE = struct__GPU_DEVICE # http://developer.download.nvidia.com/opengl/includes/wglext.h:353
PGPU_DEVICE = POINTER(struct__GPU_DEVICE) # http://developer.download.nvidia.com/opengl/includes/wglext.h:353
# ARB_buffer_region (http://developer.download.nvidia.com/opengl/includes/wglext.h:356)
WGL_ARB_buffer_region = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:357
HDC = HANDLE # C:\cygwin\home\Alex\pyglet\tools\wgl.h:61
UINT = c_uint # C:\cygwin\home\Alex\pyglet\tools\wgl.h:50
# http://developer.download.nvidia.com/opengl/includes/wglext.h:359
wglCreateBufferRegionARB = _link_function('wglCreateBufferRegionARB', HANDLE, [HDC, c_int, UINT], 'ARB_buffer_region')
VOID = None # C:\cygwin\home\Alex\pyglet\tools\wgl.h:45
# http://developer.download.nvidia.com/opengl/includes/wglext.h:360
wglDeleteBufferRegionARB = _link_function('wglDeleteBufferRegionARB', VOID, [HANDLE], 'ARB_buffer_region')
BOOL = c_long # C:\cygwin\home\Alex\pyglet\tools\wgl.h:52
# http://developer.download.nvidia.com/opengl/includes/wglext.h:361
wglSaveBufferRegionARB = _link_function('wglSaveBufferRegionARB', BOOL, [HANDLE, c_int, c_int, c_int, c_int], 'ARB_buffer_region')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:362
wglRestoreBufferRegionARB = _link_function('wglRestoreBufferRegionARB', BOOL, [HANDLE, c_int, c_int, c_int, c_int, c_int, c_int], 'ARB_buffer_region')
PFNWGLCREATEBUFFERREGIONARBPROC = CFUNCTYPE(HANDLE, HDC, c_int, UINT) # http://developer.download.nvidia.com/opengl/includes/wglext.h:364
PFNWGLDELETEBUFFERREGIONARBPROC = CFUNCTYPE(VOID, HANDLE) # http://developer.download.nvidia.com/opengl/includes/wglext.h:365
PFNWGLSAVEBUFFERREGIONARBPROC = CFUNCTYPE(BOOL, HANDLE, c_int, c_int, c_int, c_int) # http://developer.download.nvidia.com/opengl/includes/wglext.h:366
PFNWGLRESTOREBUFFERREGIONARBPROC = CFUNCTYPE(BOOL, HANDLE, c_int, c_int, c_int, c_int, c_int, c_int) # http://developer.download.nvidia.com/opengl/includes/wglext.h:367
# ARB_multisample (http://developer.download.nvidia.com/opengl/includes/wglext.h:370)
WGL_ARB_multisample = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:371
# ARB_extensions_string (http://developer.download.nvidia.com/opengl/includes/wglext.h:374)
WGL_ARB_extensions_string = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:375
# http://developer.download.nvidia.com/opengl/includes/wglext.h:377
wglGetExtensionsStringARB = _link_function('wglGetExtensionsStringARB', c_char_p, [HDC], 'ARB_extensions_string')
PFNWGLGETEXTENSIONSSTRINGARBPROC = CFUNCTYPE(c_char_p, HDC) # http://developer.download.nvidia.com/opengl/includes/wglext.h:379
# ARB_pixel_format (http://developer.download.nvidia.com/opengl/includes/wglext.h:382)
WGL_ARB_pixel_format = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:383
# http://developer.download.nvidia.com/opengl/includes/wglext.h:385
wglGetPixelFormatAttribivARB = _link_function('wglGetPixelFormatAttribivARB', BOOL, [HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(c_int)], 'ARB_pixel_format')
FLOAT = c_float # C:\cygwin\home\Alex\pyglet\tools\wgl.h:55
# http://developer.download.nvidia.com/opengl/includes/wglext.h:386
wglGetPixelFormatAttribfvARB = _link_function('wglGetPixelFormatAttribfvARB', BOOL, [HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(FLOAT)], 'ARB_pixel_format')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:387
wglChoosePixelFormatARB = _link_function('wglChoosePixelFormatARB', BOOL, [HDC, POINTER(c_int), POINTER(FLOAT), UINT, POINTER(c_int), POINTER(UINT)], 'ARB_pixel_format')
PFNWGLGETPIXELFORMATATTRIBIVARBPROC = CFUNCTYPE(BOOL, HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(c_int)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:389
PFNWGLGETPIXELFORMATATTRIBFVARBPROC = CFUNCTYPE(BOOL, HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(FLOAT)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:390
PFNWGLCHOOSEPIXELFORMATARBPROC = CFUNCTYPE(BOOL, HDC, POINTER(c_int), POINTER(FLOAT), UINT, POINTER(c_int), POINTER(UINT)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:391
# ARB_make_current_read (http://developer.download.nvidia.com/opengl/includes/wglext.h:394)
WGL_ARB_make_current_read = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:395
HGLRC = HANDLE # C:\cygwin\home\Alex\pyglet\tools\wgl.h:60
# http://developer.download.nvidia.com/opengl/includes/wglext.h:397
wglMakeContextCurrentARB = _link_function('wglMakeContextCurrentARB', BOOL, [HDC, HDC, HGLRC], 'ARB_make_current_read')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:398
wglGetCurrentReadDCARB = _link_function('wglGetCurrentReadDCARB', HDC, [], 'ARB_make_current_read')
PFNWGLMAKECONTEXTCURRENTARBPROC = CFUNCTYPE(BOOL, HDC, HDC, HGLRC) # http://developer.download.nvidia.com/opengl/includes/wglext.h:400
PFNWGLGETCURRENTREADDCARBPROC = CFUNCTYPE(HDC) # http://developer.download.nvidia.com/opengl/includes/wglext.h:401
# ARB_pbuffer (http://developer.download.nvidia.com/opengl/includes/wglext.h:404)
WGL_ARB_pbuffer = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:405
# http://developer.download.nvidia.com/opengl/includes/wglext.h:407
wglCreatePbufferARB = _link_function('wglCreatePbufferARB', HPBUFFERARB, [HDC, c_int, c_int, c_int, POINTER(c_int)], 'ARB_pbuffer')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:408
wglGetPbufferDCARB = _link_function('wglGetPbufferDCARB', HDC, [HPBUFFERARB], 'ARB_pbuffer')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:409
wglReleasePbufferDCARB = _link_function('wglReleasePbufferDCARB', c_int, [HPBUFFERARB, HDC], 'ARB_pbuffer')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:410
wglDestroyPbufferARB = _link_function('wglDestroyPbufferARB', BOOL, [HPBUFFERARB], 'ARB_pbuffer')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:411
wglQueryPbufferARB = _link_function('wglQueryPbufferARB', BOOL, [HPBUFFERARB, c_int, POINTER(c_int)], 'ARB_pbuffer')
PFNWGLCREATEPBUFFERARBPROC = CFUNCTYPE(HPBUFFERARB, HDC, c_int, c_int, c_int, POINTER(c_int)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:413
PFNWGLGETPBUFFERDCARBPROC = CFUNCTYPE(HDC, HPBUFFERARB) # http://developer.download.nvidia.com/opengl/includes/wglext.h:414
PFNWGLRELEASEPBUFFERDCARBPROC = CFUNCTYPE(c_int, HPBUFFERARB, HDC) # http://developer.download.nvidia.com/opengl/includes/wglext.h:415
PFNWGLDESTROYPBUFFERARBPROC = CFUNCTYPE(BOOL, HPBUFFERARB) # http://developer.download.nvidia.com/opengl/includes/wglext.h:416
PFNWGLQUERYPBUFFERARBPROC = CFUNCTYPE(BOOL, HPBUFFERARB, c_int, POINTER(c_int)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:417
# ARB_render_texture (http://developer.download.nvidia.com/opengl/includes/wglext.h:420)
WGL_ARB_render_texture = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:421
# http://developer.download.nvidia.com/opengl/includes/wglext.h:423
wglBindTexImageARB = _link_function('wglBindTexImageARB', BOOL, [HPBUFFERARB, c_int], 'ARB_render_texture')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:424
wglReleaseTexImageARB = _link_function('wglReleaseTexImageARB', BOOL, [HPBUFFERARB, c_int], 'ARB_render_texture')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:425
wglSetPbufferAttribARB = _link_function('wglSetPbufferAttribARB', BOOL, [HPBUFFERARB, POINTER(c_int)], 'ARB_render_texture')
PFNWGLBINDTEXIMAGEARBPROC = CFUNCTYPE(BOOL, HPBUFFERARB, c_int) # http://developer.download.nvidia.com/opengl/includes/wglext.h:427
PFNWGLRELEASETEXIMAGEARBPROC = CFUNCTYPE(BOOL, HPBUFFERARB, c_int) # http://developer.download.nvidia.com/opengl/includes/wglext.h:428
PFNWGLSETPBUFFERATTRIBARBPROC = CFUNCTYPE(BOOL, HPBUFFERARB, POINTER(c_int)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:429
# ARB_pixel_format_float (http://developer.download.nvidia.com/opengl/includes/wglext.h:432)
WGL_ARB_pixel_format_float = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:433
# EXT_display_color_table (http://developer.download.nvidia.com/opengl/includes/wglext.h:436)
WGL_EXT_display_color_table = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:437
GLboolean = c_ubyte # C:\cygwin\home\Alex\pyglet\tools\wgl.h:18
GLushort = c_ushort # C:\cygwin\home\Alex\pyglet\tools\wgl.h:25
# http://developer.download.nvidia.com/opengl/includes/wglext.h:439
wglCreateDisplayColorTableEXT = _link_function('wglCreateDisplayColorTableEXT', GLboolean, [GLushort], 'EXT_display_color_table')
GLuint = c_uint # C:\cygwin\home\Alex\pyglet\tools\wgl.h:26
# http://developer.download.nvidia.com/opengl/includes/wglext.h:440
wglLoadDisplayColorTableEXT = _link_function('wglLoadDisplayColorTableEXT', GLboolean, [POINTER(GLushort), GLuint], 'EXT_display_color_table')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:441
wglBindDisplayColorTableEXT = _link_function('wglBindDisplayColorTableEXT', GLboolean, [GLushort], 'EXT_display_color_table')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:442
wglDestroyDisplayColorTableEXT = _link_function('wglDestroyDisplayColorTableEXT', VOID, [GLushort], 'EXT_display_color_table')
PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC = CFUNCTYPE(GLboolean, GLushort) # http://developer.download.nvidia.com/opengl/includes/wglext.h:444
PFNWGLLOADDISPLAYCOLORTABLEEXTPROC = CFUNCTYPE(GLboolean, POINTER(GLushort), GLuint) # http://developer.download.nvidia.com/opengl/includes/wglext.h:445
PFNWGLBINDDISPLAYCOLORTABLEEXTPROC = CFUNCTYPE(GLboolean, GLushort) # http://developer.download.nvidia.com/opengl/includes/wglext.h:446
PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC = CFUNCTYPE(VOID, GLushort) # http://developer.download.nvidia.com/opengl/includes/wglext.h:447
# EXT_extensions_string (http://developer.download.nvidia.com/opengl/includes/wglext.h:450)
WGL_EXT_extensions_string = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:451
# http://developer.download.nvidia.com/opengl/includes/wglext.h:453
wglGetExtensionsStringEXT = _link_function('wglGetExtensionsStringEXT', c_char_p, [], 'EXT_extensions_string')
PFNWGLGETEXTENSIONSSTRINGEXTPROC = CFUNCTYPE(c_char_p) # http://developer.download.nvidia.com/opengl/includes/wglext.h:455
# EXT_make_current_read (http://developer.download.nvidia.com/opengl/includes/wglext.h:458)
WGL_EXT_make_current_read = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:459
# http://developer.download.nvidia.com/opengl/includes/wglext.h:461
wglMakeContextCurrentEXT = _link_function('wglMakeContextCurrentEXT', BOOL, [HDC, HDC, HGLRC], 'EXT_make_current_read')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:462
wglGetCurrentReadDCEXT = _link_function('wglGetCurrentReadDCEXT', HDC, [], 'EXT_make_current_read')
PFNWGLMAKECONTEXTCURRENTEXTPROC = CFUNCTYPE(BOOL, HDC, HDC, HGLRC) # http://developer.download.nvidia.com/opengl/includes/wglext.h:464
PFNWGLGETCURRENTREADDCEXTPROC = CFUNCTYPE(HDC) # http://developer.download.nvidia.com/opengl/includes/wglext.h:465
# EXT_pbuffer (http://developer.download.nvidia.com/opengl/includes/wglext.h:468)
WGL_EXT_pbuffer = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:469
# http://developer.download.nvidia.com/opengl/includes/wglext.h:471
wglCreatePbufferEXT = _link_function('wglCreatePbufferEXT', HPBUFFEREXT, [HDC, c_int, c_int, c_int, POINTER(c_int)], 'EXT_pbuffer')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:472
wglGetPbufferDCEXT = _link_function('wglGetPbufferDCEXT', HDC, [HPBUFFEREXT], 'EXT_pbuffer')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:473
wglReleasePbufferDCEXT = _link_function('wglReleasePbufferDCEXT', c_int, [HPBUFFEREXT, HDC], 'EXT_pbuffer')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:474
wglDestroyPbufferEXT = _link_function('wglDestroyPbufferEXT', BOOL, [HPBUFFEREXT], 'EXT_pbuffer')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:475
wglQueryPbufferEXT = _link_function('wglQueryPbufferEXT', BOOL, [HPBUFFEREXT, c_int, POINTER(c_int)], 'EXT_pbuffer')
PFNWGLCREATEPBUFFEREXTPROC = CFUNCTYPE(HPBUFFEREXT, HDC, c_int, c_int, c_int, POINTER(c_int)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:477
PFNWGLGETPBUFFERDCEXTPROC = CFUNCTYPE(HDC, HPBUFFEREXT) # http://developer.download.nvidia.com/opengl/includes/wglext.h:478
PFNWGLRELEASEPBUFFERDCEXTPROC = CFUNCTYPE(c_int, HPBUFFEREXT, HDC) # http://developer.download.nvidia.com/opengl/includes/wglext.h:479
PFNWGLDESTROYPBUFFEREXTPROC = CFUNCTYPE(BOOL, HPBUFFEREXT) # http://developer.download.nvidia.com/opengl/includes/wglext.h:480
PFNWGLQUERYPBUFFEREXTPROC = CFUNCTYPE(BOOL, HPBUFFEREXT, c_int, POINTER(c_int)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:481
# EXT_pixel_format (http://developer.download.nvidia.com/opengl/includes/wglext.h:484)
WGL_EXT_pixel_format = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:485
# http://developer.download.nvidia.com/opengl/includes/wglext.h:487
wglGetPixelFormatAttribivEXT = _link_function('wglGetPixelFormatAttribivEXT', BOOL, [HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(c_int)], 'EXT_pixel_format')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:488
wglGetPixelFormatAttribfvEXT = _link_function('wglGetPixelFormatAttribfvEXT', BOOL, [HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(FLOAT)], 'EXT_pixel_format')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:489
wglChoosePixelFormatEXT = _link_function('wglChoosePixelFormatEXT', BOOL, [HDC, POINTER(c_int), POINTER(FLOAT), UINT, POINTER(c_int), POINTER(UINT)], 'EXT_pixel_format')
PFNWGLGETPIXELFORMATATTRIBIVEXTPROC = CFUNCTYPE(BOOL, HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(c_int)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:491
PFNWGLGETPIXELFORMATATTRIBFVEXTPROC = CFUNCTYPE(BOOL, HDC, c_int, c_int, UINT, POINTER(c_int), POINTER(FLOAT)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:492
PFNWGLCHOOSEPIXELFORMATEXTPROC = CFUNCTYPE(BOOL, HDC, POINTER(c_int), POINTER(FLOAT), UINT, POINTER(c_int), POINTER(UINT)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:493
# EXT_swap_control (http://developer.download.nvidia.com/opengl/includes/wglext.h:496)
WGL_EXT_swap_control = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:497
# http://developer.download.nvidia.com/opengl/includes/wglext.h:499
wglSwapIntervalEXT = _link_function('wglSwapIntervalEXT', BOOL, [c_int], 'EXT_swap_control')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:500
wglGetSwapIntervalEXT = _link_function('wglGetSwapIntervalEXT', c_int, [], 'EXT_swap_control')
PFNWGLSWAPINTERVALEXTPROC = CFUNCTYPE(BOOL, c_int) # http://developer.download.nvidia.com/opengl/includes/wglext.h:502
PFNWGLGETSWAPINTERVALEXTPROC = CFUNCTYPE(c_int) # http://developer.download.nvidia.com/opengl/includes/wglext.h:503
# EXT_depth_float (http://developer.download.nvidia.com/opengl/includes/wglext.h:506)
WGL_EXT_depth_float = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:507
# NV_vertex_array_range (http://developer.download.nvidia.com/opengl/includes/wglext.h:510)
WGL_NV_vertex_array_range = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:511
GLsizei = c_int # C:\cygwin\home\Alex\pyglet\tools\wgl.h:23
GLfloat = c_float # C:\cygwin\home\Alex\pyglet\tools\wgl.h:27
# http://developer.download.nvidia.com/opengl/includes/wglext.h:513
wglAllocateMemoryNV = _link_function('wglAllocateMemoryNV', POINTER(c_void), [GLsizei, GLfloat, GLfloat, GLfloat], 'NV_vertex_array_range')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:514
wglFreeMemoryNV = _link_function('wglFreeMemoryNV', None, [POINTER(None)], 'NV_vertex_array_range')
PFNWGLALLOCATEMEMORYNVPROC = CFUNCTYPE(POINTER(c_void), GLsizei, GLfloat, GLfloat, GLfloat) # http://developer.download.nvidia.com/opengl/includes/wglext.h:516
PFNWGLFREEMEMORYNVPROC = CFUNCTYPE(None, POINTER(None)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:517
# 3DFX_multisample (http://developer.download.nvidia.com/opengl/includes/wglext.h:520)
WGL_3DFX_multisample = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:521
# EXT_multisample (http://developer.download.nvidia.com/opengl/includes/wglext.h:524)
WGL_EXT_multisample = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:525
# OML_sync_control (http://developer.download.nvidia.com/opengl/includes/wglext.h:528)
WGL_OML_sync_control = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:529
INT64 = c_longlong # C:\cygwin\home\Alex\pyglet\tools\wgl.h:42
# http://developer.download.nvidia.com/opengl/includes/wglext.h:531
wglGetSyncValuesOML = _link_function('wglGetSyncValuesOML', BOOL, [HDC, POINTER(INT64), POINTER(INT64), POINTER(INT64)], 'OML_sync_control')
INT32 = c_int # C:\cygwin\home\Alex\pyglet\tools\wgl.h:35
# http://developer.download.nvidia.com/opengl/includes/wglext.h:532
wglGetMscRateOML = _link_function('wglGetMscRateOML', BOOL, [HDC, POINTER(INT32), POINTER(INT32)], 'OML_sync_control')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:533
wglSwapBuffersMscOML = _link_function('wglSwapBuffersMscOML', INT64, [HDC, INT64, INT64, INT64], 'OML_sync_control')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:534
wglSwapLayerBuffersMscOML = _link_function('wglSwapLayerBuffersMscOML', INT64, [HDC, c_int, INT64, INT64, INT64], 'OML_sync_control')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:535
wglWaitForMscOML = _link_function('wglWaitForMscOML', BOOL, [HDC, INT64, INT64, INT64, POINTER(INT64), POINTER(INT64), POINTER(INT64)], 'OML_sync_control')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:536
wglWaitForSbcOML = _link_function('wglWaitForSbcOML', BOOL, [HDC, INT64, POINTER(INT64), POINTER(INT64), POINTER(INT64)], 'OML_sync_control')
PFNWGLGETSYNCVALUESOMLPROC = CFUNCTYPE(BOOL, HDC, POINTER(INT64), POINTER(INT64), POINTER(INT64)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:538
PFNWGLGETMSCRATEOMLPROC = CFUNCTYPE(BOOL, HDC, POINTER(INT32), POINTER(INT32)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:539
PFNWGLSWAPBUFFERSMSCOMLPROC = CFUNCTYPE(INT64, HDC, INT64, INT64, INT64) # http://developer.download.nvidia.com/opengl/includes/wglext.h:540
PFNWGLSWAPLAYERBUFFERSMSCOMLPROC = CFUNCTYPE(INT64, HDC, c_int, INT64, INT64, INT64) # http://developer.download.nvidia.com/opengl/includes/wglext.h:541
PFNWGLWAITFORMSCOMLPROC = CFUNCTYPE(BOOL, HDC, INT64, INT64, INT64, POINTER(INT64), POINTER(INT64), POINTER(INT64)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:542
PFNWGLWAITFORSBCOMLPROC = CFUNCTYPE(BOOL, HDC, INT64, POINTER(INT64), POINTER(INT64), POINTER(INT64)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:543
# I3D_digital_video_control (http://developer.download.nvidia.com/opengl/includes/wglext.h:546)
WGL_I3D_digital_video_control = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:547
# http://developer.download.nvidia.com/opengl/includes/wglext.h:549
wglGetDigitalVideoParametersI3D = _link_function('wglGetDigitalVideoParametersI3D', BOOL, [HDC, c_int, POINTER(c_int)], 'I3D_digital_video_control')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:550
wglSetDigitalVideoParametersI3D = _link_function('wglSetDigitalVideoParametersI3D', BOOL, [HDC, c_int, POINTER(c_int)], 'I3D_digital_video_control')
PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC = CFUNCTYPE(BOOL, HDC, c_int, POINTER(c_int)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:552
PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC = CFUNCTYPE(BOOL, HDC, c_int, POINTER(c_int)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:553
# I3D_gamma (http://developer.download.nvidia.com/opengl/includes/wglext.h:556)
WGL_I3D_gamma = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:557
# http://developer.download.nvidia.com/opengl/includes/wglext.h:559
wglGetGammaTableParametersI3D = _link_function('wglGetGammaTableParametersI3D', BOOL, [HDC, c_int, POINTER(c_int)], 'I3D_gamma')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:560
wglSetGammaTableParametersI3D = _link_function('wglSetGammaTableParametersI3D', BOOL, [HDC, c_int, POINTER(c_int)], 'I3D_gamma')
USHORT = c_ushort # C:\cygwin\home\Alex\pyglet\tools\wgl.h:49
# http://developer.download.nvidia.com/opengl/includes/wglext.h:561
wglGetGammaTableI3D = _link_function('wglGetGammaTableI3D', BOOL, [HDC, c_int, POINTER(USHORT), POINTER(USHORT), POINTER(USHORT)], 'I3D_gamma')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:562
wglSetGammaTableI3D = _link_function('wglSetGammaTableI3D', BOOL, [HDC, c_int, POINTER(USHORT), POINTER(USHORT), POINTER(USHORT)], 'I3D_gamma')
PFNWGLGETGAMMATABLEPARAMETERSI3DPROC = CFUNCTYPE(BOOL, HDC, c_int, POINTER(c_int)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:564
PFNWGLSETGAMMATABLEPARAMETERSI3DPROC = CFUNCTYPE(BOOL, HDC, c_int, POINTER(c_int)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:565
PFNWGLGETGAMMATABLEI3DPROC = CFUNCTYPE(BOOL, HDC, c_int, POINTER(USHORT), POINTER(USHORT), POINTER(USHORT)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:566
PFNWGLSETGAMMATABLEI3DPROC = CFUNCTYPE(BOOL, HDC, c_int, POINTER(USHORT), POINTER(USHORT), POINTER(USHORT)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:567
# I3D_genlock (http://developer.download.nvidia.com/opengl/includes/wglext.h:570)
WGL_I3D_genlock = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:571
# http://developer.download.nvidia.com/opengl/includes/wglext.h:573
wglEnableGenlockI3D = _link_function('wglEnableGenlockI3D', BOOL, [HDC], 'I3D_genlock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:574
wglDisableGenlockI3D = _link_function('wglDisableGenlockI3D', BOOL, [HDC], 'I3D_genlock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:575
wglIsEnabledGenlockI3D = _link_function('wglIsEnabledGenlockI3D', BOOL, [HDC, POINTER(BOOL)], 'I3D_genlock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:576
wglGenlockSourceI3D = _link_function('wglGenlockSourceI3D', BOOL, [HDC, UINT], 'I3D_genlock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:577
wglGetGenlockSourceI3D = _link_function('wglGetGenlockSourceI3D', BOOL, [HDC, POINTER(UINT)], 'I3D_genlock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:578
wglGenlockSourceEdgeI3D = _link_function('wglGenlockSourceEdgeI3D', BOOL, [HDC, UINT], 'I3D_genlock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:579
wglGetGenlockSourceEdgeI3D = _link_function('wglGetGenlockSourceEdgeI3D', BOOL, [HDC, POINTER(UINT)], 'I3D_genlock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:580
wglGenlockSampleRateI3D = _link_function('wglGenlockSampleRateI3D', BOOL, [HDC, UINT], 'I3D_genlock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:581
wglGetGenlockSampleRateI3D = _link_function('wglGetGenlockSampleRateI3D', BOOL, [HDC, POINTER(UINT)], 'I3D_genlock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:582
wglGenlockSourceDelayI3D = _link_function('wglGenlockSourceDelayI3D', BOOL, [HDC, UINT], 'I3D_genlock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:583
wglGetGenlockSourceDelayI3D = _link_function('wglGetGenlockSourceDelayI3D', BOOL, [HDC, POINTER(UINT)], 'I3D_genlock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:584
wglQueryGenlockMaxSourceDelayI3D = _link_function('wglQueryGenlockMaxSourceDelayI3D', BOOL, [HDC, POINTER(UINT), POINTER(UINT)], 'I3D_genlock')
PFNWGLENABLEGENLOCKI3DPROC = CFUNCTYPE(BOOL, HDC) # http://developer.download.nvidia.com/opengl/includes/wglext.h:586
PFNWGLDISABLEGENLOCKI3DPROC = CFUNCTYPE(BOOL, HDC) # http://developer.download.nvidia.com/opengl/includes/wglext.h:587
PFNWGLISENABLEDGENLOCKI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(BOOL)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:588
PFNWGLGENLOCKSOURCEI3DPROC = CFUNCTYPE(BOOL, HDC, UINT) # http://developer.download.nvidia.com/opengl/includes/wglext.h:589
PFNWGLGETGENLOCKSOURCEI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(UINT)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:590
PFNWGLGENLOCKSOURCEEDGEI3DPROC = CFUNCTYPE(BOOL, HDC, UINT) # http://developer.download.nvidia.com/opengl/includes/wglext.h:591
PFNWGLGETGENLOCKSOURCEEDGEI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(UINT)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:592
PFNWGLGENLOCKSAMPLERATEI3DPROC = CFUNCTYPE(BOOL, HDC, UINT) # http://developer.download.nvidia.com/opengl/includes/wglext.h:593
PFNWGLGETGENLOCKSAMPLERATEI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(UINT)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:594
PFNWGLGENLOCKSOURCEDELAYI3DPROC = CFUNCTYPE(BOOL, HDC, UINT) # http://developer.download.nvidia.com/opengl/includes/wglext.h:595
PFNWGLGETGENLOCKSOURCEDELAYI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(UINT)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:596
PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(UINT), POINTER(UINT)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:597
# I3D_image_buffer (http://developer.download.nvidia.com/opengl/includes/wglext.h:600)
WGL_I3D_image_buffer = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:601
LPVOID = POINTER(None) # C:\cygwin\home\Alex\pyglet\tools\wgl.h:45
# http://developer.download.nvidia.com/opengl/includes/wglext.h:603
wglCreateImageBufferI3D = _link_function('wglCreateImageBufferI3D', LPVOID, [HDC, DWORD, UINT], 'I3D_image_buffer')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:604
wglDestroyImageBufferI3D = _link_function('wglDestroyImageBufferI3D', BOOL, [HDC, LPVOID], 'I3D_image_buffer')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:605
wglAssociateImageBufferEventsI3D = _link_function('wglAssociateImageBufferEventsI3D', BOOL, [HDC, POINTER(HANDLE), POINTER(LPVOID), POINTER(DWORD), UINT], 'I3D_image_buffer')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:606
wglReleaseImageBufferEventsI3D = _link_function('wglReleaseImageBufferEventsI3D', BOOL, [HDC, POINTER(LPVOID), UINT], 'I3D_image_buffer')
PFNWGLCREATEIMAGEBUFFERI3DPROC = CFUNCTYPE(LPVOID, HDC, DWORD, UINT) # http://developer.download.nvidia.com/opengl/includes/wglext.h:608
PFNWGLDESTROYIMAGEBUFFERI3DPROC = CFUNCTYPE(BOOL, HDC, LPVOID) # http://developer.download.nvidia.com/opengl/includes/wglext.h:609
PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(HANDLE), POINTER(LPVOID), POINTER(DWORD), UINT) # http://developer.download.nvidia.com/opengl/includes/wglext.h:610
PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC = CFUNCTYPE(BOOL, HDC, POINTER(LPVOID), UINT) # http://developer.download.nvidia.com/opengl/includes/wglext.h:611
# I3D_swap_frame_lock (http://developer.download.nvidia.com/opengl/includes/wglext.h:614)
WGL_I3D_swap_frame_lock = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:615
# http://developer.download.nvidia.com/opengl/includes/wglext.h:617
wglEnableFrameLockI3D = _link_function('wglEnableFrameLockI3D', BOOL, [], 'I3D_swap_frame_lock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:618
wglDisableFrameLockI3D = _link_function('wglDisableFrameLockI3D', BOOL, [], 'I3D_swap_frame_lock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:619
wglIsEnabledFrameLockI3D = _link_function('wglIsEnabledFrameLockI3D', BOOL, [POINTER(BOOL)], 'I3D_swap_frame_lock')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:620
wglQueryFrameLockMasterI3D = _link_function('wglQueryFrameLockMasterI3D', BOOL, [POINTER(BOOL)], 'I3D_swap_frame_lock')
PFNWGLENABLEFRAMELOCKI3DPROC = CFUNCTYPE(BOOL) # http://developer.download.nvidia.com/opengl/includes/wglext.h:622
PFNWGLDISABLEFRAMELOCKI3DPROC = CFUNCTYPE(BOOL) # http://developer.download.nvidia.com/opengl/includes/wglext.h:623
PFNWGLISENABLEDFRAMELOCKI3DPROC = CFUNCTYPE(BOOL, POINTER(BOOL)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:624
PFNWGLQUERYFRAMELOCKMASTERI3DPROC = CFUNCTYPE(BOOL, POINTER(BOOL)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:625
# I3D_swap_frame_usage (http://developer.download.nvidia.com/opengl/includes/wglext.h:628)
WGL_I3D_swap_frame_usage = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:629
# http://developer.download.nvidia.com/opengl/includes/wglext.h:631
wglGetFrameUsageI3D = _link_function('wglGetFrameUsageI3D', BOOL, [POINTER(c_float)], 'I3D_swap_frame_usage')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:632
wglBeginFrameTrackingI3D = _link_function('wglBeginFrameTrackingI3D', BOOL, [], 'I3D_swap_frame_usage')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:633
wglEndFrameTrackingI3D = _link_function('wglEndFrameTrackingI3D', BOOL, [], 'I3D_swap_frame_usage')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:634
wglQueryFrameTrackingI3D = _link_function('wglQueryFrameTrackingI3D', BOOL, [POINTER(DWORD), POINTER(DWORD), POINTER(c_float)], 'I3D_swap_frame_usage')
PFNWGLGETFRAMEUSAGEI3DPROC = CFUNCTYPE(BOOL, POINTER(c_float)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:636
PFNWGLBEGINFRAMETRACKINGI3DPROC = CFUNCTYPE(BOOL) # http://developer.download.nvidia.com/opengl/includes/wglext.h:637
PFNWGLENDFRAMETRACKINGI3DPROC = CFUNCTYPE(BOOL) # http://developer.download.nvidia.com/opengl/includes/wglext.h:638
PFNWGLQUERYFRAMETRACKINGI3DPROC = CFUNCTYPE(BOOL, POINTER(DWORD), POINTER(DWORD), POINTER(c_float)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:639
# ATI_pixel_format_float (http://developer.download.nvidia.com/opengl/includes/wglext.h:642)
WGL_ATI_pixel_format_float = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:643
# NV_render_depth_texture (http://developer.download.nvidia.com/opengl/includes/wglext.h:646)
WGL_NV_render_depth_texture = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:647
# NV_render_texture_rectangle (http://developer.download.nvidia.com/opengl/includes/wglext.h:650)
WGL_NV_render_texture_rectangle = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:651
# NV_float_buffer (http://developer.download.nvidia.com/opengl/includes/wglext.h:654)
WGL_NV_float_buffer = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:655
# NV_swap_group (http://developer.download.nvidia.com/opengl/includes/wglext.h:658)
WGL_NV_swap_group = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:659
# http://developer.download.nvidia.com/opengl/includes/wglext.h:661
wglJoinSwapGroupNV = _link_function('wglJoinSwapGroupNV', BOOL, [HDC, GLuint], 'NV_swap_group')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:662
wglBindSwapBarrierNV = _link_function('wglBindSwapBarrierNV', BOOL, [GLuint, GLuint], 'NV_swap_group')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:663
wglQuerySwapGroupNV = _link_function('wglQuerySwapGroupNV', BOOL, [HDC, POINTER(GLuint), POINTER(GLuint)], 'NV_swap_group')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:664
wglQueryMaxSwapGroupsNV = _link_function('wglQueryMaxSwapGroupsNV', BOOL, [HDC, POINTER(GLuint), POINTER(GLuint)], 'NV_swap_group')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:665
wglQueryFrameCountNV = _link_function('wglQueryFrameCountNV', BOOL, [HDC, POINTER(GLuint)], 'NV_swap_group')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:666
wglResetFrameCountNV = _link_function('wglResetFrameCountNV', BOOL, [HDC], 'NV_swap_group')
PFNWGLJOINSWAPGROUPNVPROC = CFUNCTYPE(BOOL, HDC, GLuint) # http://developer.download.nvidia.com/opengl/includes/wglext.h:668
PFNWGLBINDSWAPBARRIERNVPROC = CFUNCTYPE(BOOL, GLuint, GLuint) # http://developer.download.nvidia.com/opengl/includes/wglext.h:669
PFNWGLQUERYSWAPGROUPNVPROC = CFUNCTYPE(BOOL, HDC, POINTER(GLuint), POINTER(GLuint)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:670
PFNWGLQUERYMAXSWAPGROUPSNVPROC = CFUNCTYPE(BOOL, HDC, POINTER(GLuint), POINTER(GLuint)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:671
PFNWGLQUERYFRAMECOUNTNVPROC = CFUNCTYPE(BOOL, HDC, POINTER(GLuint)) # http://developer.download.nvidia.com/opengl/includes/wglext.h:672
PFNWGLRESETFRAMECOUNTNVPROC = CFUNCTYPE(BOOL, HDC) # http://developer.download.nvidia.com/opengl/includes/wglext.h:673
# NV_gpu_affinity (http://developer.download.nvidia.com/opengl/includes/wglext.h:676)
WGL_NV_gpu_affinity = 1 # http://developer.download.nvidia.com/opengl/includes/wglext.h:677
# http://developer.download.nvidia.com/opengl/includes/wglext.h:679
wglEnumGpusNV = _link_function('wglEnumGpusNV', BOOL, [UINT, POINTER(HGPUNV)], 'NV_gpu_affinity')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:680
wglEnumGpuDevicesNV = _link_function('wglEnumGpuDevicesNV', BOOL, [HGPUNV, UINT, PGPU_DEVICE], 'NV_gpu_affinity')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:681
wglCreateAffinityDCNV = _link_function('wglCreateAffinityDCNV', HDC, [POINTER(HGPUNV)], 'NV_gpu_affinity')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:682
wglEnumGpusFromAffinityDCNV = _link_function('wglEnumGpusFromAffinityDCNV', BOOL, [HDC, UINT, POINTER(HGPUNV)], 'NV_gpu_affinity')
# http://developer.download.nvidia.com/opengl/includes/wglext.h:683
wglDeleteDCNV = _link_function('wglDeleteDCNV', BOOL, [HDC], 'NV_gpu_affinity')
__all__ = ['WIN32_LEAN_AND_MEAN', 'GLAPI', 'WGL_WGLEXT_VERSION',
'WGL_FRONT_COLOR_BUFFER_BIT_ARB', 'WGL_BACK_COLOR_BUFFER_BIT_ARB',
'WGL_DEPTH_BUFFER_BIT_ARB', 'WGL_STENCIL_BUFFER_BIT_ARB',
'WGL_SAMPLE_BUFFERS_ARB', 'WGL_SAMPLES_ARB', 'WGL_NUMBER_PIXEL_FORMATS_ARB',
'WGL_DRAW_TO_WINDOW_ARB', 'WGL_DRAW_TO_BITMAP_ARB', 'WGL_ACCELERATION_ARB',
'WGL_NEED_PALETTE_ARB', 'WGL_NEED_SYSTEM_PALETTE_ARB',
'WGL_SWAP_LAYER_BUFFERS_ARB', 'WGL_SWAP_METHOD_ARB',
'WGL_NUMBER_OVERLAYS_ARB', 'WGL_NUMBER_UNDERLAYS_ARB', 'WGL_TRANSPARENT_ARB',
'WGL_TRANSPARENT_RED_VALUE_ARB', 'WGL_TRANSPARENT_GREEN_VALUE_ARB',
'WGL_TRANSPARENT_BLUE_VALUE_ARB', 'WGL_TRANSPARENT_ALPHA_VALUE_ARB',
'WGL_TRANSPARENT_INDEX_VALUE_ARB', 'WGL_SHARE_DEPTH_ARB',
'WGL_SHARE_STENCIL_ARB', 'WGL_SHARE_ACCUM_ARB', 'WGL_SUPPORT_GDI_ARB',
'WGL_SUPPORT_OPENGL_ARB', 'WGL_DOUBLE_BUFFER_ARB', 'WGL_STEREO_ARB',
'WGL_PIXEL_TYPE_ARB', 'WGL_COLOR_BITS_ARB', 'WGL_RED_BITS_ARB',
'WGL_RED_SHIFT_ARB', 'WGL_GREEN_BITS_ARB', 'WGL_GREEN_SHIFT_ARB',
'WGL_BLUE_BITS_ARB', 'WGL_BLUE_SHIFT_ARB', 'WGL_ALPHA_BITS_ARB',
'WGL_ALPHA_SHIFT_ARB', 'WGL_ACCUM_BITS_ARB', 'WGL_ACCUM_RED_BITS_ARB',
'WGL_ACCUM_GREEN_BITS_ARB', 'WGL_ACCUM_BLUE_BITS_ARB',
'WGL_ACCUM_ALPHA_BITS_ARB', 'WGL_DEPTH_BITS_ARB', 'WGL_STENCIL_BITS_ARB',
'WGL_AUX_BUFFERS_ARB', 'WGL_NO_ACCELERATION_ARB',
'WGL_GENERIC_ACCELERATION_ARB', 'WGL_FULL_ACCELERATION_ARB',
'WGL_SWAP_EXCHANGE_ARB', 'WGL_SWAP_COPY_ARB', 'WGL_SWAP_UNDEFINED_ARB',
'WGL_TYPE_RGBA_ARB', 'WGL_TYPE_COLORINDEX_ARB',
'ERROR_INVALID_PIXEL_TYPE_ARB', 'ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB',
'WGL_DRAW_TO_PBUFFER_ARB', 'WGL_MAX_PBUFFER_PIXELS_ARB',
'WGL_MAX_PBUFFER_WIDTH_ARB', 'WGL_MAX_PBUFFER_HEIGHT_ARB',
'WGL_PBUFFER_LARGEST_ARB', 'WGL_PBUFFER_WIDTH_ARB', 'WGL_PBUFFER_HEIGHT_ARB',
'WGL_PBUFFER_LOST_ARB', 'WGL_BIND_TO_TEXTURE_RGB_ARB',
'WGL_BIND_TO_TEXTURE_RGBA_ARB', 'WGL_TEXTURE_FORMAT_ARB',
'WGL_TEXTURE_TARGET_ARB', 'WGL_MIPMAP_TEXTURE_ARB', 'WGL_TEXTURE_RGB_ARB',
'WGL_TEXTURE_RGBA_ARB', 'WGL_NO_TEXTURE_ARB', 'WGL_TEXTURE_CUBE_MAP_ARB',
'WGL_TEXTURE_1D_ARB', 'WGL_TEXTURE_2D_ARB', 'WGL_MIPMAP_LEVEL_ARB',
'WGL_CUBE_MAP_FACE_ARB', 'WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB',
'WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB', 'WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB',
'WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB', 'WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB',
'WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB', 'WGL_FRONT_LEFT_ARB',
'WGL_FRONT_RIGHT_ARB', 'WGL_BACK_LEFT_ARB', 'WGL_BACK_RIGHT_ARB',
'WGL_AUX0_ARB', 'WGL_AUX1_ARB', 'WGL_AUX2_ARB', 'WGL_AUX3_ARB',
'WGL_AUX4_ARB', 'WGL_AUX5_ARB', 'WGL_AUX6_ARB', 'WGL_AUX7_ARB',
'WGL_AUX8_ARB', 'WGL_AUX9_ARB', 'WGL_TYPE_RGBA_FLOAT_ARB',
'ERROR_INVALID_PIXEL_TYPE_EXT', 'WGL_NUMBER_PIXEL_FORMATS_EXT',
'WGL_DRAW_TO_WINDOW_EXT', 'WGL_DRAW_TO_BITMAP_EXT', 'WGL_ACCELERATION_EXT',
'WGL_NEED_PALETTE_EXT', 'WGL_NEED_SYSTEM_PALETTE_EXT',
'WGL_SWAP_LAYER_BUFFERS_EXT', 'WGL_SWAP_METHOD_EXT',
'WGL_NUMBER_OVERLAYS_EXT', 'WGL_NUMBER_UNDERLAYS_EXT', 'WGL_TRANSPARENT_EXT',
'WGL_TRANSPARENT_VALUE_EXT', 'WGL_SHARE_DEPTH_EXT', 'WGL_SHARE_STENCIL_EXT',
'WGL_SHARE_ACCUM_EXT', 'WGL_SUPPORT_GDI_EXT', 'WGL_SUPPORT_OPENGL_EXT',
'WGL_DOUBLE_BUFFER_EXT', 'WGL_STEREO_EXT', 'WGL_PIXEL_TYPE_EXT',
'WGL_COLOR_BITS_EXT', 'WGL_RED_BITS_EXT', 'WGL_RED_SHIFT_EXT',
'WGL_GREEN_BITS_EXT', 'WGL_GREEN_SHIFT_EXT', 'WGL_BLUE_BITS_EXT',
'WGL_BLUE_SHIFT_EXT', 'WGL_ALPHA_BITS_EXT', 'WGL_ALPHA_SHIFT_EXT',
'WGL_ACCUM_BITS_EXT', 'WGL_ACCUM_RED_BITS_EXT', 'WGL_ACCUM_GREEN_BITS_EXT',
'WGL_ACCUM_BLUE_BITS_EXT', 'WGL_ACCUM_ALPHA_BITS_EXT', 'WGL_DEPTH_BITS_EXT',
'WGL_STENCIL_BITS_EXT', 'WGL_AUX_BUFFERS_EXT', 'WGL_NO_ACCELERATION_EXT',
'WGL_GENERIC_ACCELERATION_EXT', 'WGL_FULL_ACCELERATION_EXT',
'WGL_SWAP_EXCHANGE_EXT', 'WGL_SWAP_COPY_EXT', 'WGL_SWAP_UNDEFINED_EXT',
'WGL_TYPE_RGBA_EXT', 'WGL_TYPE_COLORINDEX_EXT', 'WGL_DRAW_TO_PBUFFER_EXT',
'WGL_MAX_PBUFFER_PIXELS_EXT', 'WGL_MAX_PBUFFER_WIDTH_EXT',
'WGL_MAX_PBUFFER_HEIGHT_EXT', 'WGL_OPTIMAL_PBUFFER_WIDTH_EXT',
'WGL_OPTIMAL_PBUFFER_HEIGHT_EXT', 'WGL_PBUFFER_LARGEST_EXT',
'WGL_PBUFFER_WIDTH_EXT', 'WGL_PBUFFER_HEIGHT_EXT', 'WGL_DEPTH_FLOAT_EXT',
'WGL_SAMPLE_BUFFERS_3DFX', 'WGL_SAMPLES_3DFX', 'WGL_SAMPLE_BUFFERS_EXT',
'WGL_SAMPLES_EXT', 'WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D',
'WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D',
'WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D',
'WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D', 'WGL_GAMMA_TABLE_SIZE_I3D',
'WGL_GAMMA_EXCLUDE_DESKTOP_I3D', 'WGL_GENLOCK_SOURCE_MULTIVIEW_I3D',
'WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D', 'WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D',
'WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D', 'WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D',
'WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D', 'WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D',
'WGL_GENLOCK_SOURCE_EDGE_RISING_I3D', 'WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D',
'WGL_IMAGE_BUFFER_MIN_ACCESS_I3D', 'WGL_IMAGE_BUFFER_LOCK_I3D',
'WGL_BIND_TO_TEXTURE_DEPTH_NV', 'WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV',
'WGL_DEPTH_TEXTURE_FORMAT_NV', 'WGL_TEXTURE_DEPTH_COMPONENT_NV',
'WGL_DEPTH_COMPONENT_NV', 'WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV',
'WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV', 'WGL_TEXTURE_RECTANGLE_NV',
'WGL_TYPE_RGBA_FLOAT_ATI', 'WGL_RGBA_FLOAT_MODE_ATI',
'WGL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI', 'WGL_FLOAT_COMPONENTS_NV',
'WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV',
'WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV',
'WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV',
'WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV', 'WGL_TEXTURE_FLOAT_R_NV',
'WGL_TEXTURE_FLOAT_RG_NV', 'WGL_TEXTURE_FLOAT_RGB_NV',
'WGL_TEXTURE_FLOAT_RGBA_NV', 'WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV',
'WGL_ERROR_MISSING_AFFINITY_MASK_NV', 'HPBUFFERARB', 'HPBUFFEREXT', 'HGPUNV',
'GPU_DEVICE', 'PGPU_DEVICE', 'WGL_ARB_buffer_region',
'wglCreateBufferRegionARB', 'wglDeleteBufferRegionARB',
'wglSaveBufferRegionARB', 'wglRestoreBufferRegionARB',
'PFNWGLCREATEBUFFERREGIONARBPROC', 'PFNWGLDELETEBUFFERREGIONARBPROC',
'PFNWGLSAVEBUFFERREGIONARBPROC', 'PFNWGLRESTOREBUFFERREGIONARBPROC',
'WGL_ARB_multisample', 'WGL_ARB_extensions_string',
'wglGetExtensionsStringARB', 'PFNWGLGETEXTENSIONSSTRINGARBPROC',
'WGL_ARB_pixel_format', 'wglGetPixelFormatAttribivARB',
'wglGetPixelFormatAttribfvARB', 'wglChoosePixelFormatARB',
'PFNWGLGETPIXELFORMATATTRIBIVARBPROC', 'PFNWGLGETPIXELFORMATATTRIBFVARBPROC',
'PFNWGLCHOOSEPIXELFORMATARBPROC', 'WGL_ARB_make_current_read',
'wglMakeContextCurrentARB', 'wglGetCurrentReadDCARB',
'PFNWGLMAKECONTEXTCURRENTARBPROC', 'PFNWGLGETCURRENTREADDCARBPROC',
'WGL_ARB_pbuffer', 'wglCreatePbufferARB', 'wglGetPbufferDCARB',
'wglReleasePbufferDCARB', 'wglDestroyPbufferARB', 'wglQueryPbufferARB',
'PFNWGLCREATEPBUFFERARBPROC', 'PFNWGLGETPBUFFERDCARBPROC',
'PFNWGLRELEASEPBUFFERDCARBPROC', 'PFNWGLDESTROYPBUFFERARBPROC',
'PFNWGLQUERYPBUFFERARBPROC', 'WGL_ARB_render_texture', 'wglBindTexImageARB',
'wglReleaseTexImageARB', 'wglSetPbufferAttribARB',
'PFNWGLBINDTEXIMAGEARBPROC', 'PFNWGLRELEASETEXIMAGEARBPROC',
'PFNWGLSETPBUFFERATTRIBARBPROC', 'WGL_ARB_pixel_format_float',
'WGL_EXT_display_color_table', 'wglCreateDisplayColorTableEXT',
'wglLoadDisplayColorTableEXT', 'wglBindDisplayColorTableEXT',
'wglDestroyDisplayColorTableEXT', 'PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC',
'PFNWGLLOADDISPLAYCOLORTABLEEXTPROC', 'PFNWGLBINDDISPLAYCOLORTABLEEXTPROC',
'PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC', 'WGL_EXT_extensions_string',
'wglGetExtensionsStringEXT', 'PFNWGLGETEXTENSIONSSTRINGEXTPROC',
'WGL_EXT_make_current_read', 'wglMakeContextCurrentEXT',
'wglGetCurrentReadDCEXT', 'PFNWGLMAKECONTEXTCURRENTEXTPROC',
'PFNWGLGETCURRENTREADDCEXTPROC', 'WGL_EXT_pbuffer', 'wglCreatePbufferEXT',
'wglGetPbufferDCEXT', 'wglReleasePbufferDCEXT', 'wglDestroyPbufferEXT',
'wglQueryPbufferEXT', 'PFNWGLCREATEPBUFFEREXTPROC',
'PFNWGLGETPBUFFERDCEXTPROC', 'PFNWGLRELEASEPBUFFERDCEXTPROC',
'PFNWGLDESTROYPBUFFEREXTPROC', 'PFNWGLQUERYPBUFFEREXTPROC',
'WGL_EXT_pixel_format', 'wglGetPixelFormatAttribivEXT',
'wglGetPixelFormatAttribfvEXT', 'wglChoosePixelFormatEXT',
'PFNWGLGETPIXELFORMATATTRIBIVEXTPROC', 'PFNWGLGETPIXELFORMATATTRIBFVEXTPROC',
'PFNWGLCHOOSEPIXELFORMATEXTPROC', 'WGL_EXT_swap_control',
'wglSwapIntervalEXT', 'wglGetSwapIntervalEXT', 'PFNWGLSWAPINTERVALEXTPROC',
'PFNWGLGETSWAPINTERVALEXTPROC', 'WGL_EXT_depth_float',
'WGL_NV_vertex_array_range', 'wglAllocateMemoryNV', 'wglFreeMemoryNV',
'PFNWGLALLOCATEMEMORYNVPROC', 'PFNWGLFREEMEMORYNVPROC',
'WGL_3DFX_multisample', 'WGL_EXT_multisample', 'WGL_OML_sync_control',
'wglGetSyncValuesOML', 'wglGetMscRateOML', 'wglSwapBuffersMscOML',
'wglSwapLayerBuffersMscOML', 'wglWaitForMscOML', 'wglWaitForSbcOML',
'PFNWGLGETSYNCVALUESOMLPROC', 'PFNWGLGETMSCRATEOMLPROC',
'PFNWGLSWAPBUFFERSMSCOMLPROC', 'PFNWGLSWAPLAYERBUFFERSMSCOMLPROC',
'PFNWGLWAITFORMSCOMLPROC', 'PFNWGLWAITFORSBCOMLPROC',
'WGL_I3D_digital_video_control', 'wglGetDigitalVideoParametersI3D',
'wglSetDigitalVideoParametersI3D', 'PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC',
'PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC', 'WGL_I3D_gamma',
'wglGetGammaTableParametersI3D', 'wglSetGammaTableParametersI3D',
'wglGetGammaTableI3D', 'wglSetGammaTableI3D',
'PFNWGLGETGAMMATABLEPARAMETERSI3DPROC',
'PFNWGLSETGAMMATABLEPARAMETERSI3DPROC', 'PFNWGLGETGAMMATABLEI3DPROC',
'PFNWGLSETGAMMATABLEI3DPROC', 'WGL_I3D_genlock', 'wglEnableGenlockI3D',
'wglDisableGenlockI3D', 'wglIsEnabledGenlockI3D', 'wglGenlockSourceI3D',
'wglGetGenlockSourceI3D', 'wglGenlockSourceEdgeI3D',
'wglGetGenlockSourceEdgeI3D', 'wglGenlockSampleRateI3D',
'wglGetGenlockSampleRateI3D', 'wglGenlockSourceDelayI3D',
'wglGetGenlockSourceDelayI3D', 'wglQueryGenlockMaxSourceDelayI3D',
'PFNWGLENABLEGENLOCKI3DPROC', 'PFNWGLDISABLEGENLOCKI3DPROC',
'PFNWGLISENABLEDGENLOCKI3DPROC', 'PFNWGLGENLOCKSOURCEI3DPROC',
'PFNWGLGETGENLOCKSOURCEI3DPROC', 'PFNWGLGENLOCKSOURCEEDGEI3DPROC',
'PFNWGLGETGENLOCKSOURCEEDGEI3DPROC', 'PFNWGLGENLOCKSAMPLERATEI3DPROC',
'PFNWGLGETGENLOCKSAMPLERATEI3DPROC', 'PFNWGLGENLOCKSOURCEDELAYI3DPROC',
'PFNWGLGETGENLOCKSOURCEDELAYI3DPROC',
'PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC', 'WGL_I3D_image_buffer',
'wglCreateImageBufferI3D', 'wglDestroyImageBufferI3D',
'wglAssociateImageBufferEventsI3D', 'wglReleaseImageBufferEventsI3D',
'PFNWGLCREATEIMAGEBUFFERI3DPROC', 'PFNWGLDESTROYIMAGEBUFFERI3DPROC',
'PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC',
'PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC', 'WGL_I3D_swap_frame_lock',
'wglEnableFrameLockI3D', 'wglDisableFrameLockI3D', 'wglIsEnabledFrameLockI3D',
'wglQueryFrameLockMasterI3D', 'PFNWGLENABLEFRAMELOCKI3DPROC',
'PFNWGLDISABLEFRAMELOCKI3DPROC', 'PFNWGLISENABLEDFRAMELOCKI3DPROC',
'PFNWGLQUERYFRAMELOCKMASTERI3DPROC', 'WGL_I3D_swap_frame_usage',
'wglGetFrameUsageI3D', 'wglBeginFrameTrackingI3D', 'wglEndFrameTrackingI3D',
'wglQueryFrameTrackingI3D', 'PFNWGLGETFRAMEUSAGEI3DPROC',
'PFNWGLBEGINFRAMETRACKINGI3DPROC', 'PFNWGLENDFRAMETRACKINGI3DPROC',
'PFNWGLQUERYFRAMETRACKINGI3DPROC', 'WGL_ATI_pixel_format_float',
'WGL_NV_render_depth_texture', 'WGL_NV_render_texture_rectangle',
'WGL_NV_float_buffer', 'WGL_NV_swap_group', 'wglJoinSwapGroupNV',
'wglBindSwapBarrierNV', 'wglQuerySwapGroupNV', 'wglQueryMaxSwapGroupsNV',
'wglQueryFrameCountNV', 'wglResetFrameCountNV', 'PFNWGLJOINSWAPGROUPNVPROC',
'PFNWGLBINDSWAPBARRIERNVPROC', 'PFNWGLQUERYSWAPGROUPNVPROC',
'PFNWGLQUERYMAXSWAPGROUPSNVPROC', 'PFNWGLQUERYFRAMECOUNTNVPROC',
'PFNWGLRESETFRAMECOUNTNVPROC', 'WGL_NV_gpu_affinity', 'wglEnumGpusNV',
'wglEnumGpuDevicesNV', 'wglCreateAffinityDCNV', 'wglEnumGpusFromAffinityDCNV',
'wglDeleteDCNV']
# END GENERATED CONTENT (do not edit above this line)

721
pyglet/graphics/__init__.py Normal file
View file

@ -0,0 +1,721 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id:$
'''Low-level graphics rendering.
This module provides an efficient low-level abstraction over OpenGL. It gives
very good performance for rendering OpenGL primitives; far better than the
typical immediate-mode usage and, on modern graphics cards, better than using
display lists in many cases. The module is used internally by other areas of
pyglet.
See the Programming Guide for details on how to use this graphics API.
Batches and groups
==================
Without even needing to understand the details on how to draw primitives with
the graphics API, developers can make use of `Batch` and `Group`
objects to improve performance of sprite and text rendering.
The `Sprite`, `Label` and `TextLayout` classes all accept a ``batch`` and
``group`` parameter in their constructors. A batch manages a set of objects
that will be drawn all at once, and a group describes the manner in which an
object is drawn.
The following example creates a batch, adds two sprites to the batch, and then
draws the entire batch::
batch = pyglet.graphics.Batch()
car = pyglet.sprite.Sprite(car_image, batch=batch)
boat = pyglet.sprite.Sprite(boat_image, batch=batch)
def on_draw()
batch.draw()
Drawing a complete batch is much faster than drawing the items in the batch
individually, especially when those items belong to a common group.
Groups describe the OpenGL state required for an item. This is for the most
part managed by the sprite and text classes, however you can also use groups
to ensure items are drawn in a particular order. For example, the following
example adds a background sprite which is guaranteed to be drawn before the
car and the boat::
batch = pyglet.graphics.Batch()
background = pyglet.graphics.OrderedGroup(0)
foreground = pyglet.graphics.OrderedGroup(1)
background = pyglet.sprite.Sprite(background_image,
batch=batch, group=background)
car = pyglet.sprite.Sprite(car_image, batch=batch, group=foreground)
boat = pyglet.sprite.Sprite(boat_image, batch=batch, group=foreground)
def on_draw()
batch.draw()
It's preferable to manage sprites and text objects within as few batches as
possible. If the drawing of sprites or text objects need to be interleaved
with other drawing that does not use the graphics API, multiple batches will
be required.
Data item parameters
====================
Many of the functions and methods in this module accept any number of ``data``
parameters as their final parameters. In the documentation these are notated
as ``*data`` in the formal parameter list.
A data parameter describes a vertex attribute format and an optional sequence
to initialise that attribute. Examples of common attribute formats are:
``"v3f"``
Vertex position, specified as three floats.
``"c4B"``
Vertex color, specifed as four unsigned bytes.
``"t2f"``
Texture coordinate, specified as two floats.
See `pyglet.graphics.vertexattribute` for the complete syntax of the vertex
format string.
When no initial data is to be given, the data item is just the format string.
For example, the following creates a 2 element vertex list with position and
color attributes::
vertex_list = pyglet.graphics.vertex_list(2, 'v2f', 'c4B')
When initial data is required, wrap the format string and the initial data in
a tuple, for example::
vertex_list = pyglet.graphics.vertex_list(2,
('v2f', (0.0, 1.0, 1.0, 0.0)),
('c4B', (255, 255, 255, 255) * 2))
Drawing modes
=============
Methods in this module that accept a ``mode`` parameter will accept any value
in the OpenGL drawing mode enumeration; for example, ``GL_POINTS``,
``GL_LINES``, ``GL_TRIANGLES``, etc.
Because of the way the graphics API renders multiple primitives with shared
state, ``GL_POLYGON``, ``GL_LINE_LOOP`` and ``GL_TRIANGLE_FAN`` cannot be used
--- the results are undefined.
When using ``GL_LINE_STRIP``, ``GL_TRIANGLE_STRIP`` or ``GL_QUAD_STRIP`` care
must be taken to insert degenrate vertices at the beginning and end of each
vertex list. For example, given the vertex list::
A, B, C, D
the correct vertex list to provide the vertex list is::
A, A, B, C, D, D
Alternatively, the ``NV_primitive_restart`` extension can be used if it is
present. This also permits use of ``GL_POLYGON``, ``GL_LINE_LOOP`` and
``GL_TRIANGLE_FAN``. Unfortunatley the extension is not provided by older
video drivers, and requires indexed vertex lists.
:since: pyglet 1.1
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import ctypes
import pyglet
from pyglet.gl import *
from pyglet import gl
from pyglet.graphics import vertexbuffer, vertexattribute, vertexdomain
_debug_graphics_batch = pyglet.options['debug_graphics_batch']
def draw(size, mode, *data):
'''Draw a primitive immediately.
:Parameters:
`size` : int
Number of vertices given
`mode` : int
OpenGL drawing mode, e.g. ``GL_TRIANGLES``
`data` : data items
Attribute formats and data. See the module summary for
details.
'''
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
buffers = []
for format, array in data:
attribute = vertexattribute.create_attribute(format)
assert size == len(array) // attribute.count, \
'Data for %s is incorrect length' % format
buffer = vertexbuffer.create_mappable_buffer(
size * attribute.stride, vbo=False)
attribute.set_region(buffer, 0, size, array)
attribute.enable()
attribute.set_pointer(buffer.ptr)
buffers.append(buffer)
glDrawArrays(mode, 0, size)
glFlush()
glPopClientAttrib()
def draw_indexed(size, mode, indices, *data):
'''Draw a primitive with indexed vertices immediately.
:Parameters:
`size` : int
Number of vertices given
`mode` : int
OpenGL drawing mode, e.g. ``GL_TRIANGLES``
`indices` : sequence of int
Sequence of integers giving indices into the vertex list.
`data` : data items
Attribute formats and data. See the module summary for details.
'''
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
buffers = []
for format, array in data:
attribute = vertexattribute.create_attribute(format)
assert size == len(array) // attribute.count, \
'Data for %s is incorrect length' % format
buffer = vertexbuffer.create_mappable_buffer(
size * attribute.stride, vbo=False)
attribute.set_region(buffer, 0, size, array)
attribute.enable()
attribute.set_pointer(buffer.ptr)
buffers.append(buffer)
if size <= 0xff:
index_type = GL_UNSIGNED_BYTE
index_c_type = ctypes.c_ubyte
elif size <= 0xffff:
index_type = GL_UNSIGNED_SHORT
index_c_type = ctypes.c_ushort
else:
index_type = GL_UNSIGNED_INT
index_c_type = ctypes.c_uint
index_array = (index_c_type * len(indices))(*indices)
glDrawElements(mode, len(indices), index_type, index_array)
glFlush()
glPopClientAttrib()
def _parse_data(data):
'''Given a list of data items, returns (formats, initial_arrays).'''
assert data, 'No attribute formats given'
# Return tuple (formats, initial_arrays).
formats = []
initial_arrays = []
for i, format in enumerate(data):
if isinstance(format, tuple):
format, array = format
initial_arrays.append((i, array))
formats.append(format)
formats = tuple(formats)
return formats, initial_arrays
def _get_default_batch():
shared_object_space = gl.current_context.object_space
try:
return shared_object_space.pyglet_graphics_default_batch
except AttributeError:
shared_object_space.pyglet_graphics_default_batch = Batch()
return shared_object_space.pyglet_graphics_default_batch
def vertex_list(count, *data):
'''Create a `VertexList` not associated with a batch, group or mode.
:Parameters:
`count` : int
The number of vertices in the list.
`data` : data items
Attribute formats and initial data for the vertex list. See the
module summary for details.
:rtype: `VertexList`
'''
# Note that mode=0 because the default batch is never drawn: vertex lists
# returned from this function are drawn directly by the app.
return _get_default_batch().add(count, 0, None, *data)
def vertex_list_indexed(count, indices, *data):
'''Create an `IndexedVertexList` not associated with a batch, group or mode.
:Parameters:
`count` : int
The number of vertices in the list.
`indices` : sequence
Sequence of integers giving indices into the vertex list.
`data` : data items
Attribute formats and initial data for the vertex list. See the
module summary for details.
:rtype: `IndexedVertexList`
'''
# Note that mode=0 because the default batch is never drawn: vertex lists
# returned from this function are drawn directly by the app.
return _get_default_batch().add_indexed(count, 0, None, indices, *data)
class Batch(object):
'''Manage a collection of vertex lists for batched rendering.
Vertex lists are added to a `Batch` using the `add` and `add_indexed`
methods. An optional group can be specified along with the vertex list,
which gives the OpenGL state required for its rendering. Vertex lists
with shared mode and group are allocated into adjacent areas of memory and
sent to the graphics card in a single operation.
Call `VertexList.delete` to remove a vertex list from the batch.
'''
def __init__(self):
'''Create a graphics batch.'''
# Mapping to find domain.
# group -> (attributes, mode, indexed) -> domain
self.group_map = {}
# Mapping of group to list of children.
self.group_children = {}
# List of top-level groups
self.top_groups = []
self._draw_list = []
self._draw_list_dirty = False
def add(self, count, mode, group, *data):
'''Add a vertex list to the batch.
:Parameters:
`count` : int
The number of vertices in the list.
`mode` : int
OpenGL drawing mode enumeration; for example, one of
``GL_POINTS``, ``GL_LINES``, ``GL_TRIANGLES``, etc.
See the module summary for additional information.
`group` : `Group`
Group of the vertex list, or ``None`` if no group is required.
`data` : data items
Attribute formats and initial data for the vertex list. See
the module summary for details.
:rtype: `VertexList`
'''
formats, initial_arrays = _parse_data(data)
domain = self._get_domain(False, mode, group, formats)
domain.__formats = formats
# Create vertex list and initialize
vlist = domain.create(count)
for i, array in initial_arrays:
vlist._set_attribute_data(i, array)
return vlist
def add_indexed(self, count, mode, group, indices, *data):
'''Add an indexed vertex list to the batch.
:Parameters:
`count` : int
The number of vertices in the list.
`mode` : int
OpenGL drawing mode enumeration; for example, one of
``GL_POINTS``, ``GL_LINES``, ``GL_TRIANGLES``, etc.
See the module summary for additional information.
`group` : `Group`
Group of the vertex list, or ``None`` if no group is required.
`indices` : sequence
Sequence of integers giving indices into the vertex list.
`data` : data items
Attribute formats and initial data for the vertex list. See
the module summary for details.
:rtype: `IndexedVertexList`
'''
formats, initial_arrays = _parse_data(data)
domain = self._get_domain(True, mode, group, formats)
# Create vertex list and initialize
vlist = domain.create(count, len(indices))
start = vlist.start
vlist._set_index_data(map(lambda i: i + start, indices))
for i, array in initial_arrays:
vlist._set_attribute_data(i, array)
return vlist
def migrate(self, vertex_list, mode, group, batch):
'''Migrate a vertex list to another batch and/or group.
`vertex_list` and `mode` together identify the vertex list to migrate.
`group` and `batch` are new owners of the vertex list after migration.
The results are undefined if `mode` is not correct or if `vertex_list`
does not belong to this batch (they are not checked and will not
necessarily throw an exception immediately).
`batch` can remain unchanged if only a group change is desired.
:Parameters:
`vertex_list` : `VertexList`
A vertex list currently belonging to this batch.
`mode` : int
The current GL drawing mode of the vertex list.
`group` : `Group`
The new group to migrate to.
`batch` : `Batch`
The batch to migrate to (or the current batch).
'''
formats = vertex_list.domain.__formats
domain = batch._get_domain(False, mode, group, formats)
vertex_list.migrate(domain)
def _get_domain(self, indexed, mode, group, formats):
if group is None:
group = null_group
# Batch group
if group not in self.group_map:
self._add_group(group)
domain_map = self.group_map[group]
# Find domain given formats, indices and mode
key = (formats, mode, indexed)
try:
domain = domain_map[key]
except KeyError:
# Create domain
if indexed:
domain = vertexdomain.create_indexed_domain(*formats)
else:
domain = vertexdomain.create_domain(*formats)
domain_map[key] = domain
self._draw_list_dirty = True
return domain
def _add_group(self, group):
self.group_map[group] = {}
if group.parent is None:
self.top_groups.append(group)
else:
if group.parent not in self.group_map:
self._add_group(group.parent)
if group.parent not in self.group_children:
self.group_children[group.parent] = []
self.group_children[group.parent].append(group)
self._draw_list_dirty = True
def _update_draw_list(self):
'''Visit group tree in preorder and create a list of bound methods
to call.
'''
def visit(group):
draw_list = []
# Draw domains using this group
domain_map = self.group_map[group]
for (formats, mode, indexed), domain in list(domain_map.items()):
# Remove unused domains from batch
if domain._is_empty():
del domain_map[(formats, mode, indexed)]
continue
draw_list.append(
(lambda d, m: lambda: d.draw(m))(domain, mode))
# Sort and visit child groups of this group
children = self.group_children.get(group)
if children:
children.sort()
for child in list(children):
draw_list.extend(visit(child))
if children or domain_map:
return [group.set_state] + draw_list + [group.unset_state]
else:
# Remove unused group from batch
del self.group_map[group]
if group.parent:
self.group_children[group.parent].remove(group)
try:
del self.group_children[group]
except KeyError:
pass
try:
self.top_groups.remove(group)
except ValueError:
pass
return []
self._draw_list = []
self.top_groups.sort()
for group in list(self.top_groups):
self._draw_list.extend(visit(group))
self._draw_list_dirty = False
if _debug_graphics_batch:
self._dump_draw_list()
def _dump_draw_list(self):
def dump(group, indent=''):
print indent, 'Begin group', group
domain_map = self.group_map[group]
for _, domain in domain_map.items():
print indent, ' ', domain
for start, size in zip(*domain.allocator.get_allocated_regions()):
print indent, ' ', 'Region %d size %d:' % (start, size)
for key, attribute in domain.attribute_names.items():
print indent, ' ',
try:
region = attribute.get_region(attribute.buffer,
start, size)
print key, region.array[:]
except:
print key, '(unmappable)'
for child in self.group_children.get(group, ()):
dump(child, indent + ' ')
print indent, 'End group', group
print 'Draw list for %r:' % self
for group in self.top_groups:
dump(group)
def draw(self):
'''Draw the batch.
'''
if self._draw_list_dirty:
self._update_draw_list()
for func in self._draw_list:
func()
def draw_subset(self, vertex_lists):
'''Draw only some vertex lists in the batch.
The use of this method is highly discouraged, as it is quite
inefficient. Usually an application can be redesigned so that batches
can always be drawn in their entirety, using `draw`.
The given vertex lists must belong to this batch; behaviour is
undefined if this condition is not met.
:Parameters:
`vertex_lists` : sequence of `VertexList` or `IndexedVertexList`
Vertex lists to draw.
'''
# Horrendously inefficient.
def visit(group):
group.set_state()
# Draw domains using this group
domain_map = self.group_map[group]
for (_, mode, _), domain in domain_map.items():
for list in vertex_lists:
if list.domain is domain:
list.draw(mode)
# Sort and visit child groups of this group
children = self.group_children.get(group)
if children:
children.sort()
for child in children:
visit(child)
group.unset_state()
self.top_groups.sort()
for group in self.top_groups:
visit(group)
class Group(object):
'''Group of common OpenGL state.
Before a vertex list is rendered, its group's OpenGL state is set; as are
that state's ancestors' states. This can be defined arbitrarily on
subclasses; the default state change has no effect, and groups vertex
lists only in the order in which they are drawn.
'''
def __init__(self, parent=None):
'''Create a group.
:Parameters:
`parent` : `Group`
Group to contain this group; its state will be set before this
state's.
'''
self.parent = parent
def set_state(self):
'''Apply the OpenGL state change.
The default implementation does nothing.'''
pass
def unset_state(self):
'''Repeal the OpenGL state change.
The default implementation does nothing.'''
pass
def set_state_recursive(self):
'''Set this group and its ancestry.
Call this method if you are using a group in isolation: the
parent groups will be called in top-down order, with this class's
`set` being called last.
'''
if self.parent:
self.parent.set_state_recursive()
self.set_state()
def unset_state_recursive(self):
'''Unset this group and its ancestry.
The inverse of `set_state_recursive`.
'''
self.unset_state()
if self.parent:
self.parent.unset_state_recursive()
class NullGroup(Group):
'''The default group class used when ``None`` is given to a batch.
This implementation has no effect.
'''
pass
#: The default group.
#:
#: :type: `Group`
null_group = NullGroup()
class TextureGroup(Group):
'''A group that enables and binds a texture.
Texture groups are equal if their textures' targets and names are equal.
'''
# Don't use this, create your own group classes that are more specific.
# This is just an example.
def __init__(self, texture, parent=None):
'''Create a texture group.
:Parameters:
`texture` : `Texture`
Texture to bind.
`parent` : `Group`
Parent group.
'''
super(TextureGroup, self).__init__(parent)
self.texture = texture
def set_state(self):
glEnable(self.texture.target)
glBindTexture(self.texture.target, self.texture.id)
def unset_state(self):
glDisable(self.texture.target)
def __hash__(self):
return hash((self.texture.target, self.texture.id, self.parent))
def __eq__(self, other):
return (self.__class__ is other.__class__ and
self.texture.target == other.texture.target and
self.texture.id == other.texture.id and
self.parent == other.parent)
def __repr__(self):
return '%s(id=%d)' % (self.__class__.__name__, self.texture.id)
class OrderedGroup(Group):
'''A group with partial order.
Ordered groups with a common parent are rendered in ascending order of
their ``order`` field. This is a useful way to render multiple layers of
a scene within a single batch.
'''
# This can be useful as a top-level group, or as a superclass for other
# groups that need to be ordered.
#
# As a top-level group it's useful because graphics can be composited in a
# known order even if they don't know about each other or share any known
# group.
def __init__(self, order, parent=None):
'''Create an ordered group.
:Parameters:
`order` : int
Order of this group.
`parent` : `Group`
Parent of this group.
'''
super(OrderedGroup, self).__init__(parent)
self.order = order
def __cmp__(self, other):
if isinstance(other, OrderedGroup):
return cmp(self.order, other.order)
return -1
def __eq__(self, other):
return (self.__class__ is other.__class__ and
self.order == other.order and
self.parent == other.parent)
def __hash__(self):
return hash((self.order, self.parent))
def __repr__(self):
return '%s(%d)' % (self.__class__.__name__, self.order)

View file

@ -0,0 +1,390 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id:$
'''Memory allocation algorithm for vertex arrays and buffers.
The region allocator is used to allocate vertex indices within a vertex
domain's multiple buffers. ("Buffer" refers to any abstract buffer presented
by `pyglet.graphics.vertexbuffer`.
The allocator will at times request more space from the buffers. The current
policy is to double the buffer size when there is not enough room to fulfil an
allocation. The buffer is never resized smaller.
The allocator maintains references to free space only; it is the caller's
responsibility to mantain the allocated regions.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
# Common cases:
# -regions will be the same size (instances of same object, e.g. sprites)
# -regions will not usually be resized (only exception is text)
# -alignment of 4 vertices (glyphs, sprites, images, ...)
#
# Optimise for:
# -keeping regions adjacent, reduce the number of entries in glMultiDrawArrays
# -finding large blocks of allocated regions quickly (for drawing)
# -finding block of unallocated space is the _uncommon_ case!
#
# Decisions:
# -don't over-allocate regions to any alignment -- this would require more
# work in finding the allocated spaces (for drawing) and would result in
# more entries in glMultiDrawArrays
# -don't move blocks when they truncate themselves. try not to allocate the
# space they freed too soon (they will likely need grow back into it later,
# and growing will usually require a reallocation).
# -allocator does not track individual allocated regions. Trusts caller
# to provide accurate (start, size) tuple, which completely describes
# a region from the allocator's point of view.
# -this means that compacting is probably not feasible, or would be hideously
# expensive
class AllocatorMemoryException(Exception):
'''The buffer is not large enough to fulfil an allocation.
Raised by `Allocator` methods when the operation failed due to lack of
buffer space. The buffer should be increased to at least
requested_capacity and then the operation retried (guaranteed to
pass second time).
'''
def __init__(self, requested_capacity):
self.requested_capacity = requested_capacity
class Allocator(object):
'''Buffer space allocation implementation.'''
def __init__(self, capacity):
'''Create an allocator for a buffer of the specified capacity.
:Parameters:
`capacity` : int
Maximum size of the buffer.
'''
self.capacity = capacity
# Allocated blocks. Start index and size in parallel lists.
#
# # = allocated, - = free
#
# 0 3 5 15 20 24 40
# |###--##########-----####----------------------|
#
# starts = [0, 5, 20]
# sizes = [3, 10, 4]
#
# To calculate free blocks:
# for i in range(0, len(starts)):
# free_start[i] = starts[i] + sizes[i]
# free_size[i] = starts[i+1] - free_start[i]
# free_size[i+1] = self.capacity - free_start[-1]
self.starts = []
self.sizes = []
def set_capacity(self, size):
'''Resize the maximum buffer size.
The capaity cannot be reduced.
:Parameters:
`size` : int
New maximum size of the buffer.
'''
assert size > self.capacity
self.capacity = size
def alloc(self, size):
'''Allocate memory in the buffer.
Raises `AllocatorMemoryException` if the allocation cannot be
fulfilled.
:Parameters:
`size` : int
Size of region to allocate.
:rtype: int
:return: Starting index of the allocated region.
'''
assert size > 0
# return start
# or raise AllocatorMemoryException
if not self.starts:
if size <= self.capacity:
self.starts.append(0)
self.sizes.append(size)
return 0
else:
raise AllocatorMemoryException(size)
# Allocate in a free space
free_start = self.starts[0] + self.sizes[0]
for i, (alloc_start, alloc_size) in \
enumerate(zip(self.starts[1:], self.sizes[1:])):
# Danger!
# i is actually index - 1 because of slicing above...
# starts[i] points to the block before this free space
# starts[i+1] points to the block after this free space, and is
# always valid.
free_size = alloc_start - free_start
if free_size == size:
# Merge previous block with this one (removing this free space)
self.sizes[i] += free_size + alloc_size
del self.starts[i+1]
del self.sizes[i+1]
return free_start
elif free_size > size:
# Increase size of previous block to intrude into this free
# space.
self.sizes[i] += size
return free_start
free_start = alloc_start + alloc_size
# Allocate at end of capacity
free_size = self.capacity - free_start
if free_size >= size:
self.sizes[-1] += size
return free_start
raise AllocatorMemoryException(self.capacity + size - free_size)
def realloc(self, start, size, new_size):
'''Reallocate a region of the buffer.
This is more efficient than separate `dealloc` and `alloc` calls, as
the region can often be resized in-place.
Raises `AllocatorMemoryException` if the allocation cannot be
fulfilled.
:Parameters:
`start` : int
Current starting index of the region.
`size` : int
Current size of the region.
`new_size` : int
New size of the region.
'''
assert size > 0 and new_size > 0
# return start
# or raise AllocatorMemoryException
# Truncation is the same as deallocating the tail cruft
if new_size < size:
self.dealloc(start + new_size, size - new_size)
return start
# Find which block it lives in
for i, (alloc_start, alloc_size) in \
enumerate(zip(*(self.starts, self.sizes))):
p = start - alloc_start
if p >= 0 and size <= alloc_size - p:
break
if not (p >= 0 and size <= alloc_size - p):
print zip(self.starts, self.sizes)
print start, size, new_size
print p, alloc_start, alloc_size
assert p >= 0 and size <= alloc_size - p, 'Region not allocated'
if size == alloc_size - p:
# Region is at end of block. Find how much free space is after
# it.
is_final_block = i == len(self.starts) - 1
if not is_final_block:
free_size = self.starts[i + 1] - (start + size)
else:
free_size = self.capacity - (start + size)
# TODO If region is an entire block being an island in free space,
# can possibly extend in both directions.
if free_size == new_size - size and not is_final_block:
# Merge block with next (region is expanded in place to
# exactly fill the free space)
self.sizes[i] += free_size + self.sizes[i + 1]
del self.starts[i + 1]
del self.sizes[i + 1]
return start
elif free_size > new_size - size:
# Expand region in place
self.sizes[i] += new_size - size
return start
# The block must be repositioned. Dealloc then alloc.
# But don't do this! If alloc fails, we've already silently dealloc'd
# the original block.
# self.dealloc(start, size)
# return self.alloc(new_size)
# It must be alloc'd first. We're not missing an optimisation
# here, because if freeing the block would've allowed for the block to
# be placed in the resulting free space, one of the above in-place
# checks would've found it.
result = self.alloc(new_size)
self.dealloc(start, size)
return result
def dealloc(self, start, size):
'''Free a region of the buffer.
:Parameters:
`start` : int
Starting index of the region.
`size` : int
Size of the region.
'''
assert size > 0
assert self.starts
# Find which block needs to be split
for i, (alloc_start, alloc_size) in \
enumerate(zip(*(self.starts, self.sizes))):
p = start - alloc_start
if p >= 0 and size <= alloc_size - p:
break
# Assert we left via the break
assert p >= 0 and size <= alloc_size - p, 'Region not allocated'
if p == 0 and size == alloc_size:
# Remove entire block
del self.starts[i]
del self.sizes[i]
elif p == 0:
# Truncate beginning of block
self.starts[i] += size
self.sizes[i] -= size
elif size == alloc_size - p:
# Truncate end of block
self.sizes[i] -= size
else:
# Reduce size of left side, insert block at right side
# $ = dealloc'd block, # = alloc'd region from same block
#
# <------8------>
# <-5-><-6-><-7->
# 1 2 3 4
# #####$$$$$#####
#
# 1 = alloc_start
# 2 = start
# 3 = start + size
# 4 = alloc_start + alloc_size
# 5 = start - alloc_start = p
# 6 = size
# 7 = {8} - ({5} + {6}) = alloc_size - (p + size)
# 8 = alloc_size
#
self.sizes[i] = p
self.starts.insert(i + 1, start + size)
self.sizes.insert(i + 1, alloc_size - (p + size))
def get_allocated_regions(self):
'''Get a list of (aggregate) allocated regions.
The result of this method is ``(starts, sizes)``, where ``starts`` is
a list of starting indices of the regions and ``sizes`` their
corresponding lengths.
:rtype: (list, list)
'''
# return (starts, sizes); len(starts) == len(sizes)
return (self.starts, self.sizes)
def get_fragmented_free_size(self):
'''Returns the amount of space unused, not including the final
free block.
:rtype: int
'''
if not self.starts:
return 0
# Variation of search for free block.
total_free = 0
free_start = self.starts[0] + self.sizes[0]
for i, (alloc_start, alloc_size) in \
enumerate(zip(self.starts[1:], self.sizes[1:])):
total_free += alloc_start - free_start
free_start = alloc_start + alloc_size
return total_free
def get_free_size(self):
'''Return the amount of space unused.
:rtype: int
'''
if not self.starts:
return self.capacity
free_end = self.capacity - (self.starts[-1] + self.sizes[-1])
return self.get_fragmented_free_size() + free_end
def get_usage(self):
'''Return fraction of capacity currently allocated.
:rtype: float
'''
return 1. - self.get_free_size() / float(self.capacity)
def get_fragmentation(self):
'''Return fraction of free space that is not expandable.
:rtype: float
'''
free_size = self.get_free_size()
if free_size == 0:
return 0.
return self.get_fragmented_free_size() / float(self.get_free_size())
def _is_empty(self):
return not self.starts
def __str__(self):
return 'allocs=' + repr(zip(self.starts, self.sizes))
def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, str(self))

View file

@ -0,0 +1,506 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id:$
'''Access byte arrays as arrays of vertex attributes.
Use `create_attribute` to create an attribute accessor given a simple format
string. Alternatively, the classes may be constructed directly.
Attribute format strings
========================
An attribute format string specifies the format of a vertex attribute. Format
strings are accepted by the `create_attribute` function as well as most
methods in the `pyglet.graphics` module.
Format strings have the following (BNF) syntax::
attribute ::= ( name | index 'g' 'n'? ) count type
``name`` describes the vertex attribute, and is one of the following
constants for the predefined attributes:
``c``
Vertex color
``e``
Edge flag
``f``
Fog coordinate
``n``
Normal vector
``s``
Secondary color
``t``
Texture coordinate
``v``
Vertex coordinate
You can alternatively create a generic indexed vertex attribute by
specifying its index in decimal followed by the constant ``g``. For
example, ``0g`` specifies the generic vertex attribute with index 0.
If the optional constant ``n`` is present after the ``g``, the
attribute is normalised to the range ``[0, 1]`` or ``[-1, 1]`` within
the range of the data type.
``count`` gives the number of data components in the attribute. For
example, a 3D vertex position has a count of 3. Some attributes
constrain the possible counts that can be used; for example, a normal
vector must have a count of 3.
``type`` gives the data type of each component of the attribute. The
following types can be used:
``b``
``GLbyte``
``B``
``GLubyte``
``s``
``GLshort``
``S``
``GLushort``
``i``
``GLint``
``I``
``GLuint``
``f``
``GLfloat``
``d``
``GLdouble``
Some attributes constrain the possible data types; for example,
normal vectors must use one of the signed data types. The use of
some data types, while not illegal, may have severe performance
concerns. For example, the use of ``GLdouble`` is discouraged,
and colours should be specified with ``GLubyte``.
Whitespace is prohibited within the format string.
Some examples follow:
``v3f``
3-float vertex position
``c4b``
4-byte colour
``1eb``
Edge flag
``0g3f``
3-float generic vertex attribute 0
``1gn1i``
Integer generic vertex attribute 1, normalized to [-1, 1]
``2gn4B``
4-byte generic vertex attribute 2, normalized to [0, 1] (because
the type is unsigned)
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import ctypes
import re
from pyglet.gl import *
from pyglet.graphics import vertexbuffer
_c_types = {
GL_BYTE: ctypes.c_byte,
GL_UNSIGNED_BYTE: ctypes.c_ubyte,
GL_SHORT: ctypes.c_short,
GL_UNSIGNED_SHORT: ctypes.c_ushort,
GL_INT: ctypes.c_int,
GL_UNSIGNED_INT: ctypes.c_uint,
GL_FLOAT: ctypes.c_float,
GL_DOUBLE: ctypes.c_double,
}
_gl_types = {
'b': GL_BYTE,
'B': GL_UNSIGNED_BYTE,
's': GL_SHORT,
'S': GL_UNSIGNED_SHORT,
'i': GL_INT,
'I': GL_UNSIGNED_INT,
'f': GL_FLOAT,
'd': GL_DOUBLE,
}
_attribute_format_re = re.compile(r'''
(?P<name>
[cefnstv] |
(?P<generic_index>[0-9]+) g
(?P<generic_normalized>n?))
(?P<count>[1234])
(?P<type>[bBsSiIfd])
''', re.VERBOSE)
_attribute_cache = {}
def _align(v, align):
return ((v - 1) & ~(align - 1)) + align
def interleave_attributes(attributes):
'''Interleave attribute offsets.
Adjusts the offsets and strides of the given attributes so that
they are interleaved. Alignment constraints are respected.
:Parameters:
`attributes` : sequence of `AbstractAttribute`
Attributes to interleave in-place.
'''
stride = 0
max_size = 0
for attribute in attributes:
stride = _align(stride, attribute.align)
attribute.offset = stride
stride += attribute.size
max_size = max(max_size, attribute.size)
stride = _align(stride, max_size)
for attribute in attributes:
attribute.stride = stride
def serialize_attributes(count, attributes):
'''Serialize attribute offsets.
Adjust the offsets of the given attributes so that they are
packed serially against each other for `count` vertices.
:Parameters:
`count` : int
Number of vertices.
`attributes` : sequence of `AbstractAttribute`
Attributes to serialze in-place.
'''
offset = 0
for attribute in attributes:
offset = _align(offset, attribute.align)
attribute.offset = offset
offset += count * attribute.stride
def create_attribute(format):
'''Create a vertex attribute description from a format string.
The initial stride and offset of the attribute will be 0.
:Parameters:
`format` : str
Attribute format string. See the module summary for details.
:rtype: `AbstractAttribute`
'''
try:
cls, args = _attribute_cache[format]
return cls(*args)
except KeyError:
pass
match = _attribute_format_re.match(format)
assert match, 'Invalid attribute format %r' % format
count = int(match.group('count'))
gl_type = _gl_types[match.group('type')]
generic_index = match.group('generic_index')
if generic_index:
normalized = match.group('generic_normalized')
attr_class = GenericAttribute
args = int(generic_index), normalized, count, gl_type
else:
name = match.group('name')
attr_class = _attribute_classes[name]
if attr_class._fixed_count:
assert count == attr_class._fixed_count, \
'Attributes named "%s" must have count of %d' % (
name, attr_class._fixed_count)
args = (gl_type,)
else:
args = (count, gl_type)
_attribute_cache[format] = attr_class, args
return attr_class(*args)
class AbstractAttribute(object):
'''Abstract accessor for an attribute in a mapped buffer.
'''
_fixed_count = None
def __init__(self, count, gl_type):
'''Create the attribute accessor.
:Parameters:
`count` : int
Number of components in the attribute.
`gl_type` : int
OpenGL type enumerant; for example, ``GL_FLOAT``
'''
assert count in (1, 2, 3, 4), 'Component count out of range'
self.gl_type = gl_type
self.c_type = _c_types[gl_type]
self.count = count
self.align = ctypes.sizeof(self.c_type)
self.size = count * self.align
self.stride = self.size
self.offset = 0
def enable(self):
'''Enable the attribute using ``glEnableClientState``.'''
raise NotImplementedError('abstract')
def set_pointer(self, offset):
'''Setup this attribute to point to the currently bound buffer at
the given offset.
``offset`` should be based on the currently bound buffer's ``ptr``
member.
:Parameters:
`offset` : int
Pointer offset to the currently bound buffer for this
attribute.
'''
raise NotImplementedError('abstract')
def get_region(self, buffer, start, count):
'''Map a buffer region using this attribute as an accessor.
The returned region can be modified as if the buffer was a contiguous
array of this attribute (though it may actually be interleaved or
otherwise non-contiguous).
The returned region consists of a contiguous array of component
data elements. For example, if this attribute uses 3 floats per
vertex, and the `count` parameter is 4, the number of floats mapped
will be ``3 * 4 = 12``.
:Parameters:
`buffer` : `AbstractMappable`
The buffer to map.
`start` : int
Offset of the first vertex to map.
`count` : int
Number of vertices to map
:rtype: `AbstractBufferRegion`
'''
byte_start = self.stride * start
byte_size = self.stride * count
array_count = self.count * count
if self.stride == self.size:
# non-interleaved
ptr_type = ctypes.POINTER(self.c_type * array_count)
return buffer.get_region(byte_start, byte_size, ptr_type)
else:
# interleaved
byte_start += self.offset
byte_size -= self.offset
elem_stride = self.stride // ctypes.sizeof(self.c_type)
elem_offset = self.offset // ctypes.sizeof(self.c_type)
ptr_type = ctypes.POINTER(
self.c_type * (count * elem_stride - elem_offset))
region = buffer.get_region(byte_start, byte_size, ptr_type)
return vertexbuffer.IndirectArrayRegion(
region, array_count, self.count, elem_stride)
def set_region(self, buffer, start, count, data):
'''Set the data over a region of the buffer.
:Parameters:
`buffer` : AbstractMappable`
The buffer to modify.
`start` : int
Offset of the first vertex to set.
`count` : int
Number of vertices to set.
`data` : sequence
Sequence of data components.
'''
if self.stride == self.size:
# non-interleaved
byte_start = self.stride * start
byte_size = self.stride * count
array_count = self.count * count
data = (self.c_type * array_count)(*data)
buffer.set_data_region(data, byte_start, byte_size)
else:
# interleaved
region = self.get_region(buffer, start, count)
region[:] = data
class ColorAttribute(AbstractAttribute):
'''Color vertex attribute.'''
plural = 'colors'
def __init__(self, count, gl_type):
assert count in (3, 4), 'Color attributes must have count of 3 or 4'
super(ColorAttribute, self).__init__(count, gl_type)
def enable(self):
glEnableClientState(GL_COLOR_ARRAY)
def set_pointer(self, pointer):
glColorPointer(self.count, self.gl_type, self.stride,
self.offset + pointer)
class EdgeFlagAttribute(AbstractAttribute):
'''Edge flag attribute.'''
plural = 'edge_flags'
_fixed_count = 1
def __init__(self, gl_type):
assert gl_type in (GL_BYTE, GL_UNSIGNED_BYTE, GL_BOOL), \
'Edge flag attribute must have boolean type'
super(EdgeFlagAttribute, self).__init__(1, gl_type)
def enable(self):
glEnableClientState(GL_EDGE_FLAG_ARRAY)
def set_pointer(self, pointer):
glEdgeFlagPointer(self.stride, self.offset + pointer)
class FogCoordAttribute(AbstractAttribute):
'''Fog coordinate attribute.'''
plural = 'fog_coords'
def __init__(self, count, gl_type):
super(FogCoordAttribute, self).__init__(count, gl_type)
def enable(self):
glEnableClientState(GL_FOG_COORD_ARRAY)
def set_pointer(self, pointer):
glFogCoordPointer(self.count, self.gl_type, self.stride,
self.offset + pointer)
class NormalAttribute(AbstractAttribute):
'''Normal vector attribute.'''
plural = 'normals'
_fixed_count = 3
def __init__(self, gl_type):
assert gl_type in (GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT, GL_DOUBLE), \
'Normal attribute must have signed type'
super(NormalAttribute, self).__init__(3, gl_type)
def enable(self):
glEnableClientState(GL_NORMAL_ARRAY)
def set_pointer(self, pointer):
glNormalPointer(self.gl_type, self.stride, self.offset + pointer)
class SecondaryColorAttribute(AbstractAttribute):
'''Secondary color attribute.'''
plural = 'secondary_colors'
_fixed_count = 3
def __init__(self, gl_type):
super(SecondaryColorAttribute, self).__init__(3, gl_type)
def enable(self):
glEnableClientState(GL_SECONDARY_COLOR_ARRAY)
def set_pointer(self, pointer):
glSecondaryColorPointer(3, self.gl_type, self.stride,
self.offset + pointer)
class TexCoordAttribute(AbstractAttribute):
'''Texture coordinate attribute.'''
plural = 'tex_coords'
def __init__(self, count, gl_type):
assert gl_type in (GL_SHORT, GL_INT, GL_INT, GL_FLOAT, GL_DOUBLE), \
'Texture coord attribute must have non-byte signed type'
super(TexCoordAttribute, self).__init__(count, gl_type)
def enable(self):
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
def set_pointer(self, pointer):
glTexCoordPointer(self.count, self.gl_type, self.stride,
self.offset + pointer)
class VertexAttribute(AbstractAttribute):
'''Vertex coordinate attribute.'''
plural = 'vertices'
def __init__(self, count, gl_type):
assert count > 1, \
'Vertex attribute must have count of 2, 3 or 4'
assert gl_type in (GL_SHORT, GL_INT, GL_INT, GL_FLOAT, GL_DOUBLE), \
'Vertex attribute must have signed type larger than byte'
super(VertexAttribute, self).__init__(count, gl_type)
def enable(self):
glEnableClientState(GL_VERTEX_ARRAY)
def set_pointer(self, pointer):
glVertexPointer(self.count, self.gl_type, self.stride,
self.offset + pointer)
class GenericAttribute(AbstractAttribute):
'''Generic vertex attribute, used by shader programs.'''
def __init__(self, index, normalized, count, gl_type):
self.normalized = bool(normalized)
self.index = index
super(GenericAttribute, self).__init__(count, gl_type)
def enable(self):
glEnableVertexAttribArray(self.index)
def set_pointer(self, pointer):
glVertexAttribPointer(self.index, self.count, self.gl_type,
self.normalized, self.stride,
self.offset + pointer)
_attribute_classes = {
'c': ColorAttribute,
'e': EdgeFlagAttribute,
'f': FogCoordAttribute,
'n': NormalAttribute,
's': SecondaryColorAttribute,
't': TexCoordAttribute,
'v': VertexAttribute,
}

View file

@ -0,0 +1,597 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id:$
'''Byte abstractions of Vertex Buffer Objects and vertex arrays.
Use `create_buffer` or `create_mappable_buffer` to create a Vertex Buffer
Object, or a vertex array if VBOs are not supported by the current context.
Buffers can optionally be created "mappable" (incorporating the
`AbstractMappable` mix-in). In this case the buffer provides a ``get_region``
method which provides the most efficient path for updating partial data within
the buffer.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import ctypes
import sys
import pyglet
from pyglet.gl import *
from pyglet.gl import gl_info
_enable_vbo = pyglet.options['graphics_vbo']
# Enable workaround permanently if any VBO is created on a context that has
# this workaround. (On systems with multiple contexts where one is
# unaffected, the workaround will be enabled unconditionally on all of the
# contexts anyway. This is completely unlikely anyway).
_workaround_vbo_finish = False
def create_buffer(size,
target=GL_ARRAY_BUFFER,
usage=GL_DYNAMIC_DRAW,
vbo=True):
'''Create a buffer of vertex data.
:Parameters:
`size` : int
Size of the buffer, in bytes
`target` : int
OpenGL target buffer
`usage` : int
OpenGL usage constant
`vbo` : bool
True if a `VertexBufferObject` should be created if the driver
supports it; otherwise only a `VertexArray` is created.
:rtype: `AbstractBuffer`
'''
from pyglet import gl
if (vbo and
gl_info.have_version(1, 5) and
_enable_vbo and
not gl.current_context._workaround_vbo):
return VertexBufferObject(size, target, usage)
else:
return VertexArray(size)
def create_mappable_buffer(size,
target=GL_ARRAY_BUFFER,
usage=GL_DYNAMIC_DRAW,
vbo=True):
'''Create a mappable buffer of vertex data.
:Parameters:
`size` : int
Size of the buffer, in bytes
`target` : int
OpenGL target buffer
`usage` : int
OpenGL usage constant
`vbo` : bool
True if a `VertexBufferObject` should be created if the driver
supports it; otherwise only a `VertexArray` is created.
:rtype: `AbstractBuffer` with `AbstractMappable`
'''
from pyglet import gl
if (vbo and
gl_info.have_version(1, 5) and
_enable_vbo and
not gl.current_context._workaround_vbo):
return MappableVertexBufferObject(size, target, usage)
else:
return VertexArray(size)
class AbstractBuffer(object):
'''Abstract buffer of byte data.
:Ivariables:
`size` : int
Size of buffer, in bytes
`ptr` : int
Memory offset of the buffer, as used by the ``glVertexPointer``
family of functions
`target` : int
OpenGL buffer target, for example ``GL_ARRAY_BUFFER``
`usage` : int
OpenGL buffer usage, for example ``GL_DYNAMIC_DRAW``
'''
ptr = 0
size = 0
def bind(self):
'''Bind this buffer to its OpenGL target.'''
raise NotImplementedError('abstract')
def unbind(self):
'''Reset the buffer's OpenGL target.'''
raise NotImplementedError('abstract')
def set_data(self, data):
'''Set the entire contents of the buffer.
:Parameters:
`data` : sequence of int or ctypes pointer
The byte array to set.
'''
raise NotImplementedError('abstract')
def set_data_region(self, data, start, length):
'''Set part of the buffer contents.
:Parameters:
`data` : sequence of int or ctypes pointer
The byte array of data to set
`start` : int
Offset to start replacing data
`length` : int
Length of region to replace
'''
raise NotImplementedError('abstract')
def map(self, invalidate=False):
'''Map the entire buffer into system memory.
The mapped region must be subsequently unmapped with `unmap` before
performing any other operations on the buffer.
:Parameters:
`invalidate` : bool
If True, the initial contents of the mapped block need not
reflect the actual contents of the buffer.
:rtype: ``POINTER(ctypes.c_ubyte)``
:return: Pointer to the mapped block in memory
'''
raise NotImplementedError('abstract')
def unmap(self):
'''Unmap a previously mapped memory block.'''
raise NotImplementedError('abstract')
def resize(self, size):
'''Resize the buffer to a new size.
:Parameters:
`size` : int
New size of the buffer, in bytes
'''
def delete(self):
'''Delete this buffer, reducing system resource usage.'''
raise NotImplementedError('abstract')
class AbstractMappable(object):
def get_region(self, start, size, ptr_type):
'''Map a region of the buffer into a ctypes array of the desired
type. This region does not need to be unmapped, but will become
invalid if the buffer is resized.
Note that although a pointer type is required, an array is mapped.
For example::
get_region(0, ctypes.sizeof(c_int) * 20, ctypes.POINTER(c_int * 20))
will map bytes 0 to 80 of the buffer to an array of 20 ints.
Changes to the array may not be recognised until the region's
`AbstractBufferRegion.invalidate` method is called.
:Parameters:
`start` : int
Offset into the buffer to map from, in bytes
`size` : int
Size of the buffer region to map, in bytes
`ptr_type` : ctypes pointer type
Pointer type describing the array format to create
:rtype: `AbstractBufferRegion`
'''
raise NotImplementedError('abstract')
class VertexArray(AbstractBuffer, AbstractMappable):
'''A ctypes implementation of a vertex array.
Many of the methods on this class are effectively no-op's, such as `bind`,
`unbind`, `map`, `unmap` and `delete`; they exist in order to present
a consistent interface with `VertexBufferObject`.
This buffer type is also mappable, and so `get_region` can be used.
'''
def __init__(self, size):
self.size = size
self.array = (ctypes.c_byte * size)()
self.ptr = ctypes.cast(self.array, ctypes.c_void_p).value
def bind(self):
pass
def unbind(self):
pass
def set_data(self, data):
ctypes.memmove(self.ptr, data, self.size)
def set_data_region(self, data, start, length):
ctypes.memmove(self.ptr + start, data, length)
def map(self, invalidate=False):
return self.array
def unmap(self):
pass
def get_region(self, start, size, ptr_type):
array = ctypes.cast(self.ptr + start, ptr_type).contents
return VertexArrayRegion(array)
def delete(self):
pass
def resize(self, size):
array = (ctypes.c_byte * size)()
ctypes.memmove(array, self.array, min(size, self.size))
self.size = size
self.array = array
self.ptr = ctypes.cast(self.array, ctypes.c_void_p).value
class VertexBufferObject(AbstractBuffer):
'''Lightweight representation of an OpenGL VBO.
The data in the buffer is not replicated in any system memory (unless it
is done so by the video driver). While this can improve memory usage and
possibly performance, updates to the buffer are relatively slow.
This class does not implement `AbstractMappable`, and so has no
``get_region`` method. See `MappableVertexBufferObject` for a VBO class
that does implement ``get_region``.
'''
def __init__(self, size, target, usage):
self.size = size
self.target = target
self.usage = usage
self._context = pyglet.gl.current_context
id = GLuint()
glGenBuffers(1, id)
self.id = id.value
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
glBindBuffer(target, self.id)
glBufferData(target, self.size, None, self.usage)
glPopClientAttrib()
global _workaround_vbo_finish
if pyglet.gl.current_context._workaround_vbo_finish:
_workaround_vbo_finish = True
def bind(self):
glBindBuffer(self.target, self.id)
def unbind(self):
glBindBuffer(self.target, 0)
def set_data(self, data):
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
glBindBuffer(self.target, self.id)
glBufferData(self.target, self.size, data, self.usage)
glPopClientAttrib()
def set_data_region(self, data, start, length):
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
glBindBuffer(self.target, self.id)
glBufferSubData(self.target, start, length, data)
glPopClientAttrib()
def map(self, invalidate=False):
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
glBindBuffer(self.target, self.id)
if invalidate:
glBufferData(self.target, self.size, None, self.usage)
ptr = ctypes.cast(glMapBuffer(self.target, GL_WRITE_ONLY),
ctypes.POINTER(ctypes.c_byte * self.size)).contents
glPopClientAttrib()
return ptr
def unmap(self):
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
glUnmapBuffer(self.target)
glPopClientAttrib()
def __del__(self):
try:
if self.id is not None:
self._context.delete_buffer(self.id)
except:
pass
def delete(self):
id = GLuint(self.id)
glDeleteBuffers(1, id)
self.id = None
def resize(self, size):
# Map, create a copy, then reinitialize.
temp = (ctypes.c_byte * size)()
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
glBindBuffer(self.target, self.id)
data = glMapBuffer(self.target, GL_READ_ONLY)
ctypes.memmove(temp, data, min(size, self.size))
glUnmapBuffer(self.target)
self.size = size
glBufferData(self.target, self.size, temp, self.usage)
glPopClientAttrib()
class MappableVertexBufferObject(VertexBufferObject, AbstractMappable):
'''A VBO with system-memory backed store.
Updates to the data via `set_data`, `set_data_region` and `map` will be
held in local memory until `bind` is called. The advantage is that fewer
OpenGL calls are needed, increasing performance.
There may also be less performance penalty for resizing this buffer.
Updates to data via `map` are committed immediately.
'''
def __init__(self, size, target, usage):
super(MappableVertexBufferObject, self).__init__(size, target, usage)
self.data = (ctypes.c_byte * size)()
self.data_ptr = ctypes.cast(self.data, ctypes.c_void_p).value
self._dirty_min = sys.maxint
self._dirty_max = 0
def bind(self):
# Commit pending data
super(MappableVertexBufferObject, self).bind()
size = self._dirty_max - self._dirty_min
if size > 0:
if size == self.size:
glBufferData(self.target, self.size, self.data, self.usage)
else:
glBufferSubData(self.target, self._dirty_min, size,
self.data_ptr + self._dirty_min)
self._dirty_min = sys.maxint
self._dirty_max = 0
def set_data(self, data):
super(MappableVertexBufferObject, self).set_data(data)
ctypes.memmove(self.data, data, self.size)
self._dirty_min = 0
self._dirty_max = self.size
def set_data_region(self, data, start, length):
ctypes.memmove(self.data_ptr + start, data, length)
self._dirty_min = min(start, self._dirty_min)
self._dirty_max = max(start + length, self._dirty_max)
def map(self, invalidate=False):
self._dirty_min = 0
self._dirty_max = self.size
return self.data
def unmap(self):
pass
def get_region(self, start, size, ptr_type):
array = ctypes.cast(self.data_ptr + start, ptr_type).contents
return VertexBufferObjectRegion(self, start, start + size, array)
def resize(self, size):
data = (ctypes.c_byte * size)()
ctypes.memmove(data, self.data, min(size, self.size))
self.data = data
self.data_ptr = ctypes.cast(self.data, ctypes.c_void_p).value
self.size = size
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
glBindBuffer(self.target, self.id)
glBufferData(self.target, self.size, self.data, self.usage)
glPopClientAttrib()
self._dirty_min = sys.maxint
self._dirty_max = 0
class AbstractBufferRegion(object):
'''A mapped region of a buffer.
Buffer regions are obtained using `AbstractMappable.get_region`.
:Ivariables:
`array` : ctypes array
Array of data, of the type and count requested by ``get_region``.
'''
def invalidate(self):
'''Mark this region as changed.
The buffer may not be updated with the latest contents of the
array until this method is called. (However, it may not be updated
until the next time the buffer is used, for efficiency).
'''
pass
class VertexBufferObjectRegion(AbstractBufferRegion):
'''A mapped region of a VBO.'''
def __init__(self, buffer, start, end, array):
self.buffer = buffer
self.start = start
self.end = end
self.array = array
def invalidate(self):
buffer = self.buffer
buffer._dirty_min = min(buffer._dirty_min, self.start)
buffer._dirty_max = max(buffer._dirty_max, self.end)
class VertexArrayRegion(AbstractBufferRegion):
'''A mapped region of a vertex array.
The `invalidate` method is a no-op but is provided in order to present
a consistent interface with `VertexBufferObjectRegion`.
'''
def __init__(self, array):
self.array = array
class IndirectArrayRegion(AbstractBufferRegion):
'''A mapped region in which data elements are not necessarily contiguous.
This region class is used to wrap buffer regions in which the data
must be accessed with some stride. For example, in an interleaved buffer
this region can be used to access a single interleaved component as if the
data was contiguous.
'''
def __init__(self, region, size, component_count, component_stride):
'''Wrap a buffer region.
Use the `component_count` and `component_stride` parameters to specify
the data layout of the encapsulated region. For example, if RGBA
data is to be accessed as if it were packed RGB, ``component_count``
would be set to 3 and ``component_stride`` to 4. If the region
contains 10 RGBA tuples, the ``size`` parameter is ``3 * 10 = 30``.
:Parameters:
`region` : `AbstractBufferRegion`
The region with interleaved data
`size` : int
The number of elements that this region will provide access to.
`component_count` : int
The number of elements that are contiguous before some must
be skipped.
`component_stride` : int
The number of elements of interleaved data separating
the contiguous sections.
'''
self.region = region
self.size = size
self.count = component_count
self.stride = component_stride
self.array = self
def __repr__(self):
return 'IndirectArrayRegion(size=%d, count=%d, stride=%d)' % (
self.size, self.count, self.stride)
def __getitem__(self, index):
count = self.count
if not isinstance(index, slice):
elem = index // count
j = index % count
return self.region.array[elem * self.stride + j]
start = index.start or 0
stop = index.stop
step = index.step or 1
if start < 0:
start = self.size + start
if stop is None:
stop = self.size
elif stop < 0:
stop = self.size + stop
assert step == 1 or step % count == 0, \
'Step must be multiple of component count'
data_start = (start // count) * self.stride + start % count
data_stop = (stop // count) * self.stride + stop % count
data_step = step * self.stride
# TODO stepped getitem is probably wrong, see setitem for correct.
value_step = step * count
# ctypes does not support stepped slicing, so do the work in a list
# and copy it back.
data = self.region.array[:]
value = [0] * ((stop - start) // step)
stride = self.stride
for i in range(count):
value[i::value_step] = \
data[data_start + i:data_stop + i:data_step]
return value
def __setitem__(self, index, value):
count = self.count
if not isinstance(index, slice):
elem = index // count
j = index % count
self.region.array[elem * self.stride + j] = value
return
start = index.start or 0
stop = index.stop
step = index.step or 1
if start < 0:
start = self.size + start
if stop is None:
stop = self.size
elif stop < 0:
stop = self.size + stop
assert step == 1 or step % count == 0, \
'Step must be multiple of component count'
data_start = (start // count) * self.stride + start % count
data_stop = (stop // count) * self.stride + stop % count
# ctypes does not support stepped slicing, so do the work in a list
# and copy it back.
data = self.region.array[:]
if step == 1:
data_step = self.stride
value_step = count
for i in range(count):
data[data_start + i:data_stop + i:data_step] = \
value[i::value_step]
else:
data_step = (step // count) * self.stride
data[data_start:data_stop:data_step] = value
self.region.array[:] = data
def invalidate(self):
self.region.invalidate()

View file

@ -0,0 +1,778 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id:$
'''Manage related vertex attributes within a single vertex domain.
A vertex "domain" consists of a set of attribute descriptions that together
describe the layout of one or more vertex buffers which are used together to
specify the vertices in a primitive. Additionally, the domain manages the
buffers used to store the data and will resize them as necessary to accomodate
new vertices.
Domains can optionally be indexed, in which case they also manage a buffer
containing vertex indices. This buffer is grown separately and has no size
relation to the attribute buffers.
Applications can create vertices (and optionally, indices) within a domain
with the `VertexDomain.create` method. This returns a `VertexList`
representing the list of vertices created. The vertex attribute data within
the group can be modified, and the changes will be made to the underlying
buffers automatically.
The entire domain can be efficiently drawn in one step with the
`VertexDomain.draw` method, assuming all the vertices comprise primitives of
the same OpenGL primitive mode.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import ctypes
import re
from pyglet.gl import *
from pyglet.graphics import allocation, vertexattribute, vertexbuffer
_usage_format_re = re.compile(r'''
(?P<attribute>[^/]*)
(/ (?P<usage> static|dynamic|stream|none))?
''', re.VERBOSE)
_gl_usages = {
'static': GL_STATIC_DRAW,
'dynamic': GL_DYNAMIC_DRAW,
'stream': GL_STREAM_DRAW,
'none': GL_STREAM_DRAW_ARB, # Force no VBO
}
def _nearest_pow2(v):
# From http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
# Credit: Sean Anderson
v -= 1
v |= v >> 1
v |= v >> 2
v |= v >> 4
v |= v >> 8
v |= v >> 16
return v + 1
def create_attribute_usage(format):
'''Create an attribute and usage pair from a format string. The
format string is as documented in `pyglet.graphics.vertexattribute`, with
the addition of an optional usage component::
usage ::= attribute ( '/' ('static' | 'dynamic' | 'stream' | 'none') )?
If the usage is not given it defaults to 'dynamic'. The usage corresponds
to the OpenGL VBO usage hint, and for ``static`` also indicates a
preference for interleaved arrays. If ``none`` is specified a buffer
object is not created, and vertex data is stored in system memory.
Some examples:
``v3f/stream``
3D vertex position using floats, for stream usage
``c4b/static``
4-byte color attribute, for static usage
:return: attribute, usage
'''
match = _usage_format_re.match(format)
attribute_format = match.group('attribute')
attribute = vertexattribute.create_attribute(attribute_format)
usage = match.group('usage')
if usage:
vbo = not usage == 'none'
usage = _gl_usages[usage]
else:
usage = GL_DYNAMIC_DRAW
vbo = True
return (attribute, usage, vbo)
def create_domain(*attribute_usage_formats):
'''Create a vertex domain covering the given attribute usage formats.
See documentation for `create_attribute_usage` and
`pyglet.graphics.vertexattribute.create_attribute` for the grammar of
these format strings.
:rtype: `VertexDomain`
'''
attribute_usages = [create_attribute_usage(f) \
for f in attribute_usage_formats]
return VertexDomain(attribute_usages)
def create_indexed_domain(*attribute_usage_formats):
'''Create an indexed vertex domain covering the given attribute usage
formats. See documentation for `create_attribute_usage` and
`pyglet.graphics.vertexattribute.create_attribute` for the grammar of
these format strings.
:rtype: `VertexDomain`
'''
attribute_usages = [create_attribute_usage(f) \
for f in attribute_usage_formats]
return IndexedVertexDomain(attribute_usages)
class VertexDomain(object):
'''Management of a set of vertex lists.
Construction of a vertex domain is usually done with the `create_domain`
function.
'''
_version = 0
_initial_count = 16
def __init__(self, attribute_usages):
self.allocator = allocation.Allocator(self._initial_count)
static_attributes = []
attributes = []
self.buffer_attributes = [] # list of (buffer, attributes)
for attribute, usage, vbo in attribute_usages:
if usage == GL_STATIC_DRAW:
# Group attributes for interleaved buffer
static_attributes.append(attribute)
attributes.append(attribute)
else:
# Create non-interleaved buffer
attributes.append(attribute)
attribute.buffer = vertexbuffer.create_mappable_buffer(
attribute.stride * self.allocator.capacity,
usage=usage, vbo=vbo)
attribute.buffer.element_size = attribute.stride
attribute.buffer.attributes = (attribute,)
self.buffer_attributes.append(
(attribute.buffer, (attribute,)))
# Create buffer for interleaved data
if static_attributes:
vertexattribute.interleave_attributes(static_attributes)
stride = static_attributes[0].stride
buffer = vertexbuffer.create_mappable_buffer(
stride * self.allocator.capacity, usage=GL_STATIC_DRAW)
buffer.element_size = stride
self.buffer_attributes.append(
(buffer, static_attributes))
for attribute in static_attributes:
attribute.buffer = buffer
# Create named attributes for each attribute
self.attributes = attributes
self.attribute_names = {}
for attribute in attributes:
if isinstance(attribute, vertexattribute.GenericAttribute):
index = attribute.index
if 'generic' not in self.attributes:
self.attribute_names['generic'] = {}
assert index not in self.attribute_names['generic'], \
'More than one generic attribute with index %d' % index
self.attribute_names['generic'][index] = attribute
else:
name = attribute.plural
assert name not in self.attributes, \
'More than one "%s" attribute given' % name
self.attribute_names[name] = attribute
def __del__(self):
# Break circular refs that Python GC seems to miss even when forced
# collection.
for attribute in self.attributes:
del attribute.buffer
def _safe_alloc(self, count):
'''Allocate vertices, resizing the buffers if necessary.'''
try:
return self.allocator.alloc(count)
except allocation.AllocatorMemoryException, e:
capacity = _nearest_pow2(e.requested_capacity)
self._version += 1
for buffer, _ in self.buffer_attributes:
buffer.resize(capacity * buffer.element_size)
self.allocator.set_capacity(capacity)
return self.allocator.alloc(count)
def _safe_realloc(self, start, count, new_count):
'''Reallocate vertices, resizing the buffers if necessary.'''
try:
return self.allocator.realloc(start, count, new_count)
except allocation.AllocatorMemoryException, e:
capacity = _nearest_pow2(e.requested_capacity)
self._version += 1
for buffer, _ in self.buffer_attributes:
buffer.resize(capacity * buffer.element_size)
self.allocator.set_capacity(capacity)
return self.allocator.realloc(start, count, new_count)
def create(self, count):
'''Create a `VertexList` in this domain.
:Parameters:
`count` : int
Number of vertices to create.
:rtype: `VertexList`
'''
start = self._safe_alloc(count)
return VertexList(self, start, count)
def draw(self, mode, vertex_list=None):
'''Draw vertices in the domain.
If `vertex_list` is not specified, all vertices in the domain are
drawn. This is the most efficient way to render primitives.
If `vertex_list` specifies a `VertexList`, only primitives in that
list will be drawn.
:Parameters:
`mode` : int
OpenGL drawing mode, e.g. ``GL_POINTS``, ``GL_LINES``, etc.
`vertex_list` : `VertexList`
Vertex list to draw, or ``None`` for all lists in this domain.
'''
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
for buffer, attributes in self.buffer_attributes:
buffer.bind()
for attribute in attributes:
attribute.enable()
attribute.set_pointer(attribute.buffer.ptr)
if vertexbuffer._workaround_vbo_finish:
glFinish()
if vertex_list is not None:
glDrawArrays(mode, vertex_list.start, vertex_list.count)
else:
starts, sizes = self.allocator.get_allocated_regions()
primcount = len(starts)
if primcount == 0:
pass
elif primcount == 1:
# Common case
glDrawArrays(mode, starts[0], sizes[0])
elif gl_info.have_version(1, 4):
starts = (GLint * primcount)(*starts)
sizes = (GLsizei * primcount)(*sizes)
glMultiDrawArrays(mode, starts, sizes, primcount)
else:
for start, size in zip(starts, sizes):
glDrawArrays(mode, start, size)
for buffer, _ in self.buffer_attributes:
buffer.unbind()
glPopClientAttrib()
def _is_empty(self):
return not self.allocator.starts
def __repr__(self):
return '<%s@%x %s>' % (self.__class__.__name__, id(self),
self.allocator)
class VertexList(object):
'''A list of vertices within a `VertexDomain`. Use
`VertexDomain.create` to construct this list.
'''
def __init__(self, domain, start, count):
# TODO make private
self.domain = domain
self.start = start
self.count = count
def get_size(self):
'''Get the number of vertices in the list.
:rtype: int
'''
return self.count
def get_domain(self):
'''Get the domain this vertex list belongs to.
:rtype: `VertexDomain`
'''
return self.domain
def draw(self, mode):
'''Draw this vertex list in the given OpenGL mode.
:Parameters:
`mode` : int
OpenGL drawing mode, e.g. ``GL_POINTS``, ``GL_LINES``, etc.
'''
self.domain.draw(mode, self)
def resize(self, count):
'''Resize this group.
:Parameters:
`count` : int
New number of vertices in the list.
'''
new_start = self.domain._safe_realloc(self.start, self.count, count)
if new_start != self.start:
# Copy contents to new location
for attribute in self.domain.attributes:
old = attribute.get_region(attribute.buffer,
self.start, self.count)
new = attribute.get_region(attribute.buffer,
new_start, self.count)
new.array[:] = old.array[:]
new.invalidate()
self.start = new_start
self.count = count
self._colors_cache_version = None
self._fog_coords_cache_version = None
self._edge_flags_cache_version = None
self._normals_cache_version = None
self._secondary_colors_cache_version = None
self._tex_coords_cache_version = None
self._vertices_cache_version = None
def delete(self):
'''Delete this group.'''
self.domain.allocator.dealloc(self.start, self.count)
def migrate(self, domain):
'''Move this group from its current domain and add to the specified
one. Attributes on domains must match. (In practice, used to change
parent state of some vertices).
:Parameters:
`domain` : `VertexDomain`
Domain to migrate this vertex list to.
'''
assert domain.attribute_names.keys() == \
self.domain.attribute_names.keys(), 'Domain attributes must match.'
new_start = domain._safe_alloc(self.count)
for key, old_attribute in self.domain.attribute_names.items():
old = old_attribute.get_region(old_attribute.buffer,
self.start, self.count)
new_attribute = domain.attribute_names[key]
new = new_attribute.get_region(new_attribute.buffer,
new_start, self.count)
new.array[:] = old.array[:]
new.invalidate()
self.domain.allocator.dealloc(self.start, self.count)
self.domain = domain
self.start = new_start
self._colors_cache_version = None
self._fog_coords_cache_version = None
self._edge_flags_cache_version = None
self._normals_cache_version = None
self._secondary_colors_cache_version = None
self._tex_coords_cache_version = None
self._vertices_cache_version = None
def _set_attribute_data(self, i, data):
attribute = self.domain.attributes[i]
# TODO without region
region = attribute.get_region(attribute.buffer, self.start, self.count)
region.array[:] = data
region.invalidate()
# ---
def _get_colors(self):
if (self._colors_cache_version != self.domain._version):
domain = self.domain
attribute = domain.attribute_names['colors']
self._colors_cache = attribute.get_region(
attribute.buffer, self.start, self.count)
self._colors_cache_version = domain._version
region = self._colors_cache
region.invalidate()
return region.array
def _set_colors(self, data):
self._get_colors()[:] = data
_colors_cache = None
_colors_cache_version = None
colors = property(_get_colors, _set_colors,
doc='''Array of color data.''')
# ---
def _get_fog_coords(self):
if (self._fog_coords_cache_version != self.domain._version):
domain = self.domain
attribute = domain.attribute_names['fog_coords']
self._fog_coords_cache = attribute.get_region(
attribute.buffer, self.start, self.count)
self._fog_coords_cache_version = domain._version
region = self._fog_coords_cache
region.invalidate()
return region.array
def _set_fog_coords(self, data):
self._get_fog_coords()[:] = data
_fog_coords_cache = None
_fog_coords_cache_version = None
fog_coords = property(_get_fog_coords, _set_fog_coords,
doc='''Array of fog coordinate data.''')
# ---
def _get_edge_flags(self):
if (self._edge_flags_cache_version != self.domain._version):
domain = self.domain
attribute = domain.attribute_names['edge_flags']
self._edge_flags_cache = attribute.get_region(
attribute.buffer, self.start, self.count)
self._edge_flags_cache_version = domain._version
region = self._edge_flags_cache
region.invalidate()
return region.array
def _set_edge_flags(self, data):
self._get_edge_flags()[:] = data
_edge_flags_cache = None
_edge_flags_cache_version = None
edge_flags = property(_get_edge_flags, _set_edge_flags,
doc='''Array of edge flag data.''')
# ---
def _get_normals(self):
if (self._normals_cache_version != self.domain._version):
domain = self.domain
attribute = domain.attribute_names['normals']
self._normals_cache = attribute.get_region(
attribute.buffer, self.start, self.count)
self._normals_cache_version = domain._version
region = self._normals_cache
region.invalidate()
return region.array
def _set_normals(self, data):
self._get_normals()[:] = data
_normals_cache = None
_normals_cache_version = None
normals = property(_get_normals, _set_normals,
doc='''Array of normal vector data.''')
# ---
def _get_secondary_colors(self):
if (self._secondary_colors_cache_version != self.domain._version):
domain = self.domain
attribute = domain.attribute_names['secondary_colors']
self._secondary_colors_cache = attribute.get_region(
attribute.buffer, self.start, self.count)
self._secondary_colors_cache_version = domain._version
region = self._secondary_colors_cache
region.invalidate()
return region.array
def _set_secondary_colors(self, data):
self._get_secondary_colors()[:] = data
_secondary_colors_cache = None
_secondary_colors_cache_version = None
secondary_colors = property(_get_secondary_colors, _set_secondary_colors,
doc='''Array of secondary color data.''')
# ---
_tex_coords_cache = None
_tex_coords_cache_version = None
def _get_tex_coords(self):
if (self._tex_coords_cache_version != self.domain._version):
domain = self.domain
attribute = domain.attribute_names['tex_coords']
self._tex_coords_cache = attribute.get_region(
attribute.buffer, self.start, self.count)
self._tex_coords_cache_version = domain._version
region = self._tex_coords_cache
region.invalidate()
return region.array
def _set_tex_coords(self, data):
self._get_tex_coords()[:] = data
tex_coords = property(_get_tex_coords, _set_tex_coords,
doc='''Array of texture coordinate data.''')
# ---
_vertices_cache = None
_vertices_cache_version = None
def _get_vertices(self):
if (self._vertices_cache_version != self.domain._version):
domain = self.domain
attribute = domain.attribute_names['vertices']
self._vertices_cache = attribute.get_region(
attribute.buffer, self.start, self.count)
self._vertices_cache_version = domain._version
region = self._vertices_cache
region.invalidate()
return region.array
def _set_vertices(self, data):
self._get_vertices()[:] = data
vertices = property(_get_vertices, _set_vertices,
doc='''Array of vertex coordinate data.''')
class IndexedVertexDomain(VertexDomain):
'''Management of a set of indexed vertex lists.
Construction of an indexed vertex domain is usually done with the
`create_indexed_domain` function.
'''
_initial_index_count = 16
def __init__(self, attribute_usages, index_gl_type=GL_UNSIGNED_INT):
super(IndexedVertexDomain, self).__init__(attribute_usages)
self.index_allocator = allocation.Allocator(self._initial_index_count)
self.index_gl_type = index_gl_type
self.index_c_type = vertexattribute._c_types[index_gl_type]
self.index_element_size = ctypes.sizeof(self.index_c_type)
self.index_buffer = vertexbuffer.create_mappable_buffer(
self.index_allocator.capacity * self.index_element_size,
target=GL_ELEMENT_ARRAY_BUFFER)
def _safe_index_alloc(self, count):
'''Allocate indices, resizing the buffers if necessary.'''
try:
return self.index_allocator.alloc(count)
except allocation.AllocatorMemoryException, e:
capacity = _nearest_pow2(e.requested_capacity)
self._version += 1
self.index_buffer.resize(capacity * self.index_element_size)
self.index_allocator.set_capacity(capacity)
return self.index_allocator.alloc(count)
def _safe_index_realloc(self, start, count, new_count):
'''Reallocate indices, resizing the buffers if necessary.'''
try:
return self.index_allocator.realloc(start, count, new_count)
except allocation.AllocatorMemoryException, e:
capacity = _nearest_pow2(e.requested_capacity)
self._version += 1
self.index_buffer.resize(capacity * self.index_element_size)
self.index_allocator.set_capacity(capacity)
return self.index_allocator.realloc(start, count, new_count)
def create(self, count, index_count):
'''Create an `IndexedVertexList` in this domain.
:Parameters:
`count` : int
Number of vertices to create
`index_count`
Number of indices to create
'''
start = self._safe_alloc(count)
index_start = self._safe_index_alloc(index_count)
return IndexedVertexList(self, start, count, index_start, index_count)
def get_index_region(self, start, count):
'''Get a region of the index buffer.
:Parameters:
`start` : int
Start of the region to map.
`count` : int
Number of indices to map.
:rtype: Array of int
'''
byte_start = self.index_element_size * start
byte_count = self.index_element_size * count
ptr_type = ctypes.POINTER(self.index_c_type * count)
return self.index_buffer.get_region(byte_start, byte_count, ptr_type)
def draw(self, mode, vertex_list=None):
'''Draw vertices in the domain.
If `vertex_list` is not specified, all vertices in the domain are
drawn. This is the most efficient way to render primitives.
If `vertex_list` specifies a `VertexList`, only primitives in that
list will be drawn.
:Parameters:
`mode` : int
OpenGL drawing mode, e.g. ``GL_POINTS``, ``GL_LINES``, etc.
`vertex_list` : `IndexedVertexList`
Vertex list to draw, or ``None`` for all lists in this domain.
'''
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
for buffer, attributes in self.buffer_attributes:
buffer.bind()
for attribute in attributes:
attribute.enable()
attribute.set_pointer(attribute.buffer.ptr)
self.index_buffer.bind()
if vertexbuffer._workaround_vbo_finish:
glFinish()
if vertex_list is not None:
glDrawElements(mode, vertex_list.index_count, self.index_gl_type,
self.index_buffer.ptr +
vertex_list.index_start * self.index_element_size)
else:
starts, sizes = self.index_allocator.get_allocated_regions()
primcount = len(starts)
if primcount == 0:
pass
elif primcount == 1:
# Common case
glDrawElements(mode, sizes[0], self.index_gl_type,
self.index_buffer.ptr + starts[0])
elif gl_info.have_version(1, 4):
if not isinstance(self.index_buffer,
vertexbuffer.VertexBufferObject):
starts = [s + self.index_buffer.ptr for s in starts]
starts = (GLuint * primcount)(*starts)
sizes = (GLsizei * primcount)(*sizes)
glMultiDrawElements(mode, sizes, self.index_gl_type, starts,
primcount)
else:
for start, size in zip(starts, sizes):
glDrawElements(mode, size, self.index_gl_type,
self.index_buffer.ptr +
start * self.index_element_size)
self.index_buffer.unbind()
for buffer, _ in self.buffer_attributes:
buffer.unbind()
glPopClientAttrib()
class IndexedVertexList(VertexList):
'''A list of vertices within an `IndexedVertexDomain` that are indexed.
Use `IndexedVertexDomain.create` to construct this list.
'''
def __init__(self, domain, start, count, index_start, index_count):
super(IndexedVertexList, self).__init__(domain, start, count)
self.index_start = index_start
self.index_count = index_count
def draw(self, mode):
self.domain.draw(mode, self)
def resize(self, count, index_count):
'''Resize this group.
:Parameters:
`count` : int
New number of vertices in the list.
`index_count` : int
New number of indices in the list.
'''
old_start = self.start
super(IndexedVertexList, self).resize(count)
# Change indices (because vertices moved)
if old_start != self.start:
diff = self.start - old_start
self.indices[:] = map(lambda i: i + diff, self.indices)
# Resize indices
new_start = self.domain._safe_index_realloc(
self.index_start, self.index_count, index_count)
if new_start != self.index_start:
old = self.domain.get_index_region(
self.index_start, self.index_count)
new = self.domain.get_index_region(
self.index_start, self.index_count)
new.array[:] = old.array[:]
new.invalidate()
self.index_start = new_start
self.index_count = index_count
self._indices_cache_version = None
def delete(self):
'''Delete this group.'''
super(IndexedVertexList, self).delete()
self.domain.index_allocator.dealloc(self.index_start, self.index_count)
def _set_index_data(self, data):
# TODO without region
region = self.domain.get_index_region(
self.index_start, self.index_count)
region.array[:] = data
region.invalidate()
# ---
def _get_indices(self):
if self._indices_cache_version != self.domain._version:
domain = self.domain
self._indices_cache = domain.get_index_region(
self.index_start, self.index_count)
self._indices_cache_version = domain._version
region = self._indices_cache
region.invalidate()
return region.array
def _set_indices(self, data):
self._get_indices()[:] = data
_indices_cache = None
_indices_cache_version = None
indices = property(_get_indices, _set_indices,
doc='''Array of index data.''')

2501
pyglet/image/__init__.py Normal file

File diff suppressed because it is too large Load diff

259
pyglet/image/atlas.py Normal file
View file

@ -0,0 +1,259 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Group multiple small images into larger textures.
This module is used by `pyglet.resource` to efficiently pack small images into
larger textures. `TextureAtlas` maintains one texture; `TextureBin` manages a
collection of atlases of a given size.
Example usage::
# Load images from disk
car_image = pyglet.image.load('car.png')
boat_image = pyglet.image.load('boat.png')
# Pack these images into one or more textures
bin = TextureBin()
car_texture = bin.add(car_image)
boat_texture = bin.add(boat_image)
The result of `TextureBin.add` is a `TextureRegion` containing the image.
Once added, an image cannot be removed from a bin (or an atlas); nor can a
list of images be obtained from a given bin or atlas -- it is the
application's responsibility to keep track of the regions returned by the
``add`` methods.
:since: pyglet 1.1
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import pyglet
class AllocatorException(Exception):
'''The allocator does not have sufficient free space for the requested
image size.'''
pass
class _Strip(object):
def __init__(self, y, max_height):
self.x = 0
self.y = y
self.max_height = max_height
self.y2 = y
def add(self, width, height):
assert width > 0 and height > 0
assert height <= self.max_height
x, y = self.x, self.y
self.x += width
self.y2 = max(self.y + height, self.y2)
return x, y
def compact(self):
self.max_height = self.y2 - self.y
class Allocator(object):
'''Rectangular area allocation algorithm.
Initialise with a given ``width`` and ``height``, then repeatedly
call `alloc` to retrieve free regions of the area and protect that
area from future allocations.
`Allocator` uses a fairly simple strips-based algorithm. It performs best
when rectangles are allocated in decreasing height order.
'''
def __init__(self, width, height):
'''Create an `Allocator` of the given size.
:Parameters:
`width` : int
Width of the allocation region.
`height` : int
Height of the allocation region.
'''
assert width > 0 and height > 0
self.width = width
self.height = height
self.strips = [_Strip(0, height)]
self.used_area = 0
def alloc(self, width, height):
'''Get a free area in the allocator of the given size.
After calling `alloc`, the requested area will no longer be used.
If there is not enough room to fit the given area `AllocatorException`
is raised.
:Parameters:
`width` : int
Width of the area to allocate.
`height` : int
Height of the area to allocate.
:rtype: int, int
:return: The X and Y coordinates of the bottom-left corner of the
allocated region.
'''
for strip in self.strips:
if self.width - strip.x >= width and strip.max_height >= height:
self.used_area += width * height
return strip.add(width, height)
if self.width >= width and self.height - strip.y2 >= height:
self.used_area += width * height
strip.compact()
newstrip = _Strip(strip.y2, self.height - strip.y2)
self.strips.append(newstrip)
return newstrip.add(width, height)
raise AllocatorException('No more space in %r for box %dx%d' % (
self, width, height))
def get_usage(self):
'''Get the fraction of area already allocated.
This method is useful for debugging and profiling only.
:rtype: float
'''
return self.used_area / float(self.width * self.height)
def get_fragmentation(self):
'''Get the fraction of area that's unlikely to ever be used, based on
current allocation behaviour.
This method is useful for debugging and profiling only.
:rtype: float
'''
# The total unused area in each compacted strip is summed.
if not self.strips:
return 0.
possible_area = self.strips[-1].y2 * width
return 1.0 - self.used_area / float(possible_area)
class TextureAtlas(object):
'''Collection of images within a texture.
'''
def __init__(self, width=256, height=256):
'''Create a texture atlas of the given size.
:Parameters:
`width` : int
Width of the underlying texture.
`height` : int
Height of the underlying texture.
'''
self.texture = pyglet.image.Texture.create(
width, height, pyglet.gl.GL_RGBA, rectangle=True)
self.allocator = Allocator(width, height)
def add(self, img):
'''Add an image to the atlas.
This method will fail if the given image cannot be transferred
directly to a texture (for example, if it is another texture).
`ImageData` is the usual image type for this method.
`AllocatorException` will be raised if there is no room in the atlas
for the image.
:Parameters:
`img` : `AbstractImage`
The image to add.
:rtype: `TextureRegion`
:return: The region of the atlas containing the newly added image.
'''
x, y = self.allocator.alloc(img.width, img.height)
self.texture.blit_into(img, x, y, 0)
region = self.texture.get_region(x, y, img.width, img.height)
return region
class TextureBin(object):
'''Collection of texture atlases.
`TextureBin` maintains a collection of texture atlases, and creates new
ones as necessary to accomodate images added to the bin.
'''
def __init__(self, texture_width=256, texture_height=256):
'''Create a texture bin for holding atlases of the given size.
:Parameters:
`texture_width` : int
Width of texture atlases to create.
`texture_height` : int
Height of texture atlases to create.
'''
self.atlases = []
self.texture_width = texture_width
self.texture_height = texture_height
def add(self, img):
'''Add an image into this texture bin.
This method calls `TextureAtlas.add` for the first atlas that has room
for the image.
`AllocatorException` is raised if the image exceeds the dimensions of
``texture_width`` and ``texture_height``.
:Parameters:
`img` : `AbstractImage`
The image to add.
:rtype: `TextureRegion`
:return: The region of an atlas containing the newly added image.
'''
for atlas in list(self.atlases):
try:
return atlas.add(img)
except AllocatorException:
# Remove atlases that are no longer useful (this is so their
# textures can later be freed if the images inside them get
# collected).
if img.width < 64 and img.height < 64:
self.atlases.remove(atlas)
atlas = TextureAtlas(self.texture_width, self.texture_height)
self.atlases.append(atlas)
return atlas.add(img)

View file

@ -0,0 +1,231 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Collection of image encoders and decoders.
Modules must subclass ImageDecoder and ImageEncoder for each method of
decoding/encoding they support.
Modules must also implement the two functions::
def get_decoders():
# Return a list of ImageDecoder instances or []
return []
def get_encoders():
# Return a list of ImageEncoder instances or []
return []
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import os.path
_decoders = [] # List of registered ImageDecoders
_decoder_extensions = {} # Map str -> list of matching ImageDecoders
_decoder_animation_extensions = {}
# Map str -> list of matching ImageDecoders
_encoders = [] # List of registered ImageEncoders
_encoder_extensions = {} # Map str -> list of matching ImageEncoders
class ImageDecodeException(Exception):
pass
class ImageEncodeException(Exception):
pass
class ImageDecoder(object):
def get_file_extensions(self):
'''Return a list of accepted file extensions, e.g. ['.png', '.bmp']
Lower-case only.
'''
return []
def get_animation_file_extensions(self):
'''Return a list of accepted file extensions, e.g. ['.gif', '.flc']
Lower-case only.
'''
return []
def decode(self, file, filename):
'''Decode the given file object and return an instance of `Image`.
Throws ImageDecodeException if there is an error. filename
can be a file type hint.
'''
raise NotImplementedError()
def decode_animation(self, file, filename):
'''Decode the given file object and return an instance of `Animation`.
Throws ImageDecodeException if there is an error. filename
can be a file type hint.
'''
raise ImageDecodeException('This decoder cannot decode animations.')
class ImageEncoder(object):
def get_file_extensions(self):
'''Return a list of accepted file extensions, e.g. ['.png', '.bmp']
Lower-case only.
'''
return []
def encode(self, image, file, filename, options={}):
'''Encode the given image to the given file. filename
provides a hint to the file format desired. options are
encoder-specific, and unknown options should be ignored or
issue warnings.
'''
raise NotImplementedError()
def get_encoders(filename=None):
'''Get an ordered list of encoders to attempt. filename can be used
as a hint for the filetype.
'''
encoders = []
if filename:
extension = os.path.splitext(filename)[1].lower()
encoders += _encoder_extensions.get(extension, [])
encoders += [e for e in _encoders if e not in encoders]
return encoders
def get_decoders(filename=None):
'''Get an ordered list of decoders to attempt. filename can be used
as a hint for the filetype.
'''
decoders = []
if filename:
extension = os.path.splitext(filename)[1].lower()
decoders += _decoder_extensions.get(extension, [])
decoders += [e for e in _decoders if e not in decoders]
return decoders
def get_animation_decoders(filename=None):
'''Get an ordered list of decoders to attempt. filename can be used
as a hint for the filetype.
'''
decoders = []
if filename:
extension = os.path.splitext(filename)[1].lower()
decoders += _decoder_animation_extensions.get(extension, [])
decoders += [e for e in _decoders if e not in decoders]
return decoders
def add_decoders(module):
'''Add a decoder module. The module must define `get_decoders`. Once
added, the appropriate decoders defined in the codec will be returned by
pyglet.image.codecs.get_decoders.
'''
for decoder in module.get_decoders():
_decoders.append(decoder)
for extension in decoder.get_file_extensions():
if extension not in _decoder_extensions:
_decoder_extensions[extension] = []
_decoder_extensions[extension].append(decoder)
for extension in decoder.get_animation_file_extensions():
if extension not in _decoder_animation_extensions:
_decoder_animation_extensions[extension] = []
_decoder_animation_extensions[extension].append(decoder)
def add_encoders(module):
'''Add an encoder module. The module must define `get_encoders`. Once
added, the appropriate encoders defined in the codec will be returned by
pyglet.image.codecs.get_encoders.
'''
for encoder in module.get_encoders():
_encoders.append(encoder)
for extension in encoder.get_file_extensions():
if extension not in _encoder_extensions:
_encoder_extensions[extension] = []
_encoder_extensions[extension].append(encoder)
def add_default_image_codecs():
# Add the codecs we know about. These should be listed in order of
# preference. This is called automatically by pyglet.image.
# Compressed texture in DDS format
try:
from pyglet.image.codecs import dds
add_encoders(dds)
add_decoders(dds)
except ImportError:
pass
# Mac OS X default: QuickTime
try:
import pyglet.image.codecs.quicktime
add_encoders(quicktime)
add_decoders(quicktime)
except ImportError:
pass
# Windows XP default: GDI+
try:
import pyglet.image.codecs.gdiplus
add_encoders(gdiplus)
add_decoders(gdiplus)
except ImportError:
pass
# Linux default: GdkPixbuf 2.0
try:
import pyglet.image.codecs.gdkpixbuf2
add_encoders(gdkpixbuf2)
add_decoders(gdkpixbuf2)
except ImportError:
pass
# Fallback: PIL
try:
import pyglet.image.codecs.pil
add_encoders(pil)
add_decoders(pil)
except ImportError:
pass
# Fallback: PNG loader (slow)
try:
import pyglet.image.codecs.png
add_encoders(png)
add_decoders(png)
except ImportError:
pass
# Fallback: BMP loader (slow)
try:
import pyglet.image.codecs.bmp
add_encoders(bmp)
add_decoders(bmp)
except ImportError:
pass

359
pyglet/image/codecs/bmp.py Normal file
View file

@ -0,0 +1,359 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Decoder for BMP files.
Currently supports version 3 and 4 bitmaps with BI_RGB and BI_BITFIELDS
encoding. Alpha channel is supported for 32-bit BI_RGB only.
'''
# Official docs are at
# http://msdn2.microsoft.com/en-us/library/ms532311.aspx
#
# But some details including alignment and bit/byte order are omitted; see
# http://www.fileformat.info/format/bmp/egff.htm
__docformat__ = 'restructuredtext'
__version__ = '$Id: bmp.py 2019 2008-04-18 14:30:48Z Alex.Holkner $'
import ctypes
from pyglet.image import ImageData
from pyglet.image.codecs import ImageDecoder, ImageDecodeException
BYTE = ctypes.c_ubyte
WORD = ctypes.c_uint16
DWORD = ctypes.c_uint32
LONG = ctypes.c_int32
FXPT2DOT30 = ctypes.c_uint32
BI_RGB = 0
BI_RLE8 = 1
BI_RLE4 = 2
BI_BITFIELDS = 3
class BITMAPFILEHEADER(ctypes.LittleEndianStructure):
_pack_ = 1
_fields_ = [
('bfType', WORD),
('bfSize', DWORD),
('bfReserved1', WORD),
('bfReserved2', WORD),
('bfOffBits', DWORD)
]
class BITMAPINFOHEADER(ctypes.LittleEndianStructure):
_pack_ = 1
_fields_ = [
('biSize', DWORD),
('biWidth', LONG),
('biHeight', LONG),
('biPlanes', WORD),
('biBitCount', WORD),
('biCompression', DWORD),
('biSizeImage', DWORD),
('biXPelsPerMeter', LONG),
('biYPelsPerMeter', LONG),
('biClrUsed', DWORD),
('biClrImportant', DWORD)
]
CIEXYZTRIPLE = FXPT2DOT30 * 9
class BITMAPV4HEADER(ctypes.LittleEndianStructure):
_pack_ = 1
_fields_ = [
('biSize', DWORD),
('biWidth', LONG),
('biHeight', LONG),
('biPlanes', WORD),
('biBitCount', WORD),
('biCompression', DWORD),
('biSizeImage', DWORD),
('biXPelsPerMeter', LONG),
('biYPelsPerMeter', LONG),
('biClrUsed', DWORD),
('biClrImportant', DWORD),
('bV4RedMask', DWORD),
('bV4GreenMask', DWORD),
('bV4BlueMask', DWORD),
('bV4AlphaMask', DWORD),
('bV4CSType', DWORD),
('bV4Endpoints', CIEXYZTRIPLE),
('bV4GammaRed', DWORD),
('bV4GammaGreen', DWORD),
('bV4GammaBlue', DWORD),
]
class RGBFields(ctypes.LittleEndianStructure):
_pack_ = 1
_fields_ = [
('red', DWORD),
('green', DWORD),
('blue', DWORD),
]
class RGBQUAD(ctypes.LittleEndianStructure):
_pack_ = 1
_fields_ = [
('rgbBlue', BYTE),
('rgbGreen', BYTE),
('rgbRed', BYTE),
('rgbReserved', BYTE)
]
def __repr__(self):
return '<%d, %d, %d>' % (self.rgbRed, self.rgbGreen, self.rgbBlue)
def ptr_add(ptr, offset):
address = ctypes.addressof(ptr.contents) + offset
return ctypes.pointer(type(ptr.contents).from_address(address))
def to_ctypes(buffer, offset, type):
if offset + ctypes.sizeof(type) > len(buffer):
raise ImageDecodeException('BMP file is truncated')
ptr = ptr_add(ctypes.pointer(buffer), offset)
return ctypes.cast(ptr, ctypes.POINTER(type)).contents
class BMPImageDecoder(ImageDecoder):
def get_file_extensions(self):
return ['.bmp']
def decode(self, file, filename):
if not file:
file = open(filename, 'rb')
bytes = file.read()
buffer = ctypes.c_buffer(bytes)
if bytes[:2] != 'BM':
raise ImageDecodeException(
'Not a Windows bitmap file: %r' % (filename or file))
file_header = to_ctypes(buffer, 0, BITMAPFILEHEADER)
bits_offset = file_header.bfOffBits
info_header_offset = ctypes.sizeof(BITMAPFILEHEADER)
info_header = to_ctypes(buffer, info_header_offset, BITMAPINFOHEADER)
palette_offset = info_header_offset + info_header.biSize
if info_header.biSize < ctypes.sizeof(BITMAPINFOHEADER):
raise ImageDecodeException(
'Unsupported BMP type: %r' % (filename or file))
width = info_header.biWidth
height = info_header.biHeight
if width <= 0 or info_header.biPlanes != 1:
raise ImageDecodeException(
'BMP file has corrupt parameters: %r' % (filename or file))
pitch_sign = height < 0 and -1 or 1
height = abs(height)
compression = info_header.biCompression
if compression not in (BI_RGB, BI_BITFIELDS):
raise ImageDecodeException(
'Unsupported compression: %r' % (filename or file))
clr_used = 0
bitcount = info_header.biBitCount
if bitcount == 1:
pitch = (width + 7) // 8
bits_type = ctypes.c_ubyte
decoder = decode_1bit
elif bitcount == 4:
pitch = (width + 1) // 2
bits_type = ctypes.c_ubyte
decoder = decode_4bit
elif bitcount == 8:
bits_type = ctypes.c_ubyte
pitch = width
decoder = decode_8bit
elif bitcount == 16:
pitch = width * 2
bits_type = ctypes.c_uint16
decoder = decode_bitfields
elif bitcount == 24:
pitch = width * 3
bits_type = ctypes.c_ubyte
decoder = decode_24bit
elif bitcount == 32:
pitch = width * 4
if compression == BI_RGB:
decoder = decode_32bit_rgb
bits_type = ctypes.c_ubyte
elif compression == BI_BITFIELDS:
decoder = decode_bitfields
bits_type = ctypes.c_uint32
else:
raise ImageDecodeException(
'Unsupported compression: %r' % (filename or file))
else:
raise ImageDecodeException(
'Unsupported bit count %d: %r' % (bitcount, filename or file))
pitch = (pitch + 3) & ~3
packed_width = pitch // ctypes.sizeof(bits_type)
if bitcount < 16 and compression == BI_RGB:
clr_used = info_header.biClrUsed or (1 << bitcount)
palette = to_ctypes(buffer, palette_offset, RGBQUAD * clr_used)
bits = to_ctypes(buffer, bits_offset,
bits_type * packed_width * height)
return decoder(bits, palette, width, height, pitch, pitch_sign)
elif bitcount >= 16 and compression == BI_RGB:
bits = to_ctypes(buffer, bits_offset,
bits_type * (packed_width * height))
return decoder(bits, None, width, height, pitch, pitch_sign)
elif compression == BI_BITFIELDS:
if info_header.biSize >= ctypes.sizeof(BITMAPV4HEADER):
info_header = to_ctypes(buffer, info_header_offset,
BITMAPV4HEADER)
r_mask = info_header.bV4RedMask
g_mask = info_header.bV4GreenMask
b_mask = info_header.bV4BlueMask
else:
fields_offset = info_header_offset + \
ctypes.sizeof(BITMAPINFOHEADER)
fields = to_ctypes(buffer, fields_offset, RGBFields)
r_mask = fields.red
g_mask = fields.green
b_mask = fields.blue
class _BitsArray(ctypes.LittleEndianStructure):
_pack_ = 1
_fields_ = [
('data', bits_type * packed_width * height),
]
bits = to_ctypes(buffer, bits_offset, _BitsArray).data
return decoder(bits, r_mask, g_mask, b_mask,
width, height, pitch, pitch_sign)
def decode_1bit(bits, palette, width, height, pitch, pitch_sign):
rgb_pitch = (((pitch << 3) + 7) & ~0x7) * 3
buffer = (ctypes.c_ubyte * (height * rgb_pitch))()
i = 0
for row in bits:
for packed in row:
for _ in range(8):
rgb = palette[(packed & 0x80) >> 7]
buffer[i] = rgb.rgbRed
buffer[i + 1] = rgb.rgbGreen
buffer[i + 2] = rgb.rgbBlue
i += 3
packed <<= 1
return ImageData(width, height, 'RGB', buffer, pitch_sign * rgb_pitch)
def decode_4bit(bits, palette, width, height, pitch, pitch_sign):
rgb_pitch = (((pitch << 1) + 1) & ~0x1) * 3
buffer = (ctypes.c_ubyte * (height * rgb_pitch))()
i = 0
for row in bits:
for packed in row:
for index in ((packed & 0xf0) >> 4, packed & 0xf):
rgb = palette[index]
buffer[i] = rgb.rgbRed
buffer[i + 1] = rgb.rgbGreen
buffer[i + 2] = rgb.rgbBlue
i += 3
return ImageData(width, height, 'RGB', buffer, pitch_sign * rgb_pitch)
def decode_8bit(bits, palette, width, height, pitch, pitch_sign):
rgb_pitch = pitch * 3
buffer = (ctypes.c_ubyte * (height * rgb_pitch))()
i = 0
for row in bits:
for index in row:
rgb = palette[index]
buffer[i] = rgb.rgbRed
buffer[i + 1] = rgb.rgbGreen
buffer[i + 2] = rgb.rgbBlue
i += 3
return ImageData(width, height, 'RGB', buffer, pitch_sign * rgb_pitch)
def decode_24bit(bits, palette, width, height, pitch, pitch_sign):
buffer = (ctypes.c_ubyte * (height * pitch))()
ctypes.memmove(buffer, bits, len(buffer))
return ImageData(width, height, 'BGR', buffer, pitch_sign * pitch)
def decode_32bit_rgb(bits, palette, width, height, pitch, pitch_sign):
buffer = (ctypes.c_ubyte * (height * pitch))()
ctypes.memmove(buffer, bits, len(buffer))
return ImageData(width, height, 'BGRA', buffer, pitch_sign * pitch)
def get_shift(mask):
if not mask:
return 0
# Shift down
shift = 0
while not (1 << shift) & mask:
shift += 1
# Shift up
shift_up = 0
while (mask >> shift) >> shift_up:
shift_up += 1
s = shift - (8 - shift_up)
if s < 0:
return 0, -s
else:
return s, 0
def decode_bitfields(bits, r_mask, g_mask, b_mask,
width, height, pitch, pitch_sign):
r_shift1, r_shift2 = get_shift(r_mask)
g_shift1, g_shift2 = get_shift(g_mask)
b_shift1, b_shift2 = get_shift(b_mask)
rgb_pitch = 3 * len(bits[0])
buffer = (ctypes.c_ubyte * (height * rgb_pitch))()
i = 0
for row in bits:
for packed in row:
buffer[i] = (packed & r_mask) >> r_shift1 << r_shift2
buffer[i+1] = (packed & g_mask) >> g_shift1 << g_shift2
buffer[i+2] = (packed & b_mask) >> b_shift1 << b_shift2
i += 3
return ImageData(width, height, 'RGB', buffer, pitch_sign * rgb_pitch)
def get_decoders():
return [BMPImageDecoder()]
def get_encoders():
return []

238
pyglet/image/codecs/dds.py Normal file
View file

@ -0,0 +1,238 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''DDS texture loader.
Reference: http://msdn2.microsoft.com/en-us/library/bb172993.aspx
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: dds.py 1579 2008-01-15 14:47:19Z Alex.Holkner $'
from ctypes import *
import struct
from pyglet.gl import *
from pyglet.gl import gl_info
from pyglet.image import CompressedImageData
from pyglet.image import codecs
from pyglet.image.codecs import s3tc
class DDSException(codecs.ImageDecodeException):
pass
# dwFlags of DDSURFACEDESC2
DDSD_CAPS = 0x00000001
DDSD_HEIGHT = 0x00000002
DDSD_WIDTH = 0x00000004
DDSD_PITCH = 0x00000008
DDSD_PIXELFORMAT = 0x00001000
DDSD_MIPMAPCOUNT = 0x00020000
DDSD_LINEARSIZE = 0x00080000
DDSD_DEPTH = 0x00800000
# ddpfPixelFormat of DDSURFACEDESC2
DDPF_ALPHAPIXELS = 0x00000001
DDPF_FOURCC = 0x00000004
DDPF_RGB = 0x00000040
# dwCaps1 of DDSCAPS2
DDSCAPS_COMPLEX = 0x00000008
DDSCAPS_TEXTURE = 0x00001000
DDSCAPS_MIPMAP = 0x00400000
# dwCaps2 of DDSCAPS2
DDSCAPS2_CUBEMAP = 0x00000200
DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400
DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800
DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000
DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000
DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000
DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000
DDSCAPS2_VOLUME = 0x00200000
class _filestruct(object):
def __init__(self, data):
if len(data) < self.get_size():
raise DDSException('Not a DDS file')
items = struct.unpack(self.get_format(), data)
for field, value in map(None, self._fields, items):
setattr(self, field[0], value)
def __repr__(self):
name = self.__class__.__name__
return '%s(%s)' % \
(name, (', \n%s' % (' ' * (len(name) + 1))).join( \
['%s = %s' % (field[0], repr(getattr(self, field[0]))) \
for field in self._fields]))
@classmethod
def get_format(cls):
return '<' + ''.join([f[1] for f in cls._fields])
@classmethod
def get_size(cls):
return struct.calcsize(cls.get_format())
class DDSURFACEDESC2(_filestruct):
_fields = [
('dwMagic', '4s'),
('dwSize', 'I'),
('dwFlags', 'I'),
('dwHeight', 'I'),
('dwWidth', 'I'),
('dwPitchOrLinearSize', 'I'),
('dwDepth', 'I'),
('dwMipMapCount', 'I'),
('dwReserved1', '44s'),
('ddpfPixelFormat', '32s'),
('dwCaps1', 'I'),
('dwCaps2', 'I'),
('dwCapsReserved', '8s'),
('dwReserved2', 'I')
]
def __init__(self, data):
super(DDSURFACEDESC2, self).__init__(data)
self.ddpfPixelFormat = DDPIXELFORMAT(self.ddpfPixelFormat)
class DDPIXELFORMAT(_filestruct):
_fields = [
('dwSize', 'I'),
('dwFlags', 'I'),
('dwFourCC', '4s'),
('dwRGBBitCount', 'I'),
('dwRBitMask', 'I'),
('dwGBitMask', 'I'),
('dwBBitMask', 'I'),
('dwRGBAlphaBitMask', 'I')
]
_compression_formats = {
('DXT1', False): (GL_COMPRESSED_RGB_S3TC_DXT1_EXT, s3tc.decode_dxt1_rgb),
('DXT1', True): (GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, s3tc.decode_dxt1_rgba),
('DXT3', False): (GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, s3tc.decode_dxt3),
('DXT3', True): (GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, s3tc.decode_dxt3),
('DXT5', False): (GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, s3tc.decode_dxt5),
('DXT5', True): (GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, s3tc.decode_dxt5),
}
def _check_error():
e = glGetError()
if e != 0:
print 'GL error %d' % e
class DDSImageDecoder(codecs.ImageDecoder):
def get_file_extensions(self):
return ['.dds']
def decode(self, file, filename):
header = file.read(DDSURFACEDESC2.get_size())
desc = DDSURFACEDESC2(header)
if desc.dwMagic != 'DDS ' or desc.dwSize != 124:
raise DDSException('Invalid DDS file (incorrect header).')
width = desc.dwWidth
height = desc.dwHeight
compressed = False
volume = False
mipmaps = 1
if desc.dwFlags & DDSD_PITCH:
pitch = desc.dwPitchOrLinearSize
elif desc.dwFlags & DDSD_LINEARSIZE:
image_size = desc.dwPitchOrLinearSize
compressed = True
if desc.dwFlags & DDSD_DEPTH:
raise DDSException('Volume DDS files unsupported')
volume = True
depth = desc.dwDepth
if desc.dwFlags & DDSD_MIPMAPCOUNT:
mipmaps = desc.dwMipMapCount
if desc.ddpfPixelFormat.dwSize != 32:
raise DDSException('Invalid DDS file (incorrect pixel format).')
if desc.dwCaps2 & DDSCAPS2_CUBEMAP:
raise DDSException('Cubemap DDS files unsupported')
if not desc.ddpfPixelFormat.dwFlags & DDPF_FOURCC:
raise DDSException('Uncompressed DDS textures not supported.')
has_alpha = desc.ddpfPixelFormat.dwRGBAlphaBitMask != 0
format = None
format, decoder = _compression_formats.get(
(desc.ddpfPixelFormat.dwFourCC, has_alpha), None)
if not format:
raise DDSException('Unsupported texture compression %s' % \
desc.ddpfPixelFormat.dwFourCC)
if format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
block_size = 8
else:
block_size = 16
datas = []
w, h = width, height
for i in range(mipmaps):
if not w and not h:
break
if not w:
w = 1
if not h:
h = 1
size = ((w + 3) / 4) * ((h + 3) / 4) * block_size
data = file.read(size)
datas.append(data)
w >>= 1
h >>= 1
image = CompressedImageData(width, height, format, datas[0],
'GL_EXT_texture_compression_s3tc', decoder)
level = 0
for data in datas[1:]:
level += 1
image.set_mipmap_data(level, data)
return image
def get_decoders():
return [DDSImageDecoder()]
def get_encoders():
return []

View file

@ -0,0 +1,273 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: pil.py 163 2006-11-13 04:15:46Z Alex.Holkner $'
from ctypes import *
from pyglet.gl import *
from pyglet.image import *
from pyglet.image.codecs import *
from pyglet.window.win32.constants import *
from pyglet.window.win32.types import *
ole32 = windll.ole32
kernel32 = windll.kernel32
gdiplus = windll.gdiplus
LPSTREAM = c_void_p
REAL = c_float
PixelFormat1bppIndexed = 196865
PixelFormat4bppIndexed = 197634
PixelFormat8bppIndexed = 198659
PixelFormat16bppGrayScale = 1052676
PixelFormat16bppRGB555 = 135173
PixelFormat16bppRGB565 = 135174
PixelFormat16bppARGB1555 = 397319
PixelFormat24bppRGB = 137224
PixelFormat32bppRGB = 139273
PixelFormat32bppARGB = 2498570
PixelFormat32bppPARGB = 925707
PixelFormat48bppRGB = 1060876
PixelFormat64bppARGB = 3424269
PixelFormat64bppPARGB = 29622286
PixelFormatMax = 15
ImageLockModeRead = 1
ImageLockModeWrite = 2
ImageLockModeUserInputBuf = 4
class GdiplusStartupInput(Structure):
_fields_ = [
('GdiplusVersion', c_uint32),
('DebugEventCallback', c_void_p),
('SuppressBackgroundThread', BOOL),
('SuppressExternalCodecs', BOOL)
]
class GdiplusStartupOutput(Structure):
_fields = [
('NotificationHookProc', c_void_p),
('NotificationUnhookProc', c_void_p)
]
class BitmapData(Structure):
_fields_ = [
('Width', c_uint),
('Height', c_uint),
('Stride', c_int),
('PixelFormat', c_int),
('Scan0', POINTER(c_byte)),
('Reserved', POINTER(c_uint))
]
class Rect(Structure):
_fields_ = [
('X', c_int),
('Y', c_int),
('Width', c_int),
('Height', c_int)
]
kernel32.GlobalAlloc.restype = HGLOBAL
kernel32.GlobalLock.restype = c_void_p
PropertyTagFrameDelay = 0x5100
class PropertyItem(Structure):
_fields_ = [
('id', c_uint),
('length', c_ulong),
('type', c_short),
('value', c_void_p)
]
class GDIPlusDecoder(ImageDecoder):
def get_file_extensions(self):
return ['.bmp', '.gif', '.jpg', '.jpeg', '.exif', '.png', '.tif',
'.tiff']
def get_animation_file_extensions(self):
# TIFF also supported as a multi-page image; but that's not really an
# animation, is it?
return ['.gif']
def _load_bitmap(self, file, filename):
data = file.read()
# Create a HGLOBAL with image data
hglob = kernel32.GlobalAlloc(GMEM_MOVEABLE, len(data))
ptr = kernel32.GlobalLock(hglob)
memmove(ptr, data, len(data))
kernel32.GlobalUnlock(hglob)
# Create IStream for the HGLOBAL
stream = LPSTREAM()
ole32.CreateStreamOnHGlobal(hglob, True, byref(stream))
# Load image from stream
bitmap = c_void_p()
status = gdiplus.GdipCreateBitmapFromStream(stream, byref(bitmap))
if status != 0:
# TODO release stream
raise ImageDecodeException(
'GDI+ cannot load %r' % (filename or file))
return bitmap
def _get_image(self, bitmap):
# Get size of image (Bitmap subclasses Image)
width = REAL()
height = REAL()
gdiplus.GdipGetImageDimension(bitmap, byref(width), byref(height))
width = int(width.value)
height = int(height.value)
# Get image pixel format
pf = c_int()
gdiplus.GdipGetImagePixelFormat(bitmap, byref(pf))
pf = pf.value
# Reverse from what's documented because of Intel little-endianness.
format = 'BGRA'
if pf == PixelFormat24bppRGB:
format = 'BGR'
elif pf == PixelFormat32bppRGB:
pass
elif pf == PixelFormat32bppARGB:
pass
elif pf in (PixelFormat16bppARGB1555, PixelFormat32bppPARGB,
PixelFormat64bppARGB, PixelFormat64bppPARGB):
pf = PixelFormat32bppARGB
else:
format = 'BGR'
pf = PixelFormat24bppRGB
# Lock pixel data in best format
rect = Rect()
rect.X = 0
rect.Y = 0
rect.Width = width
rect.Height = height
bitmap_data = BitmapData()
gdiplus.GdipBitmapLockBits(bitmap,
byref(rect), ImageLockModeRead, pf, byref(bitmap_data))
# Create buffer for RawImage
buffer = create_string_buffer(bitmap_data.Stride * height)
memmove(buffer, bitmap_data.Scan0, len(buffer))
# Unlock data
gdiplus.GdipBitmapUnlockBits(bitmap, byref(bitmap_data))
return ImageData(width, height, format, buffer, -bitmap_data.Stride)
def _delete_bitmap(self, bitmap):
# Release image and stream
gdiplus.GdipDisposeImage(bitmap)
# TODO: How to call IUnknown::Release on stream?
def decode(self, file, filename):
bitmap = self._load_bitmap(file, filename)
image = self._get_image(bitmap)
self._delete_bitmap(bitmap)
return image
def decode_animation(self, file, filename):
bitmap = self._load_bitmap(file, filename)
dimension_count = c_uint()
gdiplus.GdipImageGetFrameDimensionsCount(bitmap, byref(dimension_count))
if dimension_count.value < 1:
self._delete_bitmap(bitmap)
raise ImageDecodeException('Image has no frame dimensions')
# XXX Make sure this dimension is time?
dimensions = (c_void_p * dimension_count.value)()
gdiplus.GdipImageGetFrameDimensionsList(bitmap, dimensions,
dimension_count.value)
frame_count = c_uint()
gdiplus.GdipImageGetFrameCount(bitmap, dimensions, byref(frame_count))
prop_id = PropertyTagFrameDelay
prop_size = c_uint()
gdiplus.GdipGetPropertyItemSize(bitmap, prop_id, byref(prop_size))
prop_buffer = c_buffer(prop_size.value)
prop_item = cast(prop_buffer, POINTER(PropertyItem)).contents
gdiplus.GdipGetPropertyItem(bitmap, prop_id, prop_size.value,
prop_buffer)
# XXX Sure it's long?
n_delays = prop_item.length / sizeof(c_long)
delays = cast(prop_item.value, POINTER(c_long * n_delays)).contents
frames = []
for i in range(frame_count.value):
gdiplus.GdipImageSelectActiveFrame(bitmap, dimensions, i)
image = self._get_image(bitmap)
delay = delays[i]
if delay <= 1:
delay = 10
frames.append(AnimationFrame(image, delay/100.))
self._delete_bitmap(bitmap)
return Animation(frames)
def get_decoders():
return [GDIPlusDecoder()]
def get_encoders():
return []
def init():
token = c_ulong()
startup_in = GdiplusStartupInput()
startup_in.GdiplusVersion = 1
startup_out = GdiplusStartupOutput()
gdiplus.GdiplusStartup(byref(token), byref(startup_in), byref(startup_out))
# Shutdown later?
# gdiplus.GdiplusShutdown(token)
init()

View file

@ -0,0 +1,165 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: gdkpixbuf2.py 1939 2008-03-21 11:48:12Z Alex.Holkner $'
from ctypes import *
from pyglet.gl import *
from pyglet.image import *
from pyglet.image.codecs import *
from pyglet.image.codecs import gif
import pyglet.lib
import pyglet.window
gdk = pyglet.lib.load_library('gdk-x11-2.0')
gdkpixbuf = pyglet.lib.load_library('gdk_pixbuf-2.0')
GdkPixbufLoader = c_void_p
GdkPixbuf = c_void_p
gdkpixbuf.gdk_pixbuf_loader_new.restype = GdkPixbufLoader
gdkpixbuf.gdk_pixbuf_loader_get_pixbuf.restype = GdkPixbuf
gdkpixbuf.gdk_pixbuf_get_pixels.restype = c_void_p
gdkpixbuf.gdk_pixbuf_loader_get_animation.restype = c_void_p
gdkpixbuf.gdk_pixbuf_animation_get_iter.restype = c_void_p
gdkpixbuf.gdk_pixbuf_animation_iter_get_pixbuf.restype = GdkPixbuf
class GTimeVal(Structure):
_fields_ = [
('tv_sec', c_long),
('tv_usec', c_long)
]
class GdkPixbuf2ImageDecoder(ImageDecoder):
def get_file_extensions(self):
return ['.png', '.xpm', '.jpg', '.jpeg', '.tif', '.tiff', '.pnm',
'.ras', '.bmp', '.gif']
def get_animation_file_extensions(self):
return ['.gif', '.ani']
def _load(self, file, filename, load_func):
data = file.read()
err = c_int()
loader = gdkpixbuf.gdk_pixbuf_loader_new()
gdkpixbuf.gdk_pixbuf_loader_write(loader, data, len(data), byref(err))
result = load_func(loader)
if not gdkpixbuf.gdk_pixbuf_loader_close(loader, byref(err)):
raise ImageDecodeException(filename)
if not result:
raise ImageDecodeException('Unable to load: %s' % filename)
return result
def _pixbuf_to_image(self, pixbuf):
# Get format and dimensions
width = gdkpixbuf.gdk_pixbuf_get_width(pixbuf)
height = gdkpixbuf.gdk_pixbuf_get_height(pixbuf)
channels = gdkpixbuf.gdk_pixbuf_get_n_channels(pixbuf)
rowstride = gdkpixbuf.gdk_pixbuf_get_rowstride(pixbuf)
has_alpha = gdkpixbuf.gdk_pixbuf_get_has_alpha(pixbuf)
pixels = gdkpixbuf.gdk_pixbuf_get_pixels(pixbuf)
# Copy pixel data.
buffer = (c_ubyte * (rowstride * height))()
memmove(buffer, pixels, rowstride * (height - 1) + width * channels)
# Release pixbuf
gdk.g_object_unref(pixbuf)
# Determine appropriate GL type
if channels == 3:
format = 'RGB'
else:
format = 'RGBA'
return ImageData(width, height, format, buffer, -rowstride)
def decode(self, file, filename):
pixbuf = self._load(file, filename,
gdkpixbuf.gdk_pixbuf_loader_get_pixbuf)
return self._pixbuf_to_image(pixbuf)
def decode_animation(self, file, filename):
# Extract GIF control data. If it's not a GIF, this method will
# raise.
gif_stream = gif.read(file)
delays = [image.delay for image in gif_stream.images]
# Get GDK animation iterator
file.seek(0)
anim = self._load(file, filename,
gdkpixbuf.gdk_pixbuf_loader_get_animation)
time = GTimeVal(0, 0)
iter = gdkpixbuf.gdk_pixbuf_animation_get_iter(anim, byref(time))
frames = []
# Extract each image
for control_delay in delays:
pixbuf = gdkpixbuf.gdk_pixbuf_animation_iter_get_pixbuf(iter)
image = self._pixbuf_to_image(pixbuf)
frames.append(AnimationFrame(image, control_delay))
gdk_delay = gdkpixbuf.gdk_pixbuf_animation_iter_get_delay_time(iter)
gdk_delay *= 1000 # milliseconds to microseconds
# Compare gdk_delay to control_delay for interest only.
#print control_delay, gdk_delay / 1000000.
if gdk_delay == -1:
break
us = time.tv_usec + gdk_delay
time.tv_sec += us // 1000000
time.tv_usec = us % 1000000
gdkpixbuf.gdk_pixbuf_animation_iter_advance(iter, byref(time))
return Animation(frames)
def get_decoders():
return [GdkPixbuf2ImageDecoder()]
def get_encoders():
return []
def init():
gdk.g_type_init()
init()

169
pyglet/image/codecs/gif.py Normal file
View file

@ -0,0 +1,169 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Read GIF control data.
http://www.w3.org/Graphics/GIF/spec-gif89a.txt
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: gif.py 1938 2008-03-21 11:47:05Z Alex.Holkner $'
import struct
from pyglet.image.codecs import ImageDecodeException
class GIFStream(object):
def __init__(self):
self.images = []
class GIFImage(object):
delay = None
class GraphicsScope(object):
delay = None
# Appendix A.
LABEL_EXTENSION_INTRODUCER = 0x21
LABEL_GRAPHIC_CONTROL_EXTENSION = 0xf9
LABEL_IMAGE_DESCRIPTOR = 0x2c
LABEL_TRAILER = 0x3b
def unpack(format, file):
size = struct.calcsize(format)
data = file.read(size)
if len(data) < size:
raise ImageDecodeException('Unexpected EOF')
return struct.unpack(format, data)
def read_byte(file):
data = file.read(1)
if not len(data):
raise ImageDecodeException('Unexpected EOF')
return ord(data)
def read(file):
'''Read a GIF file stream.
:rtype: GIFStream
'''
# 17. Header
signature = file.read(3)
version = file.read(3)
if signature != 'GIF':
raise ImageDecodeException('Not a GIF stream')
stream = GIFStream()
# 18. Logical screen descriptor
(logical_screen_width,
logical_screen_height,
fields,
background_color_index,
pixel_aspect_ratio) = unpack('HHBBB', file)
global_color_table_flag = fields & 0x80
global_color_table_size = fields & 0x7
# 19. Global color table
if global_color_table_flag:
global_color_table = file.read(6 << global_color_table_size)
# <Data>*
graphics_scope = GraphicsScope()
block_type = read_byte(file)
while block_type != LABEL_TRAILER:
if block_type == LABEL_IMAGE_DESCRIPTOR:
read_table_based_image(file, stream, graphics_scope)
graphics_scope = GraphicsScope()
elif block_type == LABEL_EXTENSION_INTRODUCER:
extension_block_type = read_byte(file)
if extension_block_type == LABEL_GRAPHIC_CONTROL_EXTENSION:
read_graphic_control_extension(file, stream, graphics_scope)
else:
skip_data_sub_blocks(file)
else:
# Skip bytes until a valid start character is found
print block_type
pass
block_type = read_byte(file)
return stream
def skip_data_sub_blocks(file):
# 15. Data sub-blocks
block_size = read_byte(file)
while block_size != 0:
data = file.read(block_size)
block_size = read_byte(file)
def read_table_based_image(file, stream, graphics_scope):
gif_image = GIFImage()
stream.images.append(gif_image)
gif_image.delay = graphics_scope.delay
# 20. Image descriptor
(image_left_position,
image_top_position,
image_width,
image_height,
fields) = unpack('HHHHB', file)
local_color_table_flag = fields & 0x80
local_color_table_size = fields & 0x7
# 21. Local color table
if local_color_table_flag:
local_color_table = file.read(6 << local_color_table_size)
# 22. Table based image data
lzw_code_size = file.read(1)
skip_data_sub_blocks(file)
def read_graphic_control_extension(file, stream, graphics_scope):
# 23. Graphic control extension
(block_size,
fields,
delay_time,
transparent_color_index,
terminator) = unpack('BBHBB', file)
if block_size != 4:
raise ImageFormatException('Incorrect block size')
if delay_time:
# Follow Firefox/Mac behaviour: use 100ms delay for any delay
# less than 10ms.
if delay_time <= 1:
delay_time = 10
graphics_scope.delay = float(delay_time) / 100

110
pyglet/image/codecs/pil.py Normal file
View file

@ -0,0 +1,110 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: pil.py 1768 2008-02-17 12:45:54Z Alex.Holkner $'
import os.path
from pyglet.gl import *
from pyglet.image import *
from pyglet.image.codecs import *
import Image
class PILImageDecoder(ImageDecoder):
def get_file_extensions(self):
# Only most common ones shown here
return ['.bmp', '.cur', '.gif', '.ico', '.jpg', '.jpeg', '.pcx', '.png',
'.tga', '.tif', '.tiff', '.xbm', '.xpm']
def decode(self, file, filename):
try:
image = Image.open(file)
except Exception, e:
raise ImageDecodeException(
'PIL cannot read %r: %s' % (filename or file, e))
image = image.transpose(Image.FLIP_TOP_BOTTOM)
# Convert bitmap and palette images to component
if image.mode in ('1', 'P'):
image = image.convert()
if image.mode not in ('L', 'LA', 'RGB', 'RGBA'):
raise ImageDecodeException('Unsupported mode "%s"' % image.mode)
type = GL_UNSIGNED_BYTE
width, height = image.size
return ImageData(width, height, image.mode, image.tostring())
class PILImageEncoder(ImageEncoder):
def get_file_extensions(self):
# Most common only
return ['.bmp', '.eps', '.gif', '.jpg', '.jpeg',
'.pcx', '.png', '.ppm', '.tiff', '.xbm']
def encode(self, image, file, filename):
# File format is guessed from filename extension, otherwise defaults
# to PNG.
pil_format = (filename and os.path.splitext(filename)[1][1:]) or 'png'
if pil_format.lower() == 'jpg':
pil_format = 'JPEG'
image = image.get_image_data()
format = image.format
if format != 'RGB':
# Only save in RGB or RGBA formats.
format = 'RGBA'
pitch = -(image.width * len(format))
# Note: Don't try and use frombuffer(..); different versions of
# PIL will orient the image differently.
pil_image = Image.fromstring(
format, (image.width, image.height), image.get_data(format, pitch))
try:
pil_image.save(file, pil_format)
except Exception, e:
raise ImageEncodeException(e)
def get_decoders():
return [PILImageDecoder()]
def get_encoders():
return [PILImageEncoder()]

110
pyglet/image/codecs/png.py Normal file
View file

@ -0,0 +1,110 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Encoder and decoder for PNG files, using PyPNG (pypng.py).
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import array
from pyglet.gl import *
from pyglet.image import *
from pyglet.image.codecs import *
import pyglet.image.codecs.pypng
class PNGImageDecoder(ImageDecoder):
def get_file_extensions(self):
return ['.png']
def decode(self, file, filename):
try:
reader = pyglet.image.codecs.pypng.Reader(file=file)
width, height, pixels, metadata = reader.read()
except Exception, e:
raise ImageDecodeException(
'PyPNG cannot read %r: %s' % (filename or file, e))
if metadata['greyscale']:
if metadata['has_alpha']:
format = 'LA'
else:
format = 'L'
else:
if metadata['has_alpha']:
format = 'RGBA'
else:
format = 'RGB'
pitch = len(format) * width
return ImageData(width, height, format, pixels.tostring(), -pitch)
class PNGImageEncoder(ImageEncoder):
def get_file_extensions(self):
return ['.png']
def encode(self, image, file, filename):
image = image.get_image_data()
has_alpha = 'A' in image.format
greyscale = len(image.format) < 3
if has_alpha:
if greyscale:
image.format = 'LA'
else:
image.format = 'RGBA'
else:
if greyscale:
image.format = 'L'
else:
image.format = 'RGB'
image.pitch = -(image.width * len(image.format))
writer = pyglet.image.codecs.pypng.Writer(
image.width, image.height,
bytes_per_sample=1,
greyscale=greyscale,
has_alpha=has_alpha)
data = array.array('B')
data.fromstring(image.data)
writer.write_array(file, data)
def get_decoders():
return [PNGImageDecoder()]
def get_encoders():
return [PNGImageEncoder()]

1092
pyglet/image/codecs/pypng.py Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,287 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: pil.py 163 2006-11-13 04:15:46Z Alex.Holkner $'
import sys
from ctypes import *
from pyglet.gl import *
from pyglet.image import *
from pyglet.image.codecs import *
from pyglet.window.carbon import carbon, quicktime, _oscheck
from pyglet.window.carbon.constants import _name
from pyglet.window.carbon.types import *
Handle = POINTER(POINTER(c_byte))
GWorldPtr = c_void_p
carbon.NewHandle.restype = Handle
HandleDataHandlerSubType = _name('hndl')
PointerDataHandlerSubType = _name('ptr ')
kDataHCanRead = 1
kDataRefExtensionFileName = _name('fnam')
kDataRefExtensionMIMEType = _name('mime')
ComponentInstance = c_void_p
k1MonochromePixelFormat = 0x00000001
k2IndexedPixelFormat = 0x00000002
k4IndexedPixelFormat = 0x00000004
k8IndexedPixelFormat = 0x00000008
k16BE555PixelFormat = 0x00000010
k24RGBPixelFormat = 0x00000018
k32ARGBPixelFormat = 0x00000020
k32BGRAPixelFormat = _name('BGRA')
k1IndexedGrayPixelFormat = 0x00000021
k2IndexedGrayPixelFormat = 0x00000022
k4IndexedGrayPixelFormat = 0x00000024
k8IndexedGrayPixelFormat = 0x00000028
kNativeEndianPixMap = 1 << 8
newMovieActive = 1
noErr = 0
movieTrackMediaType = 1 << 0
movieTrackCharacteristic = 1 << 1
movieTrackEnabledOnly = 1 << 2
VisualMediaCharacteristic = _name('eyes')
nextTimeMediaSample = 1
class PointerDataRefRecord(Structure):
_fields_ = [
('data', c_void_p),
('dataLength', c_long)
]
def Str255(value):
return create_string_buffer(chr(len(value)) + value)
class QuickTimeImageDecoder(ImageDecoder):
def get_file_extensions(self):
# Only most common ones shown here
return ['.bmp', '.cur', '.gif', '.ico', '.jpg', '.jpeg', '.pcx', '.png',
'.tga', '.tif', '.tiff', '.xbm', '.xpm']
def get_animation_file_extensions(self):
return ['.gif']
def _get_data_ref(self, file, filename):
self._data_hold = data = create_string_buffer(file.read())
dataref = carbon.NewHandle(sizeof(PointerDataRefRecord))
datarec = cast(dataref,
POINTER(POINTER(PointerDataRefRecord))).contents.contents
datarec.data = addressof(data)
datarec.dataLength = len(data)
self._data_handler_holder = data_handler = ComponentInstance()
r = quicktime.OpenADataHandler(dataref, PointerDataHandlerSubType,
None, 0, None, kDataHCanRead, byref(data_handler))
_oscheck(r)
extension_handle = Handle()
self._filename_hold = filename = Str255(filename)
r = carbon.PtrToHand(filename, byref(extension_handle), len(filename))
r = quicktime.DataHSetDataRefExtension(data_handler, extension_handle,
kDataRefExtensionFileName)
_oscheck(r)
quicktime.DisposeHandle(extension_handle)
quicktime.DisposeHandle(dataref)
dataref = c_void_p()
r = quicktime.DataHGetDataRef(data_handler, byref(dataref))
_oscheck(r)
quicktime.CloseComponent(data_handler)
return dataref
def _get_formats(self):
# TODO choose 24 bit where appropriate.
if sys.byteorder == 'big':
format = 'ARGB'
qtformat = k32ARGBPixelFormat
else:
format = 'BGRA'
qtformat = k32BGRAPixelFormat
return format, qtformat
def decode(self, file, filename):
dataref = self._get_data_ref(file, filename)
importer = ComponentInstance()
quicktime.GetGraphicsImporterForDataRef(dataref,
PointerDataHandlerSubType, byref(importer))
if not importer:
raise ImageDecodeException(filename or file)
rect = Rect()
quicktime.GraphicsImportGetNaturalBounds(importer, byref(rect))
width = rect.right
height = rect.bottom
format, qtformat = self._get_formats()
buffer = (c_byte * (width * height * len(format)))()
world = GWorldPtr()
quicktime.QTNewGWorldFromPtr(byref(world), qtformat,
byref(rect), c_void_p(), c_void_p(), 0, buffer,
len(format) * width)
quicktime.GraphicsImportSetGWorld(importer, world, c_void_p())
result = quicktime.GraphicsImportDraw(importer)
quicktime.DisposeGWorld(world)
if result != 0:
raise ImageDecodeException(filename or file)
pitch = len(format) * width
return ImageData(width, height, format, buffer, -pitch)
def decode_animation(self, file, filename):
# TODO: Stop playing chicken with the GC
# TODO: Cleanup in errors
quicktime.EnterMovies()
data_ref = self._get_data_ref(file, filename)
if not data_ref:
raise ImageDecodeException(filename or file)
movie = c_void_p()
id = c_short()
result = quicktime.NewMovieFromDataRef(byref(movie),
newMovieActive,
0,
data_ref,
PointerDataHandlerSubType)
if not movie:
#_oscheck(result)
raise ImageDecodeException(filename or file)
quicktime.GoToBeginningOfMovie(movie)
time_scale = float(quicktime.GetMovieTimeScale(movie))
format, qtformat = self._get_formats()
# Get movie width and height
rect = Rect()
quicktime.GetMovieBox(movie, byref(rect))
width = rect.right
height = rect.bottom
pitch = len(format) * width
# Set gworld
buffer = (c_byte * (width * height * len(format)))()
world = GWorldPtr()
quicktime.QTNewGWorldFromPtr(byref(world), qtformat,
byref(rect), c_void_p(), c_void_p(), 0, buffer,
len(format) * width)
quicktime.SetGWorld(world, 0)
quicktime.SetMovieGWorld(movie, world, 0)
visual = quicktime.GetMovieIndTrackType(movie, 1,
VisualMediaCharacteristic,
movieTrackCharacteristic)
if not visual:
raise ImageDecodeException('No video track')
time = 0
interesting_time = c_int()
quicktime.GetTrackNextInterestingTime(
visual,
nextTimeMediaSample,
time,
1,
byref(interesting_time),
None)
duration = interesting_time.value / time_scale
frames = []
while time >= 0:
result = quicktime.GetMoviesError()
if result == noErr:
# force redraw
result = quicktime.UpdateMovie(movie)
if result == noErr:
# process movie
quicktime.MoviesTask(movie, 0)
result = quicktime.GetMoviesError()
_oscheck(result)
buffer_copy = (c_byte * len(buffer))()
memmove(buffer_copy, buffer, len(buffer))
image = ImageData(width, height, format, buffer_copy, -pitch)
frames.append(AnimationFrame(image, duration))
interesting_time = c_int()
duration = c_int()
quicktime.GetTrackNextInterestingTime(
visual,
nextTimeMediaSample,
time,
1,
byref(interesting_time),
byref(duration))
quicktime.SetMovieTimeValue(movie, interesting_time)
time = interesting_time.value
duration = duration.value / time_scale
if duration <= 0.01:
duration = 0.1
quicktime.DisposeMovie(movie)
carbon.DisposeHandle(data_ref)
quicktime.ExitMovies()
return Animation(frames)
def get_decoders():
return [QuickTimeImageDecoder()]
def get_encoders():
return []

386
pyglet/image/codecs/s3tc.py Normal file
View file

@ -0,0 +1,386 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id:$
'''Software decoder for S3TC compressed texture (i.e., DDS).
http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_compression_s3tc.txt
'''
import ctypes
import re
import sys
from pyglet.gl import *
from pyglet.gl import gl_info
from pyglet.image import AbstractImage, Texture
split_8byte = re.compile('.' * 8, flags=re.DOTALL)
split_16byte = re.compile('.' * 16, flags=re.DOTALL)
class PackedImageData(AbstractImage):
_current_texture = None
def __init__(self, width, height, format, packed_format, data):
super(PackedImageData, self).__init__(width, height)
self.format = format
self.packed_format = packed_format
self.data = data
def unpack(self):
if self.packed_format == GL_UNSIGNED_SHORT_5_6_5:
# Unpack to GL_RGB. Assume self.data is already 16-bit
i = 0
out = (c_ubyte * (self.width * self.height * 3))()
for c in self.data:
out[i+2] = (c & 0x1f) << 3
out[i+1] = (c & 0x7e0) >> 3
out[i] = (c & 0xf800) >> 8
i += 3
self.data = out
self.packed_format = GL_UNSIGNED_BYTE
def _get_texture(self):
if self._current_texture:
return self._current_texture
texture = Texture.create_for_size(
GL_TEXTURE_2D, self.width, self.height)
glBindTexture(texture.target, texture.id)
glTexParameteri(texture.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
if not gl_info.have_version(1, 2) or True:
self.unpack()
glTexImage2D(texture.target, texture.level,
self.format, self.width, self.height, 0,
self.format, self.packed_format, self.data)
self._current_texture = texture
return texture
texture = property(_get_texture)
def decode_dxt1_rgb(data, width, height):
# Decode to 16-bit RGB UNSIGNED_SHORT_5_6_5
out = (ctypes.c_uint16 * (width * height))()
# Read 8 bytes at a time
image_offset = 0
col = 0
for c0_lo, c0_hi, c1_lo, c1_hi, b0, b1, b2, b3 in split_8byte.findall(data):
color0 = ord(c0_lo) | ord(c0_hi) << 8
color1 = ord(c1_lo) | ord(c1_hi) << 8
bits = ord(b0) | ord(b1) << 8 | ord(b2) << 16 | ord(b3) << 24
r0 = color0 & 0x1f
g0 = (color0 & 0x7e0) >> 5
b0 = (color0 & 0xf800) >> 11
r1 = color1 & 0x1f
g1 = (color1 & 0x7e0) >> 5
b1 = (color1 & 0xf800) >> 11
# i is the dest ptr for this block
i = image_offset
for y in range(4):
for x in range(4):
code = bits & 0x3
if code == 0:
out[i] = color0
elif code == 1:
out[i] = color1
elif code == 3 and color0 <= color1:
out[i] = 0
else:
if code == 2 and color0 > color1:
r = (2 * r0 + r1) / 3
g = (2 * g0 + g1) / 3
b = (2 * b0 + b1) / 3
elif code == 3 and color0 > color1:
r = (r0 + 2 * r1) / 3
g = (g0 + 2 * g1) / 3
b = (b0 + 2 * b1) / 3
else:
assert code == 2 and color0 <= color1
r = (r0 + r1) / 2
g = (g0 + g1) / 2
b = (b0 + b1) / 2
out[i] = r | g << 5 | b << 11
bits >>= 2
i += 1
i += width - 4
# Move dest ptr to next 4x4 block
advance_row = (image_offset + 4) % width == 0
image_offset += width * 3 * advance_row + 4
return PackedImageData(width, height,
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, out)
def decode_dxt1_rgba(data, width, height):
# Decode to GL_RGBA
out = (ctypes.c_ubyte * (width * height * 4))()
pitch = width << 2
# Read 8 bytes at a time
image_offset = 0
col = 0
for c0_lo, c0_hi, c1_lo, c1_hi, b0, b1, b2, b3 in split_8byte.findall(data):
color0 = ord(c0_lo) | ord(c0_hi) << 8
color1 = ord(c1_lo) | ord(c1_hi) << 8
bits = ord(b0) | ord(b1) << 8 | ord(b2) << 16 | ord(b3) << 24
r0 = color0 & 0x1f
g0 = (color0 & 0x7e0) >> 5
b0 = (color0 & 0xf800) >> 11
r1 = color1 & 0x1f
g1 = (color1 & 0x7e0) >> 5
b1 = (color1 & 0xf800) >> 11
# i is the dest ptr for this block
i = image_offset
for y in range(4):
for x in range(4):
code = bits & 0x3
a = 255
if code == 0:
r, g, b = r0, g0, b0
elif code == 1:
r, g, b = r1, g1, b1
elif code == 3 and color0 <= color1:
r = g = b = a = 0
else:
if code == 2 and color0 > color1:
r = (2 * r0 + r1) / 3
g = (2 * g0 + g1) / 3
b = (2 * b0 + b1) / 3
elif code == 3 and color0 > color1:
r = (r0 + 2 * r1) / 3
g = (g0 + 2 * g1) / 3
b = (b0 + 2 * b1) / 3
else:
assert code == 2 and color0 <= color1
r = (r0 + r1) / 2
g = (g0 + g1) / 2
b = (b0 + b1) / 2
out[i] = b << 3
out[i+1] = g << 2
out[i+2] = r << 3
out[i+3] = a << 4
bits >>= 2
i += 4
i += pitch - 16
# Move dest ptr to next 4x4 block
advance_row = (image_offset + 16) % pitch == 0
image_offset += pitch * 3 * advance_row + 16
return PackedImageData(width, height, GL_RGBA, GL_UNSIGNED_BYTE, out)
def decode_dxt3(data, width, height):
# Decode to GL_RGBA
out = (ctypes.c_ubyte * (width * height * 4))()
pitch = width << 2
# Read 16 bytes at a time
image_offset = 0
col = 0
for (a0, a1, a2, a3, a4, a5, a6, a7,
c0_lo, c0_hi, c1_lo, c1_hi,
b0, b1, b2, b3) in split_16byte.findall(data):
color0 = ord(c0_lo) | ord(c0_hi) << 8
color1 = ord(c1_lo) | ord(c1_hi) << 8
bits = ord(b0) | ord(b1) << 8 | ord(b2) << 16 | ord(b3) << 24
alpha = ord(a0) | ord(a1) << 8 | ord(a2) << 16 | ord(a3) << 24 | \
ord(a4) << 32 | ord(a5) << 40 | ord(a6) << 48 | ord(a7) << 56
r0 = color0 & 0x1f
g0 = (color0 & 0x7e0) >> 5
b0 = (color0 & 0xf800) >> 11
r1 = color1 & 0x1f
g1 = (color1 & 0x7e0) >> 5
b1 = (color1 & 0xf800) >> 11
# i is the dest ptr for this block
i = image_offset
for y in range(4):
for x in range(4):
code = bits & 0x3
a = alpha & 0xf
if code == 0:
r, g, b = r0, g0, b0
elif code == 1:
r, g, b = r1, g1, b1
elif code == 3 and color0 <= color1:
r = g = b = 0
else:
if code == 2 and color0 > color1:
r = (2 * r0 + r1) / 3
g = (2 * g0 + g1) / 3
b = (2 * b0 + b1) / 3
elif code == 3 and color0 > color1:
r = (r0 + 2 * r1) / 3
g = (g0 + 2 * g1) / 3
b = (b0 + 2 * b1) / 3
else:
assert code == 2 and color0 <= color1
r = (r0 + r1) / 2
g = (g0 + g1) / 2
b = (b0 + b1) / 2
out[i] = b << 3
out[i+1] = g << 2
out[i+2] = r << 3
out[i+3] = a << 4
bits >>= 2
alpha >>= 4
i += 4
i += pitch - 16
# Move dest ptr to next 4x4 block
advance_row = (image_offset + 16) % pitch == 0
image_offset += pitch * 3 * advance_row + 16
return PackedImageData(width, height, GL_RGBA, GL_UNSIGNED_BYTE, out)
def decode_dxt5(data, width, height):
# Decode to GL_RGBA
out = (ctypes.c_ubyte * (width * height * 4))()
pitch = width << 2
# Read 16 bytes at a time
image_offset = 0
col = 0
for (alpha0, alpha1, ab0, ab1, ab2, ab3, ab4, ab5,
c0_lo, c0_hi, c1_lo, c1_hi,
b0, b1, b2, b3) in split_16byte.findall(data):
color0 = ord(c0_lo) | ord(c0_hi) << 8
color1 = ord(c1_lo) | ord(c1_hi) << 8
alpha0 = ord(alpha0)
alpha1 = ord(alpha1)
bits = ord(b0) | ord(b1) << 8 | ord(b2) << 16 | ord(b3) << 24
abits = ord(ab0) | ord(ab1) << 8 | ord(ab2) << 16 | ord(ab3) << 24 | \
ord(ab4) << 32 | ord(ab5) << 40
r0 = color0 & 0x1f
g0 = (color0 & 0x7e0) >> 5
b0 = (color0 & 0xf800) >> 11
r1 = color1 & 0x1f
g1 = (color1 & 0x7e0) >> 5
b1 = (color1 & 0xf800) >> 11
# i is the dest ptr for this block
i = image_offset
for y in range(4):
for x in range(4):
code = bits & 0x3
acode = abits & 0x7
if code == 0:
r, g, b = r0, g0, b0
elif code == 1:
r, g, b = r1, g1, b1
elif code == 3 and color0 <= color1:
r = g = b = 0
else:
if code == 2 and color0 > color1:
r = (2 * r0 + r1) / 3
g = (2 * g0 + g1) / 3
b = (2 * b0 + b1) / 3
elif code == 3 and color0 > color1:
r = (r0 + 2 * r1) / 3
g = (g0 + 2 * g1) / 3
b = (b0 + 2 * b1) / 3
else:
assert code == 2 and color0 <= color1
r = (r0 + r1) / 2
g = (g0 + g1) / 2
b = (b0 + b1) / 2
if acode == 0:
a = alpha0
elif acode == 1:
a = alpha1
elif alpha0 > alpha1:
if acode == 2:
a = (6 * alpha0 + 1 * alpha1) / 7
elif acode == 3:
a = (5 * alpha0 + 2 * alpha1) / 7
elif acode == 4:
a = (4 * alpha0 + 3 * alpha1) / 7
elif acode == 5:
a = (3 * alpha0 + 4 * alpha1) / 7
elif acode == 6:
a = (2 * alpha0 + 5 * alpha1) / 7
else:
assert acode == 7
a = (1 * alpha0 + 6 * alpha1) / 7
else:
if acode == 2:
a = (4 * alpha0 + 1 * alpha1) / 5
elif acode == 3:
a = (3 * alpha0 + 2 * alpha1) / 5
elif acode == 4:
a = (2 * alpha0 + 3 * alpha1) / 5
elif acode == 5:
a = (1 * alpha0 + 4 * alpha1) / 5
elif acode == 6:
a = 0
else:
assert acode == 7
a = 255
out[i] = b << 3
out[i+1] = g << 2
out[i+2] = r << 3
out[i+3] = a
bits >>= 2
abits >>= 3
i += 4
i += pitch - 16
# Move dest ptr to next 4x4 block
advance_row = (image_offset + 16) % pitch == 0
image_offset += pitch * 3 * advance_row + 16
return PackedImageData(width, height, GL_RGBA, GL_UNSIGNED_BYTE, out)

191
pyglet/info.py Normal file
View file

@ -0,0 +1,191 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Get environment information useful for debugging.
Intended usage is to create a file for bug reports, e.g.::
python -m pyglet.info > info.txt
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
_first_heading = True
def _heading(heading):
global _first_heading
if not _first_heading:
print
else:
_first_heading = False
print heading
print '-' * 78
def dump_python():
'''Dump Python version and environment to stdout.'''
import os
import sys
print 'sys.version:', sys.version
print 'sys.platform:', sys.platform
print 'os.getcwd():', os.getcwd()
for key, value in os.environ.items():
if key.startswith('PYGLET_'):
print "os.environ['%s']: %s" % (key, value)
def dump_pyglet():
'''Dump pyglet version and options.'''
import pyglet
print 'pyglet.version:', pyglet.version
print 'pyglet.__file__:', pyglet.__file__
for key, value in pyglet.options.items():
print "pyglet.options['%s'] = %r" % (key, value)
def dump_window():
'''Dump display, windowm, screen and default config info.'''
import pyglet.window
platform = pyglet.window.get_platform()
print 'platform:', repr(platform)
display = platform.get_default_display()
print 'display:', repr(display)
screens = display.get_screens()
for i, screen in enumerate(screens):
print 'screens[%d]: %r' % (i, screen)
window = pyglet.window.Window(visible=False)
for key, value in window.config.get_gl_attributes():
print "config['%s'] = %r" % (key, value)
print 'context:', repr(window.context)
window.close()
def dump_gl():
'''Dump GL info.'''
from pyglet.gl import gl_info
print 'gl_info.get_version():', gl_info.get_version()
print 'gl_info.get_vendor():', gl_info.get_vendor()
print 'gl_info.get_renderer():', gl_info.get_renderer()
print 'gl_info.get_extensions():'
extensions = list(gl_info.get_extensions())
extensions.sort()
for name in extensions:
print ' ', name
def dump_glu():
'''Dump GLU info.'''
from pyglet.gl import glu_info
print 'glu_info.get_version():', glu_info.get_version()
print 'glu_info.get_extensions():'
extensions = list(glu_info.get_extensions())
extensions.sort()
for name in extensions:
print ' ', name
def dump_glx():
'''Dump GLX info.'''
try:
from pyglet.gl import glx_info
except:
print 'GLX not available.'
return
import pyglet
window = pyglet.window.Window(visible=False)
print 'context.is_direct():', window.context.is_direct()
window.close()
if not glx_info.have_version(1, 1):
print 'Version: < 1.1'
else:
print 'glx_info.get_server_vendor():', glx_info.get_server_vendor()
print 'glx_info.get_server_version():', glx_info.get_server_version()
print 'glx_info.get_server_extensions():'
for name in glx_info.get_server_extensions():
print ' ', name
print 'glx_info.get_client_vendor():', glx_info.get_client_vendor()
print 'glx_info.get_client_version():', glx_info.get_client_version()
print 'glx_info.get_client_extensions():'
for name in glx_info.get_client_extensions():
print ' ', name
print 'glx_info.get_extensions():'
for name in glx_info.get_extensions():
print ' ', name
def dump_media():
'''Dump pyglet.media info.'''
import pyglet.media
print 'driver:', pyglet.media.driver.__name__
def dump_avbin():
'''Dump AVbin info.'''
try:
import pyglet.media.avbin
print 'Library:', pyglet.media.avbin.av
print 'AVbin version:', pyglet.media.avbin.av.avbin_get_version()
print 'FFmpeg revision:', \
pyglet.media.avbin.av.avbin_get_ffmpeg_revision()
except:
print 'AVbin not available.'
def dump_al():
'''Dump OpenAL info.'''
try:
from pyglet.media.drivers import openal
print 'Library:', openal.al._lib
print 'Version:', openal.get_version()
print 'Extensions:'
for extension in openal.get_extensions():
print ' ', extension
except:
print 'OpenAL not available.'
def _try_dump(heading, func):
_heading(heading)
try:
func()
except:
import traceback
traceback.print_exc()
def dump():
'''Dump all information to stdout.'''
_try_dump('Python', dump_python)
_try_dump('pyglet', dump_pyglet)
_try_dump('pyglet.window', dump_window)
_try_dump('pyglet.gl.gl_info', dump_gl)
_try_dump('pyglet.gl.glu_info', dump_glu)
_try_dump('pyglet.gl.glx_info', dump_glx)
_try_dump('pyglet.media', dump_media)
_try_dump('pyglet.media.avbin', dump_avbin)
_try_dump('pyglet.media.drivers.openal', dump_al)
if __name__ == '__main__':
dump()

303
pyglet/lib.py Normal file
View file

@ -0,0 +1,303 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Functions for loading dynamic libraries.
These extend and correct ctypes functions.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import os
import re
import sys
import ctypes
import ctypes.util
import pyglet
_debug_lib = pyglet.options['debug_lib']
_debug_trace = pyglet.options['debug_trace']
class _TraceFunction(object):
def __init__(self, func):
self.__dict__['_func'] = func
def __str__(self):
return self._func.__name__
def __call__(self, *args, **kwargs):
return self._func(*args, **kwargs)
def __getattr__(self, name):
return getattr(self._func, name)
def __setattr__(self, name, value):
setattr(self._func, name, value)
class _TraceLibrary(object):
def __init__(self, library):
self._library = library
print library
def __getattr__(self, name):
func = getattr(self._library, name)
f = _TraceFunction(func)
return f
class LibraryLoader(object):
def load_library(self, *names, **kwargs):
'''Find and load a library.
More than one name can be specified, they will be tried in order.
Platform-specific library names (given as kwargs) are tried first.
Raises ImportError if library is not found.
'''
if 'framework' in kwargs and self.platform == 'darwin':
return self.load_framework(kwargs['framework'])
platform_names = kwargs.get(self.platform, [])
if type(platform_names) in (str, unicode):
platform_names = [platform_names]
elif type(platform_names) is tuple:
platform_names = list(platform_names)
if self.platform == 'linux2':
platform_names.extend(['lib%s.so' % n for n in names])
platform_names.extend(names)
for name in platform_names:
try:
lib = ctypes.cdll.LoadLibrary(name)
if _debug_lib:
print name
if _debug_trace:
lib = _TraceLibrary(lib)
return lib
except OSError:
path = self.find_library(name)
if path:
try:
lib = ctypes.cdll.LoadLibrary(path)
if _debug_lib:
print path
if _debug_trace:
lib = _TraceLibrary(lib)
return lib
except OSError:
pass
raise ImportError('Library "%s" not found.' % names[0])
find_library = lambda self, name: ctypes.util.find_library(name)
platform = sys.platform
if platform == 'cygwin':
platform = 'win32'
def load_framework(self, path):
raise RuntimeError("Can't load framework on this platform.")
class MachOLibraryLoader(LibraryLoader):
def __init__(self):
if 'LD_LIBRARY_PATH' in os.environ:
self.ld_library_path = os.environ['LD_LIBRARY_PATH'].split(':')
else:
self.ld_library_path = []
if 'DYLD_LIBRARY_PATH' in os.environ:
self.dyld_library_path = os.environ['DYLD_LIBRARY_PATH'].split(':')
else:
self.dyld_library_path = []
if 'DYLD_FALLBACK_LIBRARY_PATH' in os.environ:
self.dyld_fallback_library_path = \
os.environ['DYLD_FALLBACK_LIBRARY_PATH'].split(':')
else:
self.dyld_fallback_library_path = [
os.path.expanduser('~/lib'),
'/usr/local/lib',
'/usr/lib']
def find_library(self, path):
'''Implements the dylib search as specified in Apple documentation:
http://developer.apple.com/documentation/DeveloperTools/Conceptual/DynamicLibraries/Articles/DynamicLibraryUsageGuidelines.html
Before commencing the standard search, the method first checks
the bundle's ``Frameworks`` directory if the application is running
within a bundle (OS X .app).
'''
libname = os.path.basename(path)
search_path = []
if hasattr(sys, 'frozen') and sys.frozen == 'macosx_app':
search_path.append(os.path.join(
os.environ['RESOURCEPATH'],
'..',
'Frameworks',
libname))
if '/' in path:
search_path.extend(
[os.path.join(p, libname) \
for p in self.dyld_library_path])
search_path.append(path)
search_path.extend(
[os.path.join(p, libname) \
for p in self.dyld_fallback_library_path])
else:
search_path.extend(
[os.path.join(p, libname) \
for p in self.ld_library_path])
search_path.extend(
[os.path.join(p, libname) \
for p in self.dyld_library_path])
search_path.append(path)
search_path.extend(
[os.path.join(p, libname) \
for p in self.dyld_fallback_library_path])
for path in search_path:
if os.path.exists(path):
return path
return None
def find_framework(self, path):
'''Implement runtime framework search as described by:
http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkBinding.html
'''
# e.g. path == '/System/Library/Frameworks/OpenGL.framework'
# name == 'OpenGL'
# return '/System/Library/Frameworks/OpenGL.framework/OpenGL'
name = os.path.splitext(os.path.split(path)[1])[0]
realpath = os.path.join(path, name)
if os.path.exists(realpath):
return realpath
for dir in ('/Library/Frameworks',
'/System/Library/Frameworks'):
realpath = os.path.join(dir, '%s.framework' % name, name)
if os.path.exists(realpath):
return realpath
return None
def load_framework(self, path):
realpath = self.find_framework(path)
if realpath:
lib = ctypes.cdll.LoadLibrary(realpath)
if _debug_lib:
print realpath
if _debug_trace:
lib = _TraceLibrary(lib)
return lib
raise ImportError("Can't find framework %s." % path)
class LinuxLibraryLoader(LibraryLoader):
_ld_so_cache = None
def _create_ld_so_cache(self):
# Recreate search path followed by ld.so. This is going to be
# slow to build, and incorrect (ld.so uses ld.so.cache, which may
# not be up-to-date). Used only as fallback for distros without
# /sbin/ldconfig.
#
# We assume the DT_RPATH and DT_RUNPATH binary sections are omitted.
directories = []
try:
directories.extend(os.environ['LD_LIBRARY_PATH'].split(':'))
except KeyError:
pass
try:
directories.extend([dir.strip() for dir in open('/etc/ld.so.conf')])
except IOError:
pass
directories.extend(['/lib', '/usr/lib'])
cache = {}
lib_re = re.compile('lib(.*)\.so')
for dir in directories:
try:
for file in os.listdir(dir):
if '.so' not in file:
continue
# Index by filename
path = os.path.join(dir, file)
if file not in cache:
cache[file] = path
# Index by library name
match = lib_re.match(file)
if match:
library = match.group(1)
if library not in cache:
cache[library] = path
except OSError:
pass
self._ld_so_cache = cache
def find_library(self, path):
# ctypes tries ldconfig, gcc and objdump. If none of these are
# present, we implement the ld-linux.so search path as described in
# the man page.
result = ctypes.util.find_library(path)
if result:
return result
if self._ld_so_cache is None:
self._create_ld_so_cache()
return self._ld_so_cache.get(path)
if sys.platform == 'darwin':
loader = MachOLibraryLoader()
elif sys.platform == 'linux2':
loader = LinuxLibraryLoader()
else:
loader = LibraryLoader()
load_library = loader.load_library

1404
pyglet/media/__init__.py Normal file

File diff suppressed because it is too large Load diff

477
pyglet/media/avbin.py Normal file
View file

@ -0,0 +1,477 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Use avbin to decode audio and video media.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: avbin.py 2084 2008-05-27 12:42:19Z Alex.Holkner $'
from pyglet.media import (MediaFormatException, StreamingSource,
VideoFormat, AudioFormat, AudioData)
import pyglet
from pyglet import gl
from pyglet.gl import gl_info
from pyglet import image
import pyglet.lib
import ctypes
av = pyglet.lib.load_library('avbin',
darwin='/usr/local/lib/libavbin.dylib')
AVBIN_RESULT_ERROR = -1
AVBIN_RESULT_OK = 0
AVbinResult = ctypes.c_int
AVBIN_STREAM_TYPE_UNKNOWN = 0
AVBIN_STREAM_TYPE_VIDEO = 1
AVBIN_STREAM_TYPE_AUDIO = 2
AVbinStreamType = ctypes.c_int
AVBIN_SAMPLE_FORMAT_U8 = 0
AVBIN_SAMPLE_FORMAT_S16 = 1
AVBIN_SAMPLE_FORMAT_S24 = 2
AVBIN_SAMPLE_FORMAT_S32 = 3
AVBIN_SAMPLE_FORMAT_FLOAT = 4
AVbinSampleFormat = ctypes.c_int
AVBIN_LOG_QUIET = -8
AVBIN_LOG_PANIC = 0
AVBIN_LOG_FATAL = 8
AVBIN_LOG_ERROR = 16
AVBIN_LOG_WARNING = 24
AVBIN_LOG_INFO = 32
AVBIN_LOG_VERBOSE = 40
AVBIN_LOG_DEBUG = 48
AVbinLogLevel = ctypes.c_int
AVbinFileP = ctypes.c_void_p
AVbinStreamP = ctypes.c_void_p
Timestamp = ctypes.c_int64
class AVbinFileInfo(ctypes.Structure):
_fields_ = [
('structure_size', ctypes.c_size_t),
('n_streams', ctypes.c_int),
('start_time', Timestamp),
('duration', Timestamp),
('title', ctypes.c_char * 512),
('author', ctypes.c_char * 512),
('copyright', ctypes.c_char * 512),
('comment', ctypes.c_char * 512),
('album', ctypes.c_char * 512),
('year', ctypes.c_int),
('track', ctypes.c_int),
('genre', ctypes.c_char * 32),
]
class _AVbinStreamInfoVideo(ctypes.Structure):
_fields_ = [
('width', ctypes.c_uint),
('height', ctypes.c_uint),
('sample_aspect_num', ctypes.c_int),
('sample_aspect_den', ctypes.c_int),
]
class _AVbinStreamInfoAudio(ctypes.Structure):
_fields_ = [
('sample_format', ctypes.c_int),
('sample_rate', ctypes.c_uint),
('sample_bits', ctypes.c_uint),
('channels', ctypes.c_uint),
]
class _AVbinStreamInfoUnion(ctypes.Union):
_fields_ = [
('video', _AVbinStreamInfoVideo),
('audio', _AVbinStreamInfoAudio),
]
class AVbinStreamInfo(ctypes.Structure):
_fields_ = [
('structure_size', ctypes.c_size_t),
('type', ctypes.c_int),
('u', _AVbinStreamInfoUnion)
]
class AVbinPacket(ctypes.Structure):
_fields_ = [
('structure_size', ctypes.c_size_t),
('timestamp', Timestamp),
('stream_index', ctypes.c_int),
('data', ctypes.POINTER(ctypes.c_uint8)),
('size', ctypes.c_size_t),
]
AVbinLogCallback = ctypes.CFUNCTYPE(None,
ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p)
av.avbin_get_version.restype = ctypes.c_int
av.avbin_get_ffmpeg_revision.restype = ctypes.c_int
av.avbin_get_audio_buffer_size.restype = ctypes.c_size_t
av.avbin_have_feature.restype = ctypes.c_int
av.avbin_have_feature.argtypes = [ctypes.c_char_p]
av.avbin_init.restype = AVbinResult
av.avbin_set_log_level.restype = AVbinResult
av.avbin_set_log_level.argtypes = [AVbinLogLevel]
av.avbin_set_log_callback.argtypes = [AVbinLogCallback]
av.avbin_open_filename.restype = AVbinFileP
av.avbin_open_filename.argtypes = [ctypes.c_char_p]
av.avbin_close_file.argtypes = [AVbinFileP]
av.avbin_seek_file.argtypes = [AVbinFileP, Timestamp]
av.avbin_file_info.argtypes = [AVbinFileP, ctypes.POINTER(AVbinFileInfo)]
av.avbin_stream_info.argtypes = [AVbinFileP, ctypes.c_int,
ctypes.POINTER(AVbinStreamInfo)]
av.avbin_open_stream.restype = ctypes.c_void_p
av.avbin_open_stream.argtypes = [AVbinFileP, ctypes.c_int]
av.avbin_close_stream.argtypes = [AVbinStreamP]
av.avbin_read.argtypes = [AVbinFileP, ctypes.POINTER(AVbinPacket)]
av.avbin_read.restype = AVbinResult
av.avbin_decode_audio.restype = ctypes.c_int
av.avbin_decode_audio.argtypes = [AVbinStreamP,
ctypes.c_void_p, ctypes.c_size_t,
ctypes.c_void_p, ctypes.POINTER(ctypes.c_int)]
av.avbin_decode_video.restype = ctypes.c_int
av.avbin_decode_video.argtypes = [AVbinStreamP,
ctypes.c_void_p, ctypes.c_size_t,
ctypes.c_void_p]
def get_version():
return av.avbin_get_version()
class AVbinException(MediaFormatException):
pass
def timestamp_from_avbin(timestamp):
return float(timestamp) / 1000000
def timestamp_to_avbin(timestamp):
return int(timestamp * 1000000)
class BufferedPacket(object):
def __init__(self, packet):
self.timestamp = packet.timestamp
self.stream_index = packet.stream_index
self.data = (ctypes.c_uint8 * packet.size)()
self.size = packet.size
ctypes.memmove(self.data, packet.data, self.size)
class BufferedImage(object):
def __init__(self, image, timestamp):
self.image = image
self.timestamp = timestamp
class AVbinSource(StreamingSource):
def __init__(self, filename, file=None):
if file is not None:
raise NotImplementedError('TODO: Load from file stream')
self._file = av.avbin_open_filename(filename)
if not self._file:
raise AVbinException('Could not open "%s"' % filename)
self._video_stream = None
self._audio_stream = None
file_info = AVbinFileInfo()
file_info.structure_size = ctypes.sizeof(file_info)
av.avbin_file_info(self._file, ctypes.byref(file_info))
self._duration = timestamp_from_avbin(file_info.duration)
# Pick the first video and audio streams found, ignore others.
for i in range(file_info.n_streams):
info = AVbinStreamInfo()
info.structure_size = ctypes.sizeof(info)
av.avbin_stream_info(self._file, i, info)
if (info.type == AVBIN_STREAM_TYPE_VIDEO and
not self._video_stream):
stream = av.avbin_open_stream(self._file, i)
if not stream:
continue
self.video_format = VideoFormat(
width=info.u.video.width,
height=info.u.video.height)
if info.u.video.sample_aspect_num != 0:
self.video_format.sample_aspect = (
float(info.u.video.sample_aspect_num) /
info.u.video.sample_aspect_den)
self._video_stream = stream
self._video_stream_index = i
elif (info.type == AVBIN_STREAM_TYPE_AUDIO and
info.u.audio.sample_bits in (8, 16) and
info.u.audio.channels in (1, 2) and
not self._audio_stream):
stream = av.avbin_open_stream(self._file, i)
if not stream:
continue
self.audio_format = AudioFormat(
channels=info.u.audio.channels,
sample_size=info.u.audio.sample_bits,
sample_rate=info.u.audio.sample_rate)
self._audio_stream = stream
self._audio_stream_index = i
self._packet = AVbinPacket()
self._packet.structure_size = ctypes.sizeof(self._packet)
self._packet.stream_index = -1
self._buffered_packets = []
self._buffer_streams = []
self._buffered_images = []
if self.audio_format:
self._audio_packet_ptr = 0
self._audio_packet_size = 0
self._audio_packet_timestamp = 0
self._audio_buffer = \
(ctypes.c_uint8 * av.avbin_get_audio_buffer_size())()
self._buffer_streams.append(self._audio_stream_index)
if self.video_format:
self._buffer_streams.append(self._video_stream_index)
self._force_next_video_image = True
self._last_video_timestamp = None
def __del__(self):
try:
if self._video_stream:
av.avbin_close_stream(self._video_stream)
if self._audio_stream:
av.avbin_close_stream(self._audio_stream)
av.avbin_close_file(self._file)
except:
pass
def _seek(self, timestamp):
av.avbin_seek_file(self._file, timestamp_to_avbin(timestamp))
self._buffered_packets = []
self._buffered_images = []
self._audio_packet_size = 0
self._force_next_video_image = True
self._last_video_timestamp = None
def _get_packet_for_stream(self, stream_index):
# See if a packet has already been buffered
for packet in self._buffered_packets:
if packet.stream_index == stream_index:
self._buffered_packets.remove(packet)
return packet
# XXX This is ugly and needs tuning per-codec. Replace with an
# explicit API for disabling unused streams (e.g. for silent driver).
'''
# Make sure we're not buffering packets that are being ignored
for buffer in self._buffered_packets, self._buffered_images:
if len(buffer) > 20:
buffer.pop(0)
'''
# Read more packets, buffering each interesting one until we get to
# the one we want or reach end of file.
while True:
if av.avbin_read(self._file, self._packet) != AVBIN_RESULT_OK:
return None
elif self._packet.stream_index == stream_index:
return self._packet
elif self._packet.stream_index == self._video_stream_index:
buffered_image = self._decode_video_packet(self._packet)
if buffered_image:
self._buffered_images.append(buffered_image)
elif self._packet.stream_index in self._buffer_streams:
self._buffered_packets.append(BufferedPacket(self._packet))
def _get_audio_data(self, bytes):
# XXX bytes currently ignored
while True:
while self._audio_packet_size > 0:
size_out = ctypes.c_int(len(self._audio_buffer))
#print self._audio_stream, self._audio_packet_ptr, self._audio_packet_size, self._audio_buffer, size_out
used = av.avbin_decode_audio(self._audio_stream,
self._audio_packet_ptr, self._audio_packet_size,
self._audio_buffer, size_out)
if used < 0:
self._audio_packet_size = 0
break
self._audio_packet_ptr.value += used
self._audio_packet_size -= used
if size_out.value <= 0:
continue
buffer = ctypes.string_at(self._audio_buffer, size_out)
duration = \
float(len(buffer)) / self.audio_format.bytes_per_second
timestamp = self._audio_packet_timestamp
self._audio_packet_timestamp += duration
return AudioData(buffer, len(buffer), timestamp, duration)
packet = self._get_packet_for_stream(self._audio_stream_index)
if not packet:
return None
self._audio_packet_timestamp = \
timestamp_from_avbin(packet.timestamp)
self._audio_packet = packet # keep from GC
self._audio_packet_ptr = ctypes.cast(packet.data,
ctypes.c_void_p)
self._audio_packet_size = packet.size
def _init_texture(self, player):
if not self.video_format:
return
width = self.video_format.width
height = self.video_format.height
if gl_info.have_extension('GL_ARB_texture_rectangle'):
texture = image.Texture.create_for_size(
gl.GL_TEXTURE_RECTANGLE_ARB, width, height,
internalformat=gl.GL_RGB)
else:
texture = image.Texture.create_for_size(
gl.GL_TEXTURE_2D, width, height, internalformat=gl.GL_RGB)
if texture.width != width or texture.height != height:
texture = texture.get_region(0, 0, width, height)
player._texture = texture
# Flip texture coords (good enough for simple apps).
t = list(player._texture.tex_coords)
player._texture.tex_coords = t[9:12] + t[6:9] + t[3:6] + t[:3]
def _decode_video_packet(self, packet):
timestamp = timestamp_from_avbin(packet.timestamp)
width = self.video_format.width
height = self.video_format.height
pitch = width * 3
buffer = (ctypes.c_uint8 * (pitch * height))()
result = av.avbin_decode_video(self._video_stream,
packet.data, packet.size,
buffer)
if result < 0:
return None
return BufferedImage(
image.ImageData(width, height, 'RGB', buffer, pitch),
timestamp)
def _next_image(self):
img = None
while not img:
packet = self._get_packet_for_stream(self._video_stream_index)
if not packet:
return
img = self._decode_video_packet(packet)
return img
def get_next_video_timestamp(self):
if not self.video_format:
return
try:
img = self._buffered_images[0]
except IndexError:
img = self._next_image()
self._buffered_images.append(img)
if img:
return img.timestamp
def get_next_video_frame(self):
if not self.video_format:
return
try:
img = self._buffered_images.pop(0)
except IndexError:
img = self._next_image()
if img:
self._last_video_timestamp = img.timestamp
self._force_next_video_image = False
return img.image
def _update_texture(self, player, timestamp):
if not self.video_format:
return
if self._last_video_timestamp > timestamp:
return
img = None
i = 0
while (not img or
(img.timestamp < timestamp and
not self._force_next_video_image) ):
if self._buffered_images:
img = self._buffered_images.pop(0)
else:
packet = self._get_packet_for_stream(self._video_stream_index)
if not packet:
return
img = self._decode_video_packet(packet)
# Emergency loop exit when timestamps are bad
i += 1
if i > 60:
break
if img:
player._texture.blit_into(img.image, 0, 0, 0)
self._last_video_timestamp = img.timestamp
self._force_next_video_image = False
def _release_texture(self, player):
player._texture = None
av.avbin_init()
if pyglet.options['debug_media']:
av.avbin_set_log_level(AVBIN_LOG_DEBUG)
else:
av.avbin_set_log_level(AVBIN_LOG_QUIET)

View file

@ -0,0 +1,34 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------

View file

@ -0,0 +1,301 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Linux ALSA audio implementation.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: __init__.py 2084 2008-05-27 12:42:19Z Alex.Holkner $'
import ctypes
import pyglet
from pyglet.media import AudioPlayer, Listener, MediaException
from pyglet.media.drivers.alsa import asound
alsa_debug = None
if pyglet.options['debug_media']:
alsa_debug = 'alsa.log'
class ALSAException(MediaException):
pass
if alsa_debug:
def check(err):
if err < 0:
raise ALSAException(asound.snd_strerror(err))
return err
else:
check = lambda v: v
class ALSAAudioPlayer(AudioPlayer):
_device_name = 'default'
_buffer_time = 0.3
_min_write_bytes = 10000
def __init__(self, audio_format):
super(ALSAAudioPlayer, self).__init__(audio_format)
format = {
8: asound.SND_PCM_FORMAT_U8,
16: asound.SND_PCM_FORMAT_S16,
24: asound.SND_PCM_FORMAT_S24, # probably won't work
32: asound.SND_PCM_FORMAT_S32
}.get(audio_format.sample_size)
if format is None:
raise ALSAException('Unsupported audio format.')
self.pcm = ctypes.POINTER(asound.snd_pcm_t)()
self.hwparams = ctypes.POINTER(asound.snd_pcm_hw_params_t)()
self.swparams = ctypes.POINTER(asound.snd_pcm_sw_params_t)()
check(asound.snd_pcm_open(ctypes.byref(self.pcm),
self._device_name,
asound.SND_PCM_STREAM_PLAYBACK,
asound.SND_PCM_NONBLOCK))
check(asound.snd_pcm_hw_params_malloc(ctypes.byref(self.hwparams)))
check(asound.snd_pcm_sw_params_malloc(ctypes.byref(self.swparams)))
check(asound.snd_pcm_hw_params_any(self.pcm, self.hwparams))
check(asound.snd_pcm_hw_params_set_access(self.pcm, self.hwparams,
asound.SND_PCM_ACCESS_RW_INTERLEAVED))
check(asound.snd_pcm_hw_params_set_format(self.pcm, self.hwparams,
format))
check(asound.snd_pcm_hw_params_set_channels(self.pcm, self.hwparams,
audio_format.channels))
rate = ctypes.c_uint(audio_format.sample_rate)
dir = ctypes.c_int(0)
check(asound.snd_pcm_hw_params_set_rate_near(self.pcm, self.hwparams,
rate, dir))
# Note actual sample rate is in rate.value. Ignored for now because
# difference is negligible.
buffer_size = int(self._buffer_time * audio_format.sample_rate)
bs = asound.snd_pcm_uframes_t(buffer_size)
check(asound.snd_pcm_hw_params_set_buffer_size_near(self.pcm,
self.hwparams, bs))
# Actual buffer size is in bs.value. Ignored for now.
check(asound.snd_pcm_hw_params(self.pcm, self.hwparams))
if alsa_debug:
asound.snd_output_printf(debug_output,
'New device: %s\n' % self._device_name)
check(asound.snd_pcm_dump(self.pcm, debug_output))
self.can_pause = asound.snd_pcm_hw_params_can_pause(self.hwparams)
# List of (alsatime, timestamp)
self._timestamps = []
self._stop_alsatime = None
self._eos_count = 0
self._playing = False
def __del__(self):
try:
check(asound.snd_pcm_close(self.pcm))
except:
pass
def get_write_size(self):
state = asound.snd_pcm_state(self.pcm)
if state == asound.SND_PCM_STATE_PAUSED:
return 0
avail = max(0, asound.snd_pcm_avail_update(self.pcm))
bytes = avail * self.audio_format.bytes_per_sample
if bytes < self._min_write_bytes:
return 0
return bytes
def write(self, audio_data):
samples = audio_data.length // self.audio_format.bytes_per_sample
samples_out = asound.snd_pcm_writei(self.pcm, audio_data.data,
samples)
if samples_out < 0:
if samples_out == -11: # EAGAIN
return
elif samples_out == -32: # EPIPE (xrun)
check(asound.snd_pcm_prepare(self.pcm))
return
else:
raise ALSAException(asound.snd_strerror(samples_out))
delay = asound.snd_pcm_sframes_t()
check(asound.snd_pcm_delay(self.pcm, delay))
alsatime = self._get_asound_time() + \
delay.value / float(self.audio_format.sample_rate)
self._timestamps.append((alsatime, audio_data.timestamp))
audio_data.consume(samples_out * self.audio_format.bytes_per_sample,
self.audio_format)
def write_eos(self):
if self._timestamps:
self._timestamps.append((None, None))
def write_end(self):
pass
def play(self):
if self._playing:
return
state = asound.snd_pcm_state(self.pcm)
if self.can_pause and state == asound.SND_PCM_STATE_PAUSED:
check(asound.snd_pcm_pause(self.pcm, 0))
elif state not in (asound.SND_PCM_STATE_RUNNING,
asound.SND_PCM_STATE_PREPARED):
check(asound.snd_pcm_prepare(self.pcm))
self._playing = True
if self._stop_alsatime is not None:
diff = self._get_asound_time() - self._stop_alsatime
self._timestamps = [(a + diff, t) for a, t in self._timestamps]
self._stop_alsatime = None
def stop(self):
if not self._playing:
return
if self.can_pause and self._playing:
check(asound.snd_pcm_pause(self.pcm, 1))
self._stop_alsatime = self._get_asound_time()
else:
# Hardware can't pause, so we'll just drop everything that's
# been buffered. Improvement could be to rebuffer data that
# wasn't played.
self.clear()
self._playing = False
def clear(self):
check(asound.snd_pcm_drop(self.pcm))
self._stop_alsatime = None
self._timestamps = []
def _get_asound_time(self):
status = ctypes.POINTER(asound.snd_pcm_status_t)()
timestamp = asound.snd_timestamp_t()
check(asound.snd_pcm_status_malloc(ctypes.byref(status)))
check(asound.snd_pcm_status(self.pcm, status))
asound.snd_pcm_status_get_tstamp(status, ctypes.byref(timestamp))
asound.snd_pcm_status_free(status)
return timestamp.tv_sec + timestamp.tv_usec * 0.000001
def pump(self):
underrun = False
if self._stop_alsatime is not None:
return underrun
# Check that ALSA's still playing
if self._playing:
state = asound.snd_pcm_state(self.pcm)
if state not in (asound.SND_PCM_STATE_RUNNING,
asound.SND_PCM_STATE_PREPARED):
# Underrun!
check(asound.snd_pcm_prepare(self.pcm))
underrun = True
alsatime = self._get_asound_time()
try:
while self._timestamps[0][0] < alsatime:
self._timestamps.pop(0)
while self._timestamps[0][0] is None:
self._eos_count += 1
self._timestamps.pop(0)
except IndexError:
pass
return underrun
def get_time(self):
if self._stop_alsatime is None:
alsatime = self._get_asound_time()
else:
alsatime = self._stop_alsatime
if not self._timestamps:
self._playing = False
return 0.0
alsats, ts = self._timestamps[0]
t = alsatime - alsats + ts
return t
def clear_eos(self):
if self._eos_count > 0:
self._eos_count -= 1
return True
return False
class ALSAListener(Listener):
def _set_volume(self, volume):
# TODO master volume
self._volume = volume
# All other properties are silently ignored.
def _set_position(self, position):
self._position = position
def _set_velocity(self, velocity):
self._velocity = velocity
def _set_forward_orientation(self, orientation):
self._forward_orientation = orientation
def _set_up_orientation(self, orientation):
self._up_orientation = orientation
def _set_doppler_factor(self, factor):
self._doppler_factor = factor
def _set_speed_of_sound(self, speed_of_sound):
self._speed_of_sound = speed_of_sound
def driver_init():
global debug_output
debug_output = ctypes.POINTER(asound.snd_output_t)()
if alsa_debug:
check(asound.snd_output_stdio_open(ctypes.byref(debug_output),
alsa_debug,
'w'))
driver_listener = ALSAListener()
driver_audio_player_class = ALSAAudioPlayer

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,394 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Windows DirectSound audio implementation.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import ctypes
import math
import time
from pyglet.media import AudioPlayer, Listener, MediaException
from pyglet.media.drivers.directsound import lib_dsound as lib
from pyglet.window.win32 import _user32
class DirectSoundException(MediaException):
pass
def _db(gain):
'''Convert linear gain in range [0.0, 1.0] to 100ths of dB.'''
if gain <= 0:
return -10000
return max(-10000, min(int(1000 * math.log(min(gain, 1))), 0))
class DirectSoundAudioPlayer(AudioPlayer):
_buffer_size = 44800 * 1
_update_buffer_size = _buffer_size // 4
_buffer_size_secs = None
_cone_inner_angle = 360
_cone_outer_angle = 360
UPDATE_PERIOD = 0.05
def __init__(self, audio_format):
super(DirectSoundAudioPlayer, self).__init__(audio_format)
self._playing = False
self._timestamp = 0.
self._buffer = None
self._buffer_playing = False
self._data_size = 0 # amount of buffer filled by this player
self._play_cursor = 0
self._buffer_time = 0. # ts of buffer at buffer_time_pos
self._buffer_time_pos = 0
self._write_cursor = 0
self._timestamps = []
self._eos_count = 0
self._dirty_size = 0
wfx = lib.WAVEFORMATEX()
wfx.wFormatTag = lib.WAVE_FORMAT_PCM
wfx.nChannels = audio_format.channels
wfx.nSamplesPerSec = audio_format.sample_rate
wfx.wBitsPerSample = audio_format.sample_size
wfx.nBlockAlign = wfx.wBitsPerSample * wfx.nChannels // 8
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign
dsbdesc = lib.DSBUFFERDESC()
dsbdesc.dwSize = ctypes.sizeof(dsbdesc)
dsbdesc.dwFlags = (lib.DSBCAPS_GLOBALFOCUS |
lib.DSBCAPS_GETCURRENTPOSITION2 |
lib.DSBCAPS_CTRLFREQUENCY |
lib.DSBCAPS_CTRLVOLUME)
if audio_format.channels == 1:
dsbdesc.dwFlags |= lib.DSBCAPS_CTRL3D
dsbdesc.dwBufferBytes = self._buffer_size
dsbdesc.lpwfxFormat = ctypes.pointer(wfx)
self._buffer = lib.IDirectSoundBuffer()
dsound.CreateSoundBuffer(dsbdesc, ctypes.byref(self._buffer), None)
if audio_format.channels == 1:
self._buffer3d = lib.IDirectSound3DBuffer()
self._buffer.QueryInterface(lib.IID_IDirectSound3DBuffer,
ctypes.byref(self._buffer3d))
else:
self._buffer3d = None
self._buffer_size_secs = \
self._buffer_size / float(audio_format.bytes_per_second)
self._buffer.SetCurrentPosition(0)
def __del__(self):
try:
self._buffer.Stop()
self._buffer.Release()
if self._buffer3d:
self._buffer3d.Release()
except:
pass
def get_write_size(self):
if self._data_size < self._buffer_size:
return self._buffer_size - self._data_size
play_cursor = self._play_cursor
if self._write_cursor == play_cursor and self._buffer_playing:
# Polling too fast, no play cursor movement
return 0
elif self._write_cursor == play_cursor and not self._playing:
# Paused and up-to-date
return 0
elif self._write_cursor < play_cursor:
# Play cursor ahead of write cursor
write_size = play_cursor - self._write_cursor
else:
# Play cursor behind write cursor, wraps around
write_size = self._buffer_size - self._write_cursor + play_cursor
if write_size < self._update_buffer_size and not self._dirty_size:
return 0
return write_size
def write(self, audio_data, length=None):
# Pass audio_data=None, length>0 to write silence
if length is None:
write_size = self.get_write_size()
length = min(audio_data.length, write_size)
if length == 0:
return 0
if self._data_size < self._buffer_size:
self._data_size = min(self._data_size + length, self._buffer_size)
p1 = ctypes.c_void_p()
l1 = lib.DWORD()
p2 = ctypes.c_void_p()
l2 = lib.DWORD()
self._buffer.Lock(self._write_cursor, length,
ctypes.byref(p1), l1, ctypes.byref(p2), l2, 0)
assert length == l1.value + l2.value
if audio_data:
if self._write_cursor >= self._play_cursor:
wc = self._write_cursor
else:
wc = self._write_cursor + self._buffer_size
self._timestamps.append((wc, audio_data.timestamp))
ctypes.memmove(p1, audio_data.data, l1.value)
audio_data.consume(l1.value, self.audio_format)
if l2.value:
ctypes.memmove(p2, audio_data.data, l2.value)
audio_data.consume(l2.value, self.audio_format)
else:
ctypes.memset(p1, 0, l1.value)
if l2.value:
ctypes.memset(p2, 0, l2.value)
pass
self._buffer.Unlock(p1, l1, p2, l2)
self._write_cursor += length
self._write_cursor %= self._buffer_size
def write_eos(self):
if self._write_cursor > self._play_cursor:
wc = self._write_cursor
else:
wc = self._write_cursor + self._buffer_size
self._timestamps.append((wc, 'eos'))
def write_end(self):
if not self._dirty_size:
self._dirty_size = self._buffer_size
def pump(self):
# Update play cursor, check for wraparound and EOS markers
play_cursor = lib.DWORD()
self._buffer.GetCurrentPosition(play_cursor, None)
if play_cursor.value < self._play_cursor:
# Wrapped around
self._buffer_time_pos -= self._buffer_size
self._timestamps = \
[(a - self._buffer_size, t) for a, t in self._timestamps]
self._play_cursor = play_cursor.value
try:
while self._timestamps[0][0] < self._play_cursor:
pos, timestamp = self._timestamps.pop(0)
if timestamp == 'eos':
self._eos_count += 1
else:
self._buffer_time = timestamp
self._buffer_time_pos = pos
except IndexError:
pass
self._timestamp = self._buffer_time + \
(self._play_cursor - self._buffer_time_pos) \
/ float(self.audio_format.bytes_per_second)
# Write silence
if self._dirty_size:
write_size = self.get_write_size()
length = min(write_size, self._dirty_size)
self.write(None, length)
self._dirty_size -= length
if self._dirty_size < 0:
self._dirty_size = 0
if self._playing and not self._buffer_playing:
self._buffer.Play(0, 0, lib.DSBPLAY_LOOPING)
self._buffer_playing = True
def get_time(self):
return self._timestamp
def play(self):
if self._playing:
return
self._playing = True
self._buffer.Play(0, 0, lib.DSBPLAY_LOOPING)
self._buffer_playing = True
def stop(self):
if not self._playing:
return
self._playing = False
self._buffer.Stop()
self._buffer_playing = False
def clear(self):
self._eos_count = 0
self._timestamps = []
self._write_cursor = 0
self._buffer.SetCurrentPosition(0)
self._buffer_time = 0.
self._buffer_time_pos = 0
self._data_size = 0
def clear_eos(self):
if self._eos_count > 0:
self._eos_count -= 1
return True
return False
def _get_source(self):
if self._sources:
return self._sources[0]
return None
def set_volume(self, volume):
volume = _db(volume)
self._buffer.SetVolume(volume)
def set_position(self, position):
if self._buffer3d:
x, y, z = position
self._buffer3d.SetPosition(x, y, -z, lib.DS3D_IMMEDIATE)
def set_min_distance(self, min_distance):
if self._buffer3d:
self._buffer3d.SetMinDistance(min_distance, lib.DS3D_IMMEDIATE)
def set_max_distance(self, max_distance):
if self._buffer3d:
self._buffer3d.SetMaxDistance(max_distance, lib.DS3D_IMMEDIATE)
def set_pitch(self, pitch):
frequency = int(pitch * self.audio_format.sample_rate)
self._buffer.SetFrequency(frequency)
def set_cone_orientation(self, cone_orientation):
if self._buffer3d:
x, y, z = cone_orientation
self._buffer3d.SetConeOrientation(x, y, -z, lib.DS3D_IMMEDIATE)
def set_cone_inner_angle(self, cone_inner_angle):
if self._buffer3d:
self._cone_inner_angle = int(cone_inner_angle)
self._set_cone_angles()
def set_cone_outer_angle(self, cone_outer_angle):
if self._buffer3d:
self._cone_outer_angle = int(cone_outer_angle)
self._set_cone_angles()
def _set_cone_angles(self):
inner = min(self._cone_inner_angle, self._cone_outer_angle)
outer = max(self._cone_inner_angle, self._cone_outer_angle)
self._buffer3d.SetConeAngles(inner, outer, lib.DS3D_IMMEDIATE)
def set_cone_outer_gain(self, cone_outer_gain):
if self._buffer3d:
volume = _db(cone_outer_gain)
self._buffer3d.SetConeOutsideVolume(volume, lib.DS3D_IMMEDIATE)
class DirectSoundListener(Listener):
def _init(self):
# Called after driver_init()
self._buffer = lib.IDirectSoundBuffer()
dsbd = lib.DSBUFFERDESC()
dsbd.dwSize = ctypes.sizeof(dsbd)
dsbd.dwFlags = (lib.DSBCAPS_CTRL3D |
lib.DSBCAPS_CTRLVOLUME |
lib.DSBCAPS_PRIMARYBUFFER)
dsound.CreateSoundBuffer(dsbd, ctypes.byref(self._buffer), None)
self._listener = lib.IDirectSound3DListener()
self._buffer.QueryInterface(lib.IID_IDirectSound3DListener,
ctypes.byref(self._listener))
def __del__(self):
try:
self._buffer.Release()
self._listener.Release()
except:
pass
def _set_volume(self, volume):
self._volume = volume
self._buffer.SetVolume(_db(volume))
def _set_position(self, position):
self._position = position
x, y, z = position
self._listener.SetPosition(x, y, -z, lib.DS3D_IMMEDIATE)
def _set_forward_orientation(self, orientation):
self._forward_orientation = orientation
self._set_orientation()
def _set_up_orientation(self, orientation):
self._up_orientation = orientation
self._set_orientation()
def _set_orientation(self):
x, y, z = self._forward_orientation
ux, uy, uz = self._up_orientation
self._listener.SetOrientation(x, y, -z, ux, uy, -uz, lib.DS3D_IMMEDIATE)
dsound = None
def driver_init():
global dsound
dsound = lib.IDirectSound()
lib.DirectSoundCreate(None, ctypes.byref(dsound), None)
# A trick used by mplayer.. use desktop as window handle since it would
# be complex to use pyglet window handles (and what to do when application
# is audio only?).
hwnd = _user32.GetDesktopWindow()
dsound.SetCooperativeLevel(hwnd, lib.DSSCL_NORMAL)
driver_listener._init()
# Force a context switch, as some Windows audio drivers don't get time
# to process short sounds if Python hogs all the CPU. See issue #163.
from pyglet import clock
clock.Clock._force_sleep = True
driver_listener = DirectSoundListener()
driver_audio_player_class = DirectSoundAudioPlayer

View file

@ -0,0 +1,408 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id:$
import ctypes
from pyglet import com
lib = ctypes.oledll.dsound
DWORD = ctypes.c_uint32
LPDWORD = ctypes.POINTER(DWORD)
LONG = ctypes.c_long
LPLONG = ctypes.POINTER(LONG)
WORD = ctypes.c_uint16
HWND = DWORD
LPUNKNOWN = ctypes.c_void_p
D3DVALUE = ctypes.c_float
PD3DVALUE = ctypes.POINTER(D3DVALUE)
class D3DVECTOR(ctypes.Structure):
_fields_ = [
('x', ctypes.c_float),
('y', ctypes.c_float),
('z', ctypes.c_float),
]
PD3DVECTOR = ctypes.POINTER(D3DVECTOR)
class WAVEFORMATEX(ctypes.Structure):
_fields_ = [
('wFormatTag', WORD),
('nChannels', WORD),
('nSamplesPerSec', DWORD),
('nAvgBytesPerSec', DWORD),
('nBlockAlign', WORD),
('wBitsPerSample', WORD),
('cbSize', WORD),
]
LPWAVEFORMATEX = ctypes.POINTER(WAVEFORMATEX)
WAVE_FORMAT_PCM = 1
class DSCAPS(ctypes.Structure):
_fields_ = [
('dwSize', DWORD),
('dwFlags', DWORD),
('dwMinSecondarySampleRate', DWORD),
('dwMaxSecondarySampleRate', DWORD),
('dwPrimaryBuffers', DWORD),
('dwMaxHwMixingAllBuffers', DWORD),
('dwMaxHwMixingStaticBuffers', DWORD),
('dwMaxHwMixingStreamingBuffers', DWORD),
('dwFreeHwMixingAllBuffers', DWORD),
('dwFreeHwMixingStaticBuffers', DWORD),
('dwFreeHwMixingStreamingBuffers', DWORD),
('dwMaxHw3DAllBuffers', DWORD),
('dwMaxHw3DStaticBuffers', DWORD),
('dwMaxHw3DStreamingBuffers', DWORD),
('dwFreeHw3DAllBuffers', DWORD),
('dwFreeHw3DStaticBuffers', DWORD),
('dwFreeHw3DStreamingBuffers', DWORD),
('dwTotalHwMemBytes', DWORD),
('dwFreeHwMemBytes', DWORD),
('dwMaxContigFreeHwMemBytes', DWORD),
('dwUnlockTransferRateHwBuffers', DWORD),
('dwPlayCpuOverheadSwBuffers', DWORD),
('dwReserved1', DWORD),
('dwReserved2', DWORD)
]
LPDSCAPS = ctypes.POINTER(DSCAPS)
class DSBCAPS(ctypes.Structure):
_fields_ = [
('dwSize', DWORD),
('dwFlags', DWORD),
('dwBufferBytes', DWORD),
('dwUnlockTransferRate', DWORD),
('dwPlayCpuOverhead', DWORD),
]
LPDSBCAPS = ctypes.POINTER(DSBCAPS)
class DSBUFFERDESC(ctypes.Structure):
_fields_ = [
('dwSize', DWORD),
('dwFlags', DWORD),
('dwBufferBytes', DWORD),
('dwReserved', DWORD),
('lpwfxFormat', LPWAVEFORMATEX),
]
LPDSBUFFERDESC = ctypes.POINTER(DSBUFFERDESC)
class DS3DBUFFER(ctypes.Structure):
_fields_ = [
('dwSize', DWORD),
('vPosition', D3DVECTOR),
('vVelocity', D3DVECTOR),
('dwInsideConeAngle', DWORD),
('dwOutsideConeAngle', DWORD),
('vConeOrientation', D3DVECTOR),
('lConeOutsideVolume', LONG),
('flMinDistance', D3DVALUE),
('flMaxDistance', D3DVALUE),
('dwMode', DWORD),
]
LPDS3DBUFFER = ctypes.POINTER(DS3DBUFFER)
class DS3DLISTENER(ctypes.Structure):
_fields_ = [
('dwSize', DWORD),
('vPosition', D3DVECTOR),
('vVelocity', D3DVECTOR),
('vOrientFront', D3DVECTOR),
('vOrientTop', D3DVECTOR),
('flDistanceFactor', D3DVALUE),
('flRolloffFactor', D3DVALUE),
('flDopplerFactor', D3DVALUE),
]
LPDS3DLISTENER = ctypes.POINTER(DS3DLISTENER)
class IDirectSoundBuffer(com.IUnknown):
_methods_ = [
('GetCaps',
com.STDMETHOD(LPDSBCAPS)),
('GetCurrentPosition',
com.STDMETHOD(LPDWORD, LPDWORD)),
('GetFormat',
com.STDMETHOD(LPWAVEFORMATEX, DWORD, LPDWORD)),
('GetVolume',
com.STDMETHOD(LPLONG)),
('GetPan',
com.STDMETHOD(LPLONG)),
('GetFrequency',
com.STDMETHOD(LPDWORD)),
('GetStatus',
com.STDMETHOD(LPDWORD)),
('Initialize',
com.STDMETHOD(ctypes.c_void_p, LPDSBUFFERDESC)),
('Lock',
com.STDMETHOD(DWORD, DWORD,
ctypes.POINTER(ctypes.c_void_p), LPDWORD,
ctypes.POINTER(ctypes.c_void_p), LPDWORD,
DWORD)),
('Play',
com.STDMETHOD(DWORD, DWORD, DWORD)),
('SetCurrentPosition',
com.STDMETHOD(DWORD)),
('SetFormat',
com.STDMETHOD(LPWAVEFORMATEX)),
('SetVolume',
com.STDMETHOD(LONG)),
('SetPan',
com.STDMETHOD(LONG)),
('SetFrequency',
com.STDMETHOD(DWORD)),
('Stop',
com.STDMETHOD()),
('Unlock',
com.STDMETHOD(ctypes.c_void_p, DWORD, ctypes.c_void_p, DWORD)),
('Restore',
com.STDMETHOD()),
]
IID_IDirectSound3DListener = com.GUID(
0x279AFA84, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60)
class IDirectSound3DListener(com.IUnknown):
_methods_ = [
('GetAllParameters',
com.STDMETHOD(LPDS3DLISTENER)),
('GetDistanceFactor',
com.STDMETHOD(PD3DVALUE)),
('GetDopplerFactor',
com.STDMETHOD(PD3DVALUE)),
('GetOrientation',
com.STDMETHOD(PD3DVECTOR)),
('GetPosition',
com.STDMETHOD(PD3DVECTOR)),
('GetRolloffFactor',
com.STDMETHOD(PD3DVALUE)),
('GetVelocity',
com.STDMETHOD(PD3DVECTOR)),
('SetAllParameters',
com.STDMETHOD(LPDS3DLISTENER)),
('SetDistanceFactor',
com.STDMETHOD(D3DVALUE, DWORD)),
('SetDopplerFactor',
com.STDMETHOD(D3DVALUE, DWORD)),
('SetOrientation',
com.STDMETHOD(D3DVALUE, D3DVALUE, D3DVALUE,
D3DVALUE, D3DVALUE, D3DVALUE, DWORD)),
('SetPosition',
com.STDMETHOD(D3DVALUE, D3DVALUE, D3DVALUE, DWORD)),
('SetRolloffFactor',
com.STDMETHOD(D3DVALUE, DWORD)),
('SetVelocity',
com.STDMETHOD(D3DVALUE, D3DVALUE, D3DVALUE, DWORD)),
('CommitDeferredSettings',
com.STDMETHOD()),
]
IID_IDirectSound3DBuffer = com.GUID(
0x279AFA86, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60)
class IDirectSound3DBuffer(com.IUnknown):
_methods_ = [
('GetAllParameters',
com.STDMETHOD(LPDS3DBUFFER)),
('GetConeAngles',
com.STDMETHOD(LPDWORD, LPDWORD)),
('GetConeOrientation',
com.STDMETHOD(PD3DVECTOR)),
('GetConeOutsideVolume',
com.STDMETHOD(LPLONG)),
('GetMaxDistance',
com.STDMETHOD(PD3DVALUE)),
('GetMinDistance',
com.STDMETHOD(PD3DVALUE)),
('GetMode',
com.STDMETHOD(LPDWORD)),
('GetPosition',
com.STDMETHOD(PD3DVECTOR)),
('GetVelocity',
com.STDMETHOD(PD3DVECTOR)),
('SetAllParameters',
com.STDMETHOD(LPDS3DBUFFER, DWORD)),
('SetConeAngles',
com.STDMETHOD(DWORD, DWORD, DWORD)),
('SetConeOrientation',
com.STDMETHOD(D3DVALUE, D3DVALUE, D3DVALUE, DWORD)),
('SetConeOutsideVolume',
com.STDMETHOD(LONG, DWORD)),
('SetMaxDistance',
com.STDMETHOD(D3DVALUE, DWORD)),
('SetMinDistance',
com.STDMETHOD(D3DVALUE, DWORD)),
('SetMode',
com.STDMETHOD(DWORD, DWORD)),
('SetPosition',
com.STDMETHOD(D3DVALUE, D3DVALUE, D3DVALUE, DWORD)),
('SetVelocity',
com.STDMETHOD(D3DVALUE, D3DVALUE, D3DVALUE, DWORD)),
]
class IDirectSound(com.IUnknown):
_methods_ = [
('CreateSoundBuffer',
com.STDMETHOD(LPDSBUFFERDESC,
ctypes.POINTER(IDirectSoundBuffer),
LPUNKNOWN)),
('GetCaps',
com.STDMETHOD(LPDSCAPS)),
('DuplicateSoundBuffer',
com.STDMETHOD(IDirectSoundBuffer,
ctypes.POINTER(IDirectSoundBuffer))),
('SetCooperativeLevel',
com.STDMETHOD(HWND, DWORD)),
('Compact',
com.STDMETHOD()),
('GetSpeakerConfig',
com.STDMETHOD(LPDWORD)),
('SetSpeakerConfig',
com.STDMETHOD(DWORD)),
('Initialize',
com.STDMETHOD(com.LPGUID)),
]
_type_ = com.COMInterface
DirectSoundCreate = lib.DirectSoundCreate
DirectSoundCreate.argtypes = \
[com.LPGUID, ctypes.POINTER(IDirectSound), ctypes.c_void_p]
DSCAPS_PRIMARYMONO = 0x00000001
DSCAPS_PRIMARYSTEREO = 0x00000002
DSCAPS_PRIMARY8BIT = 0x00000004
DSCAPS_PRIMARY16BIT = 0x00000008
DSCAPS_CONTINUOUSRATE = 0x00000010
DSCAPS_EMULDRIVER = 0x00000020
DSCAPS_CERTIFIED = 0x00000040
DSCAPS_SECONDARYMONO = 0x00000100
DSCAPS_SECONDARYSTEREO = 0x00000200
DSCAPS_SECONDARY8BIT = 0x00000400
DSCAPS_SECONDARY16BIT = 0x00000800
DSSCL_NORMAL = 0x00000001
DSSCL_PRIORITY = 0x00000002
DSSCL_EXCLUSIVE = 0x00000003
DSSCL_WRITEPRIMARY = 0x00000004
DSSPEAKER_DIRECTOUT = 0x00000000
DSSPEAKER_HEADPHONE = 0x00000001
DSSPEAKER_MONO = 0x00000002
DSSPEAKER_QUAD = 0x00000003
DSSPEAKER_STEREO = 0x00000004
DSSPEAKER_SURROUND = 0x00000005
DSSPEAKER_5POINT1 = 0x00000006
DSSPEAKER_7POINT1 = 0x00000007
DSSPEAKER_GEOMETRY_MIN = 0x00000005 # 5 degrees
DSSPEAKER_GEOMETRY_NARROW = 0x0000000A # 10 degrees
DSSPEAKER_GEOMETRY_WIDE = 0x00000014 # 20 degrees
DSSPEAKER_GEOMETRY_MAX = 0x000000B4 # 180 degrees
DSBCAPS_PRIMARYBUFFER = 0x00000001
DSBCAPS_STATIC = 0x00000002
DSBCAPS_LOCHARDWARE = 0x00000004
DSBCAPS_LOCSOFTWARE = 0x00000008
DSBCAPS_CTRL3D = 0x00000010
DSBCAPS_CTRLFREQUENCY = 0x00000020
DSBCAPS_CTRLPAN = 0x00000040
DSBCAPS_CTRLVOLUME = 0x00000080
DSBCAPS_CTRLPOSITIONNOTIFY = 0x00000100
DSBCAPS_CTRLFX = 0x00000200
DSBCAPS_STICKYFOCUS = 0x00004000
DSBCAPS_GLOBALFOCUS = 0x00008000
DSBCAPS_GETCURRENTPOSITION2 = 0x00010000
DSBCAPS_MUTE3DATMAXDISTANCE = 0x00020000
DSBCAPS_LOCDEFER = 0x00040000
DSBPLAY_LOOPING = 0x00000001
DSBPLAY_LOCHARDWARE = 0x00000002
DSBPLAY_LOCSOFTWARE = 0x00000004
DSBPLAY_TERMINATEBY_TIME = 0x00000008
DSBPLAY_TERMINATEBY_DISTANCE = 0x000000010
DSBPLAY_TERMINATEBY_PRIORITY = 0x000000020
DSBSTATUS_PLAYING = 0x00000001
DSBSTATUS_BUFFERLOST = 0x00000002
DSBSTATUS_LOOPING = 0x00000004
DSBSTATUS_LOCHARDWARE = 0x00000008
DSBSTATUS_LOCSOFTWARE = 0x00000010
DSBSTATUS_TERMINATED = 0x00000020
DSBLOCK_FROMWRITECURSOR = 0x00000001
DSBLOCK_ENTIREBUFFER = 0x00000002
DSBFREQUENCY_MIN = 100
DSBFREQUENCY_MAX = 100000
DSBFREQUENCY_ORIGINAL = 0
DSBPAN_LEFT = -10000
DSBPAN_CENTER = 0
DSBPAN_RIGHT = 10000
DSBVOLUME_MIN = -10000
DSBVOLUME_MAX = 0
DSBSIZE_MIN = 4
DSBSIZE_MAX = 0x0FFFFFFF
DSBSIZE_FX_MIN = 150 # NOTE: Milliseconds, not bytes
DS3DMODE_NORMAL = 0x00000000
DS3DMODE_HEADRELATIVE = 0x00000001
DS3DMODE_DISABLE = 0x00000002
DS3D_IMMEDIATE = 0x00000000
DS3D_DEFERRED = 0x00000001
DS3D_MINDISTANCEFACTOR = -1000000.0 # XXX FLT_MIN
DS3D_MAXDISTANCEFACTOR = 1000000.0 # XXX FLT_MAX
DS3D_DEFAULTDISTANCEFACTOR = 1.0
DS3D_MINROLLOFFFACTOR = 0.0
DS3D_MAXROLLOFFFACTOR = 10.0
DS3D_DEFAULTROLLOFFFACTOR = 1.0
DS3D_MINDOPPLERFACTOR = 0.0
DS3D_MAXDOPPLERFACTOR = 10.0
DS3D_DEFAULTDOPPLERFACTOR = 1.0
DS3D_DEFAULTMINDISTANCE = 1.0
DS3D_DEFAULTMAXDISTANCE = 1000000000.0
DS3D_MINCONEANGLE = 0
DS3D_MAXCONEANGLE = 360
DS3D_DEFAULTCONEANGLE = 360
DS3D_DEFAULTCONEOUTSIDEVOLUME = DSBVOLUME_MAX

View file

@ -0,0 +1,360 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id: __init__.py 2270 2008-09-21 08:01:58Z Alex.Holkner $
import ctypes
import sys
import time
from pyglet.media import AudioPlayer, Listener, MediaException
from pyglet.media.drivers.openal import lib_openal as al
from pyglet.media.drivers.openal import lib_alc as alc
class OpenALException(MediaException):
pass
def _split_nul_strings(s):
# NUL-separated list of strings, double-NUL-terminated.
nul = False
i = 0
while True:
if s[i] == '\0':
if nul:
break
else:
nul = True
else:
nul = False
i += 1
s = s[:i - 1]
return s.split('\0')
def get_version():
major = alc.ALCint()
minor = alc.ALCint()
alc.alcGetIntegerv(_device, alc.ALC_MAJOR_VERSION,
ctypes.sizeof(major), major)
alc.alcGetIntegerv(_device, alc.ALC_MINOR_VERSION,
ctypes.sizeof(minor), minor)
return major.value, minor.value
def have_version(major, minor):
return (major, minor) <= get_version()
def get_extensions():
extensions = alc.alcGetString(_device, alc.ALC_EXTENSIONS)
# Check for null pointer
if not ctypes.cast(extensions, ctypes.c_void_p).value:
return []
if sys.platform == 'darwin':
return ctypes.cast(extensions, ctypes.c_char_p).value.split(' ')
else:
return _split_nul_strings(extensions)
def have_extension(extension):
return extension in get_extensions()
format_map = {
(1, 8): al.AL_FORMAT_MONO8,
(1, 16): al.AL_FORMAT_MONO16,
(2, 8): al.AL_FORMAT_STEREO8,
(2, 16): al.AL_FORMAT_STEREO16,
}
class OpenALAudioPlayer(AudioPlayer):
#: Seconds ahead to buffer audio. Keep small for low latency, but large
#: enough to avoid underruns. (0.05 is the minimum for my 2.2 GHz Linux)
_update_buffer_time = 0.2
#: Minimum size of an OpenAL buffer worth bothering with
_min_buffer_size = 512
#: Maximum size of an OpenAL buffer, in bytes. TODO: use OpenAL maximum
_max_buffer_size = 65536
UPDATE_PERIOD = 0.05
def __init__(self, audio_format):
super(OpenALAudioPlayer, self).__init__(audio_format)
try:
self._al_format = format_map[(audio_format.channels,
audio_format.sample_size)]
except KeyError:
raise OpenALException('Unsupported audio format.')
self._al_source = al.ALuint()
al.alGenSources(1, self._al_source)
# Seconds of audio currently queued not processed (estimate)
self._buffered_time = 0.0
# Seconds of audio into current (head) buffer
self._current_buffer_time = 0.0
# List of (timestamp, duration) corresponding to currently queued AL
# buffers
self._timestamps = []
# OpenAL 1.0 timestamp interpolation
self._timestamp_system_time = 0.0
# Desired play state (True even if stopped due to underrun)
self._playing = False
# Timestamp when paused
self._pause_timestamp = 0.0
self._eos_count = 0
def __del__(self):
try:
al.alDeleteSources(1, self._al_source)
except:
pass
def get_write_size(self):
t = self._buffered_time - self._current_buffer_time
size = int(max(0, self._update_buffer_time - t) * \
self.audio_format.bytes_per_second)
if size < self._min_buffer_size:
size = 0
return size
def write(self, audio_data):
buffer = al.ALuint()
al.alGenBuffers(1, buffer)
al.alBufferData(buffer,
self._al_format,
audio_data.data,
audio_data.length,
self.audio_format.sample_rate)
al.alSourceQueueBuffers(self._al_source, 1, ctypes.byref(buffer))
self._buffered_time += audio_data.duration
self._timestamps.append((audio_data.timestamp, audio_data.duration))
audio_data.consume(audio_data.length, self.audio_format)
def write_eos(self):
if self._timestamps:
self._timestamps.append((None, None))
def write_end(self):
pass
def play(self):
if self._playing:
return
self._playing = True
self._al_play()
if not _have_1_1:
self._timestamp_system_time = time.time()
def _al_play(self):
if not self._timestamps:
return
state = al.ALint()
al.alGetSourcei(self._al_source, al.AL_SOURCE_STATE, state)
if state.value != al.AL_PLAYING:
al.alSourcePlay(self._al_source)
def stop(self):
if not self._playing:
return
self._pause_timestamp = self.get_time()
al.alSourcePause(self._al_source)
self._playing = False
def clear(self):
al.alSourceStop(self._al_source)
self._playing = False
processed = al.ALint()
al.alGetSourcei(self._al_source, al.AL_BUFFERS_PROCESSED, processed)
if processed.value:
buffers = (al.ALuint * processed.value)()
al.alSourceUnqueueBuffers(self._al_source, len(buffers), buffers)
al.alDeleteBuffers(len(buffers), buffers)
self._pause_timestamp = 0.0
self._buffered_time = 0.0
self._current_buffer_time = 0.0
self._timestamps = []
def pump(self):
# Release spent buffers
processed = al.ALint()
al.alGetSourcei(self._al_source, al.AL_BUFFERS_PROCESSED, processed)
processed = processed.value
if processed:
buffers = (al.ALuint * processed)()
al.alSourceUnqueueBuffers(self._al_source, len(buffers), buffers)
al.alDeleteBuffers(len(buffers), buffers)
# Pop timestamps and check for eos markers
try:
while processed:
if not _have_1_1:
self._timestamp_system_time = time.time()
_, duration = self._timestamps.pop(0)
self._buffered_time -= duration
while self._timestamps[0][0] is None:
self._eos_count += 1
self._timestamps.pop(0)
processed -= 1
except IndexError:
pass
if _have_1_1:
samples = al.ALint()
al.alGetSourcei(self._al_source, al.AL_SAMPLE_OFFSET, samples)
self._current_buffer_time = samples.value / \
float(self.audio_format.sample_rate)
else:
# Interpolate system time past buffer timestamp
self._current_buffer_time = time.time() - \
self._timestamp_system_time
# Check for underrun
if self._playing:
state = al.ALint()
al.alGetSourcei(self._al_source, al.AL_SOURCE_STATE, state)
if state.value != al.AL_PLAYING:
al.alSourcePlay(self._al_source)
return True # underrun notification
def get_time(self):
state = al.ALint()
al.alGetSourcei(self._al_source, al.AL_SOURCE_STATE, state)
if not self._playing:
return self._pause_timestamp
if not self._timestamps:
return self._pause_timestamp
ts, _ = self._timestamps[0]
return ts + self._current_buffer_time
def clear_eos(self):
while self._eos_count > 0:
self._eos_count -= 1
return True
return False
def set_volume(self, volume):
al.alSourcef(self._al_source, al.AL_GAIN, max(0, volume))
def set_position(self, position):
x, y, z = position
al.alSource3f(self._al_source, al.AL_POSITION, x, y, z)
def set_min_distance(self, min_distance):
al.alSourcef(self._al_source, al.AL_REFERENCE_DISTANCE, min_distance)
def set_max_distance(self, max_distance):
al.alSourcef(self._al_source, al.AL_MAX_DISTANCE, max_distance)
def set_pitch(self, pitch):
al.alSourcef(self._al_source, al.AL_PITCH, max(0, pitch))
def set_cone_orientation(self, cone_orientation):
x, y, z = cone_orientation
al.alSource3f(self._al_source, al.AL_DIRECTION, x, y, z)
def set_cone_inner_angle(self, cone_inner_angle):
al.alSourcef(self._al_source, al.AL_CONE_INNER_ANGLE, cone_inner_angle)
def set_cone_outer_angle(self, cone_outer_angle):
al.alSourcef(self._al_source, al.AL_CONE_OUTER_ANGLE, cone_outer_angle)
def set_cone_outer_gain(self, cone_outer_gain):
al.alSourcef(self._al_source, al.AL_CONE_OUTER_GAIN, cone_outer_gain)
class OpenALListener(Listener):
def _set_volume(self, volume):
al.alListenerf(al.AL_GAIN, volume)
self._volume = volume
def _set_position(self, position):
x, y, z = position
al.alListener3f(al.AL_POSITION, x, y, z)
self._position = position
def _set_forward_orientation(self, orientation):
val = (al.ALfloat * 6)(*(orientation + self._up_orientation))
al.alListenerfv(al.AL_ORIENTATION, val)
self._forward_orientation = orientation
def _set_up_orientation(self, orientation):
val = (al.ALfloat * 6)(*(self._forward_orientation + orientation))
al.alListenerfv(al.AL_ORIENTATION, val)
self._up_orientation = orientation
_device = None
_have_1_1 = False
def driver_init(device_name = None):
global _device
global _have_1_1
# TODO devices must be enumerated on Windows, otherwise 1.0 context is
# returned.
_device = alc.alcOpenDevice(device_name)
if not _device:
raise OpenALException('No OpenAL device.')
alcontext = alc.alcCreateContext(_device, None)
alc.alcMakeContextCurrent(alcontext)
if have_version(1, 1):
# Good version info to cache
_have_1_1 = True
# See issue #163.
import sys
if sys.platform in ('win32', 'cygwin'):
from pyglet import clock
clock.Clock._force_sleep = True
driver_listener = OpenALListener()
driver_audio_player_class = OpenALAudioPlayer

View file

@ -0,0 +1,286 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Wrapper for openal
Generated with:
../tools/wraptypes/wrap.py /usr/include/AL/alc.h -lopenal -olib_alc.py
.. Hacked to fix ALCvoid argtypes.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: lib_alc.py 1579 2008-01-15 14:47:19Z Alex.Holkner $'
import ctypes
from ctypes import *
import sys
import pyglet.lib
_lib = pyglet.lib.load_library('openal', win32='openal32',
framework='/System/Library/Frameworks/OpenAL.framework')
_int_types = (c_int16, c_int32)
if hasattr(ctypes, 'c_int64'):
# Some builds of ctypes apparently do not have c_int64
# defined; it's a pretty good bet that these builds do not
# have 64-bit pointers.
_int_types += (ctypes.c_int64,)
for t in _int_types:
if sizeof(t) == sizeof(c_size_t):
c_ptrdiff_t = t
class c_void(Structure):
# c_void_p is a buggy return type, converting to int, so
# POINTER(None) == c_void_p is actually written as
# POINTER(c_void), so it can be treated as a real pointer.
_fields_ = [('dummy', c_int)]
ALC_API = 0 # /usr/include/AL/alc.h:19
ALCAPI = 0 # /usr/include/AL/alc.h:37
ALC_INVALID = 0 # /usr/include/AL/alc.h:39
ALC_VERSION_0_1 = 1 # /usr/include/AL/alc.h:42
class struct_ALCdevice_struct(Structure):
__slots__ = [
]
struct_ALCdevice_struct._fields_ = [
('_opaque_struct', c_int)
]
class struct_ALCdevice_struct(Structure):
__slots__ = [
]
struct_ALCdevice_struct._fields_ = [
('_opaque_struct', c_int)
]
ALCdevice = struct_ALCdevice_struct # /usr/include/AL/alc.h:44
class struct_ALCcontext_struct(Structure):
__slots__ = [
]
struct_ALCcontext_struct._fields_ = [
('_opaque_struct', c_int)
]
class struct_ALCcontext_struct(Structure):
__slots__ = [
]
struct_ALCcontext_struct._fields_ = [
('_opaque_struct', c_int)
]
ALCcontext = struct_ALCcontext_struct # /usr/include/AL/alc.h:45
ALCboolean = c_char # /usr/include/AL/alc.h:49
ALCchar = c_char # /usr/include/AL/alc.h:52
ALCbyte = c_char # /usr/include/AL/alc.h:55
ALCubyte = c_ubyte # /usr/include/AL/alc.h:58
ALCshort = c_short # /usr/include/AL/alc.h:61
ALCushort = c_ushort # /usr/include/AL/alc.h:64
ALCint = c_int # /usr/include/AL/alc.h:67
ALCuint = c_uint # /usr/include/AL/alc.h:70
ALCsizei = c_int # /usr/include/AL/alc.h:73
ALCenum = c_int # /usr/include/AL/alc.h:76
ALCfloat = c_float # /usr/include/AL/alc.h:79
ALCdouble = c_double # /usr/include/AL/alc.h:82
ALCvoid = None # /usr/include/AL/alc.h:85
ALC_FALSE = 0 # /usr/include/AL/alc.h:91
ALC_TRUE = 1 # /usr/include/AL/alc.h:94
ALC_FREQUENCY = 4103 # /usr/include/AL/alc.h:99
ALC_REFRESH = 4104 # /usr/include/AL/alc.h:104
ALC_SYNC = 4105 # /usr/include/AL/alc.h:109
ALC_MONO_SOURCES = 4112 # /usr/include/AL/alc.h:114
ALC_STEREO_SOURCES = 4113 # /usr/include/AL/alc.h:119
ALC_NO_ERROR = 0 # /usr/include/AL/alc.h:128
ALC_INVALID_DEVICE = 40961 # /usr/include/AL/alc.h:133
ALC_INVALID_CONTEXT = 40962 # /usr/include/AL/alc.h:138
ALC_INVALID_ENUM = 40963 # /usr/include/AL/alc.h:143
ALC_INVALID_VALUE = 40964 # /usr/include/AL/alc.h:148
ALC_OUT_OF_MEMORY = 40965 # /usr/include/AL/alc.h:153
ALC_DEFAULT_DEVICE_SPECIFIER = 4100 # /usr/include/AL/alc.h:159
ALC_DEVICE_SPECIFIER = 4101 # /usr/include/AL/alc.h:160
ALC_EXTENSIONS = 4102 # /usr/include/AL/alc.h:161
ALC_MAJOR_VERSION = 4096 # /usr/include/AL/alc.h:163
ALC_MINOR_VERSION = 4097 # /usr/include/AL/alc.h:164
ALC_ATTRIBUTES_SIZE = 4098 # /usr/include/AL/alc.h:166
ALC_ALL_ATTRIBUTES = 4099 # /usr/include/AL/alc.h:167
ALC_CAPTURE_DEVICE_SPECIFIER = 784 # /usr/include/AL/alc.h:172
ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER = 785 # /usr/include/AL/alc.h:173
ALC_CAPTURE_SAMPLES = 786 # /usr/include/AL/alc.h:174
# /usr/include/AL/alc.h:180
alcCreateContext = _lib.alcCreateContext
alcCreateContext.restype = POINTER(ALCcontext)
alcCreateContext.argtypes = [POINTER(ALCdevice), POINTER(ALCint)]
# /usr/include/AL/alc.h:182
alcMakeContextCurrent = _lib.alcMakeContextCurrent
alcMakeContextCurrent.restype = ALCboolean
alcMakeContextCurrent.argtypes = [POINTER(ALCcontext)]
# /usr/include/AL/alc.h:184
alcProcessContext = _lib.alcProcessContext
alcProcessContext.restype = None
alcProcessContext.argtypes = [POINTER(ALCcontext)]
# /usr/include/AL/alc.h:186
alcSuspendContext = _lib.alcSuspendContext
alcSuspendContext.restype = None
alcSuspendContext.argtypes = [POINTER(ALCcontext)]
# /usr/include/AL/alc.h:188
alcDestroyContext = _lib.alcDestroyContext
alcDestroyContext.restype = None
alcDestroyContext.argtypes = [POINTER(ALCcontext)]
# /usr/include/AL/alc.h:190
alcGetCurrentContext = _lib.alcGetCurrentContext
alcGetCurrentContext.restype = POINTER(ALCcontext)
alcGetCurrentContext.argtypes = []
# /usr/include/AL/alc.h:192
alcGetContextsDevice = _lib.alcGetContextsDevice
alcGetContextsDevice.restype = POINTER(ALCdevice)
alcGetContextsDevice.argtypes = [POINTER(ALCcontext)]
# /usr/include/AL/alc.h:198
alcOpenDevice = _lib.alcOpenDevice
alcOpenDevice.restype = POINTER(ALCdevice)
alcOpenDevice.argtypes = [POINTER(ALCchar)]
# /usr/include/AL/alc.h:200
alcCloseDevice = _lib.alcCloseDevice
alcCloseDevice.restype = ALCboolean
alcCloseDevice.argtypes = [POINTER(ALCdevice)]
# /usr/include/AL/alc.h:207
alcGetError = _lib.alcGetError
alcGetError.restype = ALCenum
alcGetError.argtypes = [POINTER(ALCdevice)]
# /usr/include/AL/alc.h:215
alcIsExtensionPresent = _lib.alcIsExtensionPresent
alcIsExtensionPresent.restype = ALCboolean
alcIsExtensionPresent.argtypes = [POINTER(ALCdevice), POINTER(ALCchar)]
# /usr/include/AL/alc.h:217
alcGetProcAddress = _lib.alcGetProcAddress
alcGetProcAddress.restype = POINTER(c_void)
alcGetProcAddress.argtypes = [POINTER(ALCdevice), POINTER(ALCchar)]
# /usr/include/AL/alc.h:219
alcGetEnumValue = _lib.alcGetEnumValue
alcGetEnumValue.restype = ALCenum
alcGetEnumValue.argtypes = [POINTER(ALCdevice), POINTER(ALCchar)]
# /usr/include/AL/alc.h:225
alcGetString = _lib.alcGetString
alcGetString.restype = POINTER(ALCchar)
alcGetString.argtypes = [POINTER(ALCdevice), ALCenum]
# /usr/include/AL/alc.h:227
alcGetIntegerv = _lib.alcGetIntegerv
alcGetIntegerv.restype = None
alcGetIntegerv.argtypes = [POINTER(ALCdevice), ALCenum, ALCsizei, POINTER(ALCint)]
# /usr/include/AL/alc.h:233
alcCaptureOpenDevice = _lib.alcCaptureOpenDevice
alcCaptureOpenDevice.restype = POINTER(ALCdevice)
alcCaptureOpenDevice.argtypes = [POINTER(ALCchar), ALCuint, ALCenum, ALCsizei]
# /usr/include/AL/alc.h:235
alcCaptureCloseDevice = _lib.alcCaptureCloseDevice
alcCaptureCloseDevice.restype = ALCboolean
alcCaptureCloseDevice.argtypes = [POINTER(ALCdevice)]
# /usr/include/AL/alc.h:237
alcCaptureStart = _lib.alcCaptureStart
alcCaptureStart.restype = None
alcCaptureStart.argtypes = [POINTER(ALCdevice)]
# /usr/include/AL/alc.h:239
alcCaptureStop = _lib.alcCaptureStop
alcCaptureStop.restype = None
alcCaptureStop.argtypes = [POINTER(ALCdevice)]
# /usr/include/AL/alc.h:241
alcCaptureSamples = _lib.alcCaptureSamples
alcCaptureSamples.restype = None
alcCaptureSamples.argtypes = [POINTER(ALCdevice), POINTER(ALCvoid), ALCsizei]
LPALCCREATECONTEXT = CFUNCTYPE(POINTER(ALCcontext), POINTER(ALCdevice), POINTER(ALCint)) # /usr/include/AL/alc.h:246
LPALCMAKECONTEXTCURRENT = CFUNCTYPE(ALCboolean, POINTER(ALCcontext)) # /usr/include/AL/alc.h:247
LPALCPROCESSCONTEXT = CFUNCTYPE(None, POINTER(ALCcontext)) # /usr/include/AL/alc.h:248
LPALCSUSPENDCONTEXT = CFUNCTYPE(None, POINTER(ALCcontext)) # /usr/include/AL/alc.h:249
LPALCDESTROYCONTEXT = CFUNCTYPE(None, POINTER(ALCcontext)) # /usr/include/AL/alc.h:250
LPALCGETCURRENTCONTEXT = CFUNCTYPE(POINTER(ALCcontext)) # /usr/include/AL/alc.h:251
LPALCGETCONTEXTSDEVICE = CFUNCTYPE(POINTER(ALCdevice), POINTER(ALCcontext)) # /usr/include/AL/alc.h:252
LPALCOPENDEVICE = CFUNCTYPE(POINTER(ALCdevice), POINTER(ALCchar)) # /usr/include/AL/alc.h:253
LPALCCLOSEDEVICE = CFUNCTYPE(ALCboolean, POINTER(ALCdevice)) # /usr/include/AL/alc.h:254
LPALCGETERROR = CFUNCTYPE(ALCenum, POINTER(ALCdevice)) # /usr/include/AL/alc.h:255
LPALCISEXTENSIONPRESENT = CFUNCTYPE(ALCboolean, POINTER(ALCdevice), POINTER(ALCchar)) # /usr/include/AL/alc.h:256
LPALCGETPROCADDRESS = CFUNCTYPE(POINTER(c_void), POINTER(ALCdevice), POINTER(ALCchar)) # /usr/include/AL/alc.h:257
LPALCGETENUMVALUE = CFUNCTYPE(ALCenum, POINTER(ALCdevice), POINTER(ALCchar)) # /usr/include/AL/alc.h:258
LPALCGETSTRING = CFUNCTYPE(POINTER(ALCchar), POINTER(ALCdevice), ALCenum) # /usr/include/AL/alc.h:259
LPALCGETINTEGERV = CFUNCTYPE(None, POINTER(ALCdevice), ALCenum, ALCsizei, POINTER(ALCint)) # /usr/include/AL/alc.h:260
LPALCCAPTUREOPENDEVICE = CFUNCTYPE(POINTER(ALCdevice), POINTER(ALCchar), ALCuint, ALCenum, ALCsizei) # /usr/include/AL/alc.h:261
LPALCCAPTURECLOSEDEVICE = CFUNCTYPE(ALCboolean, POINTER(ALCdevice)) # /usr/include/AL/alc.h:262
LPALCCAPTURESTART = CFUNCTYPE(None, POINTER(ALCdevice)) # /usr/include/AL/alc.h:263
LPALCCAPTURESTOP = CFUNCTYPE(None, POINTER(ALCdevice)) # /usr/include/AL/alc.h:264
LPALCCAPTURESAMPLES = CFUNCTYPE(None, POINTER(ALCdevice), POINTER(ALCvoid), ALCsizei) # /usr/include/AL/alc.h:265
__all__ = ['ALC_API', 'ALCAPI', 'ALC_INVALID', 'ALC_VERSION_0_1', 'ALCdevice',
'ALCcontext', 'ALCboolean', 'ALCchar', 'ALCbyte', 'ALCubyte', 'ALCshort',
'ALCushort', 'ALCint', 'ALCuint', 'ALCsizei', 'ALCenum', 'ALCfloat',
'ALCdouble', 'ALCvoid', 'ALC_FALSE', 'ALC_TRUE', 'ALC_FREQUENCY',
'ALC_REFRESH', 'ALC_SYNC', 'ALC_MONO_SOURCES', 'ALC_STEREO_SOURCES',
'ALC_NO_ERROR', 'ALC_INVALID_DEVICE', 'ALC_INVALID_CONTEXT',
'ALC_INVALID_ENUM', 'ALC_INVALID_VALUE', 'ALC_OUT_OF_MEMORY',
'ALC_DEFAULT_DEVICE_SPECIFIER', 'ALC_DEVICE_SPECIFIER', 'ALC_EXTENSIONS',
'ALC_MAJOR_VERSION', 'ALC_MINOR_VERSION', 'ALC_ATTRIBUTES_SIZE',
'ALC_ALL_ATTRIBUTES', 'ALC_CAPTURE_DEVICE_SPECIFIER',
'ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER', 'ALC_CAPTURE_SAMPLES',
'alcCreateContext', 'alcMakeContextCurrent', 'alcProcessContext',
'alcSuspendContext', 'alcDestroyContext', 'alcGetCurrentContext',
'alcGetContextsDevice', 'alcOpenDevice', 'alcCloseDevice', 'alcGetError',
'alcIsExtensionPresent', 'alcGetProcAddress', 'alcGetEnumValue',
'alcGetString', 'alcGetIntegerv', 'alcCaptureOpenDevice',
'alcCaptureCloseDevice', 'alcCaptureStart', 'alcCaptureStop',
'alcCaptureSamples', 'LPALCCREATECONTEXT', 'LPALCMAKECONTEXTCURRENT',
'LPALCPROCESSCONTEXT', 'LPALCSUSPENDCONTEXT', 'LPALCDESTROYCONTEXT',
'LPALCGETCURRENTCONTEXT', 'LPALCGETCONTEXTSDEVICE', 'LPALCOPENDEVICE',
'LPALCCLOSEDEVICE', 'LPALCGETERROR', 'LPALCISEXTENSIONPRESENT',
'LPALCGETPROCADDRESS', 'LPALCGETENUMVALUE', 'LPALCGETSTRING',
'LPALCGETINTEGERV', 'LPALCCAPTUREOPENDEVICE', 'LPALCCAPTURECLOSEDEVICE',
'LPALCCAPTURESTART', 'LPALCCAPTURESTOP', 'LPALCCAPTURESAMPLES']

View file

@ -0,0 +1,655 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Wrapper for openal
Generated with:
../tools/wraptypes/wrap.py /usr/include/AL/al.h -lopenal -olib_openal.py
.. Hacked to remove non-existant library functions.
TODO add alGetError check.
.. alListener3i and alListeneriv are present in my OS X 10.4 but not another
10.4 user's installation. They've also been removed for compatibility.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: lib_openal.py 2270 2008-09-21 08:01:58Z Alex.Holkner $'
import ctypes
from ctypes import *
import sys
import pyglet.lib
_lib = pyglet.lib.load_library('openal', win32='openal32',
framework='/System/Library/Frameworks/OpenAL.framework')
_int_types = (c_int16, c_int32)
if hasattr(ctypes, 'c_int64'):
# Some builds of ctypes apparently do not have c_int64
# defined; it's a pretty good bet that these builds do not
# have 64-bit pointers.
_int_types += (ctypes.c_int64,)
for t in _int_types:
if sizeof(t) == sizeof(c_size_t):
c_ptrdiff_t = t
class c_void(Structure):
# c_void_p is a buggy return type, converting to int, so
# POINTER(None) == c_void_p is actually written as
# POINTER(c_void), so it can be treated as a real pointer.
_fields_ = [('dummy', c_int)]
AL_API = 0 # /usr/include/AL/al.h:39
ALAPI = 0 # /usr/include/AL/al.h:59
AL_INVALID = -1 # /usr/include/AL/al.h:61
AL_ILLEGAL_ENUM = 0 # /usr/include/AL/al.h:62
AL_ILLEGAL_COMMAND = 0 # /usr/include/AL/al.h:63
ALboolean = c_int # Better return type than c_char, as generated
ALchar = c_char # /usr/include/AL/al.h:73
ALbyte = c_char # /usr/include/AL/al.h:76
ALubyte = c_ubyte # /usr/include/AL/al.h:79
ALshort = c_short # /usr/include/AL/al.h:82
ALushort = c_ushort # /usr/include/AL/al.h:85
ALint = c_int # /usr/include/AL/al.h:88
ALuint = c_uint # /usr/include/AL/al.h:91
ALsizei = c_int # /usr/include/AL/al.h:94
ALenum = c_int # /usr/include/AL/al.h:97
ALfloat = c_float # /usr/include/AL/al.h:100
ALdouble = c_double # /usr/include/AL/al.h:103
ALvoid = None # /usr/include/AL/al.h:106
AL_NONE = 0 # /usr/include/AL/al.h:112
AL_FALSE = 0 # /usr/include/AL/al.h:115
AL_TRUE = 1 # /usr/include/AL/al.h:118
AL_SOURCE_RELATIVE = 514 # /usr/include/AL/al.h:121
AL_CONE_INNER_ANGLE = 4097 # /usr/include/AL/al.h:130
AL_CONE_OUTER_ANGLE = 4098 # /usr/include/AL/al.h:137
AL_PITCH = 4099 # /usr/include/AL/al.h:145
AL_POSITION = 4100 # /usr/include/AL/al.h:157
AL_DIRECTION = 4101 # /usr/include/AL/al.h:160
AL_VELOCITY = 4102 # /usr/include/AL/al.h:163
AL_LOOPING = 4103 # /usr/include/AL/al.h:171
AL_BUFFER = 4105 # /usr/include/AL/al.h:178
AL_GAIN = 4106 # /usr/include/AL/al.h:191
AL_MIN_GAIN = 4109 # /usr/include/AL/al.h:200
AL_MAX_GAIN = 4110 # /usr/include/AL/al.h:209
AL_ORIENTATION = 4111 # /usr/include/AL/al.h:216
AL_SOURCE_STATE = 4112 # /usr/include/AL/al.h:221
AL_INITIAL = 4113 # /usr/include/AL/al.h:222
AL_PLAYING = 4114 # /usr/include/AL/al.h:223
AL_PAUSED = 4115 # /usr/include/AL/al.h:224
AL_STOPPED = 4116 # /usr/include/AL/al.h:225
AL_BUFFERS_QUEUED = 4117 # /usr/include/AL/al.h:230
AL_BUFFERS_PROCESSED = 4118 # /usr/include/AL/al.h:231
AL_SEC_OFFSET = 4132 # /usr/include/AL/al.h:236
AL_SAMPLE_OFFSET = 4133 # /usr/include/AL/al.h:237
AL_BYTE_OFFSET = 4134 # /usr/include/AL/al.h:238
AL_SOURCE_TYPE = 4135 # /usr/include/AL/al.h:246
AL_STATIC = 4136 # /usr/include/AL/al.h:247
AL_STREAMING = 4137 # /usr/include/AL/al.h:248
AL_UNDETERMINED = 4144 # /usr/include/AL/al.h:249
AL_FORMAT_MONO8 = 4352 # /usr/include/AL/al.h:252
AL_FORMAT_MONO16 = 4353 # /usr/include/AL/al.h:253
AL_FORMAT_STEREO8 = 4354 # /usr/include/AL/al.h:254
AL_FORMAT_STEREO16 = 4355 # /usr/include/AL/al.h:255
AL_REFERENCE_DISTANCE = 4128 # /usr/include/AL/al.h:265
AL_ROLLOFF_FACTOR = 4129 # /usr/include/AL/al.h:273
AL_CONE_OUTER_GAIN = 4130 # /usr/include/AL/al.h:282
AL_MAX_DISTANCE = 4131 # /usr/include/AL/al.h:292
AL_FREQUENCY = 8193 # /usr/include/AL/al.h:300
AL_BITS = 8194 # /usr/include/AL/al.h:301
AL_CHANNELS = 8195 # /usr/include/AL/al.h:302
AL_SIZE = 8196 # /usr/include/AL/al.h:303
AL_UNUSED = 8208 # /usr/include/AL/al.h:310
AL_PENDING = 8209 # /usr/include/AL/al.h:311
AL_PROCESSED = 8210 # /usr/include/AL/al.h:312
AL_NO_ERROR = 0 # /usr/include/AL/al.h:316
AL_INVALID_NAME = 40961 # /usr/include/AL/al.h:321
AL_INVALID_ENUM = 40962 # /usr/include/AL/al.h:326
AL_INVALID_VALUE = 40963 # /usr/include/AL/al.h:331
AL_INVALID_OPERATION = 40964 # /usr/include/AL/al.h:336
AL_OUT_OF_MEMORY = 40965 # /usr/include/AL/al.h:342
AL_VENDOR = 45057 # /usr/include/AL/al.h:346
AL_VERSION = 45058 # /usr/include/AL/al.h:347
AL_RENDERER = 45059 # /usr/include/AL/al.h:348
AL_EXTENSIONS = 45060 # /usr/include/AL/al.h:349
AL_DOPPLER_FACTOR = 49152 # /usr/include/AL/al.h:356
AL_DOPPLER_VELOCITY = 49153 # /usr/include/AL/al.h:361
AL_SPEED_OF_SOUND = 49155 # /usr/include/AL/al.h:366
AL_DISTANCE_MODEL = 53248 # /usr/include/AL/al.h:375
AL_INVERSE_DISTANCE = 53249 # /usr/include/AL/al.h:376
AL_INVERSE_DISTANCE_CLAMPED = 53250 # /usr/include/AL/al.h:377
AL_LINEAR_DISTANCE = 53251 # /usr/include/AL/al.h:378
AL_LINEAR_DISTANCE_CLAMPED = 53252 # /usr/include/AL/al.h:379
AL_EXPONENT_DISTANCE = 53253 # /usr/include/AL/al.h:380
AL_EXPONENT_DISTANCE_CLAMPED = 53254 # /usr/include/AL/al.h:381
# /usr/include/AL/al.h:386
alEnable = _lib.alEnable
alEnable.restype = None
alEnable.argtypes = [ALenum]
# /usr/include/AL/al.h:388
alDisable = _lib.alDisable
alDisable.restype = None
alDisable.argtypes = [ALenum]
# /usr/include/AL/al.h:390
alIsEnabled = _lib.alIsEnabled
alIsEnabled.restype = ALboolean
alIsEnabled.argtypes = [ALenum]
# /usr/include/AL/al.h:396
alGetString = _lib.alGetString
alGetString.restype = POINTER(ALchar)
alGetString.argtypes = [ALenum]
# /usr/include/AL/al.h:398
alGetBooleanv = _lib.alGetBooleanv
alGetBooleanv.restype = None
alGetBooleanv.argtypes = [ALenum, POINTER(ALboolean)]
# /usr/include/AL/al.h:400
alGetIntegerv = _lib.alGetIntegerv
alGetIntegerv.restype = None
alGetIntegerv.argtypes = [ALenum, POINTER(ALint)]
# /usr/include/AL/al.h:402
alGetFloatv = _lib.alGetFloatv
alGetFloatv.restype = None
alGetFloatv.argtypes = [ALenum, POINTER(ALfloat)]
# /usr/include/AL/al.h:404
alGetDoublev = _lib.alGetDoublev
alGetDoublev.restype = None
alGetDoublev.argtypes = [ALenum, POINTER(ALdouble)]
# /usr/include/AL/al.h:406
alGetBoolean = _lib.alGetBoolean
alGetBoolean.restype = ALboolean
alGetBoolean.argtypes = [ALenum]
# /usr/include/AL/al.h:408
alGetInteger = _lib.alGetInteger
alGetInteger.restype = ALint
alGetInteger.argtypes = [ALenum]
# /usr/include/AL/al.h:410
alGetFloat = _lib.alGetFloat
alGetFloat.restype = ALfloat
alGetFloat.argtypes = [ALenum]
# /usr/include/AL/al.h:412
alGetDouble = _lib.alGetDouble
alGetDouble.restype = ALdouble
alGetDouble.argtypes = [ALenum]
# /usr/include/AL/al.h:419
alGetError = _lib.alGetError
alGetError.restype = ALenum
alGetError.argtypes = []
# /usr/include/AL/al.h:427
alIsExtensionPresent = _lib.alIsExtensionPresent
alIsExtensionPresent.restype = ALboolean
alIsExtensionPresent.argtypes = [POINTER(ALchar)]
# /usr/include/AL/al.h:429
alGetProcAddress = _lib.alGetProcAddress
alGetProcAddress.restype = POINTER(c_void)
alGetProcAddress.argtypes = [POINTER(ALchar)]
# /usr/include/AL/al.h:431
alGetEnumValue = _lib.alGetEnumValue
alGetEnumValue.restype = ALenum
alGetEnumValue.argtypes = [POINTER(ALchar)]
# /usr/include/AL/al.h:450
alListenerf = _lib.alListenerf
alListenerf.restype = None
alListenerf.argtypes = [ALenum, ALfloat]
# /usr/include/AL/al.h:452
alListener3f = _lib.alListener3f
alListener3f.restype = None
alListener3f.argtypes = [ALenum, ALfloat, ALfloat, ALfloat]
# /usr/include/AL/al.h:454
alListenerfv = _lib.alListenerfv
alListenerfv.restype = None
alListenerfv.argtypes = [ALenum, POINTER(ALfloat)]
# /usr/include/AL/al.h:456
alListeneri = _lib.alListeneri
alListeneri.restype = None
alListeneri.argtypes = [ALenum, ALint]
# /usr/include/AL/al.h:458
#alListener3i = _lib.alListener3i
#alListener3i.restype = None
#alListener3i.argtypes = [ALenum, ALint, ALint, ALint]
# /usr/include/AL/al.h:460
#alListeneriv = _lib.alListeneriv
#alListeneriv.restype = None
#alListeneriv.argtypes = [ALenum, POINTER(ALint)]
# /usr/include/AL/al.h:465
alGetListenerf = _lib.alGetListenerf
alGetListenerf.restype = None
alGetListenerf.argtypes = [ALenum, POINTER(ALfloat)]
# /usr/include/AL/al.h:467
alGetListener3f = _lib.alGetListener3f
alGetListener3f.restype = None
alGetListener3f.argtypes = [ALenum, POINTER(ALfloat), POINTER(ALfloat), POINTER(ALfloat)]
# /usr/include/AL/al.h:469
alGetListenerfv = _lib.alGetListenerfv
alGetListenerfv.restype = None
alGetListenerfv.argtypes = [ALenum, POINTER(ALfloat)]
# /usr/include/AL/al.h:471
alGetListeneri = _lib.alGetListeneri
alGetListeneri.restype = None
alGetListeneri.argtypes = [ALenum, POINTER(ALint)]
# /usr/include/AL/al.h:473
alGetListener3i = _lib.alGetListener3i
alGetListener3i.restype = None
alGetListener3i.argtypes = [ALenum, POINTER(ALint), POINTER(ALint), POINTER(ALint)]
# /usr/include/AL/al.h:475
alGetListeneriv = _lib.alGetListeneriv
alGetListeneriv.restype = None
alGetListeneriv.argtypes = [ALenum, POINTER(ALint)]
# /usr/include/AL/al.h:512
alGenSources = _lib.alGenSources
alGenSources.restype = None
alGenSources.argtypes = [ALsizei, POINTER(ALuint)]
# /usr/include/AL/al.h:515
alDeleteSources = _lib.alDeleteSources
alDeleteSources.restype = None
alDeleteSources.argtypes = [ALsizei, POINTER(ALuint)]
# /usr/include/AL/al.h:518
alIsSource = _lib.alIsSource
alIsSource.restype = ALboolean
alIsSource.argtypes = [ALuint]
# /usr/include/AL/al.h:523
alSourcef = _lib.alSourcef
alSourcef.restype = None
alSourcef.argtypes = [ALuint, ALenum, ALfloat]
# /usr/include/AL/al.h:525
alSource3f = _lib.alSource3f
alSource3f.restype = None
alSource3f.argtypes = [ALuint, ALenum, ALfloat, ALfloat, ALfloat]
# /usr/include/AL/al.h:527
alSourcefv = _lib.alSourcefv
alSourcefv.restype = None
alSourcefv.argtypes = [ALuint, ALenum, POINTER(ALfloat)]
# /usr/include/AL/al.h:529
alSourcei = _lib.alSourcei
alSourcei.restype = None
alSourcei.argtypes = [ALuint, ALenum, ALint]
# /usr/include/AL/al.h:531
#alSource3i = _lib.alSource3i
#alSource3i.restype = None
#alSource3i.argtypes = [ALuint, ALenum, ALint, ALint, ALint]
# /usr/include/AL/al.h:533
#alSourceiv = _lib.alSourceiv
#alSourceiv.restype = None
#alSourceiv.argtypes = [ALuint, ALenum, POINTER(ALint)]
# /usr/include/AL/al.h:538
alGetSourcef = _lib.alGetSourcef
alGetSourcef.restype = None
alGetSourcef.argtypes = [ALuint, ALenum, POINTER(ALfloat)]
# /usr/include/AL/al.h:540
alGetSource3f = _lib.alGetSource3f
alGetSource3f.restype = None
alGetSource3f.argtypes = [ALuint, ALenum, POINTER(ALfloat), POINTER(ALfloat), POINTER(ALfloat)]
# /usr/include/AL/al.h:542
alGetSourcefv = _lib.alGetSourcefv
alGetSourcefv.restype = None
alGetSourcefv.argtypes = [ALuint, ALenum, POINTER(ALfloat)]
# /usr/include/AL/al.h:544
alGetSourcei = _lib.alGetSourcei
alGetSourcei.restype = None
alGetSourcei.argtypes = [ALuint, ALenum, POINTER(ALint)]
# /usr/include/AL/al.h:546
#alGetSource3i = _lib.alGetSource3i
#alGetSource3i.restype = None
#alGetSource3i.argtypes = [ALuint, ALenum, POINTER(ALint), POINTER(ALint), POINTER(ALint)]
# /usr/include/AL/al.h:548
alGetSourceiv = _lib.alGetSourceiv
alGetSourceiv.restype = None
alGetSourceiv.argtypes = [ALuint, ALenum, POINTER(ALint)]
# /usr/include/AL/al.h:556
alSourcePlayv = _lib.alSourcePlayv
alSourcePlayv.restype = None
alSourcePlayv.argtypes = [ALsizei, POINTER(ALuint)]
# /usr/include/AL/al.h:559
alSourceStopv = _lib.alSourceStopv
alSourceStopv.restype = None
alSourceStopv.argtypes = [ALsizei, POINTER(ALuint)]
# /usr/include/AL/al.h:562
alSourceRewindv = _lib.alSourceRewindv
alSourceRewindv.restype = None
alSourceRewindv.argtypes = [ALsizei, POINTER(ALuint)]
# /usr/include/AL/al.h:565
alSourcePausev = _lib.alSourcePausev
alSourcePausev.restype = None
alSourcePausev.argtypes = [ALsizei, POINTER(ALuint)]
# /usr/include/AL/al.h:572
alSourcePlay = _lib.alSourcePlay
alSourcePlay.restype = None
alSourcePlay.argtypes = [ALuint]
# /usr/include/AL/al.h:575
alSourceStop = _lib.alSourceStop
alSourceStop.restype = None
alSourceStop.argtypes = [ALuint]
# /usr/include/AL/al.h:578
alSourceRewind = _lib.alSourceRewind
alSourceRewind.restype = None
alSourceRewind.argtypes = [ALuint]
# /usr/include/AL/al.h:581
alSourcePause = _lib.alSourcePause
alSourcePause.restype = None
alSourcePause.argtypes = [ALuint]
# /usr/include/AL/al.h:586
alSourceQueueBuffers = _lib.alSourceQueueBuffers
alSourceQueueBuffers.restype = None
alSourceQueueBuffers.argtypes = [ALuint, ALsizei, POINTER(ALuint)]
# /usr/include/AL/al.h:588
alSourceUnqueueBuffers = _lib.alSourceUnqueueBuffers
alSourceUnqueueBuffers.restype = None
alSourceUnqueueBuffers.argtypes = [ALuint, ALsizei, POINTER(ALuint)]
# /usr/include/AL/al.h:606
alGenBuffers = _lib.alGenBuffers
alGenBuffers.restype = None
alGenBuffers.argtypes = [ALsizei, POINTER(ALuint)]
# /usr/include/AL/al.h:609
alDeleteBuffers = _lib.alDeleteBuffers
alDeleteBuffers.restype = None
alDeleteBuffers.argtypes = [ALsizei, POINTER(ALuint)]
# /usr/include/AL/al.h:612
alIsBuffer = _lib.alIsBuffer
alIsBuffer.restype = ALboolean
alIsBuffer.argtypes = [ALuint]
# /usr/include/AL/al.h:615
alBufferData = _lib.alBufferData
alBufferData.restype = None
alBufferData.argtypes = [ALuint, ALenum, POINTER(ALvoid), ALsizei, ALsizei]
# /usr/include/AL/al.h:620
alBufferf = _lib.alBufferf
alBufferf.restype = None
alBufferf.argtypes = [ALuint, ALenum, ALfloat]
# /usr/include/AL/al.h:622
alBuffer3f = _lib.alBuffer3f
alBuffer3f.restype = None
alBuffer3f.argtypes = [ALuint, ALenum, ALfloat, ALfloat, ALfloat]
# /usr/include/AL/al.h:624
alBufferfv = _lib.alBufferfv
alBufferfv.restype = None
alBufferfv.argtypes = [ALuint, ALenum, POINTER(ALfloat)]
# /usr/include/AL/al.h:626
alBufferi = _lib.alBufferi
alBufferi.restype = None
alBufferi.argtypes = [ALuint, ALenum, ALint]
# /usr/include/AL/al.h:628
alBuffer3i = _lib.alBuffer3i
alBuffer3i.restype = None
alBuffer3i.argtypes = [ALuint, ALenum, ALint, ALint, ALint]
# /usr/include/AL/al.h:630
alBufferiv = _lib.alBufferiv
alBufferiv.restype = None
alBufferiv.argtypes = [ALuint, ALenum, POINTER(ALint)]
# /usr/include/AL/al.h:635
alGetBufferf = _lib.alGetBufferf
alGetBufferf.restype = None
alGetBufferf.argtypes = [ALuint, ALenum, POINTER(ALfloat)]
# /usr/include/AL/al.h:637
alGetBuffer3f = _lib.alGetBuffer3f
alGetBuffer3f.restype = None
alGetBuffer3f.argtypes = [ALuint, ALenum, POINTER(ALfloat), POINTER(ALfloat), POINTER(ALfloat)]
# /usr/include/AL/al.h:639
alGetBufferfv = _lib.alGetBufferfv
alGetBufferfv.restype = None
alGetBufferfv.argtypes = [ALuint, ALenum, POINTER(ALfloat)]
# /usr/include/AL/al.h:641
alGetBufferi = _lib.alGetBufferi
alGetBufferi.restype = None
alGetBufferi.argtypes = [ALuint, ALenum, POINTER(ALint)]
# /usr/include/AL/al.h:643
alGetBuffer3i = _lib.alGetBuffer3i
alGetBuffer3i.restype = None
alGetBuffer3i.argtypes = [ALuint, ALenum, POINTER(ALint), POINTER(ALint), POINTER(ALint)]
# /usr/include/AL/al.h:645
alGetBufferiv = _lib.alGetBufferiv
alGetBufferiv.restype = None
alGetBufferiv.argtypes = [ALuint, ALenum, POINTER(ALint)]
# /usr/include/AL/al.h:651
alDopplerFactor = _lib.alDopplerFactor
alDopplerFactor.restype = None
alDopplerFactor.argtypes = [ALfloat]
# /usr/include/AL/al.h:653
alDopplerVelocity = _lib.alDopplerVelocity
alDopplerVelocity.restype = None
alDopplerVelocity.argtypes = [ALfloat]
# /usr/include/AL/al.h:655
alSpeedOfSound = _lib.alSpeedOfSound
alSpeedOfSound.restype = None
alSpeedOfSound.argtypes = [ALfloat]
# /usr/include/AL/al.h:657
alDistanceModel = _lib.alDistanceModel
alDistanceModel.restype = None
alDistanceModel.argtypes = [ALenum]
LPALENABLE = CFUNCTYPE(None, ALenum) # /usr/include/AL/al.h:662
LPALDISABLE = CFUNCTYPE(None, ALenum) # /usr/include/AL/al.h:663
LPALISENABLED = CFUNCTYPE(ALboolean, ALenum) # /usr/include/AL/al.h:664
LPALGETSTRING = CFUNCTYPE(POINTER(ALchar), ALenum) # /usr/include/AL/al.h:665
LPALGETBOOLEANV = CFUNCTYPE(None, ALenum, POINTER(ALboolean)) # /usr/include/AL/al.h:666
LPALGETINTEGERV = CFUNCTYPE(None, ALenum, POINTER(ALint)) # /usr/include/AL/al.h:667
LPALGETFLOATV = CFUNCTYPE(None, ALenum, POINTER(ALfloat)) # /usr/include/AL/al.h:668
LPALGETDOUBLEV = CFUNCTYPE(None, ALenum, POINTER(ALdouble)) # /usr/include/AL/al.h:669
LPALGETBOOLEAN = CFUNCTYPE(ALboolean, ALenum) # /usr/include/AL/al.h:670
LPALGETINTEGER = CFUNCTYPE(ALint, ALenum) # /usr/include/AL/al.h:671
LPALGETFLOAT = CFUNCTYPE(ALfloat, ALenum) # /usr/include/AL/al.h:672
LPALGETDOUBLE = CFUNCTYPE(ALdouble, ALenum) # /usr/include/AL/al.h:673
LPALGETERROR = CFUNCTYPE(ALenum) # /usr/include/AL/al.h:674
LPALISEXTENSIONPRESENT = CFUNCTYPE(ALboolean, POINTER(ALchar)) # /usr/include/AL/al.h:675
LPALGETPROCADDRESS = CFUNCTYPE(POINTER(c_void), POINTER(ALchar)) # /usr/include/AL/al.h:676
LPALGETENUMVALUE = CFUNCTYPE(ALenum, POINTER(ALchar)) # /usr/include/AL/al.h:677
LPALLISTENERF = CFUNCTYPE(None, ALenum, ALfloat) # /usr/include/AL/al.h:678
LPALLISTENER3F = CFUNCTYPE(None, ALenum, ALfloat, ALfloat, ALfloat) # /usr/include/AL/al.h:679
LPALLISTENERFV = CFUNCTYPE(None, ALenum, POINTER(ALfloat)) # /usr/include/AL/al.h:680
LPALLISTENERI = CFUNCTYPE(None, ALenum, ALint) # /usr/include/AL/al.h:681
LPALLISTENER3I = CFUNCTYPE(None, ALenum, ALint, ALint, ALint) # /usr/include/AL/al.h:682
LPALLISTENERIV = CFUNCTYPE(None, ALenum, POINTER(ALint)) # /usr/include/AL/al.h:683
LPALGETLISTENERF = CFUNCTYPE(None, ALenum, POINTER(ALfloat)) # /usr/include/AL/al.h:684
LPALGETLISTENER3F = CFUNCTYPE(None, ALenum, POINTER(ALfloat), POINTER(ALfloat), POINTER(ALfloat)) # /usr/include/AL/al.h:685
LPALGETLISTENERFV = CFUNCTYPE(None, ALenum, POINTER(ALfloat)) # /usr/include/AL/al.h:686
LPALGETLISTENERI = CFUNCTYPE(None, ALenum, POINTER(ALint)) # /usr/include/AL/al.h:687
LPALGETLISTENER3I = CFUNCTYPE(None, ALenum, POINTER(ALint), POINTER(ALint), POINTER(ALint)) # /usr/include/AL/al.h:688
LPALGETLISTENERIV = CFUNCTYPE(None, ALenum, POINTER(ALint)) # /usr/include/AL/al.h:689
LPALGENSOURCES = CFUNCTYPE(None, ALsizei, POINTER(ALuint)) # /usr/include/AL/al.h:690
LPALDELETESOURCES = CFUNCTYPE(None, ALsizei, POINTER(ALuint)) # /usr/include/AL/al.h:691
LPALISSOURCE = CFUNCTYPE(ALboolean, ALuint) # /usr/include/AL/al.h:692
LPALSOURCEF = CFUNCTYPE(None, ALuint, ALenum, ALfloat) # /usr/include/AL/al.h:693
LPALSOURCE3F = CFUNCTYPE(None, ALuint, ALenum, ALfloat, ALfloat, ALfloat) # /usr/include/AL/al.h:694
LPALSOURCEFV = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALfloat)) # /usr/include/AL/al.h:695
LPALSOURCEI = CFUNCTYPE(None, ALuint, ALenum, ALint) # /usr/include/AL/al.h:696
LPALSOURCE3I = CFUNCTYPE(None, ALuint, ALenum, ALint, ALint, ALint) # /usr/include/AL/al.h:697
LPALSOURCEIV = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALint)) # /usr/include/AL/al.h:698
LPALGETSOURCEF = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALfloat)) # /usr/include/AL/al.h:699
LPALGETSOURCE3F = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALfloat), POINTER(ALfloat), POINTER(ALfloat)) # /usr/include/AL/al.h:700
LPALGETSOURCEFV = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALfloat)) # /usr/include/AL/al.h:701
LPALGETSOURCEI = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALint)) # /usr/include/AL/al.h:702
LPALGETSOURCE3I = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALint), POINTER(ALint), POINTER(ALint)) # /usr/include/AL/al.h:703
LPALGETSOURCEIV = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALint)) # /usr/include/AL/al.h:704
LPALSOURCEPLAYV = CFUNCTYPE(None, ALsizei, POINTER(ALuint)) # /usr/include/AL/al.h:705
LPALSOURCESTOPV = CFUNCTYPE(None, ALsizei, POINTER(ALuint)) # /usr/include/AL/al.h:706
LPALSOURCEREWINDV = CFUNCTYPE(None, ALsizei, POINTER(ALuint)) # /usr/include/AL/al.h:707
LPALSOURCEPAUSEV = CFUNCTYPE(None, ALsizei, POINTER(ALuint)) # /usr/include/AL/al.h:708
LPALSOURCEPLAY = CFUNCTYPE(None, ALuint) # /usr/include/AL/al.h:709
LPALSOURCESTOP = CFUNCTYPE(None, ALuint) # /usr/include/AL/al.h:710
LPALSOURCEREWIND = CFUNCTYPE(None, ALuint) # /usr/include/AL/al.h:711
LPALSOURCEPAUSE = CFUNCTYPE(None, ALuint) # /usr/include/AL/al.h:712
LPALSOURCEQUEUEBUFFERS = CFUNCTYPE(None, ALuint, ALsizei, POINTER(ALuint)) # /usr/include/AL/al.h:713
LPALSOURCEUNQUEUEBUFFERS = CFUNCTYPE(None, ALuint, ALsizei, POINTER(ALuint)) # /usr/include/AL/al.h:714
LPALGENBUFFERS = CFUNCTYPE(None, ALsizei, POINTER(ALuint)) # /usr/include/AL/al.h:715
LPALDELETEBUFFERS = CFUNCTYPE(None, ALsizei, POINTER(ALuint)) # /usr/include/AL/al.h:716
LPALISBUFFER = CFUNCTYPE(ALboolean, ALuint) # /usr/include/AL/al.h:717
LPALBUFFERDATA = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALvoid), ALsizei, ALsizei) # /usr/include/AL/al.h:718
LPALBUFFERF = CFUNCTYPE(None, ALuint, ALenum, ALfloat) # /usr/include/AL/al.h:719
LPALBUFFER3F = CFUNCTYPE(None, ALuint, ALenum, ALfloat, ALfloat, ALfloat) # /usr/include/AL/al.h:720
LPALBUFFERFV = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALfloat)) # /usr/include/AL/al.h:721
LPALBUFFERI = CFUNCTYPE(None, ALuint, ALenum, ALint) # /usr/include/AL/al.h:722
LPALBUFFER3I = CFUNCTYPE(None, ALuint, ALenum, ALint, ALint, ALint) # /usr/include/AL/al.h:723
LPALBUFFERIV = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALint)) # /usr/include/AL/al.h:724
LPALGETBUFFERF = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALfloat)) # /usr/include/AL/al.h:725
LPALGETBUFFER3F = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALfloat), POINTER(ALfloat), POINTER(ALfloat)) # /usr/include/AL/al.h:726
LPALGETBUFFERFV = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALfloat)) # /usr/include/AL/al.h:727
LPALGETBUFFERI = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALint)) # /usr/include/AL/al.h:728
LPALGETBUFFER3I = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALint), POINTER(ALint), POINTER(ALint)) # /usr/include/AL/al.h:729
LPALGETBUFFERIV = CFUNCTYPE(None, ALuint, ALenum, POINTER(ALint)) # /usr/include/AL/al.h:730
LPALDOPPLERFACTOR = CFUNCTYPE(None, ALfloat) # /usr/include/AL/al.h:731
LPALDOPPLERVELOCITY = CFUNCTYPE(None, ALfloat) # /usr/include/AL/al.h:732
LPALSPEEDOFSOUND = CFUNCTYPE(None, ALfloat) # /usr/include/AL/al.h:733
LPALDISTANCEMODEL = CFUNCTYPE(None, ALenum) # /usr/include/AL/al.h:734
__all__ = ['AL_API', 'ALAPI', 'AL_INVALID', 'AL_ILLEGAL_ENUM',
'AL_ILLEGAL_COMMAND', 'ALboolean', 'ALchar', 'ALbyte', 'ALubyte', 'ALshort',
'ALushort', 'ALint', 'ALuint', 'ALsizei', 'ALenum', 'ALfloat', 'ALdouble',
'ALvoid', 'AL_NONE', 'AL_FALSE', 'AL_TRUE', 'AL_SOURCE_RELATIVE',
'AL_CONE_INNER_ANGLE', 'AL_CONE_OUTER_ANGLE', 'AL_PITCH', 'AL_POSITION',
'AL_DIRECTION', 'AL_VELOCITY', 'AL_LOOPING', 'AL_BUFFER', 'AL_GAIN',
'AL_MIN_GAIN', 'AL_MAX_GAIN', 'AL_ORIENTATION', 'AL_SOURCE_STATE',
'AL_INITIAL', 'AL_PLAYING', 'AL_PAUSED', 'AL_STOPPED', 'AL_BUFFERS_QUEUED',
'AL_BUFFERS_PROCESSED', 'AL_SEC_OFFSET', 'AL_SAMPLE_OFFSET', 'AL_BYTE_OFFSET',
'AL_SOURCE_TYPE', 'AL_STATIC', 'AL_STREAMING', 'AL_UNDETERMINED',
'AL_FORMAT_MONO8', 'AL_FORMAT_MONO16', 'AL_FORMAT_STEREO8',
'AL_FORMAT_STEREO16', 'AL_REFERENCE_DISTANCE', 'AL_ROLLOFF_FACTOR',
'AL_CONE_OUTER_GAIN', 'AL_MAX_DISTANCE', 'AL_FREQUENCY', 'AL_BITS',
'AL_CHANNELS', 'AL_SIZE', 'AL_UNUSED', 'AL_PENDING', 'AL_PROCESSED',
'AL_NO_ERROR', 'AL_INVALID_NAME', 'AL_INVALID_ENUM', 'AL_INVALID_VALUE',
'AL_INVALID_OPERATION', 'AL_OUT_OF_MEMORY', 'AL_VENDOR', 'AL_VERSION',
'AL_RENDERER', 'AL_EXTENSIONS', 'AL_DOPPLER_FACTOR', 'AL_DOPPLER_VELOCITY',
'AL_SPEED_OF_SOUND', 'AL_DISTANCE_MODEL', 'AL_INVERSE_DISTANCE',
'AL_INVERSE_DISTANCE_CLAMPED', 'AL_LINEAR_DISTANCE',
'AL_LINEAR_DISTANCE_CLAMPED', 'AL_EXPONENT_DISTANCE',
'AL_EXPONENT_DISTANCE_CLAMPED', 'alEnable', 'alDisable', 'alIsEnabled',
'alGetString', 'alGetBooleanv', 'alGetIntegerv', 'alGetFloatv',
'alGetDoublev', 'alGetBoolean', 'alGetInteger', 'alGetFloat', 'alGetDouble',
'alGetError', 'alIsExtensionPresent', 'alGetProcAddress', 'alGetEnumValue',
'alListenerf', 'alListener3f', 'alListenerfv', 'alListeneri', 'alListener3i',
'alListeneriv', 'alGetListenerf', 'alGetListener3f', 'alGetListenerfv',
'alGetListeneri', 'alGetListener3i', 'alGetListeneriv', 'alGenSources',
'alDeleteSources', 'alIsSource', 'alSourcef', 'alSource3f', 'alSourcefv',
'alSourcei', 'alSource3i', 'alSourceiv', 'alGetSourcef', 'alGetSource3f',
'alGetSourcefv', 'alGetSourcei', 'alGetSource3i', 'alGetSourceiv',
'alSourcePlayv', 'alSourceStopv', 'alSourceRewindv', 'alSourcePausev',
'alSourcePlay', 'alSourceStop', 'alSourceRewind', 'alSourcePause',
'alSourceQueueBuffers', 'alSourceUnqueueBuffers', 'alGenBuffers',
'alDeleteBuffers', 'alIsBuffer', 'alBufferData', 'alBufferf', 'alBuffer3f',
'alBufferfv', 'alBufferi', 'alBuffer3i', 'alBufferiv', 'alGetBufferf',
'alGetBuffer3f', 'alGetBufferfv', 'alGetBufferi', 'alGetBuffer3i',
'alGetBufferiv', 'alDopplerFactor', 'alDopplerVelocity', 'alSpeedOfSound',
'alDistanceModel', 'LPALENABLE', 'LPALDISABLE', 'LPALISENABLED',
'LPALGETSTRING', 'LPALGETBOOLEANV', 'LPALGETINTEGERV', 'LPALGETFLOATV',
'LPALGETDOUBLEV', 'LPALGETBOOLEAN', 'LPALGETINTEGER', 'LPALGETFLOAT',
'LPALGETDOUBLE', 'LPALGETERROR', 'LPALISEXTENSIONPRESENT',
'LPALGETPROCADDRESS', 'LPALGETENUMVALUE', 'LPALLISTENERF', 'LPALLISTENER3F',
'LPALLISTENERFV', 'LPALLISTENERI', 'LPALLISTENER3I', 'LPALLISTENERIV',
'LPALGETLISTENERF', 'LPALGETLISTENER3F', 'LPALGETLISTENERFV',
'LPALGETLISTENERI', 'LPALGETLISTENER3I', 'LPALGETLISTENERIV',
'LPALGENSOURCES', 'LPALDELETESOURCES', 'LPALISSOURCE', 'LPALSOURCEF',
'LPALSOURCE3F', 'LPALSOURCEFV', 'LPALSOURCEI', 'LPALSOURCE3I', 'LPALSOURCEIV',
'LPALGETSOURCEF', 'LPALGETSOURCE3F', 'LPALGETSOURCEFV', 'LPALGETSOURCEI',
'LPALGETSOURCE3I', 'LPALGETSOURCEIV', 'LPALSOURCEPLAYV', 'LPALSOURCESTOPV',
'LPALSOURCEREWINDV', 'LPALSOURCEPAUSEV', 'LPALSOURCEPLAY', 'LPALSOURCESTOP',
'LPALSOURCEREWIND', 'LPALSOURCEPAUSE', 'LPALSOURCEQUEUEBUFFERS',
'LPALSOURCEUNQUEUEBUFFERS', 'LPALGENBUFFERS', 'LPALDELETEBUFFERS',
'LPALISBUFFER', 'LPALBUFFERDATA', 'LPALBUFFERF', 'LPALBUFFER3F',
'LPALBUFFERFV', 'LPALBUFFERI', 'LPALBUFFER3I', 'LPALBUFFERIV',
'LPALGETBUFFERF', 'LPALGETBUFFER3F', 'LPALGETBUFFERFV', 'LPALGETBUFFERI',
'LPALGETBUFFER3I', 'LPALGETBUFFERIV', 'LPALDOPPLERFACTOR',
'LPALDOPPLERVELOCITY', 'LPALSPEEDOFSOUND', 'LPALDISTANCEMODEL']

View file

@ -0,0 +1,158 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Fallback driver producing no audio.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: silent.py 1680 2008-01-27 09:13:50Z Alex.Holkner $'
import time
from pyglet.media import AudioPlayer, Listener, AudioData
from pyglet.media import MediaException
class SilentAudioPlayer(AudioPlayer):
UPDATE_PERIOD = 0.1
def __init__(self, audio_format):
super(SilentAudioPlayer, self).__init__(audio_format)
self._playing = False
self._eos_count = 0
self._audio_data_list = []
self._head_time = 0.0
self._head_timestamp = 0.0
self._head_system_time = time.time()
def get_write_size(self):
bytes = int(self.audio_format.bytes_per_second * self.UPDATE_PERIOD)
return max(0, bytes - sum(
[a.length for a in self._audio_data_list if a is not None]))
def write(self, audio_data):
if not self._audio_data_list:
self._head_time = 0.0
self._head_timestamp = audio_data.timestamp
self._head_system_time = time.time()
self._audio_data_list.append(
AudioData(None,
audio_data.length,
audio_data.timestamp,
audio_data.duration))
audio_data.consume(audio_data.length, self.audio_format)
def write_eos(self):
if self._audio_data_list:
self._audio_data_list.append(None)
def write_end(self):
pass
def play(self):
self._playing = True
self._head_system_time = time.time()
def stop(self):
self._playing = False
self._head_time = time.time() - self._head_system_time
def clear(self):
self._audio_data_list = []
self._head_time = 0.0
self._head_system_time = time.time()
self._eos_count = 0
def pump(self):
if not self._playing:
return
system_time = time.time()
head_time = system_time - self._head_system_time
try:
while head_time >= self._audio_data_list[0].duration:
head_time -= self._audio_data_list[0].duration
self._audio_data_list.pop(0)
while self._audio_data_list[0] is None:
self._eos_count += 1
self._audio_data_list.pop(0)
self._head_timestamp = self._audio_data_list[0].timestamp
self._head_system_time = system_time - head_time
except IndexError:
pass
def get_time(self):
if not self._audio_data_list:
return time.time() - self._head_system_time + self._head_timestamp
if self._playing:
system_time = time.time()
head_time = system_time - self._head_system_time
return head_time + self._audio_data_list[0].timestamp
else:
return self._audio_data_list[0].timestamp + self._head_time
def clear_eos(self):
if self._eos_count:
self._eos_count -= 1
return True
return False
class SilentListener(Listener):
def _set_volume(self, volume):
self._volume = volume
def _set_position(self, position):
self._position = position
def _set_velocity(self, velocity):
self._velocity = velocity
def _set_forward_orientation(self, orientation):
self._forward_orientation = orientation
def _set_up_orientation(self, orientation):
self._up_orientation = orientation
def _set_doppler_factor(self, factor):
self._doppler_factor = factor
def _set_speed_of_sound(self, speed_of_sound):
self._speed_of_sound = speed_of_sound
def driver_init():
pass
driver_listener = SilentListener()
driver_audio_player_class = SilentAudioPlayer

181
pyglet/media/procedural.py Normal file
View file

@ -0,0 +1,181 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id:$
from pyglet.media import Source, AudioFormat, AudioData
import ctypes
import os
import math
class ProceduralSource(Source):
def __init__(self, duration, sample_rate=44800, sample_size=16):
self._duration = float(duration)
self.audio_format = AudioFormat(
channels=1,
sample_size=sample_size,
sample_rate=sample_rate)
self._offset = 0
self._bytes_per_sample = sample_size >> 3
self._bytes_per_second = self._bytes_per_sample * sample_rate
self._max_offset = int(self._bytes_per_second * self._duration)
if self._bytes_per_sample == 2:
self._max_offset &= 0xfffffffe
def _get_audio_data(self, bytes):
bytes = min(bytes, self._max_offset - self._offset)
if bytes <= 0:
return None
timestamp = float(self._offset) / self._bytes_per_second
duration = float(bytes) / self._bytes_per_second
data = self._generate_data(bytes, self._offset)
self._offset += bytes
is_eos = self._offset >= self._max_offset
return AudioData(data,
bytes,
timestamp,
duration)
def _generate_data(self, bytes, offset):
'''Generate `bytes` bytes of data.
Return data as ctypes array or string.
'''
raise NotImplementedError('abstract')
def _seek(self, timestamp):
self._offset = int(timestamp * self._bytes_per_second)
# Bound within duration
self._offset = min(max(self._offset, 0), self._max_offset)
# Align to sample
if self._bytes_per_sample == 2:
self._offset &= 0xfffffffe
class Silence(ProceduralSource):
def _generate_data(self, bytes, offset):
if self._bytes_per_sample == 1:
return '\127' * bytes
else:
return '\0' * bytes
class WhiteNoise(ProceduralSource):
def _generate_data(self, bytes, offset):
return os.urandom(bytes)
class Sine(ProceduralSource):
def __init__(self, duration, frequency=440, **kwargs):
super(Sine, self).__init__(duration, **kwargs)
self.frequency = frequency
def _generate_data(self, bytes, offset):
if self._bytes_per_sample == 1:
start = offset
samples = bytes
bias = 127
amplitude = 127
data = (ctypes.c_ubyte * samples)()
else:
start = offset >> 1
samples = bytes >> 1
bias = 0
amplitude = 32767
data = (ctypes.c_short * samples)()
step = self.frequency * (math.pi * 2) / self.audio_format.sample_rate
for i in range(samples):
data[i] = int(math.sin(step * (i + start)) * amplitude + bias)
return data
class Saw(ProceduralSource):
def __init__(self, duration, frequency=440, **kwargs):
super(Saw, self).__init__(duration, **kwargs)
self.frequency = frequency
def _generate_data(self, bytes, offset):
# XXX TODO consider offset
if self._bytes_per_sample == 1:
samples = bytes
value = 127
max = 255
min = 0
data = (ctypes.c_ubyte * samples)()
else:
samples = bytes >> 1
value = 0
max = 32767
min = -32768
data = (ctypes.c_short * samples)()
step = (max - min) * 2 * self.frequency / self.audio_format.sample_rate
for i in range(samples):
value += step
if value > max:
value = max - (value - max)
step = -step
if value < min:
value = min - (value - min)
step = -step
data[i] = value
return data
class Square(ProceduralSource):
def __init__(self, duration, frequency=440, **kwargs):
super(Square, self).__init__(duration, **kwargs)
self.frequency = frequency
def _generate_data(self, bytes, offset):
# XXX TODO consider offset
if self._bytes_per_sample == 1:
samples = bytes
value = 0
amplitude = 255
data = (ctypes.c_ubyte * samples)()
else:
samples = bytes >> 1
value = -32768
amplitude = 65535
data = (ctypes.c_short * samples)()
period = self.audio_format.sample_rate / self.frequency / 2
count = 0
for i in range(samples):
count += 1
if count == period:
value = amplitude - value
count = 0
data[i] = value
return data

249
pyglet/media/riff.py Normal file
View file

@ -0,0 +1,249 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Simple Python-only RIFF reader, supports uncompressed WAV files.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: riff.py 2005 2008-04-13 01:03:03Z Alex.Holkner $'
# RIFF reference:
# http://www.saettler.com/RIFFMCI/riffmci.html
#
# More readable WAVE summaries:
#
# http://www.borg.com/~jglatt/tech/wave.htm
# http://www.sonicspot.com/guide/wavefiles.html
from pyglet.media import StreamingSource, AudioData, AudioFormat
from pyglet.media import MediaFormatException
import ctypes
import struct
import StringIO
WAVE_FORMAT_PCM = 0x0001
IBM_FORMAT_MULAW = 0x0101
IBM_FORMAT_ALAW = 0x0102
IBM_FORMAT_ADPCM = 0x0103
class RIFFFormatException(MediaFormatException):
pass
class WAVEFormatException(RIFFFormatException):
pass
class RIFFChunk(object):
header_fmt = '<4sL'
header_length = struct.calcsize(header_fmt)
def __init__(self, file, name, length, offset):
self.file = file
self.name = name
self.length = length
self.offset = offset
def get_data(self):
self.file.seek(self.offset)
return self.file.read(self.length)
def __repr__(self):
return '%s(%r, offset=%r, length=%r)' % (
self.__class__.__name__,
self.name,
self.offset,
self.length)
class RIFFForm(object):
_chunks = None
def __init__(self, file, offset):
self.file = file
self.offset = offset
def get_chunks(self):
if self._chunks:
return self._chunks
self._chunks = []
self.file.seek(self.offset)
offset = self.offset
while True:
header = self.file.read(RIFFChunk.header_length)
if not header:
break
name, length = struct.unpack(RIFFChunk.header_fmt, header)
offset += RIFFChunk.header_length
cls = self._chunk_types.get(name, RIFFChunk)
chunk = cls(self.file, name, length, offset)
self._chunks.append(chunk)
offset += length
if offset & 0x3 != 0:
offset = (offset | 0x3) + 1
self.file.seek(offset)
return self._chunks
def __repr__(self):
return '%s(offset=%r)' % (self.__class__.__name__, self.offset)
class RIFFType(RIFFChunk):
def __init__(self, *args, **kwargs):
super(RIFFType, self).__init__(*args, **kwargs)
self.file.seek(self.offset)
form = self.file.read(4)
if form != 'WAVE':
raise RIFFFormatException('Unsupported RIFF form "%s"' % form)
self.form = WaveForm(self.file, self.offset + 4)
class RIFFFile(RIFFForm):
_chunk_types = {
'RIFF': RIFFType,
}
def __init__(self, file):
if not hasattr(file, 'seek'):
file = StringIO.StringIO(file.read())
super(RIFFFile, self).__init__(file, 0)
def get_wave_form(self):
chunks = self.get_chunks()
if len(chunks) == 1 and isinstance(chunks[0], RIFFType):
return chunks[0].form
class WaveFormatChunk(RIFFChunk):
def __init__(self, *args, **kwargs):
super(WaveFormatChunk, self).__init__(*args, **kwargs)
fmt = '<HHLLHH'
if struct.calcsize(fmt) != self.length:
raise RIFFFormatException('Size of format chunk is incorrect.')
(self.wFormatTag,
self.wChannels,
self.dwSamplesPerSec,
self.dwAvgBytesPerSec,
self.wBlockAlign,
self.wBitsPerSample) = struct.unpack(fmt, self.get_data())
class WaveDataChunk(RIFFChunk):
pass
class WaveForm(RIFFForm):
_chunk_types = {
'fmt ': WaveFormatChunk,
'data': WaveDataChunk
}
def get_format_chunk(self):
for chunk in self.get_chunks():
if isinstance(chunk, WaveFormatChunk):
return chunk
def get_data_chunk(self):
for chunk in self.get_chunks():
if isinstance(chunk, WaveDataChunk):
return chunk
class WaveSource(StreamingSource):
def __init__(self, filename, file=None):
if file is None:
file = open(filename, 'rb')
self._file = file
# Read RIFF format, get format and data chunks
riff = RIFFFile(file)
wave_form = riff.get_wave_form()
if wave_form:
format = wave_form.get_format_chunk()
data_chunk = wave_form.get_data_chunk()
if not wave_form or not format or not data_chunk:
if not filename or filename.lower().endswith('.wav'):
raise WAVEFormatException('Not a WAVE file')
else:
raise WAVEFormatException(
'AVbin is required to decode compressed media')
if format.wFormatTag != WAVE_FORMAT_PCM:
raise WAVEFormatException('Unsupported WAVE format category')
if format.wBitsPerSample not in (8, 16):
raise WAVEFormatException('Unsupported sample bit size: %d' %
format.wBitsPerSample)
self.audio_format = AudioFormat(
channels=format.wChannels,
sample_size=format.wBitsPerSample,
sample_rate=format.dwSamplesPerSec)
self._duration = \
float(data_chunk.length) / self.audio_format.bytes_per_second
self._start_offset = data_chunk.offset
self._max_offset = data_chunk.length
self._offset = 0
self._file.seek(self._start_offset)
def _get_audio_data(self, bytes):
bytes = min(bytes, self._max_offset - self._offset)
if not bytes:
return None
data = self._file.read(bytes)
self._offset += len(data)
timestamp = float(self._offset) / self.audio_format.bytes_per_second
duration = float(bytes) / self.audio_format.bytes_per_second
return AudioData(data, len(data), timestamp, duration)
def seek(self, timestamp):
offset = int(timestamp * self.audio_format.bytes_per_second)
# Bound within duration
offset = min(max(offset, 0), self._max_offset)
# Align to sample
if self.audio_format.bytes_per_sample == 2:
offset &= 0xfffffffe
elif self.audio_format.bytes_per_sample == 4:
offset &= 0xfffffffc
self._file.seek(offset + self._start_offset)
self._offset = offset

685
pyglet/resource.py Normal file
View file

@ -0,0 +1,685 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Load application resources from a known path.
Loading resources by specifying relative paths to filenames is often
problematic in Python, as the working directory is not necessarily the same
directory as the application's script files.
This module allows applications to specify a search path for resources.
Relative paths are taken to be relative to the application's __main__ module.
ZIP files can appear on the path; they will be searched inside. The resource
module also behaves as expected when applications are bundled using py2exe or
py2app.
As well as providing file references (with the `file` function), the resource
module also contains convenience functions for loading images, textures,
fonts, media and documents.
3rd party modules or packages not bound to a specific application should
construct their own `Loader` instance and override the path to use the
resources in the module's directory.
Path format
^^^^^^^^^^^
The resource path `path` (see also `Loader.__init__` and `Loader.path`)
is a list of locations to search for resources. Locations are searched in the
order given in the path. If a location is not valid (for example, if the
directory does not exist), it is skipped.
Locations in the path beginning with an ampersand (''@'' symbol) specify
Python packages. Other locations specify a ZIP archive or directory on the
filesystem. Locations that are not absolute are assumed to be relative to the
script home. Some examples::
# Search just the `res` directory, assumed to be located alongside the
# main script file.
path = ['res']
# Search the directory containing the module `levels.level1`, followed
# by the `res` directory.
path = ['@levels.level1', 'res']
Paths are always case-sensitive, even if the filesystem is not. This
avoids a common programmer error when porting applications between platforms.
The default path is ``['.']``. If you modify the path, you must call
`reindex`.
:since: pyglet 1.1
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import operator
import os
import weakref
import sys
import zipfile
import StringIO
import pyglet
class ResourceNotFoundException(Exception):
'''The named resource was not found on the search path.'''
def __init__(self, name):
message = ('Resource "%s" was not found on the path. '
'Ensure that the filename has the correct captialisation.') % name
Exception.__init__(self, message)
def get_script_home():
'''Get the directory containing the program entry module.
For ordinary Python scripts, this is the directory containing the
``__main__`` module. For executables created with py2exe the result is
the directory containing the running executable file. For OS X bundles
created using Py2App the result is the Resources directory within the
running bundle.
If none of the above cases apply and the file for ``__main__`` cannot
be determined the working directory is returned.
:rtype: str
'''
frozen = getattr(sys, 'frozen', None)
if frozen in ('windows_exe', 'console_exe'):
return os.path.dirname(sys.executable)
elif frozen == 'macosx_app':
return os.environ['RESOURCEPATH']
else:
main = sys.modules['__main__']
if hasattr(main, '__file__'):
return os.path.dirname(main.__file__)
# Probably interactive
return ''
def get_settings_path(name):
'''Get a directory to save user preferences.
Different platforms have different conventions for where to save user
preferences, saved games, and settings. This function implements those
conventions. Note that the returned path may not exist: applications
should use ``os.makedirs`` to construct it if desired.
On Linux, a hidden directory `name` in the user's home directory is
returned.
On Windows (including under Cygwin) the `name` directory in the user's
``Application Settings`` directory is returned.
On Mac OS X the `name` directory under ``~/Library/Application Support``
is returned.
:Parameters:
`name` : str
The name of the application.
:rtype: str
'''
if sys.platform in ('cygwin', 'win32'):
if 'APPDATA' in os.environ:
return os.path.join(os.environ['APPDATA'], name)
else:
return os.path.expanduser('~/%s' % name)
elif sys.platform == 'darwin':
return os.path.expanduser('~/Library/Application Support/%s' % name)
else:
return os.path.expanduser('~/.%s' % name)
class Location(object):
'''Abstract resource location.
Given a location, a file can be loaded from that location with the `open`
method. This provides a convenient way to specify a path to load files
from, and not necessarily have that path reside on the filesystem.
'''
def open(self, filename, mode='rb'):
'''Open a file at this locaiton.
:Parameters:
`filename` : str
The filename to open. Absolute paths are not supported.
Relative paths are not supported by most locations (you
should specify only a filename with no path component).
`mode` : str
The file mode to open with. Only files opened on the
filesystem make use of this parameter; others ignore it.
:rtype: file object
'''
raise NotImplementedError('abstract')
class FileLocation(Location):
'''Location on the filesystem.
'''
def __init__(self, path):
'''Create a location given a relative or absolute path.
:Parameters:
`path` : str
Path on the filesystem.
'''
self.path = path
def open(self, filename, mode='rb'):
return open(os.path.join(self.path, filename), mode)
class ZIPLocation(Location):
'''Location within a ZIP file.
'''
def __init__(self, zip, dir):
'''Create a location given an open ZIP file and a path within that
file.
:Parameters:
`zip` : ``zipfile.ZipFile``
An open ZIP file from the ``zipfile`` module.
`dir` : str
A path within that ZIP file. Can be empty to specify files at
the top level of the ZIP file.
'''
self.zip = zip
self.dir = dir
def open(self, filename, mode='rb'):
path = os.path.join(self.dir, filename)
text = self.zip.read(path)
return StringIO.StringIO(text)
class URLLocation(Location):
'''Location on the network.
This class uses the ``urlparse`` and ``urllib2`` modules to open files on
the network given a URL.
'''
def __init__(self, base_url):
'''Create a location given a base URL.
:Parameters:
`base_url` : str
URL string to prepend to filenames.
'''
self.base = base_url
def open(self, filename, mode='rb'):
import urlparse
import urllib2
url = urlparse.urljoin(self.base, filename)
return urllib2.urlopen(url)
class Loader(object):
'''Load program resource files from disk.
The loader contains a search path which can include filesystem
directories, ZIP archives and Python packages.
:Ivariables:
`path` : list of str
List of search locations. After modifying the path you must
call the `reindex` method.
`script_home` : str
Base resource location, defaulting to the location of the
application script.
'''
def __init__(self, path=None, script_home=None):
'''Create a loader for the given path.
If no path is specified it defaults to ``['.']``; that is, just the
program directory.
See the module documentation for details on the path format.
:Parameters:
`path` : list of str
List of locations to search for resources.
`script_home` : str
Base location of relative files. Defaults to the result of
`get_script_home`.
'''
if path is None:
path = ['.']
if type(path) in (str, unicode):
path = [path]
self.path = list(path)
if script_home is None:
script_home = get_script_home()
self._script_home = script_home
self.reindex()
# Map name to image
self._cached_textures = weakref.WeakValueDictionary()
self._cached_images = weakref.WeakValueDictionary()
self._cached_animations = weakref.WeakValueDictionary()
# Map bin size to list of atlases
self._texture_atlas_bins = {}
def reindex(self):
'''Refresh the file index.
You must call this method if `path` is changed or the filesystem
layout changes.
'''
self._index = {}
for path in self.path:
if path.startswith('@'):
# Module
name = path[1:]
try:
module = __import__(name)
except:
continue
for component in name.split('.')[1:]:
module = getattr(module, component)
if hasattr(module, '__file__'):
path = os.path.dirname(module.__file__)
else:
path = '' # interactive
elif not os.path.isabs(path):
# Add script base unless absolute
assert '\\' not in path, \
'Backslashes not permitted in relative path'
path = os.path.join(self._script_home, path)
if os.path.isdir(path):
# Filesystem directory
path = path.rstrip(os.path.pathsep)
location = FileLocation(path)
for dirpath, dirnames, filenames in os.walk(path):
dirpath = dirpath[len(path) + 1:]
# Force forward slashes for index
if dirpath:
parts = filter(None, dirpath.split(os.sep))
dirpath = '/'.join(parts)
for filename in filenames:
if dirpath:
index_name = dirpath + '/' + filename
else:
index_name = filename
self._index_file(index_name, location)
else:
# Find path component that is the ZIP file.
dir = ''
while path and not os.path.isfile(path):
path, tail_dir = os.path.split(path)
dir = '/'.join((tail_dir, dir))
dir = dir.rstrip('/')
# path is a ZIP file, dir resides within ZIP
if path and zipfile.is_zipfile(path):
zip = zipfile.ZipFile(path, 'r')
location = ZIPLocation(zip, dir)
for zip_name in zip.namelist():
#zip_name_dir, zip_name = os.path.split(zip_name)
#assert '\\' not in name_dir
#assert not name_dir.endswith('/')
if zip_name.startswith(dir):
if dir:
zip_name = zip_name[len(dir)+1:]
self._index_file(zip_name, location)
def _index_file(self, name, location):
if name not in self._index:
self._index[name] = location
def file(self, name, mode='rb'):
'''Load a resource.
:Parameters:
`name` : str
Filename of the resource to load.
`mode` : str
Combination of ``r``, ``w``, ``a``, ``b`` and ``t`` characters
with the meaning as for the builtin ``open`` function.
:rtype: file object
'''
try:
location = self._index[name]
return location.open(name, mode)
except KeyError:
raise ResourceNotFoundException(name)
def location(self, name):
'''Get the location of a resource.
This method is useful for opening files referenced from a resource.
For example, an HTML file loaded as a resource might reference some
images. These images should be located relative to the HTML file, not
looked up individually in the loader's path.
:Parameters:
`name` : str
Filename of the resource to locate.
:rtype: `Location`
'''
try:
return self._index[name]
except KeyError:
raise ResourceNotFoundException(name)
def add_font(self, name):
'''Add a font resource to the application.
Fonts not installed on the system must be added to pyglet before they
can be used with `font.load`. Although the font is added with
its filename using this function, it is loaded by specifying its
family name. For example::
resource.add_font('action_man.ttf')
action_man = font.load('Action Man')
:Parameters:
`name` : str
Filename of the font resource to add.
'''
from pyglet import font
file = self.file(name)
font.add_file(file)
def _alloc_image(self, name):
file = self.file(name)
img = pyglet.image.load(name, file=file)
bin = self._get_texture_atlas_bin(img.width, img.height)
if bin is None:
return img.get_texture(True)
return bin.add(img)
def _get_texture_atlas_bin(self, width, height):
'''A heuristic for determining the atlas bin to use for a given image
size. Returns None if the image should not be placed in an atlas (too
big), otherwise the bin (a list of TextureAtlas).
'''
# Large images are not placed in an atlas
if width > 128 or height > 128:
return None
# Group images with small height separately to larger height (as the
# allocator can't stack within a single row).
bin_size = 1
if height > 32:
bin_size = 2
try:
bin = self._texture_atlas_bins[bin_size]
except KeyError:
bin = self._texture_atlas_bins[bin_size] = \
pyglet.image.atlas.TextureBin()
return bin
def image(self, name, flip_x=False, flip_y=False, rotate=0):
'''Load an image with optional transformation.
This is similar to `texture`, except the resulting image will be
packed into a `TextureBin` if it is an appropriate size for packing.
This is more efficient than loading images into separate textures.
:Parameters:
`name` : str
Filename of the image source to load.
`flip_x` : bool
If True, the returned image will be flipped horizontally.
`flip_y` : bool
If True, the returned image will be flipped vertically.
`rotate` : int
The returned image will be rotated clockwise by the given
number of degrees (a mulitple of 90).
:rtype: `Texture`
:return: A complete texture if the image is large, otherwise a
`TextureRegion` of a texture atlas.
'''
if name in self._cached_images:
identity = self._cached_images[name]
else:
identity = self._cached_images[name] = self._alloc_image(name)
if not rotate and not flip_x and not flip_y:
return identity
return identity.get_transform(flip_x, flip_y, rotate)
def animation(self, name, flip_x=False, flip_y=False, rotate=0):
'''Load an animation with optional transformation.
Animations loaded from the same source but with different
transformations will use the same textures.
:Parameters:
`name` : str
Filename of the animation source to load.
`flip_x` : bool
If True, the returned image will be flipped horizontally.
`flip_y` : bool
If True, the returned image will be flipped vertically.
`rotate` : int
The returned image will be rotated clockwise by the given
number of degrees (a mulitple of 90).
:rtype: `Animation`
'''
try:
identity = self._cached_animations[name]
except KeyError:
animation = pyglet.image.load_animation(name, self.file(name))
bin = self._get_texture_atlas_bin(animation.get_max_width(),
animation.get_max_height())
if bin:
animation.add_to_texture_bin(bin)
identity = self._cached_animations[name] = animation
if not rotate and not flip_x and not flip_y:
return identity
return identity.get_transform(flip_x, flip_y, rotate)
def get_cached_image_names(self):
'''Get a list of image filenames that have been cached.
This is useful for debugging and profiling only.
:rtype: list
:return: List of str
'''
return self._cached_images.keys()
def get_cached_animation_names(self):
'''Get a list of animation filenames that have been cached.
This is useful for debugging and profiling only.
:rtype: list
:return: List of str
'''
return self._cached_animations.keys()
def get_texture_bins(self):
'''Get a list of texture bins in use.
This is useful for debugging and profiling only.
:rtype: list
:return: List of `TextureBin`
'''
return self._texture_atlas_bins.values()
def media(self, name, streaming=True):
'''Load a sound or video resource.
The meaning of `streaming` is as for `media.load`. Compressed
sources cannot be streamed (that is, video and compressed audio
cannot be streamed from a ZIP archive).
:Parameters:
`name` : str
Filename of the media source to load.
`streaming` : bool
True if the source should be streamed from disk, False if
it should be entirely decoded into memory immediately.
:rtype: `media.Source`
'''
from pyglet import media
try:
location = self._index[name]
if isinstance(location, FileLocation):
# Don't open the file if it's streamed from disk -- AVbin
# needs to do it.
path = os.path.join(location.path, name)
return media.load(path, streaming=streaming)
else:
file = location.open(name)
return media.load(name, file=file, streaming=streaming)
except KeyError:
raise ResourceNotFoundException(name)
def texture(self, name):
'''Load a texture.
The named image will be loaded as a single OpenGL texture. If the
dimensions of the image are not powers of 2 a `TextureRegion` will
be returned.
:Parameters:
`name` : str
Filename of the image resource to load.
:rtype: `Texture`
'''
if name in self._cached_textures:
return self._cached_textures[name]
file = self.file(name)
texture = pyglet.image.load(name, file=file).get_texture()
self._cached_textures[name] = texture
return texture
def html(self, name):
'''Load an HTML document.
:Parameters:
`name` : str
Filename of the HTML resource to load.
:rtype: `FormattedDocument`
'''
file = self.file(name)
return pyglet.text.decode_html(file.read(), self.location(name))
def attributed(self, name):
'''Load an attributed text document.
See `pyglet.text.formats.attributed` for details on this format.
:Parameters:
`name` : str
Filename of the attribute text resource to load.
:rtype: `FormattedDocument`
'''
file = self.file(name)
return pyglet.text.load(name, file, 'text/vnd.pyglet-attributed')
def text(self, name):
'''Load a plain text document.
:Parameters:
`name` : str
Filename of the plain text resource to load.
:rtype: `UnformattedDocument`
'''
file = self.file(name)
return pyglet.text.load(name, file, 'text/plain')
def get_cached_texture_names(self):
'''Get the names of textures currently cached.
:rtype: list of str
'''
return self._cached_textures.keys()
#: Default resource search path.
#:
#: Locations in the search path are searched in order and are always
#: case-sensitive. After changing the path you must call `reindex`.
#:
#: See the module documentation for details on the path format.
#:
#: :type: list of str
path = []
class _DefaultLoader(Loader):
def _get_path(self):
return path
def _set_path(self, value):
global path
path = value
path = property(_get_path, _set_path)
_default_loader = _DefaultLoader()
reindex = _default_loader.reindex
file = _default_loader.file
location = _default_loader.location
add_font = _default_loader.add_font
image = _default_loader.image
animation = _default_loader.animation
get_cached_image_names = _default_loader.get_cached_image_names
get_cached_animation_names = _default_loader.get_cached_animation_names
get_texture_bins = _default_loader.get_texture_bins
media = _default_loader.media
texture = _default_loader.texture
html = _default_loader.html
attributed = _default_loader.attributed
text = _default_loader.text
get_cached_texture_names = _default_loader.get_cached_texture_names

568
pyglet/sprite.py Normal file
View file

@ -0,0 +1,568 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Display positioned, scaled and rotated images.
A sprite is an instance of an image displayed on-screen. Multiple sprites can
display the same image at different positions on the screen. Sprites can also
be scaled larger or smaller, rotated at any angle and drawn at a fractional
opacity.
The following complete example loads a ``"ball.png"`` image and creates a
sprite for that image. The sprite is then drawn in the window's
draw event handler::
import pyglet
ball_image = pyglet.image.load('ball.png')
ball = pyglet.sprite.Sprite(ball_image, x=50, y=50)
window = pyglet.window.Window()
@window.event
def on_draw():
ball.draw()
pyglet.app.run()
The sprite can be moved by modifying the ``x`` and ``y`` properties. Other
properties determine the sprite's rotation, scale and opacity.
The sprite's positioning, rotation and scaling all honor the original
image's anchor (anchor_x, anchor_y).
Drawing multiple sprites
========================
Sprites can be "batched" together and drawn at once more quickly than if each
of their ``draw`` methods were called individually. The following example
creates one hundred ball sprites and adds each of them to a `Batch`. The
entire batch of sprites is then drawn in one call::
batch = pyglet.graphics.Batch()
ball_sprites = []
for i in range(100):
x, y = i * 10, 50
ball_sprites.append(pyglet.sprite.Sprite(ball_image, x, y, batch=batch)
@window.event
def on_draw():
batch.draw()
Sprites can be freely modified in any way even after being added to a batch,
however a sprite can belong to at most one batch. See the documentation for
`pyglet.graphics` for more details on batched rendering, and grouping of
sprites within batches.
:since: pyglet 1.1
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: sprite.py 2120 2008-06-17 12:08:05Z Alex.Holkner $'
import math
import sys
from pyglet.gl import *
from pyglet import clock
from pyglet import event
from pyglet import graphics
from pyglet import image
_is_epydoc = hasattr(sys, 'is_epydoc') and sys.is_epydoc
class SpriteGroup(graphics.Group):
'''Shared sprite rendering group.
The group is automatically coallesced with other sprite groups sharing the
same parent group, texture and blend parameters.
'''
def __init__(self, texture, blend_src, blend_dest, parent=None):
'''Create a sprite group.
The group is created internally within `Sprite`; applications usually
do not need to explicitly create it.
:Parameters:
`texture` : `Texture`
The (top-level) texture containing the sprite image.
`blend_src` : int
OpenGL blend source mode; for example,
``GL_SRC_ALPHA``.
`blend_dest` : int
OpenGL blend destination mode; for example,
``GL_ONE_MINUS_SRC_ALPHA``.
`parent` : `Group`
Optional parent group.
'''
super(SpriteGroup, self).__init__(parent)
self.texture = texture
self.blend_src = blend_src
self.blend_dest = blend_dest
def set_state(self):
glEnable(self.texture.target)
glBindTexture(self.texture.target, self.texture.id)
glPushAttrib(GL_COLOR_BUFFER_BIT)
glEnable(GL_BLEND)
glBlendFunc(self.blend_src, self.blend_dest)
def unset_state(self):
glPopAttrib()
glDisable(self.texture.target)
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, self.texture)
def __eq__(self, other):
return (other.__class__ is self.__class__ and
self.parent is other.parent and
self.texture.target == other.texture.target and
self.texture.id == other.texture.id and
self.blend_src == other.blend_src and
self.blend_dest == other.blend_dest)
def __hash__(self):
return hash((id(self.parent),
self.texture.id, self.texture.target,
self.blend_src, self.blend_dest))
class Sprite(event.EventDispatcher):
'''Instance of an on-screen image.
See the module documentation for usage.
'''
_batch = None
_animation = None
_rotation = 0
_opacity = 255
_rgb = (255, 255, 255)
_scale = 1.0
_visible = True
_vertex_list = None
def __init__(self,
img, x=0, y=0,
blend_src=GL_SRC_ALPHA,
blend_dest=GL_ONE_MINUS_SRC_ALPHA,
batch=None,
group=None,
usage='dynamic'):
'''Create a sprite.
:Parameters:
`img` : `AbstractImage` or `Animation`
Image or animation to display.
`x` : int
X coordinate of the sprite.
`y` : int
Y coordinate of the sprite.
`blend_src` : int
OpenGL blend source mode. The default is suitable for
compositing sprites drawn from back-to-front.
`blend_dest` : int
OpenGL blend destination mode. The default is suitable for
compositing sprites drawn from back-to-front.
`batch` : `Batch`
Optional batch to add the sprite to.
`group` : `Group`
Optional parent group of the sprite.
`usage` : str
Vertex buffer object usage hint, one of ``"none"`` (default),
``"stream"``, ``"dynamic"`` or ``"static"``. Applies
only to vertex data.
'''
if batch is not None:
self._batch = batch
self._x = x
self._y = y
if isinstance(img, image.Animation):
self._animation = img
self._frame_index = 0
self._texture = img.frames[0].image.get_texture()
self._next_dt = img.frames[0].duration
if self._next_dt:
clock.schedule_once(self._animate, self._next_dt)
else:
self._texture = img.get_texture()
self._group = SpriteGroup(self._texture, blend_src, blend_dest, group)
self._usage = usage
self._create_vertex_list()
def __del__(self):
try:
if self._vertex_list is not None:
self._vertex_list.delete()
except:
pass
def delete(self):
'''Force immediate removal of the sprite from video memory.
This is often necessary when using batches, as the Python garbage
collector will not necessarily call the finalizer as soon as the
sprite is garbage.
'''
if self._animation:
clock.unschedule(self._animate)
self._vertex_list.delete()
self._vertex_list = None
self._texture = None
# Easy way to break circular reference, speeds up GC
self._group = None
def _animate(self, dt):
self._frame_index += 1
if self._frame_index >= len(self._animation.frames):
self._frame_index = 0
self.dispatch_event('on_animation_end')
if self._vertex_list is None:
return # Deleted in event handler.
frame = self._animation.frames[self._frame_index]
self._set_texture(frame.image.get_texture())
if frame.duration is not None:
duration = frame.duration - (self._next_dt - dt)
duration = min(max(0, duration), frame.duration)
clock.schedule_once(self._animate, duration)
self._next_dt = duration
else:
self.dispatch_event('on_animation_end')
def _set_batch(self, batch):
if self._batch == batch:
return
if batch is not None and self._batch is not None:
self._batch.migrate(self._vertex_list, GL_QUADS, self._group, batch)
self._batch = batch
else:
self._vertex_list.delete()
self._batch = batch
self._create_vertex_list()
def _get_batch(self):
return self._batch
batch = property(_get_batch, _set_batch,
doc='''Graphics batch.
The sprite can be migrated from one batch to another, or removed from its
batch (for individual drawing). Note that this can be an expensive
operation.
:type: `Batch`
''')
def _set_group(self, group):
if self._group.parent == group:
return
self._group = SpriteGroup(self._texture,
self._group.blend_src,
self._group.blend_dest,
group)
if self._batch is not None:
self._batch.migrate(self._vertex_list, GL_QUADS, self._group,
self._batch)
def _get_group(self):
return self._group.parent
group = property(_get_group, _set_group,
doc='''Parent graphics group.
The sprite can change its rendering group, however this can be an
expensive operation.
:type: `Group`
''')
def _get_image(self):
if self._animation:
return self._animation
return self._texture
def _set_image(self, img):
if self._animation is not None:
clock.unschedule(self._animate)
self._animation = None
if isinstance(img, image.Animation):
self._animation = img
self._frame_index = 0
self._set_texture(img.frames[0].image.get_texture())
self._next_dt = img.frames[0].duration
clock.schedule_once(self._animate, self._next_dt)
else:
self._set_texture(img.get_texture())
self._update_position()
image = property(_get_image, _set_image,
doc='''Image or animation to display.
:type: `AbstractImage` or `Animation`
''')
def _set_texture(self, texture):
if texture.id is not self._texture.id:
self._group = SpriteGroup(texture,
self._group.blend_src,
self._group.blend_dest,
self._group.parent)
if self._batch is None:
self._vertex_list.tex_coords[:] = texture.tex_coords
else:
self._vertex_list.delete()
self._texture = texture
self._create_vertex_list()
else:
self._vertex_list.tex_coords[:] = texture.tex_coords
self._texture = texture
def _create_vertex_list(self):
if self._batch is None:
self._vertex_list = graphics.vertex_list(4,
'v2i/%s' % self._usage,
'c4B', ('t3f', self._texture.tex_coords))
else:
self._vertex_list = self._batch.add(4, GL_QUADS, self._group,
'v2i/%s' % self._usage,
'c4B', ('t3f', self._texture.tex_coords))
self._update_position()
self._update_color()
def _update_position(self):
img = self._texture
if not self._visible:
self._vertex_list.vertices[:] = [0, 0, 0, 0, 0, 0, 0, 0]
elif self._rotation:
x1 = -img.anchor_x * self._scale
y1 = -img.anchor_y * self._scale
x2 = x1 + img.width * self._scale
y2 = y1 + img.height * self._scale
x = self._x
y = self._y
r = -math.radians(self._rotation)
cr = math.cos(r)
sr = math.sin(r)
ax = int(x1 * cr - y1 * sr + x)
ay = int(x1 * sr + y1 * cr + y)
bx = int(x2 * cr - y1 * sr + x)
by = int(x2 * sr + y1 * cr + y)
cx = int(x2 * cr - y2 * sr + x)
cy = int(x2 * sr + y2 * cr + y)
dx = int(x1 * cr - y2 * sr + x)
dy = int(x1 * sr + y2 * cr + y)
self._vertex_list.vertices[:] = [ax, ay, bx, by, cx, cy, dx, dy]
elif self._scale != 1.0:
x1 = int(self._x - img.anchor_x * self._scale)
y1 = int(self._y - img.anchor_y * self._scale)
x2 = int(x1 + img.width * self._scale)
y2 = int(y1 + img.height * self._scale)
self._vertex_list.vertices[:] = [x1, y1, x2, y1, x2, y2, x1, y2]
else:
x1 = int(self._x - img.anchor_x)
y1 = int(self._y - img.anchor_y)
x2 = x1 + img.width
y2 = y1 + img.height
self._vertex_list.vertices[:] = [x1, y1, x2, y1, x2, y2, x1, y2]
def _update_color(self):
r, g, b = self._rgb
self._vertex_list.colors[:] = [r, g, b, int(self._opacity)] * 4
def set_position(self, x, y):
'''Set the X and Y coordinates of the sprite simultaneously.
:Parameters:
`x` : int
X coordinate of the sprite.
`y` : int
Y coordinate of the sprite.
'''
self._x = x
self._y = y
self._update_position()
position = property(lambda self: (self._x, self._y),
lambda self, t: self.set_position(*t),
doc='''The (x, y) coordinates of the sprite.
:type: (int, int)
''')
def _set_x(self, x):
self._x = x
self._update_position()
x = property(lambda self: self._x, _set_x,
doc='''X coordinate of the sprite.
:type: int
''')
def _set_y(self, y):
self._y = y
self._update_position()
y = property(lambda self: self._y, _set_y,
doc='''Y coordinate of the sprite.
:type: int
''')
def _set_rotation(self, rotation):
self._rotation = rotation
self._update_position()
rotation = property(lambda self: self._rotation, _set_rotation,
doc='''Clockwise rotation of the sprite, in degrees.
The sprite image will be rotated about its image's (anchor_x, anchor_y)
position.
:type: float
''')
def _set_scale(self, scale):
self._scale = scale
self._update_position()
scale = property(lambda self: self._scale, _set_scale,
doc='''Scaling factor.
A scaling factor of 1 (the default) has no effect. A scale of 2 will draw
the sprite at twice the native size of its image.
:type: float
''')
width = property(lambda self: int(self._texture.width * self._scale),
doc='''Scaled width of the sprite.
Read-only. Invariant under rotation.
:type: int
''')
height = property(lambda self: int(self._texture.height * self._scale),
doc='''Scaled height of the sprite.
Read-only. Invariant under rotation.
:type: int
''')
def _set_opacity(self, opacity):
self._opacity = opacity
self._update_color()
opacity = property(lambda self: self._opacity, _set_opacity,
doc='''Blend opacity.
This property sets the alpha component of the colour of the sprite's
vertices. With the default blend mode (see the constructor), this
allows the sprite to be drawn with fractional opacity, blending with the
background.
An opacity of 255 (the default) has no effect. An opacity of 128 will
make the sprite appear translucent.
:type: int
''')
def _set_color(self, rgb):
self._rgb = map(int, rgb)
self._update_color()
color = property(lambda self: self._rgb, _set_color,
doc='''Blend color.
This property sets the color of the sprite's vertices. This allows the
sprite to be drawn with a color tint.
The color is specified as an RGB tuple of integers ``(red, green, blue)``.
Each color component must be in the range 0 (dark) to 255 (saturated).
:type: (int, int, int)
''')
def _set_visible(self, visible):
self._visible = visible
self._update_position()
visible = property(lambda self: self._visible, _set_visible,
'''True if the sprite will be drawn.
:type: bool
''')
def draw(self):
'''Draw the sprite at its current position.
See the module documentation for hints on drawing multiple sprites
efficiently.
'''
self._group.set_state_recursive()
self._vertex_list.draw(GL_QUADS)
self._group.unset_state_recursive()
if _is_epydoc:
def on_animation_end():
'''The sprite animation reached the final frame.
The event is triggered only if the sprite has an animation, not an
image. For looping animations, the event is triggered each time
the animation loops.
:event:
'''
Sprite.register_event_type('on_animation_end')

505
pyglet/text/__init__.py Normal file
View file

@ -0,0 +1,505 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id: $
'''Text formatting, layout and display.
This module provides classes for loading styled documents from text files,
HTML files and a pyglet-specific markup format. Documents can be styled with
multiple fonts, colours, styles, text sizes, margins, paragraph alignments,
and so on.
Using the layout classes, documents can be laid out on a single line or
word-wrapped to fit a rectangle. A layout can then be efficiently drawn in
a window or updated incrementally (for example, to support interactive text
editing).
The label classes provide a simple interface for the common case where an
application simply needs to display some text in a window.
A plain text label can be created with::
label = pyglet.text.Label('Hello, world',
font_name='Times New Roman',
font_size=36,
x=10, y=10)
Alternatively, a styled text label using HTML can be created with::
label = pyglet.text.HTMLLabel('<b>Hello</b>, <i>world</i>',
x=10, y=10)
Either label can then be drawn at any time with::
label.draw()
For details on the subset of HTML supported, see `pyglet.text.formats.html`.
Refer to the Programming Guide for advanced usage of the document and layout
classes, including interactive editing, embedding objects within documents and
creating scrollable layouts.
:since: pyglet 1.1
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import os.path
import pyglet
from pyglet.text import layout, document, caret
class DocumentDecodeException(Exception):
'''An error occured decoding document text.'''
pass
class DocumentDecoder(object):
'''Abstract document decoder.
'''
def decode(self, text, location=None):
'''Decode document text.
:Parameters:
`text` : str
Text to decode
`location` : `Location`
Location to use as base path for additional resources
referenced within the document (for example, HTML images).
:rtype: `AbstractDocument`
'''
raise NotImplementedError('abstract')
def get_decoder(filename, mimetype=None):
'''Get a document decoder for the given filename and MIME type.
If `mimetype` is omitted it is guessed from the filename extension.
The following MIME types are supported:
``text/plain``
Plain text
``text/html``
HTML 4 Transitional
``text/vnd.pyglet-attributed``
Attributed text; see `pyglet.text.formats.attributed`
`DocumentDecodeException` is raised if another MIME type is given.
:Parameters:
`filename` : str
Filename to guess the MIME type from. If a MIME type is given,
the filename is ignored.
`mimetype` : str
MIME type to lookup, or ``None`` to guess the type from the
filename.
:rtype: `DocumentDecoder`
'''
if mimetype is None:
_, ext = os.path.splitext(filename)
if ext.lower() in ('.htm', '.html', '.xhtml'):
mimetype = 'text/html'
else:
mimetype = 'text/plain'
if mimetype == 'text/plain':
from pyglet.text.formats import plaintext
return plaintext.PlainTextDecoder()
elif mimetype == 'text/html':
from pyglet.text.formats import html
return html.HTMLDecoder()
elif mimetype == 'text/vnd.pyglet-attributed':
from pyglet.text.formats import attributed
return attributed.AttributedTextDecoder()
else:
raise DocumentDecodeException('Unknown format "%s"' % mimetype)
def load(filename, file=None, mimetype=None):
'''Load a document from a file.
:Parameters:
`filename` : str
Filename of document to load.
`file` : file-like object
File object containing encoded data. If omitted, `filename` is
loaded from disk.
`mimetype` : str
MIME type of the document. If omitted, the filename extension is
used to guess a MIME type. See `get_decoder` for a list of
supported MIME types.
:rtype: `AbstractDocument`
'''
decoder = get_decoder(filename, mimetype)
if file is None:
file = open(filename)
location = pyglet.resource.FileLocation(os.path.dirname(filename))
return decoder.decode(file.read(), location)
def decode_html(text, location=None):
'''Create a document directly from some HTML formatted text.
:Parameters:
`text` : str
HTML data to decode.
`location` : str
Location giving the base path for additional resources
referenced from the document (e.g., images).
:rtype: `FormattedDocument`
'''
decoder = get_decoder(None, 'text/html')
return decoder.decode(text, location)
def decode_attributed(text):
'''Create a document directly from some attributed text.
See `pyglet.text.formats.attributed` for a description of attributed text.
:Parameters:
`text` : str
Attributed text to decode.
:rtype: `FormattedDocument`
'''
decoder = get_decoder(None, 'text/vnd.pyglet-attributed')
return decoder.decode(text)
def decode_text(text):
'''Create a document directly from some plain text.
:Parameters:
`text` : str
Plain text to initialise the document with.
:rtype: `UnformattedDocument`
'''
decoder = get_decoder(None, 'text/plain')
return decoder.decode(text)
class DocumentLabel(layout.TextLayout):
'''Base label class.
A label is a layout that exposes convenience methods for manipulating the
associated document.
'''
def __init__(self, document=None,
x=0, y=0, width=None, height=None,
anchor_x='left', anchor_y='baseline',
multiline=False, dpi=None, batch=None, group=None):
'''Create a label for a given document.
:Parameters:
`document` : `AbstractDocument`
Document to attach to the layout.
`x` : int
X coordinate of the label.
`y` : int
Y coordinate of the label.
`width` : int
Width of the label in pixels, or None
`height` : int
Height of the label in pixels, or None
`anchor_x` : str
Anchor point of the X coordinate: one of ``"left"``,
``"center"`` or ``"right"``.
`anchor_y` : str
Anchor point of the Y coordinate: one of ``"bottom"``,
``"baseline"``, ``"center"`` or ``"top"``.
`multiline` : bool
If True, the label will be word-wrapped and accept newline
characters. You must also set the width of the label.
`dpi` : float
Resolution of the fonts in this layout. Defaults to 96.
`batch` : `Batch`
Optional graphics batch to add the label to.
`group` : `Group`
Optional graphics group to use.
'''
super(DocumentLabel, self).__init__(document,
width=width, height=height,
multiline=multiline,
dpi=dpi, batch=batch, group=group)
self._x = x
self._y = y
self._anchor_x = anchor_x
self._anchor_y = anchor_y
self._update()
def _get_text(self):
return self.document.text
def _set_text(self, text):
self.document.text = text
text = property(_get_text, _set_text,
doc='''The text of the label.
:type: str
''')
def _get_color(self):
return self.document.get_style('color')
def _set_color(self, color):
self.document.set_style(0, len(self.document.text),
{'color': color})
color = property(_get_color, _set_color,
doc='''Text color.
Color is a 4-tuple of RGBA components, each in range [0, 255].
:type: (int, int, int, int)
''')
def _get_font_name(self):
return self.document.get_style('font_name')
def _set_font_name(self, font_name):
self.document.set_style(0, len(self.document.text),
{'font_name': font_name})
font_name = property(_get_font_name, _set_font_name,
doc='''Font family name.
The font name, as passed to `pyglet.font.load`. A list of names can
optionally be given: the first matching font will be used.
:type: str or list
''')
def _get_font_size(self):
return self.document.get_style('font_size')
def _set_font_size(self, font_size):
self.document.set_style(0, len(self.document.text),
{'font_size': font_size})
font_size = property(_get_font_size, _set_font_size,
doc='''Font size, in points.
:type: float
''')
def _get_bold(self):
return self.document.get_style('bold')
def _set_bold(self, bold):
self.document.set_style(0, len(self.document.text),
{'bold': bold})
bold = property(_get_bold, _set_bold,
doc='''Bold font style.
:type: bool
''')
def _get_italic(self):
return self.document.get_style('italic')
def _set_italic(self, italic):
self.document.set_style(0, len(self.document.text),
{'italic': italic})
italic = property(_get_italic, _set_italic,
doc='''Italic font style.
:type: bool
''')
def get_style(self, name):
'''Get a document style value by name.
If the document has more than one value of the named style,
`pyglet.text.document.STYLE_INDETERMINATE` is returned.
:Parameters:
`name` : str
Style name to query. See documentation for
`pyglet.text.layout` for known style names.
:rtype: object
'''
return self.document.get_style_range(name, 0, len(self.document.text))
def set_style(self, name, value):
'''Set a document style value by name over the whole document.
:Parameters:
`name` : str
Name of the style to set. See documentation for
`pyglet.text.layout` for known style names.
`value` : object
Value of the style.
'''
self.document.set_style(0, len(self.document.text), {name: value})
class Label(DocumentLabel):
'''Plain text label.
'''
def __init__(self, text='',
font_name=None, font_size=None, bold=False, italic=False,
color=(255, 255, 255, 255),
x=0, y=0, width=None, height=None,
anchor_x='left', anchor_y='baseline',
halign='left',
multiline=False, dpi=None, batch=None, group=None):
'''Create a plain text label.
:Parameters:
`text` : str
Text to display.
`font_name` : str or list
Font family name(s). If more than one name is given, the
first matching name is used.
`font_size` : float
Font size, in points.
`bold` : bool
Bold font style.
`italic` : bool
Italic font style.
`color` : (int, int, int, int)
Font colour, as RGBA components in range [0, 255].
`x` : int
X coordinate of the label.
`y` : int
Y coordinate of the label.
`width` : int
Width of the label in pixels, or None
`height` : int
Height of the label in pixels, or None
`anchor_x` : str
Anchor point of the X coordinate: one of ``"left"``,
``"center"`` or ``"right"``.
`anchor_y` : str
Anchor point of the Y coordinate: one of ``"bottom"``,
``"baseline"``, ``"center"`` or ``"top"``.
`halign` : str
Horizontal alignment of text on a line, only applies if
a width is supplied. One of ``"left"``, ``"center"``
or ``"right"``.
`multiline` : bool
If True, the label will be word-wrapped and accept newline
characters. You must also set the width of the label.
`dpi` : float
Resolution of the fonts in this layout. Defaults to 96.
`batch` : `Batch`
Optional graphics batch to add the label to.
`group` : `Group`
Optional graphics group to use.
'''
document = decode_text(text)
super(Label, self).__init__(document, x, y, width, height,
anchor_x, anchor_y,
multiline, dpi, batch, group)
self.document.set_style(0, len(self.document.text), {
'font_name': font_name,
'font_size': font_size,
'bold': bold,
'italic': italic,
'color': color,
'halign': halign,
})
class HTMLLabel(DocumentLabel):
'''HTML formatted text label.
A subset of HTML 4.01 is supported. See `pyglet.text.formats.html` for
details.
'''
def __init__(self, text='', location=None,
x=0, y=0, width=None, height=None,
anchor_x='left', anchor_y='baseline',
multiline=False, dpi=None, batch=None, group=None):
'''Create a label with an HTML string.
:Parameters:
`text` : str
HTML formatted text to display.
`location` : `Location`
Location object for loading images referred to in the
document. By default, the working directory is used.
`x` : int
X coordinate of the label.
`y` : int
Y coordinate of the label.
`width` : int
Width of the label in pixels, or None
`height` : int
Height of the label in pixels, or None
`anchor_x` : str
Anchor point of the X coordinate: one of ``"left"``,
``"center"`` or ``"right"``.
`anchor_y` : str
Anchor point of the Y coordinate: one of ``"bottom"``,
``"baseline"``, ``"center"`` or ``"top"``.
`multiline` : bool
If True, the label will be word-wrapped and render paragraph
and line breaks. You must also set the width of the label.
`dpi` : float
Resolution of the fonts in this layout. Defaults to 96.
`batch` : `Batch`
Optional graphics batch to add the label to.
`group` : `Group`
Optional graphics group to use.
'''
self._text = text
self._location = location
document = decode_html(text, location)
super(HTMLLabel, self).__init__(document, x, y, width, height,
anchor_x, anchor_y,
multiline, dpi, batch, group)
def _set_text(self, text):
self._text = text
self.document = decode_html(text, self._location)
def _get_text(self):
return self._text
text = property(_get_text, _set_text,
doc='''HTML formatted text of the label.
:type: str
''')

591
pyglet/text/caret.py Normal file
View file

@ -0,0 +1,591 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id:$
'''Provides keyboard and mouse editing procedures for text layout.
Example usage::
from pyglet import window
from pyglet.text import layout, caret
my_window = window.Window(...)
my_layout = layout.IncrementalTextLayout(...)
my_caret = caret.Caret(my_layout)
my_window.push_handlers(my_caret)
:since: pyglet 1.1
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import re
import time
from pyglet import clock
from pyglet import event
from pyglet.window import key
class Caret(object):
'''Visible text insertion marker for
`pyglet.text.layout.IncrementalTextLayout`.
The caret is drawn as a single vertical bar at the document `position`
on a text layout object. If `mark` is not None, it gives the unmoving
end of the current text selection. The visible text selection on the
layout is updated along with `mark` and `position`.
By default the layout's graphics batch is used, so the caret does not need
to be drawn explicitly. Even if a different graphics batch is supplied,
the caret will be correctly positioned and clipped within the layout.
Updates to the document (and so the layout) are automatically propogated
to the caret.
The caret object can be pushed onto a window event handler stack with
`Window.push_handlers`. The caret will respond correctly to keyboard,
text, mouse and activation events, including double- and triple-clicks.
If the text layout is being used alongside other graphical widgets, a
GUI toolkit will be needed to delegate keyboard and mouse events to the
appropriate widget. pyglet does not provide such a toolkit at this stage.
'''
_next_word_re = re.compile(r'(?<=\W)\w')
_previous_word_re = re.compile(r'(?<=\W)\w+\W*$')
_next_para_re = re.compile(r'\n', flags=re.DOTALL)
_previous_para_re = re.compile(r'\n', flags=re.DOTALL)
_position = 0
_active = True
_visible = True
_blink_visible = True
_click_count = 0
_click_time = 0
#: Blink period, in seconds.
PERIOD = 0.5
#: Pixels to scroll viewport per mouse scroll wheel movement. Defaults
#: to 12pt at 96dpi.
SCROLL_INCREMENT= 12 * 96 / 72
def __init__(self, layout, batch=None, color=(0, 0, 0)):
'''Create a caret for a layout.
By default the layout's batch is used, so the caret does not need to
be drawn explicitly.
:Parameters:
`layout` : `TextLayout`
Layout to control.
`batch` : `Batch`
Graphics batch to add vertices to.
`color` : (int, int, int)
RGB tuple with components in range [0, 255].
'''
from pyglet import gl
self._layout = layout
if batch is None:
batch = layout.batch
r, g, b = color
colors = (r, g, b, 255, r, g, b, 255)
self._list = batch.add(2, gl.GL_LINES, layout.background_group,
'v2f', ('c4B', colors))
self._ideal_x = None
self._ideal_line = None
self._next_attributes = {}
self.visible = True
layout.push_handlers(self)
def delete(self):
'''Remove the caret from its batch.
Also disconnects the caret from further layout events.
'''
self._list.delete()
self._layout.remove_handlers(self)
def _blink(self, dt):
if self.PERIOD:
self._blink_visible = not self._blink_visible
if self._visible and self._active and self._blink_visible:
alpha = 255
else:
alpha = 0
self._list.colors[3] = alpha
self._list.colors[7] = alpha
def _nudge(self):
self.visible = True
def _set_visible(self, visible):
self._visible = visible
clock.unschedule(self._blink)
if visible and self._active and self.PERIOD:
clock.schedule_interval(self._blink, self.PERIOD)
self._blink_visible = False # flipped immediately by next blink
self._blink(0)
def _get_visible(self):
return self._visible
visible = property(_get_visible, _set_visible,
doc='''Caret visibility.
The caret may be hidden despite this property due to the periodic blinking
or by `on_deactivate` if the event handler is attached to a window.
:type: bool
''')
def _set_color(self, color):
self._list.colors[:3] = color
self._list.colors[4:7] = color
def _get_color(self):
return self._list.colors[:3]
color = property(_get_color, _set_color,
doc='''Caret color.
The default caret color is ``[0, 0, 0]`` (black). Each RGB color
component is in the range 0 to 255.
:type: (int, int, int)
''')
def _set_position(self, index):
self._position = index
self._next_attributes.clear()
self._update()
def _get_position(self):
return self._position
position = property(_get_position, _set_position,
doc='''Position of caret within document.
:type: int
''')
_mark = None
def _set_mark(self, mark):
self._mark = mark
self._update(line=self._ideal_line)
if mark is None:
self._layout.set_selection(0, 0)
def _get_mark(self):
return self._mark
mark = property(_get_mark, _set_mark,
doc='''Position of immovable end of text selection within
document.
An interactive text selection is determined by its immovable end (the
caret's position when a mouse drag begins) and the caret's position, which
moves interactively by mouse and keyboard input.
This property is ``None`` when there is no selection.
:type: int
''')
def _set_line(self, line):
if self._ideal_x is None:
self._ideal_x, _ = \
self._layout.get_point_from_position(self._position)
self._position = \
self._layout.get_position_on_line(line, self._ideal_x)
self._update(line=line, update_ideal_x=False)
def _get_line(self):
if self._ideal_line is not None:
return self._ideal_line
else:
return self._layout.get_line_from_position(self._position)
line = property(_get_line, _set_line,
doc='''Index of line containing the caret's position.
When set, `position` is modified to place the caret on requested line
while maintaining the closest possible X offset.
:type: int
''')
def get_style(self, attribute):
'''Get the document's named style at the caret's current position.
If there is a text selection and the style varies over the selection,
`pyglet.text.document.STYLE_INDETERMINATE` is returned.
:Parameters:
`attribute` : str
Name of style attribute to retrieve. See
`pyglet.text.document` for a list of recognised attribute
names.
:rtype: object
'''
if self._mark is None or self._mark == self._position:
try:
return self._next_attributes[attribute]
except KeyError:
return self._layout.document.get_style(attribute,
self._position)
start = min(self._position, self._mark)
end = max(self._position, self._mark)
return self._layout.document.get_style_range(attribute, start, end)
def set_style(self, attributes):
'''Set the document style at the caret's current position.
If there is a text selection the style is modified immediately.
Otherwise, the next text that is entered before the position is
modified will take on the given style.
:Parameters:
`attributes` : dict
Dict mapping attribute names to style values. See
`pyglet.text.document` for a list of recognised attribute
names.
'''
if self._mark is None or self._mark == self._position:
self._next_attributes.update(attributes)
return
start = min(self._position, self._mark)
end = max(self._position, self._mark)
self._layout.document.set_style(start, end, attributes)
def _delete_selection(self):
start = min(self._mark, self._position)
end = max(self._mark, self._position)
self._position = start
self._mark = None
self._layout.document.delete_text(start, end)
self._layout.set_selection(0, 0)
def move_to_point(self, x, y):
'''Move the caret close to the given window coordinate.
The `mark` will be reset to ``None``.
:Parameters:
`x` : int
X coordinate.
`y` : int
Y coordinate.
'''
line = self._layout.get_line_from_point(x, y)
self._mark = None
self._layout.set_selection(0, 0)
self._position = self._layout.get_position_on_line(line, x)
self._update(line=line)
self._next_attributes.clear()
def select_to_point(self, x, y):
'''Move the caret close to the given window coordinate while
maintaining the `mark`.
:Parameters:
`x` : int
X coordinate.
`y` : int
Y coordinate.
'''
line = self._layout.get_line_from_point(x, y)
self._position = self._layout.get_position_on_line(line, x)
self._update(line=line)
self._next_attributes.clear()
def select_word(self, x, y):
'''Select the word at the given window coordinate.
:Parameters:
`x` : int
X coordinate.
`y` : int
Y coordinate.
'''
line = self._layout.get_line_from_point(x, y)
p = self._layout.get_position_on_line(line, x)
m1 = self._previous_word_re.search(self._layout.document.text,
0, p+1)
if not m1:
m1 = 0
else:
m1 = m1.start()
self.mark = m1
m2 = self._next_word_re.search(self._layout.document.text, p)
if not m2:
m2 = len(self._layout.document.text)
else:
m2 = m2.start()
self._position = m2
self._update(line=line)
self._next_attributes.clear()
def select_paragraph(self, x, y):
'''Select the paragraph at the given window coordinate.
:Parameters:
`x` : int
X coordinate.
`y` : int
Y coordinate.
'''
line = self._layout.get_line_from_point(x, y)
p = self._layout.get_position_on_line(line, x)
self.mark = self._layout.document.get_paragraph_start(p)
self._position = self._layout.document.get_paragraph_end(p)
self._update(line=line)
self._next_attributes.clear()
def _update(self, line=None, update_ideal_x=True):
if line is None:
line = self._layout.get_line_from_position(self._position)
self._ideal_line = None
else:
self._ideal_line = line
x, y = self._layout.get_point_from_position(self._position, line)
if update_ideal_x:
self._ideal_x = x
x -= self._layout.top_group.translate_x
y -= self._layout.top_group.translate_y
font = self._layout.document.get_font(max(0, self._position - 1))
self._list.vertices[:] = [x, y + font.descent, x, y + font.ascent]
if self._mark is not None:
self._layout.set_selection(min(self._position, self._mark),
max(self._position, self._mark))
self._layout.ensure_line_visible(line)
self._layout.ensure_x_visible(x)
def on_layout_update(self):
if self.position > len(self._layout.document.text):
self.position = len(self._layout.document.text)
self._update()
def on_text(self, text):
'''Handler for the `pyglet.window.Window.on_text` event.
Caret keyboard handlers assume the layout always has keyboard focus.
GUI toolkits should filter keyboard and text events by widget focus
before invoking this handler.
'''
if self._mark is not None:
self._delete_selection()
text = text.replace('\r', '\n')
pos = self._position
self._position += len(text)
self._layout.document.insert_text(pos, text, self._next_attributes)
self._nudge()
return event.EVENT_HANDLED
def on_text_motion(self, motion, select=False):
'''Handler for the `pyglet.window.Window.on_text_motion` event.
Caret keyboard handlers assume the layout always has keyboard focus.
GUI toolkits should filter keyboard and text events by widget focus
before invoking this handler.
'''
if motion == key.MOTION_BACKSPACE:
if self.mark is not None:
self._delete_selection()
elif self._position > 0:
self._position -= 1
self._layout.document.delete_text(
self._position, self._position + 1)
elif motion == key.MOTION_DELETE:
if self.mark is not None:
self._delete_selection()
elif self._position < len(self._layout.document.text):
self._layout.document.delete_text(
self._position, self._position + 1)
elif self._mark is not None and not select:
self._mark = None
self._layout.set_selection(0, 0)
if motion == key.MOTION_LEFT:
self.position = max(0, self.position - 1)
elif motion == key.MOTION_RIGHT:
self.position = min(len(self._layout.document.text),
self.position + 1)
elif motion == key.MOTION_UP:
self.line = max(0, self.line - 1)
elif motion == key.MOTION_DOWN:
line = self.line
if line < self._layout.get_line_count() - 1:
self.line = line + 1
elif motion == key.MOTION_BEGINNING_OF_LINE:
self.position = self._layout.get_position_from_line(self.line)
elif motion == key.MOTION_END_OF_LINE:
line = self.line
if line < self._layout.get_line_count() - 1:
self._position = \
self._layout.get_position_from_line(line + 1) - 1
self._update(line)
else:
self.position = len(self._layout.document.text)
elif motion == key.MOTION_BEGINNING_OF_FILE:
self.position = 0
elif motion == key.MOTION_END_OF_FILE:
self.position = len(self._layout.document.text)
elif motion == key.MOTION_NEXT_WORD:
pos = self._position + 1
m = self._next_word_re.search(self._layout.document.text, pos)
if not m:
self.position = len(self._layout.document.text)
else:
self.position = m.start()
elif motion == key.MOTION_PREVIOUS_WORD:
pos = self._position
m = self._previous_word_re.search(self._layout.document.text,
0, pos)
if not m:
self.position = 0
else:
self.position = m.start()
self._next_attributes.clear()
self._nudge()
return event.EVENT_HANDLED
def on_text_motion_select(self, motion):
'''Handler for the `pyglet.window.Window.on_text_motion_select` event.
Caret keyboard handlers assume the layout always has keyboard focus.
GUI toolkits should filter keyboard and text events by widget focus
before invoking this handler.
'''
if self.mark is None:
self.mark = self.position
self.on_text_motion(motion, True)
return event.EVENT_HANDLED
def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
'''Handler for the `pyglet.window.Window.on_mouse_scroll` event.
Mouse handlers do not check the bounds of the coordinates: GUI
toolkits should filter events that do not intersect the layout
before invoking this handler.
The layout viewport is scrolled by `SCROLL_INCREMENT` pixels per
"click".
'''
self._layout.view_x -= scroll_x * self.SCROLL_INCREMENT
self._layout.view_y += scroll_y * self.SCROLL_INCREMENT
return event.EVENT_HANDLED
def on_mouse_press(self, x, y, button, modifiers):
'''Handler for the `pyglet.window.Window.on_mouse_press` event.
Mouse handlers do not check the bounds of the coordinates: GUI
toolkits should filter events that do not intersect the layout
before invoking this handler.
This handler keeps track of the number of mouse presses within
a short span of time and uses this to reconstruct double- and
triple-click events for selecting words and paragraphs. This
technique is not suitable when a GUI toolkit is in use, as the active
widget must also be tracked. Do not use this mouse handler if
a GUI toolkit is being used.
'''
t = time.time()
if t - self._click_time < 0.25:
self._click_count += 1
else:
self._click_count = 1
self._click_time = time.time()
if self._click_count == 1:
self.move_to_point(x, y)
elif self._click_count == 2:
self.select_word(x, y)
elif self._click_count == 3:
self.select_paragraph(x, y)
self._click_count = 0
self._nudge()
return event.EVENT_HANDLED
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
'''Handler for the `pyglet.window.Window.on_mouse_drag` event.
Mouse handlers do not check the bounds of the coordinates: GUI
toolkits should filter events that do not intersect the layout
before invoking this handler.
'''
if self.mark is None:
self.mark = self.position
self.select_to_point(x, y)
self._nudge()
return event.EVENT_HANDLED
def on_activate(self):
'''Handler for the `pyglet.window.Window.on_activate` event.
The caret is hidden when the window is not active.
'''
self._active = True
self.visible = self.visible
return event.EVENT_HANDLED
def on_deactivate(self):
'''Handler for the `pyglet.window.Window.on_deactivate` event.
The caret is hidden when the window is not active.
'''
self._active = False
self.visible = self.visible
return event.EVENT_HANDLED

731
pyglet/text/document.py Normal file
View file

@ -0,0 +1,731 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
# $Id:$
'''Formatted and unformatted document interfaces used by text layout.
Abstract representation
=======================
Styled text in pyglet is represented by one of the `AbstractDocument` classes,
which manage the state representation of text and style independently of how
it is loaded or rendered.
A document consists of the document text (a Unicode string) and a set of
named style ranges. For example, consider the following (artificial)
example::
0 5 10 15 20
The cat sat on the mat.
+++++++ +++++++ "bold"
++++++ "italic"
If this example were to be rendered, "The cat" and "the mat" would be in bold,
and "on the" in italics. Note that the second "the" is both bold and italic.
The document styles recorded for this example would be ``"bold"`` over ranges
(0-7, 15-22) and ``"italic"`` over range (12-18). Overlapping styles are
permitted; unlike HTML and other structured markup, the ranges need not be
nested.
The document has no knowledge of the semantics of ``"bold"`` or ``"italic"``,
it stores only the style names. The pyglet layout classes give meaning to
these style names in the way they are rendered; but you are also free to
invent your own style names (which will be ignored by the layout classes).
This can be useful to tag areas of interest in a document, or maintain
references back to the source material.
As well as text, the document can contain arbitrary elements represented by
`InlineElement`. An inline element behaves like a single character in the
documented, but can be rendered by the application.
Paragraph breaks
================
Paragraph breaks are marked with a "newline" character (U+0010). The Unicode
paragraph break (U+2029) can also be used.
Line breaks (U+2028) can be used to force a line break within a paragraph.
See Unicode recommendation UTR #13 for more information:
http://unicode.org/reports/tr13/tr13-5.html.
Document classes
================
Any class implementing `AbstractDocument` provides a an interface to a
document model as described above. In theory a structured document such as
HTML or XML could export this model, though the classes provided by pyglet
implement only unstructured documents.
The `UnformattedDocument` class assumes any styles set are set over the entire
document. So, regardless of the range specified when setting a ``"bold"``
style attribute, for example, the entire document will receive that style.
The `FormattedDocument` class implements the document model directly, using
the `RunList` class to represent style runs efficiently.
Style attributes
================
The following character style attribute names are recognised by pyglet:
``font_name``
Font family name, as given to `pyglet.font.load`.
``font_size``
Font size, in points.
``bold``
Boolean.
``italic``
Boolean.
``underline``
4-tuple of ints in range (0, 255) giving RGBA underline color, or None
(default) for no underline.
``kerning``
Additional space to insert between glyphs, in points. Defaults to 0.
``baseline``
Offset of glyph baseline from line baseline, in points. Positive values
give a superscript, negative values give a subscript. Defaults to 0.
``color``
4-tuple of ints in range (0, 255) giving RGBA text color
``background_color``
4-tuple of ints in range (0, 255) giving RGBA text background color; or
``None`` for no background fill.
The following paragraph style attribute names are recognised by pyglet. Note
that paragraph styles are handled no differently from character styles by the
document: it is the application's responsibility to set the style over an
entire paragraph, otherwise results are undefined.
``align``
``left`` (default), ``center`` or ``right``.
``indent``
Additional horizontal space to insert before the first
``leading``
Additional space to insert between consecutive lines within a paragraph,
in points. Defaults to 0.
``line_spacing``
Distance between consecutive baselines in a paragraph, in points.
Defaults to ``None``, which automatically calculates the tightest line
spacing for each line based on the font ascent and descent.
``margin_left``
Left paragraph margin, in pixels.
``margin_right``
Right paragraph margin, in pixels.
``margin_top``
Margin above paragraph, in pixels.
``margin_bottom``
Margin below paragraph, in pixels. Adjacent margins do not collapse.
``tab_stops``
List of horizontal tab stops, in pixels, measured from the left edge of
the text layout. Defaults to the empty list. When the tab stops
are exhausted, they implicitly continue at 50 pixel intervals.
``wrap``
Boolean. If True (the default), text wraps within the width of the layout.
Other attributes can be used to store additional style information within the
document; it will be ignored by the built-in text classes.
All style attributes (including those not present in a document) default to
``None`` (including the so-called "boolean" styles listed above). The meaning
of a ``None`` style is style- and application-dependent.
:since: pyglet 1.1
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import re
import sys
from pyglet import event
from pyglet.text import runlist
_is_epydoc = hasattr(sys, 'is_epydoc') and sys.is_epydoc
#: The style attribute takes on multiple values in the document.
STYLE_INDETERMINATE = 'indeterminate'
class InlineElement(object):
'''Arbitrary inline element positioned within a formatted document.
Elements behave like a single glyph in the document. They are
measured by their horizontal advance, ascent above the baseline, and
descent below the baseline.
The pyglet layout classes reserve space in the layout for elements and
call the element's methods to ensure they are rendered at the
appropriate position.
If the size of a element (any of the `advance`, `ascent`, or `descent`
instance variables) is modified it is the application's responsibility to
trigger a reflow of the appropriate area in the affected layouts. This
can be done by forcing a style change over the element's position.
:Ivariables:
`ascent` : int
Ascent of the element above the baseline, in pixels.
`descent` : int
Descent of the element below the baseline, in pixels.
Typically negative.
`advance` : int
Width of the element, in pixels.
'''
def __init__(self, ascent, descent, advance):
self.ascent = ascent
self.descent = descent
self.advance = advance
self._position = None
position = property(lambda self: self._position,
doc='''Position of the element within the
document. Read-only.
:type: int
''')
def place(self, layout, x, y):
'''Construct an instance of the element at the given coordinates.
Called when the element's position within a layout changes, either
due to the initial condition, changes in the document or changes in
the layout size.
It is the responsibility of the element to clip itself against
the layout boundaries, and position itself appropriately with respect
to the layout's position and viewport offset.
The `TextLayout.top_state` graphics state implements this transform
and clipping into window space.
:Parameters:
`layout` : `pyglet.text.layout.TextLayout`
The layout the element moved within.
`x` : int
Position of the left edge of the element, relative
to the left edge of the document, in pixels.
`y` : int
Position of the baseline, relative to the top edge of the
document, in pixels. Note that this is typically negative.
'''
raise NotImplementedError('abstract')
def remove(self, layout):
'''Remove this element from a layout.
The couterpart of `place`; called when the element is no longer
visible in the given layout.
:Parameters:
`layout` : `pyglet.text.layout.TextLayout`
The layout the element was removed from.
'''
raise NotImplementedError('abstract')
class AbstractDocument(event.EventDispatcher):
'''Abstract document interface used by all `pyglet.text` classes.
This class can be overridden to interface pyglet with a third-party
document format. It may be easier to implement the document format in
terms of one of the supplied concrete classes `FormattedDocument` or
`UnformattedDocument`.
'''
_previous_paragraph_re = re.compile(u'\n[^\n\u2029]*$')
_next_paragraph_re = re.compile(u'[\n\u2029]')
def __init__(self, text=''):
super(AbstractDocument, self).__init__()
self._text = ''
self._elements = []
if text:
self.insert_text(0, text)
def _get_text(self):
return self._text
def _set_text(self, text):
if text == self._text:
return
self.delete_text(0, len(self._text))
self.insert_text(0, text)
text = property(_get_text, _set_text,
doc='''Document text.
For efficient incremental updates, use the `insert_text` and
`delete_text` methods instead of replacing this property.
:type: str
''')
def get_paragraph_start(self, pos):
'''Get the starting position of a paragraph.
:Parameters:
`pos` : int
Character position within paragraph.
:rtype: int
'''
# Tricky special case where the $ in pattern matches before the \n at
# the end of the string instead of the end of the string.
if (self._text[:pos + 1].endswith('\n') or
self._text[:pos + 1].endswith(u'\u2029')):
return pos
m = self._previous_paragraph_re.search(self._text, 0, pos + 1)
if not m:
return 0
return m.start() + 1
def get_paragraph_end(self, pos):
'''Get the end position of a paragraph.
:Parameters:
`pos` : int
Character position within paragraph.
:rtype: int
'''
m = self._next_paragraph_re.search(self._text, pos)
if not m:
return len(self._text)
return m.start() + 1
def get_style_runs(self, attribute):
'''Get a style iterator over the given style attribute.
:Parameters:
`attribute` : str
Name of style attribute to query.
:rtype: `AbstractRunIterator`
'''
raise NotImplementedError('abstract')
def get_style(self, attribute, position=0):
'''Get an attribute style at the given position.
:Parameters:
`attribute` : str
Name of style attribute to query.
`position` : int
Character position of document to query.
:return: The style set for the attribute at the given position.
'''
raise NotImplementedError('abstract')
def get_style_range(self, attribute, start, end):
'''Get an attribute style over the given range.
If the style varies over the range, `STYLE_INDETERMINATE` is returned.
:Parameters:
`attribute` : str
Name of style attribute to query.
`start` : int
Starting character position.
`end` : int
Ending character position (exclusive).
:return: The style set for the attribute over the given range, or
`STYLE_INDETERMINATE` if more than one value is set.
'''
iter = self.get_style_runs(attribute)
_, value_end, value = iter.ranges(start, end).next()
if value_end < end:
return STYLE_INDETERMINATE
else:
return value
def get_font_runs(self, dpi=None):
'''Get a style iterator over the `pyglet.font.Font` instances used in
the document.
The font instances are created on-demand by inspection of the
``font_name``, ``font_size``, ``bold`` and ``italic`` style
attributes.
:Parameters:
`dpi` : float
Optional resolution to construct fonts at. See
`pyglet.font.load`.
:rtype: `AbstractRunIterator`
'''
raise NotImplementedError('abstract')
def get_font(self, position, dpi=None):
'''Get the font instance used at the given position.
:see: `get_font_runs`
:Parameters:
`position` : int
Character position of document to query.
`dpi` : float
Optional resolution to construct fonts at. See
`pyglet.font.load`.
:rtype: `pyglet.font.Font`
:return: The font at the given position.
'''
raise NotImplementedError('abstract')
def insert_text(self, start, text, attributes=None):
'''Insert text into the document.
:Parameters:
`start` : int
Character insertion point within document.
`text` : str
Text to insert.
`attributes` : dict
Optional dictionary giving named style attributes of the
inserted text.
'''
self._insert_text(start, text, attributes)
self.dispatch_event('on_insert_text', start, text)
def _insert_text(self, start, text, attributes):
self._text = ''.join((self._text[:start], text, self._text[start:]))
len_text = len(text)
for element in self._elements:
if element._position >= start:
element._position += len_text
def delete_text(self, start, end):
'''Delete text from the document.
:Parameters:
`start` : int
Starting character position to delete from.
`end` : int
Ending character position to delete to (exclusive).
'''
self._delete_text(start, end)
self.dispatch_event('on_delete_text', start, end)
def _delete_text(self, start, end):
for element in list(self._elements):
if start <= element.position < end:
self._elements.remove(element)
self._text = self._text[:start] + self._text[end:]
def insert_element(self, position, element, attributes=None):
'''Insert a element into the document.
See the `InlineElement` class documentation for details of
usage.
:Parameters:
`position` : int
Character insertion point within document.
`element` : `InlineElement`
Element to insert.
`attributes` : dict
Optional dictionary giving named style attributes of the
inserted text.
'''
assert element._position is None, \
'Element is already in a document.'
self.insert_text(position, '\0', attributes)
element._position = position
self._elements.append(element)
self._elements.sort(key=lambda d:d.position)
def get_element(self, position):
'''Get the element at a specified position.
:Parameters:
`position` : int
Position in the document of the element.
:rtype: `InlineElement`
'''
for element in self._elements:
if element._position == position:
return element
raise RuntimeError('No element at position %d' % position)
def set_style(self, start, end, attributes):
'''Set text style of some or all of the document.
:Parameters:
`start` : int
Starting character position.
`end` : int
Ending character position (exclusive).
`attributes` : dict
Dictionary giving named style attributes of the text.
'''
self._set_style(start, end, attributes)
self.dispatch_event('on_style_text', start, end, attributes)
def _set_style(self, start, end, attributes):
raise NotImplementedError('abstract')
def set_paragraph_style(self, start, end, attributes):
'''Set the style for a range of paragraphs.
This is a convenience method for `set_style` that aligns the
character range to the enclosing paragraph(s).
:Parameters:
`start` : int
Starting character position.
`end` : int
Ending character position (exclusive).
`attributes` : dict
Dictionary giving named style attributes of the paragraphs.
'''
start = self.get_paragraph_start(start)
end = self.get_paragraph_end(end)
self._set_style(start, end, attributes)
self.dispatch_event('on_style_text', start, end, attributes)
if _is_epydoc:
def on_insert_text(start, text):
'''Text was inserted into the document.
:Parameters:
`start` : int
Character insertion point within document.
`text` : str
The text that was inserted.
:event:
'''
def on_delete_text(start, end):
'''Text was deleted from the document.
:Parameters:
`start` : int
Starting character position of deleted text.
`end` : int
Ending character position of deleted text (exclusive).
:event:
'''
def on_style_text(start, end, attributes):
'''Text character style was modified.
:Parameters:
`start` : int
Starting character position of modified text.
`end` : int
Ending character position of modified text (exclusive).
`attributes` : dict
Dictionary giving updated named style attributes of the
text.
:event:
'''
AbstractDocument.register_event_type('on_insert_text')
AbstractDocument.register_event_type('on_delete_text')
AbstractDocument.register_event_type('on_style_text')
class UnformattedDocument(AbstractDocument):
'''A document having uniform style over all text.
Changes to the style of text within the document affects the entire
document. For convenience, the ``position`` parameters of the style
methods may therefore be omitted.
'''
def __init__(self, text=''):
super(UnformattedDocument, self).__init__(text)
self.styles = {}
def get_style_runs(self, attribute):
value = self.styles.get(attribute)
return runlist.ConstRunIterator(len(self.text), value)
def get_style(self, attribute, position=None):
return self.styles.get(attribute)
def set_style(self, start, end, attributes):
return super(UnformattedDocument, self).set_style(
0, len(self.text), attributes)
def _set_style(self, start, end, attributes):
self.styles.update(attributes)
def set_paragraph_style(self, start, end, attributes):
return super(UnformattedDocument, self).set_paragraph_style(
0, len(self.text), attributes)
def get_font_runs(self, dpi=None):
ft = self.get_font(dpi=dpi)
return runlist.ConstRunIterator(len(self.text), ft)
def get_font(self, position=None, dpi=None):
from pyglet import font
font_name = self.styles.get('font_name')
font_size = self.styles.get('font_size')
bold = self.styles.get('bold', False)
italic = self.styles.get('italic', False)
return font.load(font_name, font_size,
bold=bool(bold), italic=bool(italic), dpi=dpi)
def get_element_runs(self):
return runlist.ConstRunIterator(len(self._text), None)
class FormattedDocument(AbstractDocument):
'''Simple implementation of a document that maintains text formatting.
Changes to text style are applied according to the description in
`AbstractDocument`. All styles default to ``None``.
'''
def __init__(self, text=''):
self._style_runs = {}
super(FormattedDocument, self).__init__(text)
def get_style_runs(self, attribute):
try:
return self._style_runs[attribute].get_run_iterator()
except KeyError:
return _no_style_range_iterator
def get_style(self, attribute, position=0):
try:
return self._style_runs[attribute][position]
except KeyError:
return None
def _set_style(self, start, end, attributes):
for attribute, value in attributes.items():
try:
runs = self._style_runs[attribute]
except KeyError:
runs = self._style_runs[attribute] = runlist.RunList(0, None)
runs.insert(0, len(self._text))
runs.set_run(start, end, value)
def get_font_runs(self, dpi=None):
return _FontStyleRunsRangeIterator(
self.get_style_runs('font_name'),
self.get_style_runs('font_size'),
self.get_style_runs('bold'),
self.get_style_runs('italic'),
dpi)
def get_font(self, position, dpi=None):
iter = self.get_font_runs(dpi)
return iter[position]
def get_element_runs(self):
return _ElementIterator(self._elements, len(self._text))
def _insert_text(self, start, text, attributes):
super(FormattedDocument, self)._insert_text(start, text, attributes)
len_text = len(text)
for runs in self._style_runs.values():
runs.insert(start, len_text)
if attributes is not None:
for attribute, value in attributes.items():
try:
runs = self._style_runs[attribute]
except KeyError:
runs = self._style_runs[attribute] = \
runlist.RunList(0, None)
runs.insert(0, len(self.text))
runs.set_run(start, start + len_text, value)
def _delete_text(self, start, end):
super(FormattedDocument, self)._delete_text(start, end)
for runs in self._style_runs.values():
runs.delete(start, end)
def _iter_elements(elements, length):
last = 0
for element in elements:
p = element.position
yield last, p, None
yield p, p + 1, element
last = p + 1
yield last, length, None
class _ElementIterator(runlist.RunIterator):
def __init__(self, elements, length):
self.next = _iter_elements(elements, length).next
self.start, self.end, self.value = self.next()
class _FontStyleRunsRangeIterator(object):
# XXX subclass runlist
def __init__(self, font_names, font_sizes, bolds, italics, dpi):
self.zip_iter = runlist.ZipRunIterator(
(font_names, font_sizes, bolds, italics))
self.dpi = dpi
def ranges(self, start, end):
from pyglet import font
for start, end, styles in self.zip_iter.ranges(start, end):
font_name, font_size, bold, italic = styles
ft = font.load(font_name, font_size,
bold=bool(bold), italic=bool(italic),
dpi=self.dpi)
yield start, end, ft
def __getitem__(self, index):
from pyglet import font
font_name, font_size, bold, italic = self.zip_iter[index]
return font.load(font_name, font_size,
bold=bool(bold), italic=bool(italic),
dpi=self.dpi)
class _NoStyleRangeIterator(object):
# XXX subclass runlist
def ranges(self, start, end):
yield start, end, None
def __getitem__(self, index):
return None
_no_style_range_iterator = _NoStyleRangeIterator()

View file

@ -0,0 +1,40 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Document formats.
:since: pyglet 1.1
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: __init__.py 1848 2008-03-01 04:21:43Z Alex.Holkner $'

View file

@ -0,0 +1,139 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Extensible attributed text format for representing pyglet formatted
documents.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import operator
import parser
import re
import symbol
import token
import pyglet
_pattern = re.compile(r'''
(?P<escape_hex>\{\#x(?P<escape_hex_val>[0-9a-fA-F]+)\})
| (?P<escape_dec>\{\#(?P<escape_dec_val>[0-9]+)\})
| (?P<escape_lbrace>\{\{)
| (?P<escape_rbrace>\}\})
| (?P<attr>\{
(?P<attr_name>[^ \{\}]+)\s+
(?P<attr_val>[^\}]+)\})
| (?P<nl_hard1>\n(?=[ \t]))
| (?P<nl_hard2>\{\}\n)
| (?P<nl_soft>\n(?=\S))
| (?P<nl_para>\n\n+)
| (?P<text>[^\{\}\n]+)
''', re.VERBOSE | re.DOTALL)
class AttributedTextDecoder(pyglet.text.DocumentDecoder):
def decode(self, text, location=None):
self.doc = pyglet.text.document.FormattedDocument()
self.length = 0
self.attributes = {}
next_trailing_space = True
trailing_newline = True
for m in _pattern.finditer(text):
group = m.lastgroup
trailing_space = True
if group == 'text':
t = m.group('text')
self.append(t)
trailing_space = t.endswith(' ')
trailing_newline = False
elif group == 'nl_soft':
if not next_trailing_space:
self.append(' ')
trailing_newline = False
elif group in ('nl_hard1', 'nl_hard2'):
self.append('\n')
trailing_newline = True
elif group == 'nl_para':
self.append(m.group('nl_para'))
trailing_newline = True
elif group == 'attr':
try:
ast = parser.expr(m.group('attr_val'))
if self.safe(ast):
val = eval(ast.compile())
else:
val = None
except (parser.ParserError, SyntaxError):
val = None
name = m.group('attr_name')
if name[0] == '.':
if trailing_newline:
self.attributes[name[1:]] = val
else:
self.doc.set_paragraph_style(self.length, self.length,
{name[1:]: val})
else:
self.attributes[name] = val
elif group == 'escape_dec':
self.append(unichr(int(m.group('escape_dec_val'))))
elif group == 'escape_hex':
self.append(unichr(int(m.group('escape_hex_val'), 16)))
elif group == 'escape_lbrace':
self.append('{')
elif group == 'escape_rbrace':
self.append('}')
next_trailing_space = trailing_space
return self.doc
def append(self, text):
self.doc.insert_text(self.length, text, self.attributes)
self.length += len(text)
self.attributes.clear()
_safe_names = ('True', 'False', 'None')
def safe(self, ast):
tree = ast.totuple()
return self.safe_node(tree)
def safe_node(self, node):
if token.ISNONTERMINAL(node[0]):
return reduce(operator.and_, map(self.safe_node, node[1:]))
elif node[0] == token.NAME:
return node[1] in self._safe_names
else:
return True

364
pyglet/text/formats/html.py Normal file
View file

@ -0,0 +1,364 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Decode HTML into attributed text.
A subset of HTML 4.01 Transitional is implemented. The following elements are
supported fully::
B BLOCKQUOTE BR CENTER CODE DD DIR DL EM FONT H1 H2 H3 H4 H5 H6 I IMG KBD
LI MENU OL P PRE Q SAMP STRONG SUB SUP TT U UL VAR
The mark (bullet or number) of a list item is separated from the body of the
list item with a tab, as the pyglet document model does not allow
out-of-stream text. This means lists display as expected, but behave a little
oddly if edited.
No CSS styling is supported.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import HTMLParser
import htmlentitydefs
import os
import re
import pyglet
from pyglet.text.formats import structured
def _hex_color(val):
return [(val >> 16) & 0xff, (val >> 8) & 0xff, val & 0xff, 255]
_color_names = {
'black': _hex_color(0x000000),
'silver': _hex_color(0xc0c0c0),
'gray': _hex_color(0x808080),
'white': _hex_color(0xffffff),
'maroon': _hex_color(0x800000),
'red': _hex_color(0xff0000),
'purple': _hex_color(0x800080),
'fucsia': _hex_color(0x008000),
'green': _hex_color(0x00ff00),
'lime': _hex_color(0xffff00),
'olive': _hex_color(0x808000),
'yellow': _hex_color(0xff0000),
'navy': _hex_color(0x000080),
'blue': _hex_color(0x0000ff),
'teal': _hex_color(0x008080),
'aqua': _hex_color(0x00ffff),
}
def _parse_color(value):
if value.startswith('#'):
return _hex_color(int(value[1:], 16))
else:
try:
return _color_names[value.lower()]
except KeyError:
raise ValueError()
_whitespace_re = re.compile(u'[\u0020\u0009\u000c\u200b\r\n]+', re.DOTALL)
_metadata_elements = ['head', 'title']
_block_elements = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
'ul', 'ol', 'dir', 'menu',
'pre', 'dl', 'div', 'center',
'noscript', 'noframes', 'blockquote', 'form',
'isindex', 'hr', 'table', 'fieldset', 'address',
# Incorrect, but we treat list items as blocks:
'li', 'dd', 'dt', ]
_block_containers = ['_top_block',
'body', 'div', 'center', 'object', 'applet',
'blockquote', 'ins', 'del', 'dd', 'li', 'form',
'fieldset', 'button', 'th', 'td', 'iframe', 'noscript',
'noframes',
# Incorrect, but we treat list items as blocks:
'ul', 'ol', 'dir', 'menu', 'dl']
class HTMLDecoder(HTMLParser.HTMLParser, structured.StructuredTextDecoder):
'''Decoder for HTML documents.
'''
#: Default style attributes for unstyled text in the HTML document.
#:
#: :type: dict
default_style = {
'font_name': 'Times New Roman',
'font_size': 12,
'margin_bottom': '12pt',
}
#: Map HTML font sizes to actual font sizes, in points.
#:
#: :type: dict
font_sizes = {
1: 8,
2: 10,
3: 12,
4: 14,
5: 18,
6: 24,
7: 48
}
def decode_structured(self, text, location):
self.location = location
self._font_size_stack = [3]
self.list_stack.append(structured.UnorderedListBuilder({}))
self.strip_leading_space = True
self.block_begin = True
self.need_block_begin = False
self.element_stack = ['_top_block']
self.in_metadata = False
self.in_pre = False
self.push_style('_default', self.default_style)
self.feed(text)
self.close()
def get_image(self, filename):
return pyglet.image.load(filename, file=self.location.open(filename))
def prepare_for_data(self):
if self.need_block_begin:
self.add_text('\n')
self.block_begin = True
self.need_block_begin = False
def handle_data(self, data):
if self.in_metadata:
return
if self.in_pre:
self.add_text(data)
else:
data = _whitespace_re.sub(' ', data)
if data.strip():
self.prepare_for_data()
if self.block_begin or self.strip_leading_space:
data = data.lstrip()
self.block_begin = False
self.add_text(data)
self.strip_leading_space = data.endswith(' ')
def handle_starttag(self, tag, case_attrs):
if self.in_metadata:
return
element = tag.lower()
attrs = {}
for key, value in case_attrs:
attrs[key.lower()] = value
if element in _metadata_elements:
self.in_metadata = True
elif element in _block_elements:
# Pop off elements until we get to a block container.
while self.element_stack[-1] not in _block_containers:
self.handle_endtag(self.element_stack[-1])
if not self.block_begin:
self.add_text('\n')
self.block_begin = True
self.need_block_begin = False
self.element_stack.append(element)
style = {}
if element in ('b', 'strong'):
style['bold'] = True
elif element in ('i', 'em', 'var'):
style['italic'] = True
elif element in ('tt', 'code', 'samp', 'kbd'):
style['font_name'] = 'Courier New'
elif element == 'u':
color = self.current_style.get('color')
if color is None:
color = [0, 0, 0, 255]
style['underline'] = color
elif element == 'font':
if 'face' in attrs:
style['font_name'] = attrs['face'].split(',')
if 'size' in attrs:
size = attrs['size']
try:
if size.startswith('+'):
size = self._font_size_stack[-1] + int(size[1:])
elif size.startswith('-'):
size = self._font_size_stack[-1] - int(size[1:])
else:
size = int(size)
except ValueError:
size = 3
self._font_size_stack.append(size)
if size in self.font_sizes:
style['font_size'] = self.font_sizes.get(size, 3)
else:
self._font_size_stack.append(self._font_size_stack[-1])
if 'color' in attrs:
try:
style['color'] = _parse_color(attrs['color'])
except ValueError:
pass
elif element == 'sup':
size = self._font_size_stack[-1] - 1
style['font_size'] = self.font_sizes.get(size, 1)
style['baseline'] = '3pt'
elif element == 'sub':
size = self._font_size_stack[-1] - 1
style['font_size'] = self.font_sizes.get(size, 1)
style['baseline'] = '-3pt'
elif element == 'h1':
style['font_size'] = 24
style['bold'] = True
style['align'] = 'center'
elif element == 'h2':
style['font_size'] = 18
style['bold'] = True
elif element == 'h3':
style['font_size'] = 16
style['bold'] = True
elif element == 'h4':
style['font_size'] = 14
style['bold'] = True
elif element == 'h5':
style['font_size'] = 12
style['bold'] = True
elif element == 'h6':
style['font_size'] = 12
style['italic'] = True
elif element == 'br':
self.add_text(u'\u2028')
self.strip_leading_space = True
elif element == 'p':
if attrs.get('align') in ('left', 'center', 'right'):
style['align'] = attrs['align']
elif element == 'center':
style['align'] = 'center'
elif element == 'pre':
style['font_name'] = 'Courier New'
style['margin_bottom'] = 0
self.in_pre = True
elif element == 'blockquote':
left_margin = self.current_style.get('margin_left') or 0
right_margin = self.current_style.get('margin_right') or 0
style['margin_left'] = left_margin + 60
style['margin_right'] = right_margin + 60
elif element == 'q':
self.handle_data(u'\u201c')
elif element == 'ol':
try:
start = int(attrs.get('start', 1))
except ValueError:
start = 1
format = attrs.get('type', '1') + '.'
builder = structured.OrderedListBuilder(start, format)
builder.begin(self, style)
self.list_stack.append(builder)
elif element in ('ul', 'dir', 'menu'):
type = attrs.get('type', 'disc').lower()
if type == 'circle':
mark = u'\u25cb'
elif type == 'square':
mark = u'\u25a1'
else:
mark = u'\u25cf'
builder = structured.UnorderedListBuilder(mark)
builder.begin(self, style)
self.list_stack.append(builder)
elif element == 'li':
self.list_stack[-1].item(self, style)
self.strip_leading_space = True
elif element == 'dl':
style['margin_bottom'] = 0
elif element == 'dd':
left_margin = self.current_style.get('margin_left') or 0
style['margin_left'] = left_margin + 30
elif element == 'img':
image = self.get_image(attrs.get('src'))
if image:
width = attrs.get('width')
if width:
width = int(width)
height = attrs.get('height')
if height:
height = int(height)
self.prepare_for_data()
self.add_element(structured.ImageElement(image, width, height))
self.strip_leading_space = False
self.push_style(element, style)
def handle_endtag(self, tag):
element = tag.lower()
if element not in self.element_stack:
return
self.pop_style(element)
while self.element_stack.pop() != element:
pass
if element in _metadata_elements:
self.in_metadata = False
elif element in _block_elements:
self.block_begin = False
self.need_block_begin = True
if element == 'font' and len(self._font_size_stack) > 1:
self._font_size_stack.pop()
elif element == 'pre':
self.in_pre = False
elif element == 'q':
self.handle_data(u'\u201d')
elif element in ('ul', 'ol'):
if len(self.list_stack) > 1:
self.list_stack.pop()
def handle_entityref(self, name):
if name in htmlentitydefs.name2codepoint:
self.handle_data(unichr(htmlentitydefs.name2codepoint[name]))
def handle_charref(self, name):
name = name.lower()
try:
if name.startswith('x'):
self.handle_data(unichr(int(name[1:], 16)))
else:
self.handle_data(unichr(int(name)))
except ValueError:
pass

View file

@ -0,0 +1,47 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Plain text decoder.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import pyglet
class PlainTextDecoder(pyglet.text.DocumentDecoder):
def decode(self, text, location=None):
document = pyglet.text.document.UnformattedDocument()
document.insert_text(0, text)
return document

View file

@ -0,0 +1,261 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Base class for structured (hierarchical) document formats.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
import re
import pyglet
class ImageElement(pyglet.text.document.InlineElement):
def __init__(self, image, width=None, height=None):
self.image = image.get_texture()
self.width = width is None and image.width or width
self.height = height is None and image.height or height
self.vertex_lists = {}
anchor_y = self.height / image.height * image.anchor_y
ascent = max(0, self.height - anchor_y)
descent = min(0, -anchor_y)
super(ImageElement, self).__init__(ascent, descent, self.width)
def place(self, layout, x, y):
group = pyglet.graphics.TextureGroup(self.image.texture,
layout.top_group)
x1 = x
y1 = y + self.descent
x2 = x + self.width
y2 = y + self.height + self.descent
vertex_list = layout.batch.add(4, pyglet.gl.GL_QUADS, group,
('v2i', (x1, y1, x2, y1, x2, y2, x1, y2)),
('c3B', (255, 255, 255) * 4),
('t3f', self.image.tex_coords))
self.vertex_lists[layout] = vertex_list
def remove(self, layout):
self.vertex_lists[layout].delete()
del self.vertex_lists[layout]
def _int_to_roman(input):
# From http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81611
if not 0 < input < 4000:
raise ValueError, "Argument must be between 1 and 3999"
ints = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
nums = ('M', 'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I')
result = ""
for i in range(len(ints)):
count = int(input / ints[i])
result += nums[i] * count
input -= ints[i] * count
return result
class ListBuilder(object):
def begin(self, decoder, style):
'''Begin a list.
:Parameters:
`decoder` : `StructuredTextDecoder`
Decoder.
`style` : dict
Style dictionary that applies over the entire list.
'''
left_margin = decoder.current_style.get('margin_left') or 0
tab_stops = decoder.current_style.get('tab_stops')
if tab_stops:
tab_stops = list(tab_stops)
else:
tab_stops = []
tab_stops.append(left_margin + 50)
style['margin_left'] = left_margin + 50
style['indent'] = -30
style['tab_stops'] = tab_stops
def item(self, decoder, style, value=None):
'''Begin a list item.
:Parameters:
`decoder` : `StructuredTextDecoder`
Decoder.
`style` : dict
Style dictionary that applies over the list item.
`value` : str
Optional value of the list item. The meaning is list-type
dependent.
'''
mark = self.get_mark(value)
if mark:
decoder.add_text(mark)
decoder.add_text('\t')
def get_mark(self, value=None):
'''Get the mark text for the next list item.
:Parameters:
`value` : str
Optional value of the list item. The meaning is list-type
dependent.
:rtype: str
'''
return ''
class UnorderedListBuilder(ListBuilder):
def __init__(self, mark):
'''Create an unordered list with constant mark text.
:Parameters:
`mark` : str
Mark to prepend to each list item.
'''
self.mark = mark
def get_mark(self, value):
return self.mark
class OrderedListBuilder(ListBuilder):
format_re = re.compile('(.*?)([1aAiI])(.*)')
def __init__(self, start, format):
'''Create an ordered list with sequentially numbered mark text.
The format is composed of an optional prefix text, a numbering
scheme character followed by suffix text. Valid numbering schemes
are:
``1``
Decimal Arabic
``a``
Lowercase alphanumberic
``A``
Uppercase alphanumeric
``i``
Lowercase Roman
``I``
Uppercase Roman
Prefix text may typically be ``(`` or ``[`` and suffix text is
typically ``.``, ``)`` or empty, but either can be any string.
:Parameters:
`start` : int
First list item number.
`format` : str
Format style, for example ``"1."``.
'''
self.next_value = start
self.prefix, self.numbering, self.suffix = self.format_re.match(format).groups()
assert self.numbering in '1aAiI'
def get_mark(self, value):
if value is None:
value = self.next_value
self.next_value = value + 1
if self.numbering in 'aA':
try:
mark = 'abcdefghijklmnopqrstuvwxyz'[value - 1]
except ValueError:
mark = '?'
if self.numbering == 'A':
mark = mark.upper()
return '%s%s%s' % (self.prefix, mark, self.suffix)
elif self.numbering in 'iI':
try:
mark = _int_to_roman(value)
except ValueError:
mark = '?'
if self.numbering == 'i':
mark = mark.lower()
return '%s%s%s' % (self.prefix, mark, self.suffix)
else:
return '%s%d%s' % (self.prefix, value, self.suffix)
class StructuredTextDecoder(pyglet.text.DocumentDecoder):
def decode(self, text, location=None):
self.len_text = 0
self.current_style = {}
self.next_style = {}
self.stack = []
self.list_stack = []
self.document = pyglet.text.document.FormattedDocument()
if location is None:
location = pyglet.resource.FileLocation('')
self.decode_structured(text, location)
return self.document
def decode_structured(self, text, location):
raise NotImplementedError('abstract')
def push_style(self, key, styles):
old_styles = {}
for name in styles.keys():
old_styles[name] = self.current_style.get(name)
self.stack.append((key, old_styles))
self.current_style.update(styles)
self.next_style.update(styles)
def pop_style(self, key):
# Don't do anything if key is not in stack
for match, _ in self.stack:
if key == match:
break
else:
return
# Remove all innermost elements until key is closed.
while True:
match, old_styles = self.stack.pop()
self.next_style.update(old_styles)
self.current_style.update(old_styles)
if match == key:
break
def add_text(self, text):
self.document.insert_text(self.len_text, text, self.next_style)
self.next_style.clear()
self.len_text += len(text)
def add_element(self, element):
self.document.insert_element(self.len_text, element, self.next_style)
self.next_style.clear()
self.len_text += 1

2390
pyglet/text/layout.py Normal file

File diff suppressed because it is too large Load diff

418
pyglet/text/runlist.py Normal file
View file

@ -0,0 +1,418 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Run list encoding utilities.
:since: pyglet 1.1
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: $'
class _Run(object):
def __init__(self, value, count):
self.value = value
self.count = count
def __repr__(self):
return 'Run(%r, %d)' % (self.value, self.count)
class RunList(object):
'''List of contiguous runs of values.
A `RunList` is an efficient encoding of a sequence of values. For
example, the sequence ``aaaabbccccc`` is encoded as ``(4, a), (2, b),
(5, c)``. The class provides methods for modifying and querying the
run list without needing to deal with the tricky cases of splitting and
merging the run list entries.
Run lists are used to represent formatted character data in pyglet. A
separate run list is maintained for each style attribute, for example,
bold, italic, font size, and so on. Unless you are overriding the
document interfaces, the only interaction with run lists is via
`RunIterator`.
The length and ranges of a run list always refer to the character
positions in the decoded list. For example, in the above sequence,
``set_run(2, 5, 'x')`` would change the sequence to ``aaxxxbccccc``.
'''
def __init__(self, size, initial):
'''Create a run list of the given size and a default value.
:Parameters:
`size` : int
Number of characters to represent initially.
`initial` : object
The value of all characters in the run list.
'''
self.runs = [_Run(initial, size)]
def insert(self, pos, length):
'''Insert characters into the run list.
The inserted characters will take on the value immediately preceding
the insertion point (or the value of the first character, if `pos` is
0).
:Parameters:
`pos` : int
Insertion index
`length` : int
Number of characters to insert.
'''
i = 0
for run in self.runs:
if i <= pos <= i + run.count:
run.count += length
i += run.count
def delete(self, start, end):
'''Remove characters from the run list.
:Parameters:
`start` : int
Starting index to remove from.
`end` : int
End index, exclusive.
'''
i = 0
for run in self.runs:
if end - start == 0:
break
if i <= start <= i + run.count:
trim = min(end - start, i + run.count - start)
run.count -= trim
end -= trim
i += run.count
self.runs = [r for r in self.runs if r.count > 0]
# Don't leave an empty list
if not self.runs:
self.runs = [_Run(run.value, 0)]
def set_run(self, start, end, value):
'''Set the value of a range of characters.
:Parameters:
`start` : int
Start index of range.
`end` : int
End of range, exclusive.
`value` : object
Value to set over the range.
'''
if end - start <= 0:
return
# Find runs that need to be split
i = 0
start_i = None
start_trim = 0
end_i = None
end_trim = 0
for run_i, run in enumerate(self.runs):
count = run.count
if i < start < i + count:
start_i = run_i
start_trim = start - i
if i < end < i + count:
end_i = run_i
end_trim = end - i
i += count
# Split runs
if start_i is not None:
run = self.runs[start_i]
self.runs.insert(start_i, _Run(run.value, start_trim))
run.count -= start_trim
if end_i is not None:
if end_i == start_i:
end_trim -= start_trim
end_i += 1
if end_i is not None:
run = self.runs[end_i]
self.runs.insert(end_i, _Run(run.value, end_trim))
run.count -= end_trim
# Set new value on runs
i = 0
for run in self.runs:
if start <= i and i + run.count <= end:
run.value = value
i += run.count
# Merge adjacent runs
last_run = self.runs[0]
for run in self.runs[1:]:
if run.value == last_run.value:
run.count += last_run.count
last_run.count = 0
last_run = run
# Delete collapsed runs
self.runs = [r for r in self.runs if r.count > 0]
def __iter__(self):
i = 0
for run in self.runs:
yield i, i + run.count, run.value
i += run.count
def get_run_iterator(self):
'''Get an extended iterator over the run list.
:rtype: `RunIterator`
'''
return RunIterator(self)
def __getitem__(self, index):
'''Get the value at a character position.
:Parameters:
`index` : int
Index of character. Must be within range and non-negative.
:rtype: object
'''
i = 0
for run in self.runs:
if i <= index < i + run.count:
return run.value
i += run.count
# Append insertion point
if index == i:
return self.runs[-1].value
assert False, 'Index not in range'
def __repr__(self):
return str(list(self))
class AbstractRunIterator(object):
'''Range iteration over `RunList`.
`AbstractRunIterator` objects allow any monotonically non-decreasing
access of the iteration, including repeated iteration over the same index.
Use the ``[index]`` operator to get the value at a particular index within
the document. For example::
run_iter = iter(run_list)
value = run_iter[0]
value = run_iter[0] # non-decreasing access is OK
value = run_iter[15]
value = run_iter[17]
value = run_iter[16] # this is illegal, the index decreased.
Using `AbstractRunIterator` to access increasing indices of the value runs
is more efficient than calling `RunList.__getitem__` repeatedly.
You can also iterate over monotonically non-decreasing ranges over the
iteration. For example::
run_iter = iter(run_list)
for start, end, value in run_iter.ranges(0, 20):
pass
for start, end, value in run_iter.ranges(25, 30):
pass
for start, end, value in run_iter.ranges(30, 40):
pass
Both start and end indices of the slice are required and must be positive.
'''
def __getitem__(self, index):
'''Get the value at a given index.
See the class documentation for examples of valid usage.
:Parameters:
`index` : int
Document position to query.
:rtype: object
'''
def ranges(self, start, end):
'''Iterate over a subrange of the run list.
See the class documentation for examples of valid usage.
:Parameters:
`start` : int
Start index to iterate from.
`end` : int
End index, exclusive.
:rtype: iterator
:return: Iterator over (start, end, value) tuples.
'''
class RunIterator(AbstractRunIterator):
def __init__(self, run_list):
self.next = iter(run_list).next
self.start, self.end, self.value = self.next()
def __getitem__(self, index):
while index >= self.end:
self.start, self.end, self.value = self.next()
return self.value
def ranges(self, start, end):
while start >= self.end:
self.start, self.end, self.value = self.next()
yield start, min(self.end, end), self.value
while end > self.end:
self.start, self.end, self.value = self.next()
yield self.start, min(self.end, end), self.value
class OverriddenRunIterator(AbstractRunIterator):
'''Iterator over a `RunIterator`, with a value temporarily replacing
a given range.
'''
def __init__(self, base_iterator, start, end, value):
'''Create a derived iterator.
:Parameters:
`start` : int
Start of range to override
`end` : int
End of range to override, exclusive
`value` : object
Value to replace over the range
'''
self.iter = base_iterator
self.override_start = start
self.override_end = end
self.override_value = value
def ranges(self, start, end):
if end <= self.override_start or start >= self.override_end:
# No overlap
for r in self.iter.ranges(start, end):
yield r
else:
# Overlap: before, override, after
if start < self.override_start < end:
for r in self.iter.ranges(start, self.override_start):
yield r
yield (max(self.override_start, start),
min(self.override_end, end),
self.override_value)
if start < self.override_end < end:
for r in self.iter.ranges(self.override_end, end):
yield r
def __getitem__(self, index):
if self.override_start <= index < self.override_end:
return self.override_value
else:
return self.iter[index]
class FilteredRunIterator(AbstractRunIterator):
'''Iterate over an `AbstractRunIterator` with filtered values replaced
by a default value.
'''
def __init__(self, base_iterator, filter, default):
'''Create a filtered run iterator.
:Parameters:
`base_iterator` : `AbstractRunIterator`
Source of runs.
`filter` : ``lambda object: bool``
Function taking a value as parameter, and returning ``True``
if the value is acceptable, and ``False`` if the default value
should be substituted.
`default` : object
Default value to replace filtered values.
'''
self.iter = base_iterator
self.filter = filter
self.default = default
def ranges(self, start, end):
for start, end, value in self.iter.ranges(start, end):
if self.filter(value):
yield start, end, value
else:
yield start, end, self.default
def __getitem__(self, index):
value = self.iter[index]
if self.filter(value):
return value
return self.default
class ZipRunIterator(AbstractRunIterator):
'''Iterate over multiple run iterators concurrently.'''
def __init__(self, range_iterators):
self.range_iterators = range_iterators
def ranges(self, start, end):
iterators = [i.ranges(start, end) for i in self.range_iterators]
starts, ends, values = zip(*[i.next() for i in iterators])
starts = list(starts)
ends = list(ends)
values = list(values)
while start < end:
min_end = min(ends)
yield start, min_end, values
start = min_end
for i, iterator in enumerate(iterators):
if ends[i] == min_end:
starts[i], ends[i], values[i] = iterator.next()
def __getitem__(self, index):
return [i[index] for i in self.range_iterators]
class ConstRunIterator(AbstractRunIterator):
'''Iterate over a constant value without creating a RunList.'''
def __init__(self, length, value):
self.length = length
self.value = value
def next(self):
yield 0, self.length, self.value
def ranges(self, start, end):
yield start, end, self.value
def __getitem__(self, index):
return self.value

1682
pyglet/window/__init__.py Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,525 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: $'
# CFString.h
kCFStringEncodingMacRoman = 0
kCFStringEncodingWindowsLatin1 = 0x0500
kCFStringEncodingISOLatin1 = 0x0201
kCFStringEncodingNextStepLatin = 0x0B01
kCFStringEncodingASCII = 0x0600
kCFStringEncodingUnicode = 0x0100
kCFStringEncodingUTF8 = 0x08000100
kCFStringEncodingNonLossyASCII = 0x0BFF
# MacTypes.h
noErr = 0
# CarbonEventsCore.h
eventLoopTimedOutErr = -9875
eventLoopQuitErr = -9876
# MacApplication.h
kUIModeNormal = 0
kUIModeContentSuppressed = 1
kUIModeContentHidden = 2
kUIModeAllSuppressed = 4
kUIModeAllHidden = 3
kUIOptionAutoShowMenuBar = 1 << 0
kUIOptionDisableAppleMenu = 1 << 2
kUIOptionDisableProcessSwitch = 1 << 3
kUIOptionDisableForceQuit = 1 << 4
kUIOptionDisableSessionTerminate = 1 << 5
kUIOptionDisableHide = 1 << 6
# MacWindows.h
kAlertWindowClass = 1
kMovableAlertWindowClass = 2
kModalWindowClass = 3
kMovableModalWindowClass = 4
kFloatingWindowClass = 5
kDocumentWindowClass = 6
kUtilityWindowClass = 8
kHelpWindowClass = 10
kSheetWindowClass = 11
kToolbarWindowClass = 12
kPlainWindowClass = 13
kOverlayWindowClass = 14
kSheetAlertWindowClass = 15
kAltPlainWindowClass = 16
kSimpleWindowClass = 18 # no window frame
kDrawerWindowClass = 20
kWindowNoAttributes = 0x0
kWindowCloseBoxAttribute = 0x1
kWindowHorizontalZoomAttribute = 0x2
kWindowVerticalZoomAttribute = 0x4
kWindowFullZoomAttribute = kWindowHorizontalZoomAttribute | \
kWindowVerticalZoomAttribute
kWindowCollapseBoxAttribute = 0x8
kWindowResizableAttribute = 0x10
kWindowSideTitlebarAttribute = 0x20
kWindowToolbarAttribute = 0x40
kWindowMetalAttribute = 1 << 8
kWindowDoesNotCycleAttribute = 1 << 15
kWindowNoupdatesAttribute = 1 << 16
kWindowNoActivatesAttribute = 1 << 17
kWindowOpaqueForEventsAttribute = 1 << 18
kWindowCompositingAttribute = 1 << 19
kWindowNoShadowAttribute = 1 << 21
kWindowHideOnSuspendAttribute = 1 << 24
kWindowAsyncDragAttribute = 1 << 23
kWindowStandardHandlerAttribute = 1 << 25
kWindowHideOnFullScreenAttribute = 1 << 26
kWindowInWindowMenuAttribute = 1 << 27
kWindowLiveResizeAttribute = 1 << 28
kWindowIgnoreClicksAttribute = 1 << 29
kWindowNoConstrainAttribute = 1 << 31
kWindowStandardDocumentAttributes = kWindowCloseBoxAttribute | \
kWindowFullZoomAttribute | \
kWindowCollapseBoxAttribute | \
kWindowResizableAttribute
kWindowStandardFloatingAttributes = kWindowCloseBoxAttribute | \
kWindowCollapseBoxAttribute
kWindowCenterOnMainScreen = 1
kWindowCenterOnParentWindow = 2
kWindowCenterOnParentWindowScreen = 3
kWindowCascadeOnMainScreen = 4
kWindowCascadeOnParentWindow = 5
kWindowCascadeonParentWindowScreen = 6
kWindowCascadeStartAtParentWindowScreen = 10
kWindowAlertPositionOnMainScreen = 7
kWindowAlertPositionOnParentWindow = 8
kWindowAlertPositionOnParentWindowScreen = 9
kWindowTitleBarRgn = 0
kWindowTitleTextRgn = 1
kWindowCloseBoxRgn = 2
kWindowZoomBoxRgn = 3
kWindowDragRgn = 5
kWindowGrowRgn = 6
kWindowCollapseBoxRgn = 7
kWindowTitleProxyIconRgn = 8
kWindowStructureRgn = 32
kWindowContentRgn = 33
kWindowUpdateRgn = 34
kWindowOpaqueRgn = 35
kWindowGlobalPortRgn = 40
kWindowToolbarButtonRgn = 41
inDesk = 0
inNoWindow = 0
inMenuBar = 1
inSysWindow = 2
inContent = 3
inDrag = 4
inGrow = 5
inGoAway = 6
inZoomIn = 7
inZoomOut = 8
inCollapseBox = 11
inProxyIcon = 12
inToolbarButton = 13
inStructure = 15
def _name(name):
return ord(name[0]) << 24 | \
ord(name[1]) << 16 | \
ord(name[2]) << 8 | \
ord(name[3])
# AEDataModel.h
typeBoolean = _name('bool')
typeChar = _name('TEXT')
typeSInt16 = _name('shor')
typeSInt32 = _name('long')
typeUInt32 = _name('magn')
typeSInt64 = _name('comp')
typeIEEE32BitFloatingPoint = _name('sing')
typeIEEE64BitFloatingPoint = _name('doub')
type128BitFloatingPoint = _name('ldbl')
typeDecimalStruct = _name('decm')
# AERegistry.h
typeUnicodeText = _name('utxt')
typeStyledUnicodeText = _name('sutx')
typeUTF8Text = _name('utf8')
typeEncodedString = _name('encs')
typeCString = _name('cstr')
typePString = _name('pstr')
typeEventRef = _name('evrf')
# CarbonEvents.h
kEventParamWindowRef = _name('wind')
kEventParamWindowPartCode = _name('wpar')
kEventParamGrafPort = _name('graf')
kEventParamMenuRef = _name('menu')
kEventParamEventRef = _name('evnt')
kEventParamControlRef = _name('ctrl')
kEventParamRgnHandle = _name('rgnh')
kEventParamEnabled = _name('enab')
kEventParamDimensions = _name('dims')
kEventParamBounds = _name('boun')
kEventParamAvailableBounds = _name('avlb')
#kEventParamAEEventID = keyAEEventID
#kEventParamAEEventClass = keyAEEventClass
kEventParamCGContextRef = _name('cntx')
kEventParamDeviceDepth = _name('devd')
kEventParamDeviceColor = _name('devc')
kEventParamMutableArray = _name('marr')
kEventParamResult = _name('ansr')
kEventParamMinimumSize = _name('mnsz')
kEventParamMaximumSize = _name('mxsz')
kEventParamAttributes = _name('attr')
kEventParamReason = _name('why?')
kEventParamTransactionID = _name('trns')
kEventParamGDevice = _name('gdev')
kEventParamIndex = _name('indx')
kEventParamUserData = _name('usrd')
kEventParamShape = _name('shap')
typeWindowRef = _name('wind')
typeWindowPartCode = _name('wpar')
typeGrafPtr = _name('graf')
typeGWorldPtr = _name('gwld')
typeMenuRef = _name('menu')
typeControlRef = _name('ctrl')
typeCollection = _name('cltn')
typeQDRgnHandle = _name('rgnh')
typeOSStatus = _name('osst')
typeCFIndex = _name('cfix')
typeCGContextRef = _name('cntx')
typeQDPoint = _name('QDpt')
typeHICommand = _name('hcmd')
typeHIPoint = _name('hipt')
typeHISize = _name('hisz')
typeHIRect = _name('hirc')
typeHIShapeRef = _name('shap')
typeVoidPtr = _name('void')
typeGDHandle = _name('gdev')
kCoreEventClass = _name('aevt')
kEventClassMouse = _name('mous')
kEventClassKeyboard = _name('keyb')
kEventClassTextInput = _name('text')
kEventClassApplication = _name('appl')
kEventClassAppleEvent = _name('eppc')
kEventClassMenu = _name('menu')
kEventClassWindow = _name('wind')
kEventClassControl = _name('cntl')
kEventClassCommand = _name('cmds')
kEventClassTablet = _name('tblt')
kEventClassVolume = _name('vol ')
kEventClassAppearance = _name('appm')
kEventClassService = _name('serv')
kEventClassToolbar = _name('tbar')
kEventClassToolbarItem = _name('tbit')
kEventClassToolbarItemView = _name('tbiv')
kEventClassAccessibility = _name('acce')
kEventClassSystem = _name('macs')
kEventClassInk = _name('ink ')
kEventClassTSMDocumentAccess = _name('tdac')
kEventDurationForever = -1.0
# Appearance.h
kThemeArrowCursor = 0
kThemeCopyArrowCursor = 1
kThemeAliasArrowCursor = 2
kThemeContextualMenuArrowCursor = 3
kThemeIBeamCursor = 4
kThemeCrossCursor = 5
kThemePlusCursor = 6
kThemeWatchCursor = 7
kThemeClosedHandCursor = 8
kThemeOpenHandCursor = 9
kThemePointingHandCursor = 10
kThemeCountingUpHandCursor = 11
kThemeCountingDownHandCursor = 12
kThemeCountingUpAndDownHandCursor = 13
kThemeSpinningCursor = 14
kThemeResizeLeftCursor = 15
kThemeResizeRightCursor = 16
kThemeResizeLeftRightCursor = 17
kThemeNotAllowedCursor = 18
kThemeResizeUpCursor = 19
kThemeResizeDownCursor = 20
kThemeResizeUpDownCursor = 21
kThemePoofCursor = 22
# AE
kEventAppleEvent = 1
kEventAppQuit = 3
kAEQuitApplication = _name('quit')
# Commands
kEventProcessCommand = 1
kEventParamHICommand = _name('hcmd')
kEventParamDirectObject = _name('----')
kHICommandQuit = _name('quit')
# Keyboard
kEventRawKeyDown = 1
kEventRawKeyRepeat = 2
kEventRawKeyUp = 3
kEventRawKeyModifiersChanged = 4
kEventHotKeyPressed = 5
kEventHotKeyReleased = 6
kEventParamKeyCode = _name('kcod')
kEventParamKeyMacCharCodes = _name('kchr')
kEventParamKeyModifiers = _name('kmod')
kEventParamKeyUnicodes = _name('kuni')
kEventParamKeyboardType = _name('kbdt')
typeEventHotKeyID = _name('hkid')
activeFlagBit = 0
btnStateBit = 7
cmdKeyBit = 8
shiftKeyBit = 9
alphaLockBit = 10
optionKeyBit = 11
controlKeyBit = 12
rightShiftKeyBit = 13
rightOptionKeyBit = 14
rightControlKeyBit = 15
numLockBit = 16
activeFlag = 1 << activeFlagBit
btnState = 1 << btnStateBit
cmdKey = 1 << cmdKeyBit
shiftKey = 1 << shiftKeyBit
alphaLock = 1 << alphaLockBit
optionKey = 1 << optionKeyBit
controlKey = 1 << controlKeyBit
rightShiftKey = 1 << rightShiftKeyBit
rightOptionKey = 1 << rightOptionKeyBit
rightControlKey = 1 << rightControlKeyBit
numLock = 1 << numLockBit
# TextInput
kEventTextInputUpdateActiveInputArea = 1
kEventTextInputUnicodeForKeyEvent = 2
kEventTextInputOffsetToPos = 3
kEventTextInputPosToOffset = 4
kEventTextInputShowHideBottomWindow = 5
kEventTextInputGetSelectedText = 6
kEventTextInputUnicodeText = 7
kEventParamTextInputSendText = _name('tstx')
kEventParamTextInputSendKeyboardEvent = _name('tske')
# Mouse
kEventMouseDown = 1
kEventMouseUp = 2
kEventMouseMoved = 5
kEventMouseDragged = 6
kEventMouseEntered = 8
kEventMouseExited = 9
kEventMouseWheelMoved = 10
kEventParamMouseLocation = _name('mloc')
kEventParamWindowMouseLocation = _name('wmou')
kEventParamMouseButton = _name('mbtn')
kEventParamClickCount = _name('ccnt')
kEventParamMouseWheelAxis = _name('mwax')
kEventParamMouseWheelDelta = _name('mwdl')
kEventParamMouseDelta = _name('mdta')
kEventParamMouseChord = _name('chor')
kEventParamTabletEventType = _name('tblt')
kEventParamMouseTrackingRef = _name('mtrf')
typeMouseButton = _name('mbtn')
typeMouseWheelAxis = _name('mwax')
typeMouseTrackingRef = _name('mtrf')
kMouseTrackingOptionsLocalClip = 0
kMouseTrackingOptionsGlobalClip = 1
kEventMouseButtonPrimary = 1
kEventMouseButtonSecondary = 2
kEventMouseButtonTertiary = 3
kEventMouseWheelAxisX = 0
kEventMouseWheelAxisY = 1
DEFAULT_CREATOR_CODE = _name('PYGL') # <ah> this is registered for Pyglet
# apps. register your own at:
# http://developer.apple.com/datatype
# Window
kEventWindowUpdate = 1
kEventWindowDrawContent = 2
# -- window activation events --
kEventWindowActivated = 5
kEventWindowDeactivated = 6
kEventWindowHandleActivate = 91
kEventWindowHandleDeactivate = 92
kEventWindowGetClickActivation = 7
kEventWindowGetClickModality = 8
# -- window state change events --
kEventWindowShowing = 22
kEventWindowHiding = 23
kEventWindowShown = 24
kEventWindowHidden = 25
kEventWindowCollapsing = 86
kEventWindowCollapsed = 67
kEventWindowExpanding = 87
kEventWindowExpanded = 70
kEventWindowZoomed = 76
kEventWindowBoundsChanging = 26
kEventWindowBoundsChanged = 27
kEventWindowResizeStarted = 28
kEventWindowResizeCompleted = 29
kEventWindowDragStarted = 30
kEventWindowDragCompleted = 31
kEventWindowClosed = 73
kEventWindowTransitionStarted = 88
kEventWindowTransitionCompleted = 89
# -- window click events --
kEventWindowClickDragRgn = 32
kEventWindowClickResizeRgn = 33
kEventWindowClickCollapseRgn = 34
kEventWindowClickCloseRgn = 35
kEventWindowClickZoomRgn = 36
kEventWindowClickContentRgn = 37
kEventWindowClickProxyIconRgn = 38
kEventWindowClickToolbarButtonRgn = 41
kEventWindowClickStructureRgn = 42
# -- window cursor change events --
kEventWindowCursorChange = 40
# -- window action events --
kEventWindowCollapse = 66
kEventWindowCollapsed = 67
kEventWindowCollapseAll = 68
kEventWindowExpand = 69
kEventWindowExpanded = 70
kEventWindowExpandAll = 71
kEventWindowClose = 72
kEventWindowClosed = 73
kEventWindowCloseAll = 74
kEventWindowZoom = 75
kEventWindowZoomed = 76
kEventWindowZoomAll = 77
kEventWindowContextualMenuSelect = 78
kEventWindowPathSelect = 79
kEventWindowGetIdealSize = 80
kEventWindowGetMinimumSize = 81
kEventWindowGetMaximumSize = 82
kEventWindowConstrain = 83
kEventWindowHandleContentClick = 85
kEventWindowCollapsing = 86
kEventWindowExpanding = 87
kEventWindowTransitionStarted = 88
kEventWindowTransitionCompleted = 89
kEventWindowGetDockTileMenu = 90
kEventWindowHandleActivate = 91
kEventWindowHandleDeactivate = 92
kEventWindowProxyBeginDrag = 128
kEventWindowProxyEndDrag = 129
kEventWindowToolbarSwitchMode = 150
# -- window focus events --
kEventWindowFocusAcquired = 200
kEventWindowFocusRelinquish = 201
kEventWindowFocusContent = 202
kEventWindowFocusToolbar = 203
kEventWindowFocusDrawer = 204
# -- sheet events --
kEventWindowSheetOpening = 210
kEventWindowSheetOpened = 211
kEventWindowSheetClosing = 212
kEventWindowSheetClosed = 213
# -- drawer events --
kEventWindowDrawerOpening = 220
kEventWindowDrawerOpened = 221
kEventWindowDrawerClosing = 222
kEventWindowDrawerClosed = 223
# -- window definition events --
kEventWindowDrawFrame = 1000
kEventWindowDrawPart = 1001
kEventWindowGetRegion = 1002
kEventWindowHitTest = 1003
kEventWindowInit = 1004
kEventWindowDispose = 1005
kEventWindowDragHilite = 1006
kEventWindowModified = 1007
kEventWindowSetupProxyDragImage = 1008
kEventWindowStateChanged = 1009
kEventWindowMeasureTitle = 1010
kEventWindowDrawGrowBox = 1011
kEventWindowGetGrowImageRegion = 1012
kEventWindowPaint = 1013
# Process.h
kNoProcess = 0
kSystemProcess = 1
kCurrentProcess = 2
# CGColorSpace.h
kCGRenderingIntentDefault = 0
# CGImage.h
kCGImageAlphaNone = 0
kCGImageAlphaPremultipliedLast = 1
kCGImageAlphaPremultipliedFirst = 2
kCGImageAlphaLast = 3
kCGImageAlphaFirst = 4
kCGImageAlphaNoneSkipLast = 5
kCGImageAlphaNoneSkipFirst = 6
kCGImageAlphaOnly = 7

View file

@ -0,0 +1,270 @@
# ----------------------------------------------------------------------------
# pyglet
# 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__ = ''
from pyglet.window import key
# From SDL: src/video/quartz/SDL_QuartzKeys.h
# These are the Macintosh key scancode constants -- from Inside Macintosh
QZ_ESCAPE = 0x35
QZ_F1 = 0x7A
QZ_F2 = 0x78
QZ_F3 = 0x63
QZ_F4 = 0x76
QZ_F5 = 0x60
QZ_F6 = 0x61
QZ_F7 = 0x62
QZ_F8 = 0x64
QZ_F9 = 0x65
QZ_F10 = 0x6D
QZ_F11 = 0x67
QZ_F12 = 0x6F
QZ_PRINT = 0x69
QZ_SCROLLOCK = 0x6B
QZ_PAUSE = 0x71
QZ_POWER = 0x7F
QZ_BACKQUOTE = 0x32
QZ_1 = 0x12
QZ_2 = 0x13
QZ_3 = 0x14
QZ_4 = 0x15
QZ_5 = 0x17
QZ_6 = 0x16
QZ_7 = 0x1A
QZ_8 = 0x1C
QZ_9 = 0x19
QZ_0 = 0x1D
QZ_MINUS = 0x1B
QZ_EQUALS = 0x18
QZ_BACKSPACE = 0x33
QZ_INSERT = 0x72
QZ_HOME = 0x73
QZ_PAGEUP = 0x74
QZ_NUMLOCK = 0x47
QZ_KP_EQUALS = 0x51
QZ_KP_DIVIDE = 0x4B
QZ_KP_MULTIPLY = 0x43
QZ_TAB = 0x30
QZ_q = 0x0C
QZ_w = 0x0D
QZ_e = 0x0E
QZ_r = 0x0F
QZ_t = 0x11
QZ_y = 0x10
QZ_u = 0x20
QZ_i = 0x22
QZ_o = 0x1F
QZ_p = 0x23
QZ_LEFTBRACKET = 0x21
QZ_RIGHTBRACKET = 0x1E
QZ_BACKSLASH = 0x2A
QZ_DELETE = 0x75
QZ_END = 0x77
QZ_PAGEDOWN = 0x79
QZ_KP7 = 0x59
QZ_KP8 = 0x5B
QZ_KP9 = 0x5C
QZ_KP_MINUS = 0x4E
QZ_CAPSLOCK = 0x39
QZ_a = 0x00
QZ_s = 0x01
QZ_d = 0x02
QZ_f = 0x03
QZ_g = 0x05
QZ_h = 0x04
QZ_j = 0x26
QZ_k = 0x28
QZ_l = 0x25
QZ_SEMICOLON = 0x29
QZ_QUOTE = 0x27
QZ_RETURN = 0x24
QZ_KP4 = 0x56
QZ_KP5 = 0x57
QZ_KP6 = 0x58
QZ_KP_PLUS = 0x45
QZ_LSHIFT = 0x38
QZ_z = 0x06
QZ_x = 0x07
QZ_c = 0x08
QZ_v = 0x09
QZ_b = 0x0B
QZ_n = 0x2D
QZ_m = 0x2E
QZ_COMMA = 0x2B
QZ_PERIOD = 0x2F
QZ_SLASH = 0x2C
QZ_RSHIFT = 0x3C
QZ_UP = 0x7E
QZ_KP1 = 0x53
QZ_KP2 = 0x54
QZ_KP3 = 0x55
QZ_KP_ENTER = 0x4C
QZ_LCTRL = 0x3B
QZ_LALT = 0x3A
QZ_LMETA = 0x37
QZ_SPACE = 0x31
QZ_RMETA = 0x36
QZ_RALT = 0x3D
QZ_RCTRL = 0x3E
QZ_LEFT = 0x7B
QZ_DOWN = 0x7D
QZ_RIGHT = 0x7C
QZ_KP0 = 0x52
QZ_KP_PERIOD = 0x41
QZ_IBOOK_ENTER = 0x34
QZ_IBOOK_LEFT = 0x3B
QZ_IBOOK_RIGHT = 0x3C
QZ_IBOOK_DOWN = 0x3D
QZ_IBOOK_UP = 0x3E
keymap = {
QZ_ESCAPE: key.ESCAPE,
QZ_F1: key.F1,
QZ_F2: key.F2,
QZ_F3: key.F3,
QZ_F4: key.F4,
QZ_F5: key.F5,
QZ_F6: key.F6,
QZ_F7: key.F7,
QZ_F8: key.F8,
QZ_F9: key.F9,
QZ_F10: key.F10,
QZ_F11: key.F11,
QZ_F12: key.F12,
QZ_PRINT: key.PRINT,
QZ_SCROLLOCK: key.SCROLLLOCK,
QZ_PAUSE: key.PAUSE,
#QZ_POWER: key.POWER,
QZ_BACKQUOTE: key.QUOTELEFT,
QZ_1: key._1,
QZ_2: key._2,
QZ_3: key._3,
QZ_4: key._4,
QZ_5: key._5,
QZ_6: key._6,
QZ_7: key._7,
QZ_8: key._8,
QZ_9: key._9,
QZ_0: key._0,
QZ_MINUS: key.MINUS,
QZ_EQUALS: key.EQUAL,
QZ_BACKSPACE: key.BACKSPACE,
QZ_INSERT: key.INSERT,
QZ_HOME: key.HOME,
QZ_PAGEUP: key.PAGEUP,
QZ_NUMLOCK: key.NUMLOCK,
QZ_KP_EQUALS: key.NUM_EQUAL,
QZ_KP_DIVIDE: key.NUM_DIVIDE,
QZ_KP_MULTIPLY: key.NUM_MULTIPLY,
QZ_TAB: key.TAB,
QZ_q: key.Q,
QZ_w: key.W,
QZ_e: key.E,
QZ_r: key.R,
QZ_t: key.T,
QZ_y: key.Y,
QZ_u: key.U,
QZ_i: key.I,
QZ_o: key.O,
QZ_p: key.P,
QZ_LEFTBRACKET: key.BRACKETLEFT,
QZ_RIGHTBRACKET: key.BRACKETRIGHT,
QZ_BACKSLASH: key.BACKSLASH,
QZ_DELETE: key.DELETE,
QZ_END: key.END,
QZ_PAGEDOWN: key.PAGEDOWN,
QZ_KP7: key.NUM_7,
QZ_KP8: key.NUM_8,
QZ_KP9: key.NUM_9,
QZ_KP_MINUS: key.NUM_SUBTRACT,
QZ_CAPSLOCK: key.CAPSLOCK,
QZ_a: key.A,
QZ_s: key.S,
QZ_d: key.D,
QZ_f: key.F,
QZ_g: key.G,
QZ_h: key.H,
QZ_j: key.J,
QZ_k: key.K,
QZ_l: key.L,
QZ_SEMICOLON: key.SEMICOLON,
QZ_QUOTE: key.APOSTROPHE,
QZ_RETURN: key.RETURN,
QZ_KP4: key.NUM_4,
QZ_KP5: key.NUM_5,
QZ_KP6: key.NUM_6,
QZ_KP_PLUS: key.NUM_ADD,
QZ_LSHIFT: key.LSHIFT,
QZ_z: key.Z,
QZ_x: key.X,
QZ_c: key.C,
QZ_v: key.V,
QZ_b: key.B,
QZ_n: key.N,
QZ_m: key.M,
QZ_COMMA: key.COMMA,
QZ_PERIOD: key.PERIOD,
QZ_SLASH: key.SLASH,
QZ_RSHIFT: key.RSHIFT,
QZ_UP: key.UP,
QZ_KP1: key.NUM_1,
QZ_KP2: key.NUM_2,
QZ_KP3: key.NUM_3,
QZ_KP_ENTER: key.NUM_ENTER,
QZ_LCTRL: key.LCTRL,
QZ_LALT: key.LALT,
QZ_LMETA: key.LMETA,
QZ_SPACE: key.SPACE,
QZ_RMETA: key.RMETA,
QZ_RALT: key.RALT,
QZ_RCTRL: key.RCTRL,
QZ_LEFT: key.LEFT,
QZ_DOWN: key.DOWN,
QZ_RIGHT: key.RIGHT,
QZ_KP0: key.NUM_0,
QZ_KP_PERIOD: key.NUM_DECIMAL,
QZ_IBOOK_ENTER: key.ENTER,
QZ_IBOOK_LEFT: key.LEFT,
QZ_IBOOK_RIGHT: key.RIGHT,
QZ_IBOOK_DOWN: key.DOWN,
QZ_IBOOK_UP: key.UP,
}

View file

@ -0,0 +1,159 @@
# ----------------------------------------------------------------------------
# pyglet
# 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: $'
from ctypes import *
import pyglet.gl.agl
agl = pyglet.gl.agl
Boolean = c_ubyte # actually an unsigned char
Fixed = c_int32
ItemCount = c_uint32
ByteOffset = ByteCount = c_uint32
GDHandle = agl.GDHandle
class Rect(Structure):
_fields_ = [
('top', c_short),
('left', c_short),
('bottom', c_short),
('right', c_short)
]
class Point(Structure):
_fields_ = [
('v', c_short),
('h', c_short),
]
class CGPoint(Structure):
_fields_ = [
('x', c_float),
('y', c_float),
]
class CGSize(Structure):
_fields_ = [
('width', c_float),
('height', c_float)
]
class CGRect(Structure):
_fields_ = [
('origin', CGPoint),
('size', CGSize)
]
__slots__ = ['origin', 'size']
CGDirectDisplayID = c_void_p
CGDisplayCount = c_uint32
CGTableCount = c_uint32
CGDisplayCoord = c_int32
CGByteValue = c_ubyte
CGOpenGLDisplayMask = c_uint32
CGRefreshRate = c_double
CGCaptureOptions = c_uint32
HIPoint = CGPoint
HISize = CGSize
HIRect = CGRect
class EventTypeSpec(Structure):
_fields_ = [
('eventClass', c_uint32),
('eventKind', c_uint32)
]
WindowRef = c_void_p
EventRef = c_void_p
EventTargetRef = c_void_p
EventHandlerRef = c_void_p
MenuRef = c_void_p
MenuID = c_int16
MenuItemIndex = c_uint16
MenuCommand = c_uint32
CFStringEncoding = c_uint
WindowClass = c_uint32
WindowAttributes = c_uint32
WindowPositionMethod = c_uint32
EventMouseButton = c_uint16
EventMouseWheelAxis = c_uint16
OSType = c_uint32
OSStatus = c_int32
class MouseTrackingRegionID(Structure):
_fields_ = [('signature', OSType),
('id', c_int32)]
MouseTrackingRef = c_void_p
RgnHandle = c_void_p
class ProcessSerialNumber(Structure):
_fields_ = [('highLongOfPSN', c_uint32),
('lowLongOfPSN', c_uint32)]
class HICommand_Menu(Structure):
_fields_ = [
('menuRef', MenuRef),
('menuItemIndex', MenuItemIndex),
]
class HICommand(Structure):
_fields_ = [
('attributes', c_uint32),
('commandID', c_uint32),
('menu', HICommand_Menu)
]
class EventRecord(Structure):
_fields_ = [
('what', c_uint16),
('message', c_uint32),
('when', c_uint32),
('where', Point),
('modifiers', c_uint16)
]

177
pyglet/window/event.py Normal file
View file

@ -0,0 +1,177 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Events for `pyglet.window`.
See `Window` for a description of the window event types.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: event.py 1669 2008-01-27 01:31:58Z Alex.Holkner $'
import sys
from pyglet.window import key
from pyglet.window import mouse
class WindowExitHandler(object):
'''Determine if the window should be closed.
This event handler watches for the ESC key or the window close event
and sets `self.has_exit` to True when either is pressed. An instance
of this class is automatically attached to all new `pyglet.window.Window`
objects.
:deprecated: This class's functionality is provided directly on `Window`
in pyglet 1.1.
:Ivariables:
`has_exit` : bool
True if the user wants to close the window.
'''
has_exit = False
def on_close(self):
self.has_exit = True
def on_key_press(self, symbol, modifiers):
if symbol == key.ESCAPE:
self.has_exit = True
class WindowEventLogger(object):
'''Print all events to a file.
When this event handler is added to a window it prints out all events
and their parameters; useful for debugging or discovering which events
you need to handle.
Example::
win = window.Window()
win.push_handlers(WindowEventLogger())
'''
def __init__(self, logfile=None):
'''Create a `WindowEventLogger` which writes to `logfile`.
:Parameters:
`logfile` : file-like object
The file to write to. If unspecified, stdout will be used.
'''
if logfile is None:
import sys
logfile = sys.stdout
self.file = logfile
def on_key_press(self, symbol, modifiers):
print >> self.file, 'on_key_press(symbol=%s, modifiers=%s)' % (
key.symbol_string(symbol), key.modifiers_string(modifiers))
def on_key_release(self, symbol, modifiers):
print >> self.file, 'on_key_release(symbol=%s, modifiers=%s)' % (
key.symbol_string(symbol), key.modifiers_string(modifiers))
def on_text(self, text):
print >> self.file, 'on_text(text=%r)' % text
def on_text_motion(self, motion):
print >> self.file, 'on_text_motion(motion=%s)' % (
key.motion_string(motion))
def on_text_motion_select(self, motion):
print >> self.file, 'on_text_motion_select(motion=%s)' % (
key.motion_string(motion))
def on_mouse_motion(self, x, y, dx, dy):
print >> self.file, 'on_mouse_motion(x=%d, y=%d, dx=%d, dy=%d)' % (
x, y, dx, dy)
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
print >> self.file, 'on_mouse_drag(x=%d, y=%d, dx=%d, dy=%d, '\
'buttons=%s, modifiers=%s)' % (
x, y, dx, dy,
mouse.buttons_string(buttons), key.modifiers_string(modifiers))
def on_mouse_press(self, x, y, button, modifiers):
print >> self.file, 'on_mouse_press(x=%d, y=%d, button=%r, '\
'modifiers=%s)' % (x, y,
mouse.buttons_string(button), key.modifiers_string(modifiers))
def on_mouse_release(self, x, y, button, modifiers):
print >> self.file, 'on_mouse_release(x=%d, y=%d, button=%r, '\
'modifiers=%s)' % (x, y,
mouse.buttons_string(button), key.modifiers_string(modifiers))
def on_mouse_scroll(self, x, y, dx, dy):
print >> self.file, 'on_mouse_scroll(x=%f, y=%f, dx=%f, dy=%f)' % (
x, y, dx, dy)
def on_close(self):
print >> self.file, 'on_close()'
def on_mouse_enter(self, x, y):
print >> self.file, 'on_mouse_enter(x=%d, y=%d)' % (x, y)
def on_mouse_leave(self, x, y):
print >> self.file, 'on_mouse_leave(x=%d, y=%d)' % (x, y)
def on_expose(self):
print >> self.file, 'on_expose()'
def on_resize(self, width, height):
print >> self.file, 'on_resize(width=%d, height=%d)' % (width, height)
def on_move(self, x, y):
print >> self.file, 'on_move(x=%d, y=%d)' % (x, y)
def on_activate(self):
print >> self.file, 'on_activate()'
def on_deactivate(self):
print >> self.file, 'on_deactivate()'
def on_show(self):
print >> self.file, 'on_show()'
def on_hide(self):
print >> self.file, 'on_hide()'
def on_context_lost(self):
print >> self.file, 'on_context_lost()'
def on_context_state_lost(self):
print >> self.file, 'on_context_state_lost()'

407
pyglet/window/key.py Normal file
View file

@ -0,0 +1,407 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Key constants and utilities for pyglet.window.
Usage::
from pyglet.window import Window
from pyglet.window import key
window = Window()
@window.event
def on_key_press(symbol, modifiers):
# Symbolic names:
if symbol == key.RETURN:
# Alphabet keys:
elif symbol == key.Z:
# Number keys:
elif symbol == key._1:
# Number keypad keys:
elif symbol == key.NUM_1:
# Modifiers:
if modifiers & key.MOD_CTRL:
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: key.py 1919 2008-03-19 07:47:01Z Alex.Holkner $'
class KeyStateHandler(dict):
'''Simple handler that tracks the state of keys on the keyboard. If a
key is pressed then this handler holds a True value for it.
For example::
>>> win = window.Window
>>> keyboard = key.KeyStateHandler()
>>> win.push_handlers(keyboard)
# Hold down the "up" arrow...
>>> keyboard[key.UP]
True
>>> keyboard[key.DOWN]
False
'''
def on_key_press(self, symbol, modifiers):
self[symbol] = True
def on_key_release(self, symbol, modifiers):
self[symbol] = False
def __getitem__(self, key):
return self.get(key, False)
def modifiers_string(modifiers):
'''Return a string describing a set of modifiers.
Example::
>>> modifiers_string(MOD_SHIFT | MOD_CTRL)
'MOD_SHIFT|MOD_CTRL'
:Parameters:
`modifiers` : int
Bitwise combination of modifier constants.
:rtype: str
'''
mod_names = []
if modifiers & MOD_SHIFT:
mod_names.append('MOD_SHIFT')
if modifiers & MOD_CTRL:
mod_names.append('MOD_CTRL')
if modifiers & MOD_ALT:
mod_names.append('MOD_ALT')
if modifiers & MOD_CAPSLOCK:
mod_names.append('MOD_CAPSLOCK')
if modifiers & MOD_NUMLOCK:
mod_names.append('MOD_NUMLOCK')
if modifiers & MOD_SCROLLLOCK:
mod_names.append('MOD_SCROLLLOCK')
if modifiers & MOD_COMMAND:
mod_names.append('MOD_COMMAND')
if modifiers & MOD_OPTION:
mod_names.append('MOD_OPTION')
return '|'.join(mod_names)
def symbol_string(symbol):
'''Return a string describing a key symbol.
Example::
>>> symbol_string(BACKSPACE)
'BACKSPACE'
:Parameters:
`symbol` : int
Symbolic key constant.
:rtype: str
'''
if symbol < 1 << 32:
return _key_names.get(symbol, str(symbol))
else:
return 'user_key(%x)' % (symbol >> 32)
def motion_string(motion):
'''Return a string describing a text motion.
Example::
>>> motion_string(MOTION_NEXT_WORD):
'MOTION_NEXT_WORD'
:Parameters:
`motion` : int
Text motion constant.
:rtype: str
'''
return _motion_names.get(motion, str(motion))
def user_key(scancode):
'''Return a key symbol for a key not supported by pyglet.
This can be used to map virtual keys or scancodes from unsupported
keyboard layouts into a machine-specific symbol. The symbol will
be meaningless on any other machine, or under a different keyboard layout.
Applications should use user-keys only when user explicitly binds them
(for example, mapping keys to actions in a game options screen).
'''
assert scancode > 0
return scancode << 32
# Modifier mask constants
MOD_SHIFT = 1 << 0
MOD_CTRL = 1 << 1
MOD_ALT = 1 << 2
MOD_CAPSLOCK = 1 << 3
MOD_NUMLOCK = 1 << 4
MOD_WINDOWS = 1 << 5
MOD_COMMAND = 1 << 6
MOD_OPTION = 1 << 7
MOD_SCROLLLOCK = 1 << 8
#: Accelerator modifier. On Windows and Linux, this is ``MOD_CTRL``, on
#: Mac OS X it's ``MOD_COMMAND``.
MOD_ACCEL = MOD_CTRL
import sys as _sys
if _sys.platform == 'darwin':
MOD_ACCEL = MOD_COMMAND
# Key symbol constants
# ASCII commands
BACKSPACE = 0xff08
TAB = 0xff09
LINEFEED = 0xff0a
CLEAR = 0xff0b
RETURN = 0xff0d
ENTER = 0xff0d # synonym
PAUSE = 0xff13
SCROLLLOCK = 0xff14
SYSREQ = 0xff15
ESCAPE = 0xff1b
SPACE = 0xff20
# Cursor control and motion
HOME = 0xff50
LEFT = 0xff51
UP = 0xff52
RIGHT = 0xff53
DOWN = 0xff54
PAGEUP = 0xff55
PAGEDOWN = 0xff56
END = 0xff57
BEGIN = 0xff58
# Misc functions
DELETE = 0xffff
SELECT = 0xff60
PRINT = 0xff61
EXECUTE = 0xff62
INSERT = 0xff63
UNDO = 0xff65
REDO = 0xff66
MENU = 0xff67
FIND = 0xff68
CANCEL = 0xff69
HELP = 0xff6a
BREAK = 0xff6b
MODESWITCH = 0xff7e
SCRIPTSWITCH = 0xff7e
# Text motion constants: these are allowed to clash with key constants
MOTION_UP = UP
MOTION_RIGHT = RIGHT
MOTION_DOWN = DOWN
MOTION_LEFT = LEFT
MOTION_NEXT_WORD = 1
MOTION_PREVIOUS_WORD = 2
MOTION_BEGINNING_OF_LINE = 3
MOTION_END_OF_LINE = 4
MOTION_NEXT_PAGE = PAGEDOWN
MOTION_PREVIOUS_PAGE = PAGEUP
MOTION_BEGINNING_OF_FILE = 5
MOTION_END_OF_FILE = 6
MOTION_BACKSPACE = BACKSPACE
MOTION_DELETE = DELETE
# Number pad
NUMLOCK = 0xff7f
NUM_SPACE = 0xff80
NUM_TAB = 0xff89
NUM_ENTER = 0xff8d
NUM_F1 = 0xff91
NUM_F2 = 0xff92
NUM_F3 = 0xff93
NUM_F4 = 0xff94
NUM_HOME = 0xff95
NUM_LEFT = 0xff96
NUM_UP = 0xff97
NUM_RIGHT = 0xff98
NUM_DOWN = 0xff99
NUM_PRIOR = 0xff9a
NUM_PAGE_UP = 0xff9a
NUM_NEXT = 0xff9b
NUM_PAGE_DOWN = 0xff9b
NUM_END = 0xff9c
NUM_BEGIN = 0xff9d
NUM_INSERT = 0xff9e
NUM_DELETE = 0xff9f
NUM_EQUAL = 0xffbd
NUM_MULTIPLY = 0xffaa
NUM_ADD = 0xffab
NUM_SEPARATOR = 0xffac
NUM_SUBTRACT = 0xffad
NUM_DECIMAL = 0xffae
NUM_DIVIDE = 0xffaf
NUM_0 = 0xffb0
NUM_1 = 0xffb1
NUM_2 = 0xffb2
NUM_3 = 0xffb3
NUM_4 = 0xffb4
NUM_5 = 0xffb5
NUM_6 = 0xffb6
NUM_7 = 0xffb7
NUM_8 = 0xffb8
NUM_9 = 0xffb9
# Function keys
F1 = 0xffbe
F2 = 0xffbf
F3 = 0xffc0
F4 = 0xffc1
F5 = 0xffc2
F6 = 0xffc3
F7 = 0xffc4
F8 = 0xffc5
F9 = 0xffc6
F10 = 0xffc7
F11 = 0xffc8
F12 = 0xffc9
F13 = 0xffca
F14 = 0xffcb
F15 = 0xffcc
F16 = 0xffcd
# Modifiers
LSHIFT = 0xffe1
RSHIFT = 0xffe2
LCTRL = 0xffe3
RCTRL = 0xffe4
CAPSLOCK = 0xffe5
LMETA = 0xffe7
RMETA = 0xffe8
LALT = 0xffe9
RALT = 0xffea
LWINDOWS = 0xffeb
RWINDOWS = 0xffec
LCOMMAND = 0xffed
RCOMMAND = 0xffee
LOPTION = 0xffd0
ROPTION = 0xffd1
# Latin-1
SPACE = 0x020
EXCLAMATION = 0x021
DOUBLEQUOTE = 0x022
HASH = 0x023
POUND = 0x023 # synonym
DOLLAR = 0x024
PERCENT = 0x025
AMPERSAND = 0x026
APOSTROPHE = 0x027
PARENLEFT = 0x028
PARENRIGHT = 0x029
ASTERISK = 0x02a
PLUS = 0x02b
COMMA = 0x02c
MINUS = 0x02d
PERIOD = 0x02e
SLASH = 0x02f
_0 = 0x030
_1 = 0x031
_2 = 0x032
_3 = 0x033
_4 = 0x034
_5 = 0x035
_6 = 0x036
_7 = 0x037
_8 = 0x038
_9 = 0x039
COLON = 0x03a
SEMICOLON = 0x03b
LESS = 0x03c
EQUAL = 0x03d
GREATER = 0x03e
QUESTION = 0x03f
AT = 0x040
BRACKETLEFT = 0x05b
BACKSLASH = 0x05c
BRACKETRIGHT = 0x05d
ASCIICIRCUM = 0x05e
UNDERSCORE = 0x05f
GRAVE = 0x060
QUOTELEFT = 0x060
A = 0x061
B = 0x062
C = 0x063
D = 0x064
E = 0x065
F = 0x066
G = 0x067
H = 0x068
I = 0x069
J = 0x06a
K = 0x06b
L = 0x06c
M = 0x06d
N = 0x06e
O = 0x06f
P = 0x070
Q = 0x071
R = 0x072
S = 0x073
T = 0x074
U = 0x075
V = 0x076
W = 0x077
X = 0x078
Y = 0x079
Z = 0x07a
BRACELEFT = 0x07b
BAR = 0x07c
BRACERIGHT = 0x07d
ASCIITILDE = 0x07e
_key_names = {}
_motion_names = {}
for _name, _value in locals().items():
if _name[:2] != '__' and _name.upper() == _name and \
not _name.startswith('MOD_'):
if _name.startswith('MOTION_'):
_motion_names[_value] = _name
else:
_key_names[_value] = _name

67
pyglet/window/mouse.py Normal file
View file

@ -0,0 +1,67 @@
# ----------------------------------------------------------------------------
# pyglet
# 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.
# ----------------------------------------------------------------------------
'''Mouse constants and utilities for pyglet.window.
'''
__docformat__ = 'restructuredtext'
__version__ = '$Id: mouse.py 1579 2008-01-15 14:47:19Z Alex.Holkner $'
def buttons_string(buttons):
'''Return a string describing a set of active mouse buttons.
Example::
>>> buttons_string(LEFT | RIGHT)
'LEFT|RIGHT'
:Parameters:
`buttons` : int
Bitwise combination of mouse button constants.
:rtype: str
'''
button_names = []
if buttons & LEFT:
button_names.append('LEFT')
if buttons & MIDDLE:
button_names.append('MIDDLE')
if buttons & RIGHT:
button_names.append('RIGHT')
return '|'.join(button_names)
# Symbolic names for the mouse buttons
LEFT = 1 << 0
MIDDLE = 1 << 1
RIGHT = 1 << 2

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more