initial version
This commit is contained in:
commit
242d4a972b
107 changed files with 86684 additions and 0 deletions
409
extract.py
Normal file
409
extract.py
Normal 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
51
hr.py
Normal 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
0
lib/__init__.py
Normal file
596
lib/h3m.py
Normal file
596
lib/h3m.py
Normal 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
38
lib/interface.py
Normal 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
382
lib/mapset.py
Normal 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
335
lib/mapview.py
Normal 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
52
lib/window.py
Normal 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
363
pyglet/__init__.py
Normal 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
297
pyglet/app/__init__.py
Normal 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
144
pyglet/app/carbon.py
Normal 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
106
pyglet/app/win32.py
Normal 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
99
pyglet/app/xlib.py
Normal 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
948
pyglet/clock.py
Normal 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
154
pyglet/com.py
Normal 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
435
pyglet/event.py
Normal 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
695
pyglet/font/__init__.py
Normal 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
442
pyglet/font/base.py
Normal 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
438
pyglet/font/carbon.py
Normal 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
354
pyglet/font/freetype.py
Normal 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
427
pyglet/font/freetype_lib.py
Normal 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
635
pyglet/font/ttf.py
Normal 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
574
pyglet/font/win32.py
Normal 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
507
pyglet/gl/__init__.py
Normal 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
452
pyglet/gl/agl.py
Normal 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
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
196
pyglet/gl/gl_info.py
Normal 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
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
127
pyglet/gl/glext_missing.py
Normal 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
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
494
pyglet/gl/glu.py
Normal 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
160
pyglet/gl/glu_info.py
Normal 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
587
pyglet/gl/glx.py
Normal 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
143
pyglet/gl/glx_info.py
Normal 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
756
pyglet/gl/glxext_arb.py
Normal 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
45
pyglet/gl/glxext_mesa.py
Normal 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
901
pyglet/gl/glxext_nv.py
Normal 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
144
pyglet/gl/lib.py
Normal 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
74
pyglet/gl/lib_agl.py
Normal 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
92
pyglet/gl/lib_glx.py
Normal 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
153
pyglet/gl/lib_wgl.py
Normal 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
374
pyglet/gl/wgl.py
Executable 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
71
pyglet/gl/wgl_info.py
Normal 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
811
pyglet/gl/wglext_arb.py
Normal 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
909
pyglet/gl/wglext_nv.py
Normal 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
721
pyglet/graphics/__init__.py
Normal 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)
|
390
pyglet/graphics/allocation.py
Normal file
390
pyglet/graphics/allocation.py
Normal 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))
|
506
pyglet/graphics/vertexattribute.py
Normal file
506
pyglet/graphics/vertexattribute.py
Normal 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,
|
||||
}
|
597
pyglet/graphics/vertexbuffer.py
Normal file
597
pyglet/graphics/vertexbuffer.py
Normal 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()
|
778
pyglet/graphics/vertexdomain.py
Normal file
778
pyglet/graphics/vertexdomain.py
Normal 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
2501
pyglet/image/__init__.py
Normal file
File diff suppressed because it is too large
Load diff
259
pyglet/image/atlas.py
Normal file
259
pyglet/image/atlas.py
Normal 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)
|
231
pyglet/image/codecs/__init__.py
Normal file
231
pyglet/image/codecs/__init__.py
Normal 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
359
pyglet/image/codecs/bmp.py
Normal 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
238
pyglet/image/codecs/dds.py
Normal 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 []
|
273
pyglet/image/codecs/gdiplus.py
Normal file
273
pyglet/image/codecs/gdiplus.py
Normal 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()
|
165
pyglet/image/codecs/gdkpixbuf2.py
Normal file
165
pyglet/image/codecs/gdkpixbuf2.py
Normal 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
169
pyglet/image/codecs/gif.py
Normal 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
110
pyglet/image/codecs/pil.py
Normal 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
110
pyglet/image/codecs/png.py
Normal 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
1092
pyglet/image/codecs/pypng.py
Normal file
File diff suppressed because it is too large
Load diff
287
pyglet/image/codecs/quicktime.py
Normal file
287
pyglet/image/codecs/quicktime.py
Normal 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
386
pyglet/image/codecs/s3tc.py
Normal 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
191
pyglet/info.py
Normal 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
303
pyglet/lib.py
Normal 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
1404
pyglet/media/__init__.py
Normal file
File diff suppressed because it is too large
Load diff
477
pyglet/media/avbin.py
Normal file
477
pyglet/media/avbin.py
Normal 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)
|
34
pyglet/media/drivers/__init__.py
Normal file
34
pyglet/media/drivers/__init__.py
Normal 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.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
301
pyglet/media/drivers/alsa/__init__.py
Normal file
301
pyglet/media/drivers/alsa/__init__.py
Normal 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
|
9673
pyglet/media/drivers/alsa/asound.py
Normal file
9673
pyglet/media/drivers/alsa/asound.py
Normal file
File diff suppressed because it is too large
Load diff
394
pyglet/media/drivers/directsound/__init__.py
Normal file
394
pyglet/media/drivers/directsound/__init__.py
Normal 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
|
408
pyglet/media/drivers/directsound/lib_dsound.py
Normal file
408
pyglet/media/drivers/directsound/lib_dsound.py
Normal 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
|
||||
|
360
pyglet/media/drivers/openal/__init__.py
Normal file
360
pyglet/media/drivers/openal/__init__.py
Normal 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
|
||||
|
286
pyglet/media/drivers/openal/lib_alc.py
Normal file
286
pyglet/media/drivers/openal/lib_alc.py
Normal 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']
|
655
pyglet/media/drivers/openal/lib_openal.py
Normal file
655
pyglet/media/drivers/openal/lib_openal.py
Normal 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']
|
158
pyglet/media/drivers/silent.py
Normal file
158
pyglet/media/drivers/silent.py
Normal 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
181
pyglet/media/procedural.py
Normal 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
249
pyglet/media/riff.py
Normal 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
685
pyglet/resource.py
Normal 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
568
pyglet/sprite.py
Normal 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
505
pyglet/text/__init__.py
Normal 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
591
pyglet/text/caret.py
Normal 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
731
pyglet/text/document.py
Normal 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()
|
40
pyglet/text/formats/__init__.py
Normal file
40
pyglet/text/formats/__init__.py
Normal 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 $'
|
139
pyglet/text/formats/attributed.py
Normal file
139
pyglet/text/formats/attributed.py
Normal 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
364
pyglet/text/formats/html.py
Normal 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
|
47
pyglet/text/formats/plaintext.py
Normal file
47
pyglet/text/formats/plaintext.py
Normal 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
|
261
pyglet/text/formats/structured.py
Normal file
261
pyglet/text/formats/structured.py
Normal 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
2390
pyglet/text/layout.py
Normal file
File diff suppressed because it is too large
Load diff
418
pyglet/text/runlist.py
Normal file
418
pyglet/text/runlist.py
Normal 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
1682
pyglet/window/__init__.py
Normal file
File diff suppressed because it is too large
Load diff
1366
pyglet/window/carbon/__init__.py
Normal file
1366
pyglet/window/carbon/__init__.py
Normal file
File diff suppressed because it is too large
Load diff
525
pyglet/window/carbon/constants.py
Normal file
525
pyglet/window/carbon/constants.py
Normal 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
|
270
pyglet/window/carbon/quartzkey.py
Normal file
270
pyglet/window/carbon/quartzkey.py
Normal 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,
|
||||
}
|
||||
|
||||
|
159
pyglet/window/carbon/types.py
Normal file
159
pyglet/window/carbon/types.py
Normal 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
177
pyglet/window/event.py
Normal 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
407
pyglet/window/key.py
Normal 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
67
pyglet/window/mouse.py
Normal 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
|
1191
pyglet/window/win32/__init__.py
Normal file
1191
pyglet/window/win32/__init__.py
Normal file
File diff suppressed because it is too large
Load diff
4986
pyglet/window/win32/constants.py
Normal file
4986
pyglet/window/win32/constants.py
Normal file
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
Loading…
Reference in a new issue