General modernizations and porting to Python3
Included some missing files
|
@ -1,3 +1,8 @@
|
|||
syntax: glob
|
||||
*.pyc
|
||||
settings.cfg
|
||||
lib
|
||||
bin
|
||||
include
|
||||
pip-selfcheck.json
|
||||
__pycache__
|
||||
|
|
18
__init__.py
|
@ -1,4 +1,4 @@
|
|||
import roc
|
||||
from roc_core import *
|
||||
import universe
|
||||
import pipeline
|
||||
import inputs
|
||||
|
@ -9,4 +9,18 @@ import enums
|
|||
import files
|
||||
import gametimer
|
||||
import shader
|
||||
import video
|
||||
import video
|
||||
|
||||
#from .universe import *
|
||||
#from .pipeline import *
|
||||
#from .inputs import *
|
||||
#from .physics import *
|
||||
#from .models import *
|
||||
#from .gamedata import *
|
||||
#from .enums import *
|
||||
#from .files import *
|
||||
#from .gametimer import *
|
||||
#from .shader import *
|
||||
#from .video import *
|
||||
#
|
||||
|
||||
|
|
2
asset.py
|
@ -1,5 +1,5 @@
|
|||
|
||||
from gameobj import gameobj
|
||||
from .gameobj import gameobj
|
||||
|
||||
class asset_manager(object):
|
||||
def __init__(self):
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from gameobj import game_object
|
||||
from .gameobj import game_object
|
||||
import math
|
||||
from quat import *
|
||||
from py3dutil import vect
|
||||
|
|
90
config.py
|
@ -1,45 +1,45 @@
|
|||
import os
|
||||
import files
|
||||
|
||||
class configmanager(object):
|
||||
def __init__(self):
|
||||
self.filepath = None
|
||||
self.data = {}
|
||||
|
||||
def load(self):
|
||||
self.filepath = os.path.join(files.get_basedir(), 'settings.cfg')
|
||||
if not os.path.exists(self.filepath):
|
||||
return
|
||||
fd = open(self.filepath, 'r')
|
||||
for x in fd:
|
||||
x = x.strip()
|
||||
if not '=' in x:
|
||||
continue
|
||||
x = x.split('=')
|
||||
k = x[0].strip()
|
||||
v = '='.join(x[1:]).strip()
|
||||
self.data[k] = v
|
||||
fd.close()
|
||||
|
||||
|
||||
def save(self):
|
||||
fd = open(self.filepath, 'w')
|
||||
for k, v in self.data.items():
|
||||
fd.write("%s = %s\n" % (k, v))
|
||||
fd.close()
|
||||
|
||||
def read_key(self, key):
|
||||
if key in self.data:
|
||||
return self.data[key]
|
||||
else:
|
||||
return None
|
||||
|
||||
def write_key(self, key, value):
|
||||
self.data[key] = value
|
||||
|
||||
def init():
|
||||
global mgr
|
||||
mgr = configmanager()
|
||||
mgr.load()
|
||||
|
||||
mgr = None
|
||||
import os
|
||||
import files
|
||||
|
||||
class configmanager(object):
|
||||
def __init__(self):
|
||||
self.filepath = None
|
||||
self.data = {}
|
||||
|
||||
def load(self):
|
||||
self.filepath = os.path.join(files.get_basedir(), 'settings.cfg')
|
||||
if not os.path.exists(self.filepath):
|
||||
return
|
||||
fd = open(self.filepath, 'r')
|
||||
for x in fd:
|
||||
x = x.strip()
|
||||
if not '=' in x:
|
||||
continue
|
||||
x = x.split('=')
|
||||
k = x[0].strip()
|
||||
v = '='.join(x[1:]).strip()
|
||||
self.data[k] = v
|
||||
fd.close()
|
||||
|
||||
|
||||
def save(self):
|
||||
fd = open(self.filepath, 'w')
|
||||
for k, v in list(self.data.items()):
|
||||
fd.write("%s = %s\n" % (k, v))
|
||||
fd.close()
|
||||
|
||||
def read_key(self, key):
|
||||
if key in self.data:
|
||||
return self.data[key]
|
||||
else:
|
||||
return None
|
||||
|
||||
def write_key(self, key, value):
|
||||
self.data[key] = value
|
||||
|
||||
def init():
|
||||
global mgr
|
||||
mgr = configmanager()
|
||||
mgr.load()
|
||||
|
||||
mgr = None
|
||||
|
|
BIN
data/font/coure10.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
102
data/font/coure10.tfd
Normal file
|
@ -0,0 +1,102 @@
|
|||
fontheader
|
||||
32,128
|
||||
9,14
|
||||
13,8
|
||||
128,128
|
||||
charsizes
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
||||
8,13
|
BIN
data/font/micross20.png
Normal file
After Width: | Height: | Size: 14 KiB |
102
data/font/micross20.tfd
Normal file
|
@ -0,0 +1,102 @@
|
|||
fontheader
|
||||
32,128
|
||||
21,25
|
||||
11,9
|
||||
256,256
|
||||
charsizes
|
||||
5,24
|
||||
6,24
|
||||
7,24
|
||||
13,24
|
||||
11,24
|
||||
17,24
|
||||
13,24
|
||||
4,24
|
||||
7,24
|
||||
7,24
|
||||
8,24
|
||||
11,24
|
||||
6,24
|
||||
7,24
|
||||
6,24
|
||||
6,24
|
||||
11,24
|
||||
12,24
|
||||
12,24
|
||||
11,24
|
||||
12,24
|
||||
11,24
|
||||
11,24
|
||||
11,24
|
||||
11,24
|
||||
11,24
|
||||
6,24
|
||||
6,24
|
||||
12,24
|
||||
11,24
|
||||
12,24
|
||||
12,24
|
||||
20,24
|
||||
15,24
|
||||
14,24
|
||||
14,24
|
||||
15,24
|
||||
14,24
|
||||
12,24
|
||||
15,24
|
||||
15,24
|
||||
6,24
|
||||
10,24
|
||||
14,24
|
||||
12,24
|
||||
17,24
|
||||
15,24
|
||||
16,24
|
||||
14,24
|
||||
16,24
|
||||
14,24
|
||||
13,24
|
||||
13,24
|
||||
15,24
|
||||
14,24
|
||||
19,24
|
||||
14,24
|
||||
14,24
|
||||
13,24
|
||||
6,24
|
||||
6,24
|
||||
6,24
|
||||
9,24
|
||||
11,24
|
||||
7,24
|
||||
11,24
|
||||
11,24
|
||||
10,24
|
||||
11,24
|
||||
11,24
|
||||
7,24
|
||||
11,24
|
||||
11,24
|
||||
4,24
|
||||
5,24
|
||||
10,24
|
||||
4,24
|
||||
16,24
|
||||
11,24
|
||||
12,24
|
||||
11,24
|
||||
11,24
|
||||
7,24
|
||||
11,24
|
||||
7,24
|
||||
11,24
|
||||
10,24
|
||||
15,24
|
||||
10,24
|
||||
10,24
|
||||
11,24
|
||||
7,24
|
||||
6,24
|
||||
8,24
|
||||
12,24
|
||||
6,24
|
BIN
data/font/micross42.png
Normal file
After Width: | Height: | Size: 34 KiB |
102
data/font/micross42.tfd
Normal file
|
@ -0,0 +1,102 @@
|
|||
fontheader
|
||||
32,128
|
||||
43,49
|
||||
11,10
|
||||
512,512
|
||||
charsizes
|
||||
11,48
|
||||
12,48
|
||||
15,48
|
||||
25,48
|
||||
23,48
|
||||
38,48
|
||||
28,48
|
||||
8,48
|
||||
15,48
|
||||
15,48
|
||||
16,48
|
||||
24,48
|
||||
12,48
|
||||
13,48
|
||||
12,48
|
||||
12,48
|
||||
24,48
|
||||
24,48
|
||||
23,48
|
||||
24,48
|
||||
24,48
|
||||
24,48
|
||||
24,48
|
||||
23,48
|
||||
24,48
|
||||
24,48
|
||||
12,48
|
||||
12,48
|
||||
24,48
|
||||
24,48
|
||||
24,48
|
||||
24,48
|
||||
42,48
|
||||
30,48
|
||||
27,48
|
||||
30,48
|
||||
30,48
|
||||
28,48
|
||||
26,48
|
||||
33,48
|
||||
30,48
|
||||
12,48
|
||||
21,48
|
||||
28,48
|
||||
23,48
|
||||
34,48
|
||||
30,48
|
||||
33,48
|
||||
28,48
|
||||
33,48
|
||||
30,48
|
||||
28,48
|
||||
26,48
|
||||
30,48
|
||||
28,48
|
||||
40,48
|
||||
28,48
|
||||
28,48
|
||||
26,48
|
||||
12,48
|
||||
12,48
|
||||
12,48
|
||||
20,48
|
||||
24,48
|
||||
14,48
|
||||
24,48
|
||||
23,48
|
||||
21,48
|
||||
23,48
|
||||
23,48
|
||||
13,48
|
||||
23,48
|
||||
24,48
|
||||
10,48
|
||||
12,48
|
||||
22,48
|
||||
10,48
|
||||
36,48
|
||||
24,48
|
||||
22,48
|
||||
23,48
|
||||
23,48
|
||||
15,48
|
||||
21,48
|
||||
12,48
|
||||
24,48
|
||||
21,48
|
||||
31,48
|
||||
21,48
|
||||
21,48
|
||||
21,48
|
||||
14,48
|
||||
11,48
|
||||
13,48
|
||||
25,48
|
||||
12,48
|
BIN
data/font/monopro6.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
102
data/font/monopro6.tfd
Normal file
|
@ -0,0 +1,102 @@
|
|||
fontheader
|
||||
32,128
|
||||
7,11
|
||||
13,8
|
||||
128,128
|
||||
charsizes
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
BIN
data/font/proggysquaresz12.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
102
data/font/proggysquaresz12.tfd
Normal file
|
@ -0,0 +1,102 @@
|
|||
fontheader
|
||||
32,128
|
||||
8,12
|
||||
12,8
|
||||
128,128
|
||||
charsizes
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
||||
7,11
|
BIN
data/font/proggytinysz12.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
102
data/font/proggytinysz12.tfd
Normal file
|
@ -0,0 +1,102 @@
|
|||
fontheader
|
||||
32,128
|
||||
7,11
|
||||
13,8
|
||||
128,128
|
||||
charsizes
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
||||
6,10
|
BIN
data/font/vgafix12.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
102
data/font/vgafix12.tfd
Normal file
|
@ -0,0 +1,102 @@
|
|||
fontheader
|
||||
32,128
|
||||
9,16
|
||||
14,8
|
||||
128,128
|
||||
charsizes
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
||||
8,15
|
BIN
data/tex/black.png
Executable file → Normal file
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 281 B |
BIN
data/tex/dralthi.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
data/tex/nm_flat.png
Executable file → Normal file
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 298 B |
BIN
data/tex/plasma1.png
Executable file → Normal file
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 9.7 KiB |
BIN
data/tex/plasma2.png
Executable file → Normal file
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 17 KiB |
BIN
data/tex/star_sprite_main.png
Normal file
After Width: | Height: | Size: 283 B |
BIN
data/tex/test1.png
Executable file → Normal file
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 17 KiB |
BIN
data/tex/white.png
Executable file → Normal file
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 283 B |
BIN
data/tex/whitelight_static.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
422
fonts.py
|
@ -1,212 +1,212 @@
|
|||
import os
|
||||
import pygame
|
||||
from OpenGL.GL import *
|
||||
|
||||
class TextureFile(object):
|
||||
def __init__(self):
|
||||
self.id = None
|
||||
self.filename = None
|
||||
self.h = None
|
||||
self.w = None
|
||||
|
||||
def load(self, filename):
|
||||
self.filename = filename
|
||||
img = pygame.image.load(filename)
|
||||
img.convert_alpha()
|
||||
glActiveTexture(GL_TEXTURE0)
|
||||
texid = glGenTextures(1)
|
||||
#print "Generated font texture id %s" % (texid,)
|
||||
|
||||
self.id = texid
|
||||
|
||||
imgdata = pygame.image.tostring(img, "RGBA")
|
||||
imgr = img.get_rect()
|
||||
self.h = imgr.h
|
||||
self.w = imgr.w
|
||||
|
||||
dimension = GL_TEXTURE_2D
|
||||
glBindTexture(dimension, texid)
|
||||
glTexImage2D(dimension, 0, GL_RGBA8, imgr.w, imgr.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgdata)
|
||||
glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP)
|
||||
glTexParameteri(dimension, GL_TEXTURE_WRAP_T, GL_CLAMP)
|
||||
glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
||||
glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
||||
|
||||
class TexFont(object):
|
||||
def __init__(self):
|
||||
self.image = None
|
||||
self.start = None
|
||||
self.end = None
|
||||
self.rows = None
|
||||
self.cols = None
|
||||
self.charheight = None
|
||||
self.charwidth = None
|
||||
self.texwidth = None
|
||||
self.texheight = None
|
||||
self.gltex = None
|
||||
self.monospace = False
|
||||
self.charsizes = []
|
||||
self.colors = (1.0, 1.0, 1.0, 1.0)
|
||||
|
||||
@staticmethod
|
||||
def new(fontdir, fontname):
|
||||
tf = TexFont()
|
||||
tf.load_definition(os.path.join(fontdir, "%s.tfd" % (fontname,)))
|
||||
tf.load_texture(os.path.join(fontdir, "%s.png" % (fontname,)))
|
||||
return tf
|
||||
|
||||
def render(self, text, color=None):
|
||||
if color is None:
|
||||
color = self.colors
|
||||
#print "Binding texture %s" % (self.gltex.id,)
|
||||
glActiveTexture(GL_TEXTURE0)
|
||||
dimension = GL_TEXTURE_2D
|
||||
glBindTexture(GL_TEXTURE_2D, self.gltex.id)
|
||||
glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP)
|
||||
glTexParameteri(dimension, GL_TEXTURE_WRAP_T, GL_CLAMP)
|
||||
glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
||||
glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
||||
|
||||
glBegin(GL_TRIANGLES)
|
||||
glNormal3f(0.0, 0.0, 1.0)
|
||||
glColor4f(*color)
|
||||
#print "Rendering font"
|
||||
offset = 0.0
|
||||
for i, letter in enumerate(text):
|
||||
offset = self.render_letter(letter, offset)
|
||||
|
||||
glEnd()
|
||||
|
||||
|
||||
def render_letter(self, letter, offset):
|
||||
charidx = self.mapchar(letter)
|
||||
x1, y1, x2, y2 = self.get_coordinates(charidx)
|
||||
cx, cy = self.charsize(charidx)
|
||||
|
||||
#print "Printing letter %s(%s) from %s, %s to %s, %s using texcoords %s, %s, %s, %s" % (letter, charidx, offset, 0.0, offset + cx, cy, x1*128.0, y1*128.0, x2*128.0, y2*128.0)
|
||||
glTexCoord2f(x1, y1); glVertex3f( offset + 0.0, 0.0, 0.0)
|
||||
glTexCoord2f(x1, y2); glVertex3f( offset + 0.0, cy, 0.0)
|
||||
glTexCoord2f(x2, y1); glVertex3f( offset + cx, 0.0, 0.0)
|
||||
glTexCoord2f(x2, y1); glVertex3f( offset + cx, 0.0, 0.0)
|
||||
glTexCoord2f(x1, y2); glVertex3f( offset + 0.0, cy, 0.0)
|
||||
glTexCoord2f(x2, y2); glVertex3f( offset + cx, cy, 0.0)
|
||||
glTexCoord2f(0.0, 0.0)
|
||||
|
||||
return offset + cx
|
||||
|
||||
def charsize(self, idx):
|
||||
if self.monospace:
|
||||
return (self.charwidth, self.charheight)
|
||||
else:
|
||||
return self.charsizes[idx]
|
||||
|
||||
|
||||
|
||||
def mapchar(self, char):
|
||||
"""
|
||||
Maps a char to an index.
|
||||
|
||||
Takes a character either as ascii ordinal number or as a 1-length string.
|
||||
Returns the index of that character in this texture font.
|
||||
|
||||
If the character is not valid in this texture font, the index number will
|
||||
instead reference the last character in the font, which is usually a
|
||||
symbol for unknown characters (either totally blank or a box.)
|
||||
"""
|
||||
|
||||
if isinstance(char, basestring):
|
||||
char = ord(char)
|
||||
|
||||
if char >= self.start and char < self.end:
|
||||
return char - self.start
|
||||
else:
|
||||
return self.end - self.start - 1
|
||||
|
||||
|
||||
def get_coordinates(self, idx):
|
||||
"""
|
||||
Maps an index to their x, y coordinates in the texture.
|
||||
|
||||
Invalid indexes will be mapped to the last character in the font.
|
||||
"""
|
||||
if idx < 0 or idx >= (self.end - self.start):
|
||||
idx = (self.end - self.start - 1)
|
||||
|
||||
xp1 = (idx % self.cols) * (self.charwidth + 1)
|
||||
yp1 = (idx // self.cols) * (self.charheight + 1)
|
||||
|
||||
if self.monospace:
|
||||
xp2 = xp1 + self.charwidth + 1
|
||||
yp2 = yp1 + self.charheight + 1
|
||||
else:
|
||||
xp2 = xp1 + self.charsizes[idx][0] + 1
|
||||
yp2 = yp1 + self.charsizes[idx][1] + 1
|
||||
|
||||
xtc1 = (float(xp1) + 0.0) / self.texwidth
|
||||
ytc1 = (float(yp1) + 0.0) / self.texheight
|
||||
xtc2 = (float(xp2) - 1.0) / self.texwidth
|
||||
ytc2 = (float(yp2) - 1.0) / self.texheight
|
||||
|
||||
return (xtc1, ytc1, xtc2, ytc2)
|
||||
|
||||
def load_definition(self, deffile):
|
||||
"""
|
||||
Loads a texture font definition (.tfd).
|
||||
|
||||
These simple datafiles are generated by fontmaker.py to provide character
|
||||
spacing information about the associated texture font.
|
||||
|
||||
This should be called before load_texture.
|
||||
"""
|
||||
dd = open(deffile, 'r')
|
||||
|
||||
if dd.readline() != "fontheader\n":
|
||||
raise ValueError('"%s" is not a font definition file' % (deffile,))
|
||||
|
||||
def nextline(dd):
|
||||
return [int(x) for x in dd.readline().rstrip().split(',')]
|
||||
|
||||
self.start, self.end = nextline(dd)
|
||||
self.charwidth, self.charheight = nextline(dd)
|
||||
self.cols, self.rows = nextline(dd)
|
||||
self.texwidth, self.texheight = nextline(dd)
|
||||
|
||||
self.charwidth -= 1
|
||||
self.charheight -= 1
|
||||
|
||||
assert dd.readline() == "charsizes\n"
|
||||
|
||||
self.charsizes = [None] * (self.end - self.start)
|
||||
monospace = True
|
||||
monoheight = True
|
||||
|
||||
for i in xrange(0, (self.end - self.start)):
|
||||
x, y = nextline(dd)
|
||||
if x != self.charwidth:
|
||||
monospace = False
|
||||
if y != self.charheight:
|
||||
monoheight = False
|
||||
self.charsizes[i] = (x, y)
|
||||
|
||||
"not yet capable of dealing properly with fonts of variable height"
|
||||
assert monoheight
|
||||
self.monospace = monospace
|
||||
|
||||
|
||||
def load_texture(self, texfile):
|
||||
"""
|
||||
Loads a texture image (.png)
|
||||
|
||||
The PNG image should contain 32-bit color with alpha channel. The image
|
||||
will be loaded as an OpenGL texture.
|
||||
|
||||
This function must be called after load_definition.
|
||||
"""
|
||||
tf = TextureFile()
|
||||
tf.load(texfile)
|
||||
self.gltex = tf
|
||||
assert self.gltex.w == self.texwidth
|
||||
assert self.gltex.h == self.texheight
|
||||
|
||||
|
||||
import os
|
||||
import pygame
|
||||
from OpenGL.GL import *
|
||||
|
||||
class TextureFile(object):
|
||||
def __init__(self):
|
||||
self.id = None
|
||||
self.filename = None
|
||||
self.h = None
|
||||
self.w = None
|
||||
|
||||
def load(self, filename):
|
||||
self.filename = filename
|
||||
img = pygame.image.load(filename)
|
||||
img.convert_alpha()
|
||||
glActiveTexture(GL_TEXTURE0)
|
||||
texid = glGenTextures(1)
|
||||
#print "Generated font texture id %s" % (texid,)
|
||||
|
||||
self.id = texid
|
||||
|
||||
imgdata = pygame.image.tostring(img, "RGBA")
|
||||
imgr = img.get_rect()
|
||||
self.h = imgr.h
|
||||
self.w = imgr.w
|
||||
|
||||
dimension = GL_TEXTURE_2D
|
||||
glBindTexture(dimension, texid)
|
||||
glTexImage2D(dimension, 0, GL_RGBA8, imgr.w, imgr.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgdata)
|
||||
glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP)
|
||||
glTexParameteri(dimension, GL_TEXTURE_WRAP_T, GL_CLAMP)
|
||||
glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
||||
glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
||||
|
||||
class TexFont(object):
|
||||
def __init__(self):
|
||||
self.image = None
|
||||
self.start = None
|
||||
self.end = None
|
||||
self.rows = None
|
||||
self.cols = None
|
||||
self.charheight = None
|
||||
self.charwidth = None
|
||||
self.texwidth = None
|
||||
self.texheight = None
|
||||
self.gltex = None
|
||||
self.monospace = False
|
||||
self.charsizes = []
|
||||
self.colors = (1.0, 1.0, 1.0, 1.0)
|
||||
|
||||
@staticmethod
|
||||
def new(fontdir, fontname):
|
||||
tf = TexFont()
|
||||
tf.load_definition(os.path.join(fontdir, "%s.tfd" % (fontname,)))
|
||||
tf.load_texture(os.path.join(fontdir, "%s.png" % (fontname,)))
|
||||
return tf
|
||||
|
||||
def render(self, text, color=None):
|
||||
if color is None:
|
||||
color = self.colors
|
||||
#print "Binding texture %s" % (self.gltex.id,)
|
||||
glActiveTexture(GL_TEXTURE0)
|
||||
dimension = GL_TEXTURE_2D
|
||||
glBindTexture(GL_TEXTURE_2D, self.gltex.id)
|
||||
glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP)
|
||||
glTexParameteri(dimension, GL_TEXTURE_WRAP_T, GL_CLAMP)
|
||||
glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
||||
glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
||||
|
||||
glBegin(GL_TRIANGLES)
|
||||
glNormal3f(0.0, 0.0, 1.0)
|
||||
glColor4f(*color)
|
||||
#print "Rendering font"
|
||||
offset = 0.0
|
||||
for i, letter in enumerate(text):
|
||||
offset = self.render_letter(letter, offset)
|
||||
|
||||
glEnd()
|
||||
|
||||
|
||||
def render_letter(self, letter, offset):
|
||||
charidx = self.mapchar(letter)
|
||||
x1, y1, x2, y2 = self.get_coordinates(charidx)
|
||||
cx, cy = self.charsize(charidx)
|
||||
|
||||
#print "Printing letter %s(%s) from %s, %s to %s, %s using texcoords %s, %s, %s, %s" % (letter, charidx, offset, 0.0, offset + cx, cy, x1*128.0, y1*128.0, x2*128.0, y2*128.0)
|
||||
glTexCoord2f(x1, y1); glVertex3f( offset + 0.0, 0.0, 0.0)
|
||||
glTexCoord2f(x1, y2); glVertex3f( offset + 0.0, cy, 0.0)
|
||||
glTexCoord2f(x2, y1); glVertex3f( offset + cx, 0.0, 0.0)
|
||||
glTexCoord2f(x2, y1); glVertex3f( offset + cx, 0.0, 0.0)
|
||||
glTexCoord2f(x1, y2); glVertex3f( offset + 0.0, cy, 0.0)
|
||||
glTexCoord2f(x2, y2); glVertex3f( offset + cx, cy, 0.0)
|
||||
glTexCoord2f(0.0, 0.0)
|
||||
|
||||
return offset + cx
|
||||
|
||||
def charsize(self, idx):
|
||||
if self.monospace:
|
||||
return (self.charwidth, self.charheight)
|
||||
else:
|
||||
return self.charsizes[idx]
|
||||
|
||||
|
||||
|
||||
def mapchar(self, char):
|
||||
"""
|
||||
Maps a char to an index.
|
||||
|
||||
Takes a character either as ascii ordinal number or as a 1-length string.
|
||||
Returns the index of that character in this texture font.
|
||||
|
||||
If the character is not valid in this texture font, the index number will
|
||||
instead reference the last character in the font, which is usually a
|
||||
symbol for unknown characters (either totally blank or a box.)
|
||||
"""
|
||||
|
||||
if isinstance(char, str):
|
||||
char = ord(char)
|
||||
|
||||
if char >= self.start and char < self.end:
|
||||
return char - self.start
|
||||
else:
|
||||
return self.end - self.start - 1
|
||||
|
||||
|
||||
def get_coordinates(self, idx):
|
||||
"""
|
||||
Maps an index to their x, y coordinates in the texture.
|
||||
|
||||
Invalid indexes will be mapped to the last character in the font.
|
||||
"""
|
||||
if idx < 0 or idx >= (self.end - self.start):
|
||||
idx = (self.end - self.start - 1)
|
||||
|
||||
xp1 = (idx % self.cols) * (self.charwidth + 1)
|
||||
yp1 = (idx // self.cols) * (self.charheight + 1)
|
||||
|
||||
if self.monospace:
|
||||
xp2 = xp1 + self.charwidth + 1
|
||||
yp2 = yp1 + self.charheight + 1
|
||||
else:
|
||||
xp2 = xp1 + self.charsizes[idx][0] + 1
|
||||
yp2 = yp1 + self.charsizes[idx][1] + 1
|
||||
|
||||
xtc1 = (float(xp1) + 0.0) / self.texwidth
|
||||
ytc1 = (float(yp1) + 0.0) / self.texheight
|
||||
xtc2 = (float(xp2) - 1.0) / self.texwidth
|
||||
ytc2 = (float(yp2) - 1.0) / self.texheight
|
||||
|
||||
return (xtc1, ytc1, xtc2, ytc2)
|
||||
|
||||
def load_definition(self, deffile):
|
||||
"""
|
||||
Loads a texture font definition (.tfd).
|
||||
|
||||
These simple datafiles are generated by fontmaker.py to provide character
|
||||
spacing information about the associated texture font.
|
||||
|
||||
This should be called before load_texture.
|
||||
"""
|
||||
dd = open(deffile, 'r')
|
||||
|
||||
if dd.readline() != "fontheader\n":
|
||||
raise ValueError('"%s" is not a font definition file' % (deffile,))
|
||||
|
||||
def nextline(dd):
|
||||
return [int(x) for x in dd.readline().rstrip().split(',')]
|
||||
|
||||
self.start, self.end = nextline(dd)
|
||||
self.charwidth, self.charheight = nextline(dd)
|
||||
self.cols, self.rows = nextline(dd)
|
||||
self.texwidth, self.texheight = nextline(dd)
|
||||
|
||||
self.charwidth -= 1
|
||||
self.charheight -= 1
|
||||
|
||||
assert dd.readline() == "charsizes\n"
|
||||
|
||||
self.charsizes = [None] * (self.end - self.start)
|
||||
monospace = True
|
||||
monoheight = True
|
||||
|
||||
for i in range(0, (self.end - self.start)):
|
||||
x, y = nextline(dd)
|
||||
if x != self.charwidth:
|
||||
monospace = False
|
||||
if y != self.charheight:
|
||||
monoheight = False
|
||||
self.charsizes[i] = (x, y)
|
||||
|
||||
"not yet capable of dealing properly with fonts of variable height"
|
||||
assert monoheight
|
||||
self.monospace = monospace
|
||||
|
||||
|
||||
def load_texture(self, texfile):
|
||||
"""
|
||||
Loads a texture image (.png)
|
||||
|
||||
The PNG image should contain 32-bit color with alpha channel. The image
|
||||
will be loaded as an OpenGL texture.
|
||||
|
||||
This function must be called after load_definition.
|
||||
"""
|
||||
tf = TextureFile()
|
||||
tf.load(texfile)
|
||||
self.gltex = tf
|
||||
assert self.gltex.w == self.texwidth
|
||||
assert self.gltex.h == self.texheight
|
||||
|
||||
|
||||
|
552
gamedata.py
|
@ -1,276 +1,276 @@
|
|||
import glob
|
||||
import os
|
||||
try:
|
||||
from xml.etree.cElementTree import parse
|
||||
except ImportError:
|
||||
from elementtree.ElementTree import parse
|
||||
import files
|
||||
import shader
|
||||
from deprecate import deprecated
|
||||
|
||||
class MissingNode(object):
|
||||
def __init__(self):
|
||||
self.text = None
|
||||
def get(self, name):
|
||||
return None
|
||||
|
||||
class GameDataTagDef(object):
|
||||
def __init__(self):
|
||||
self.multi = False
|
||||
self.opt = False
|
||||
self.type = None
|
||||
self.default = None
|
||||
|
||||
class GameDataNode(object):
|
||||
def __init__(self):
|
||||
self.dict = {}
|
||||
self.missing = False
|
||||
|
||||
def __setitem__(self, name, val):
|
||||
self.dict[name] = val
|
||||
def __getitem__(self, name):
|
||||
return self.dict[name]._value
|
||||
def __getattr__(self, name):
|
||||
if name == 'dict':
|
||||
raise AttributeError, name
|
||||
try:
|
||||
return self.dict[name]
|
||||
except KeyError:
|
||||
if name == '_value':
|
||||
return None
|
||||
raise AttributeError, name
|
||||
def __setattr__(self, name, val):
|
||||
if name == 'dict':
|
||||
return object.__setattr__(self, name, val)
|
||||
try:
|
||||
self.dict[name] = val
|
||||
except KeyError:
|
||||
object.__setattr__(self, name, val)
|
||||
def add_multi(self, key, value):
|
||||
if not self.dict.has_key(key):
|
||||
self.dict[key] = []
|
||||
self.dict[key].append(value)
|
||||
def add_single(self, key, value):
|
||||
self.dict[key] = value
|
||||
def __repr__(self):
|
||||
return """<GameDataNode "%s">""" % (self.dict['_name'],)
|
||||
def has_key(self, key):
|
||||
return self.dict.has_key(key)
|
||||
|
||||
class XMLGameDataReader(object):
|
||||
def __init__(self, bin, xml):
|
||||
self._bin = bin
|
||||
self._xml = xml
|
||||
self._tree = self.construct()
|
||||
self._name = xml.tag
|
||||
|
||||
|
||||
def value_as_type(self, value, type):
|
||||
if type == 'string':
|
||||
return value
|
||||
elif type == 'bool':
|
||||
if value and value[0].lower() in ('y', 't', '1'):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif type == 'int':
|
||||
return int(value)
|
||||
elif type == 'float':
|
||||
return float(value)
|
||||
elif type == 'csvarray':
|
||||
# csvarrays are always ints...
|
||||
return [int(x.strip()) for x in value.split(',')]
|
||||
else:
|
||||
raise TypeError, type
|
||||
|
||||
def create_datatag_def(self, tag):
|
||||
d = GameDataTagDef()
|
||||
if tag.get('multiple') != None and tag.get('multiple')[0].lower() == 'y':
|
||||
d.multi = True
|
||||
if tag.get('optional') != None and tag.get('optional')[0].lower() == 'y':
|
||||
d.opt = True
|
||||
if tag.get('data') != None:
|
||||
d.type = tag.get('data')
|
||||
if tag.get('default') != None:
|
||||
d.default = self.value_as_type(tag.get('default'), d.type)
|
||||
d.opt = True
|
||||
return d
|
||||
|
||||
def create_attribute_def(self, tag):
|
||||
return self.create_datatag_def(tag)
|
||||
|
||||
def construct_node(self, bin, xml, allow_missing=False):
|
||||
node = GameDataNode()
|
||||
if isinstance(xml, MissingNode):
|
||||
node.missing = True
|
||||
value = None
|
||||
if bin.tag == 'datatag':
|
||||
df = self.create_datatag_def(bin)
|
||||
if df.type:
|
||||
value = xml.text
|
||||
if df.type == 'bool':
|
||||
# if tag exists, since it is a bool, that means it's True
|
||||
value = not node.missing
|
||||
elif (node.missing or value == None) and df.opt:
|
||||
value = df.default
|
||||
elif (node.missing or value == None) and not allow_missing:
|
||||
raise ValueError, "Missing value for mandatory tag %s" % (bin.get('name'),)
|
||||
elif (node.missing or value == None):
|
||||
value = None
|
||||
else:
|
||||
value = self.value_as_type(value, df.type)
|
||||
|
||||
node['_value'] = value
|
||||
elif bin.tag == 'attribute':
|
||||
df = self.create_attribute_def(bin)
|
||||
if df.type:
|
||||
value = xml.get(bin.get('name'))
|
||||
if value == None and df.opt:
|
||||
value = df.default
|
||||
elif not value and not allow_missing:
|
||||
raise ValueError, "Missing value for mandatory tag %s" % (bin.get('name'),)
|
||||
elif not value:
|
||||
value = None
|
||||
else:
|
||||
value = self.value_as_type(value, df.type)
|
||||
|
||||
node['_value'] = value
|
||||
|
||||
node['_def'] = df
|
||||
node['_name'] = bin.get('name')
|
||||
return node
|
||||
|
||||
|
||||
def construct_recurse(self, bin, xml, allow_missing=False):
|
||||
xmldict = {}
|
||||
tagdict = {}
|
||||
attrdict = {}
|
||||
|
||||
if bin.tag == 'xml_binary_packing':
|
||||
node = GameDataNode()
|
||||
else:
|
||||
node = self.construct_node(bin, xml, allow_missing)
|
||||
|
||||
for child in bin.getchildren():
|
||||
if child.tag == 'datatag':
|
||||
tagdict[child.get('name')] = child
|
||||
elif child.tag == 'attribute':
|
||||
attrdict[child.get('name')] = child
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
xmlattrdict = {}
|
||||
xmltagdict = {}
|
||||
|
||||
if not isinstance(xml, MissingNode):
|
||||
for k, v in xml.items():
|
||||
if not k in attrdict:
|
||||
raise ValueError, "Key %s not a valid attribute: %s" % (k, attrdict.keys())
|
||||
continue
|
||||
binchild = attrdict[k]
|
||||
xmlchild = xml
|
||||
xmlattrdict[k] = 0
|
||||
subnode = self.construct_node(binchild, xml, allow_missing)
|
||||
if subnode._def.multi:
|
||||
node.add_multi(k, subnode)
|
||||
else:
|
||||
node.add_single(k, subnode)
|
||||
|
||||
for child in xml.getchildren():
|
||||
if not child.tag in tagdict:
|
||||
raise ValueError
|
||||
continue
|
||||
binchild = tagdict[child.tag]
|
||||
xmlchild = child
|
||||
xmltagdict[child.tag] = 0
|
||||
subnode = self.construct_recurse(binchild, xmlchild, allow_missing)
|
||||
if subnode._def.multi:
|
||||
node.add_multi(child.tag, subnode)
|
||||
else:
|
||||
node.add_single(child.tag, subnode)
|
||||
|
||||
|
||||
missing = MissingNode()
|
||||
for k in tagdict.keys():
|
||||
if not k in xmltagdict:
|
||||
# Missing datatag
|
||||
subnode = self.construct_recurse(tagdict[k], missing, isinstance(xml, MissingNode))
|
||||
if not subnode._def.multi:
|
||||
node.add_single(k, subnode)
|
||||
else:
|
||||
node.add_single(k, [])
|
||||
|
||||
for k in attrdict.keys():
|
||||
if not k in xmlattrdict:
|
||||
# Missing attribute
|
||||
subnode = self.construct_node(attrdict[k], missing, isinstance(xml, MissingNode))
|
||||
if not subnode._def.multi:
|
||||
node.add_single(k, subnode)
|
||||
else:
|
||||
node.add_single(k, [])
|
||||
|
||||
|
||||
|
||||
return node
|
||||
|
||||
def construct(self):
|
||||
rootname = self._bin.get('name')
|
||||
assert rootname == self._xml.tag
|
||||
|
||||
return self.construct_recurse(self._bin, self._xml)
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == 'tree':
|
||||
raise AttributeError, name
|
||||
return self._tree.__getattr__(name)
|
||||
def __getitem__(self, name):
|
||||
return self._tree.__getitem__(name)
|
||||
|
||||
|
||||
def load_xml_files(binfile, xmlfile):
|
||||
bintree = parse(binfile).getroot()
|
||||
xmltree = parse(xmlfile).getroot()
|
||||
|
||||
return XMLGameDataReader(bintree, xmltree)
|
||||
|
||||
def get(dataname):
|
||||
if dataname in get.cache:
|
||||
return get.cache[dataname]
|
||||
|
||||
bin = files.mgr.path("xml/def", "%s.xml" % (dataname,))
|
||||
xml = files.mgr.path("xml", "%s.xml" % (dataname,))
|
||||
|
||||
if not os.path.exists(bin) or not os.path.exists(xml):
|
||||
raise OSError("XML data file does not exist")
|
||||
|
||||
dataobj = load_xml_files(bin, xml)
|
||||
|
||||
get.cache[dataname] = dataobj
|
||||
return dataobj
|
||||
|
||||
get.cache = {}
|
||||
|
||||
@deprecated
|
||||
def load_gamedata():
|
||||
bins = glob.glob(files.mgr.path("xml/def", "*.xml"))
|
||||
xmls = glob.glob(files.mgr.path("xml", "*.xml"))
|
||||
|
||||
binfns = [os.path.split(x)[1] for x in bins]
|
||||
xmlfns = [os.path.split(x)[1] for x in xmls]
|
||||
ffns = []
|
||||
for bfn in binfns:
|
||||
if bfn in xmlfns:
|
||||
ffns.append(bfn)
|
||||
|
||||
dataobjs = {}
|
||||
for fn in ffns:
|
||||
binfile = files.mgr.path("xml/def", fn)
|
||||
xmlfile = files.mgr.path("xml", fn)
|
||||
dataobj = load_xml_files(binfile, xmlfile)
|
||||
dataobjs[dataobj._name] = dataobj
|
||||
|
||||
shader.mgr.load_shaders(dataobjs['shaders'])
|
||||
return dataobjs
|
||||
|
||||
|
||||
|
||||
import glob
|
||||
import os
|
||||
try:
|
||||
from xml.etree.cElementTree import parse
|
||||
except ImportError:
|
||||
from elementtree.ElementTree import parse
|
||||
import files
|
||||
import shader
|
||||
from deprecate import deprecated
|
||||
|
||||
class MissingNode(object):
|
||||
def __init__(self):
|
||||
self.text = None
|
||||
def get(self, name):
|
||||
return None
|
||||
|
||||
class GameDataTagDef(object):
|
||||
def __init__(self):
|
||||
self.multi = False
|
||||
self.opt = False
|
||||
self.type = None
|
||||
self.default = None
|
||||
|
||||
class GameDataNode(object):
|
||||
def __init__(self):
|
||||
self.dict = {}
|
||||
self.missing = False
|
||||
|
||||
def __setitem__(self, name, val):
|
||||
self.dict[name] = val
|
||||
def __getitem__(self, name):
|
||||
return self.dict[name]._value
|
||||
def __getattr__(self, name):
|
||||
if name == 'dict':
|
||||
raise AttributeError(name)
|
||||
try:
|
||||
return self.dict[name]
|
||||
except KeyError:
|
||||
if name == '_value':
|
||||
return None
|
||||
raise AttributeError(name)
|
||||
def __setattr__(self, name, val):
|
||||
if name == 'dict':
|
||||
return object.__setattr__(self, name, val)
|
||||
try:
|
||||
self.dict[name] = val
|
||||
except KeyError:
|
||||
object.__setattr__(self, name, val)
|
||||
def add_multi(self, key, value):
|
||||
if key not in self.dict:
|
||||
self.dict[key] = []
|
||||
self.dict[key].append(value)
|
||||
def add_single(self, key, value):
|
||||
self.dict[key] = value
|
||||
def __repr__(self):
|
||||
return """<GameDataNode "%s">""" % (self.dict['_name'],)
|
||||
def has_key(self, key):
|
||||
return key in self.dict
|
||||
|
||||
class XMLGameDataReader(object):
|
||||
def __init__(self, bin, xml):
|
||||
self._bin = bin
|
||||
self._xml = xml
|
||||
self._tree = self.construct()
|
||||
self._name = xml.tag
|
||||
|
||||
|
||||
def value_as_type(self, value, type):
|
||||
if type == 'string':
|
||||
return value
|
||||
elif type == 'bool':
|
||||
if value and value[0].lower() in ('y', 't', '1'):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif type == 'int':
|
||||
return int(value)
|
||||
elif type == 'float':
|
||||
return float(value)
|
||||
elif type == 'csvarray':
|
||||
# csvarrays are always ints...
|
||||
return [int(x.strip()) for x in value.split(',')]
|
||||
else:
|
||||
raise TypeError(type)
|
||||
|
||||
def create_datatag_def(self, tag):
|
||||
d = GameDataTagDef()
|
||||
if tag.get('multiple') != None and tag.get('multiple')[0].lower() == 'y':
|
||||
d.multi = True
|
||||
if tag.get('optional') != None and tag.get('optional')[0].lower() == 'y':
|
||||
d.opt = True
|
||||
if tag.get('data') != None:
|
||||
d.type = tag.get('data')
|
||||
if tag.get('default') != None:
|
||||
d.default = self.value_as_type(tag.get('default'), d.type)
|
||||
d.opt = True
|
||||
return d
|
||||
|
||||
def create_attribute_def(self, tag):
|
||||
return self.create_datatag_def(tag)
|
||||
|
||||
def construct_node(self, bin, xml, allow_missing=False):
|
||||
node = GameDataNode()
|
||||
if isinstance(xml, MissingNode):
|
||||
node.missing = True
|
||||
value = None
|
||||
if bin.tag == 'datatag':
|
||||
df = self.create_datatag_def(bin)
|
||||
if df.type:
|
||||
value = xml.text
|
||||
if df.type == 'bool':
|
||||
# if tag exists, since it is a bool, that means it's True
|
||||
value = not node.missing
|
||||
elif (node.missing or value == None) and df.opt:
|
||||
value = df.default
|
||||
elif (node.missing or value == None) and not allow_missing:
|
||||
raise ValueError("Missing value for mandatory tag %s" % (bin.get('name'),))
|
||||
elif (node.missing or value == None):
|
||||
value = None
|
||||
else:
|
||||
value = self.value_as_type(value, df.type)
|
||||
|
||||
node['_value'] = value
|
||||
elif bin.tag == 'attribute':
|
||||
df = self.create_attribute_def(bin)
|
||||
if df.type:
|
||||
value = xml.get(bin.get('name'))
|
||||
if value == None and df.opt:
|
||||
value = df.default
|
||||
elif not value and not allow_missing:
|
||||
raise ValueError("Missing value for mandatory tag %s" % (bin.get('name'),))
|
||||
elif not value:
|
||||
value = None
|
||||
else:
|
||||
value = self.value_as_type(value, df.type)
|
||||
|
||||
node['_value'] = value
|
||||
|
||||
node['_def'] = df
|
||||
node['_name'] = bin.get('name')
|
||||
return node
|
||||
|
||||
|
||||
def construct_recurse(self, bin, xml, allow_missing=False):
|
||||
xmldict = {}
|
||||
tagdict = {}
|
||||
attrdict = {}
|
||||
|
||||
if bin.tag == 'xml_binary_packing':
|
||||
node = GameDataNode()
|
||||
else:
|
||||
node = self.construct_node(bin, xml, allow_missing)
|
||||
|
||||
for child in bin.getchildren():
|
||||
if child.tag == 'datatag':
|
||||
tagdict[child.get('name')] = child
|
||||
elif child.tag == 'attribute':
|
||||
attrdict[child.get('name')] = child
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
xmlattrdict = {}
|
||||
xmltagdict = {}
|
||||
|
||||
if not isinstance(xml, MissingNode):
|
||||
for k, v in list(xml.items()):
|
||||
if not k in attrdict:
|
||||
raise ValueError("Key %s not a valid attribute: %s" % (k, list(attrdict.keys())))
|
||||
continue
|
||||
binchild = attrdict[k]
|
||||
xmlchild = xml
|
||||
xmlattrdict[k] = 0
|
||||
subnode = self.construct_node(binchild, xml, allow_missing)
|
||||
if subnode._def.multi:
|
||||
node.add_multi(k, subnode)
|
||||
else:
|
||||
node.add_single(k, subnode)
|
||||
|
||||
for child in xml.getchildren():
|
||||
if not child.tag in tagdict:
|
||||
raise ValueError
|
||||
continue
|
||||
binchild = tagdict[child.tag]
|
||||
xmlchild = child
|
||||
xmltagdict[child.tag] = 0
|
||||
subnode = self.construct_recurse(binchild, xmlchild, allow_missing)
|
||||
if subnode._def.multi:
|
||||
node.add_multi(child.tag, subnode)
|
||||
else:
|
||||
node.add_single(child.tag, subnode)
|
||||
|
||||
|
||||
missing = MissingNode()
|
||||
for k in list(tagdict.keys()):
|
||||
if not k in xmltagdict:
|
||||
# Missing datatag
|
||||
subnode = self.construct_recurse(tagdict[k], missing, isinstance(xml, MissingNode))
|
||||
if not subnode._def.multi:
|
||||
node.add_single(k, subnode)
|
||||
else:
|
||||
node.add_single(k, [])
|
||||
|
||||
for k in list(attrdict.keys()):
|
||||
if not k in xmlattrdict:
|
||||
# Missing attribute
|
||||
subnode = self.construct_node(attrdict[k], missing, isinstance(xml, MissingNode))
|
||||
if not subnode._def.multi:
|
||||
node.add_single(k, subnode)
|
||||
else:
|
||||
node.add_single(k, [])
|
||||
|
||||
|
||||
|
||||
return node
|
||||
|
||||
def construct(self):
|
||||
rootname = self._bin.get('name')
|
||||
assert rootname == self._xml.tag
|
||||
|
||||
return self.construct_recurse(self._bin, self._xml)
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == 'tree':
|
||||
raise AttributeError(name)
|
||||
return self._tree.__getattr__(name)
|
||||
def __getitem__(self, name):
|
||||
return self._tree.__getitem__(name)
|
||||
|
||||
|
||||
def load_xml_files(binfile, xmlfile):
|
||||
bintree = parse(binfile).getroot()
|
||||
xmltree = parse(xmlfile).getroot()
|
||||
|
||||
return XMLGameDataReader(bintree, xmltree)
|
||||
|
||||
def get(dataname):
|
||||
if dataname in get.cache:
|
||||
return get.cache[dataname]
|
||||
|
||||
bin = files.mgr.path("xml/def", "%s.xml" % (dataname,))
|
||||
xml = files.mgr.path("xml", "%s.xml" % (dataname,))
|
||||
|
||||
if not os.path.exists(bin) or not os.path.exists(xml):
|
||||
raise OSError("XML data file does not exist")
|
||||
|
||||
dataobj = load_xml_files(bin, xml)
|
||||
|
||||
get.cache[dataname] = dataobj
|
||||
return dataobj
|
||||
|
||||
get.cache = {}
|
||||
|
||||
@deprecated
|
||||
def load_gamedata():
|
||||
bins = glob.glob(files.mgr.path("xml/def", "*.xml"))
|
||||
xmls = glob.glob(files.mgr.path("xml", "*.xml"))
|
||||
|
||||
binfns = [os.path.split(x)[1] for x in bins]
|
||||
xmlfns = [os.path.split(x)[1] for x in xmls]
|
||||
ffns = []
|
||||
for bfn in binfns:
|
||||
if bfn in xmlfns:
|
||||
ffns.append(bfn)
|
||||
|
||||
dataobjs = {}
|
||||
for fn in ffns:
|
||||
binfile = files.mgr.path("xml/def", fn)
|
||||
xmlfile = files.mgr.path("xml", fn)
|
||||
dataobj = load_xml_files(binfile, xmlfile)
|
||||
dataobjs[dataobj._name] = dataobj
|
||||
|
||||
shader.mgr.load_shaders(dataobjs['shaders'])
|
||||
return dataobjs
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ def num_frames(delay, offset=0):
|
|||
return int((g_timer - offset) / delay) - int((g_timer - g_elapsed - offset) / delay)
|
||||
|
||||
def loop_frames(delay, offset=0):
|
||||
return xrange(num_frames(delay, offset))
|
||||
return range(num_frames(delay, offset))
|
||||
|
||||
def get_timer():
|
||||
return g_timer
|
||||
|
@ -81,7 +81,7 @@ def average(d):
|
|||
# pass
|
||||
|
||||
v2 = float(d[0])
|
||||
for i in xrange(1, len(d)):
|
||||
for i in range(1, len(d)):
|
||||
v1 = float(d[i])
|
||||
v2 = (smooth * v2) + ((1.0 - smooth) * v1)
|
||||
|
||||
|
|
|
@ -221,6 +221,6 @@ def main():
|
|||
glutMainLoop()
|
||||
|
||||
# Print message to console, and kick off the main to get it rolling.
|
||||
print "Hit ESC key to quit."
|
||||
print("Hit ESC key to quit.")
|
||||
main()
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ class Model_Manager(object):
|
|||
self.textypes[enums.tt.specular] = TextureType(GL_TEXTURE2, GL_TEXTURE_2D)
|
||||
self.textypes[enums.tt.normal] = TextureType(GL_TEXTURE3, GL_TEXTURE_2D)
|
||||
|
||||
for tt in self.textypes.values():
|
||||
for tt in list(self.textypes.values()):
|
||||
tt.initialize()
|
||||
|
||||
|
||||
|
@ -119,7 +119,7 @@ class Model_Manager(object):
|
|||
fontname = os.path.splitext(os.path.split(fontfile)[1])[0]
|
||||
fontobj = fonts.TexFont.new(fontdir, fontname)
|
||||
self.fontlib[fontname] = fontobj
|
||||
print "Loaded font %s" % (fontname,)
|
||||
print("Loaded font %s" % (fontname,))
|
||||
|
||||
def get_font(self, name):
|
||||
return self.fontlib[name]
|
||||
|
@ -214,7 +214,7 @@ class TextureFile(object):
|
|||
self.filename = filename
|
||||
img = files.mgr.png(filename)
|
||||
texid = glGenTextures(1)
|
||||
print "Generated texture id %s from %s" % (texid, self.filename)
|
||||
print("Generated texture id %s from %s" % (texid, self.filename))
|
||||
|
||||
self.id = texid
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ class physics_manager(object):
|
|||
if not other.massless:
|
||||
moved2 = obj.collide(other)
|
||||
|
||||
print "Collision!"
|
||||
print("Collision!")
|
||||
assert False
|
||||
return moved1 or moved2
|
||||
|
||||
|
@ -78,7 +78,7 @@ class physics_manager(object):
|
|||
positions_adjusted = False
|
||||
iter += 1
|
||||
pairmap = {}
|
||||
for key, cell in self.cells.items():
|
||||
for key, cell in list(self.cells.items()):
|
||||
for obj in cell:
|
||||
self._postcollide_single(obj, key, pairmap)
|
||||
|
||||
|
|
18
platform.py
|
@ -1,9 +1,9 @@
|
|||
import sys
|
||||
if sys.platform == 'win32':
|
||||
from platform_win32 import *
|
||||
elif sys.platform == 'darwin':
|
||||
from platform_darwin import *
|
||||
elif sys.platform == 'posix':
|
||||
from platform_posix import *
|
||||
else:
|
||||
raise NotImplementedError("Not ported to this platform")
|
||||
import sys
|
||||
if sys.platform == 'win32':
|
||||
from platform_win32 import *
|
||||
elif sys.platform == 'darwin':
|
||||
from platform_darwin import *
|
||||
elif sys.platform in ('posix', 'linux'):
|
||||
from platform_posix import *
|
||||
else:
|
||||
raise NotImplementedError("Not ported to this platform")
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
|
||||
def enable_vsync():
|
||||
try:
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
ogl = ctypes.cdll.LoadLibrary(ctypes.util.find_library("OpenGL"))
|
||||
v = ctypes.c_int(1)
|
||||
ogl.CGLSetParameter(ogl.CGLGetCurrentContext(), ctypes.c_int(222), ctypes.pointer(v))
|
||||
except:
|
||||
print "Unable to set vsync mode, using driver defaults"
|
||||
|
||||
def get_window_handle():
|
||||
return None
|
||||
|
||||
def get_window_rect(handle=None):
|
||||
pass
|
||||
|
||||
def enable_vsync():
|
||||
try:
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
ogl = ctypes.cdll.LoadLibrary(ctypes.util.find_library("OpenGL"))
|
||||
v = ctypes.c_int(1)
|
||||
ogl.CGLSetParameter(ogl.CGLGetCurrentContext(), ctypes.c_int(222), ctypes.pointer(v))
|
||||
except:
|
||||
print("Unable to set vsync mode, using driver defaults")
|
||||
|
||||
def get_window_handle():
|
||||
return None
|
||||
|
||||
def get_window_rect(handle=None):
|
||||
pass
|
||||
|
|
@ -19,7 +19,7 @@ try:
|
|||
from PIL import PngImagePlugin
|
||||
except:
|
||||
import PngImagePlugin
|
||||
from gameobj import *
|
||||
from .gameobj import *
|
||||
from player import *
|
||||
from particles import *
|
||||
from ai import *
|
||||
|
|
31
roc_test.py
|
@ -1,12 +1,16 @@
|
|||
#import roc
|
||||
import os
|
||||
import sys
|
||||
sys.path.append(os.path.abspath('..'))
|
||||
import roc
|
||||
import pygame
|
||||
from OpenGL.GL import *
|
||||
from py3dutil import vect, quat
|
||||
import models
|
||||
import fonts
|
||||
import gametimer
|
||||
from platform import *
|
||||
import pipeline
|
||||
from roc import models
|
||||
from roc import fonts
|
||||
from roc import gametimer
|
||||
from roc.platform import *
|
||||
from roc import pipeline
|
||||
import time
|
||||
import collections
|
||||
import random
|
||||
|
@ -24,8 +28,8 @@ class partycle(object):
|
|||
|
||||
@classmethod
|
||||
def random(cls):
|
||||
x, y = [((random.random() * 2.0) - 1.0) * 10.0 for _ in xrange(2)]
|
||||
xd, yd = [((random.random() * 2.0) - 1.0) * 4.0 for _ in xrange(2)]
|
||||
x, y = [((random.random() * 2.0) - 1.0) * 10.0 for _ in range(2)]
|
||||
xd, yd = [((random.random() * 2.0) - 1.0) * 4.0 for _ in range(2)]
|
||||
hue = random.random()
|
||||
m1 = 1.0
|
||||
h1 = hue * 6.0
|
||||
|
@ -56,7 +60,7 @@ class partycle(object):
|
|||
self.yd *= 0.985
|
||||
self.rot += self.rotd
|
||||
|
||||
class test_universe(roc.base_universe):
|
||||
class test_universe(roc.universe.base_universe):
|
||||
def __init__(self):
|
||||
self.font = models.mgr.fontlib["micross20"]
|
||||
self.text1 = models.TextModel("micross20", "#$% 0123 ,,,, Hello world!\xa8\xa8\xa8F", (1.0, 1.0, 0.5, 1.0))
|
||||
|
@ -112,7 +116,7 @@ class test_universe(roc.base_universe):
|
|||
self.text1.render()
|
||||
glPopMatrix()
|
||||
|
||||
for x in xrange(gametimer.num_frames(10)):
|
||||
for x in range(gametimer.num_frames(10)):
|
||||
self.move = self.move + self.moveinc
|
||||
if self.move > 300.0:
|
||||
self.moveinc = -1.0
|
||||
|
@ -139,7 +143,7 @@ class test_universe(roc.base_universe):
|
|||
for x in xrange(gametimer.num_frames(1000)):
|
||||
self.string = self.string + str(len(self.string) % 10)
|
||||
"""
|
||||
for x in xrange(gametimer.num_frames(100)):
|
||||
for x in range(gametimer.num_frames(100)):
|
||||
self.string = str(round(gametimer.get_fps(), 1))
|
||||
#print len(gametimer.g_framelist)
|
||||
|
||||
|
@ -148,20 +152,21 @@ class test_universe(roc.base_universe):
|
|||
glPopMatrix()
|
||||
|
||||
# texture test
|
||||
mdl2 = models.mgr.create("m_dralthi")
|
||||
mdl2 = models.mgr.create("m_particle")
|
||||
mdl2.layers[0].color = None
|
||||
#print mdl2.layers[0].mesh
|
||||
for party in self.particles:
|
||||
glPushMatrix()
|
||||
glTranslate(600.0 + party.x, 350.0 + party.y, 6.0)
|
||||
glRotate(party.rot, 0.0, 0.0, 1.0)
|
||||
#glColor4f(*party.color)
|
||||
glColor4f(*party.color)
|
||||
mdl2.render()
|
||||
glPopMatrix()
|
||||
|
||||
|
||||
|
||||
|
||||
roc.video.width = 1024
|
||||
roc.video.height = 768
|
||||
roc.init2d()
|
||||
roc.set_universe(test_universe())
|
||||
roc.main()
|
||||
|
|
439
shader.py
|
@ -1,219 +1,220 @@
|
|||
import ctypes
|
||||
from OpenGL.GL import *
|
||||
try:
|
||||
import OpenGL.raw.GL
|
||||
raw = OpenGL.raw
|
||||
except ImportError:
|
||||
pass
|
||||
from OpenGL.arrays import GLintArray, GLcharArray, GLsizeiArray, GLcharARBArray
|
||||
import sys
|
||||
import gamedata
|
||||
|
||||
|
||||
class shader_manager(object):
|
||||
def __init__(self):
|
||||
# Fixed Pipeline is always zero
|
||||
self.shaderlib = {'ffp': 0}
|
||||
self.shaderprograms = {}
|
||||
|
||||
self.initshadersources = []
|
||||
self.initmode = 'auto'
|
||||
self.initialized = False
|
||||
|
||||
def use_gl2_shaders(self):
|
||||
self.funcs = {
|
||||
'create': glCreateShader,
|
||||
'source': glShaderSource,
|
||||
'compile': glCompileShader,
|
||||
'program': glCreateProgram,
|
||||
'attach': glAttachShader,
|
||||
'link': glLinkProgram,
|
||||
'use': glUseProgram,
|
||||
'param': glGetShaderiv,
|
||||
'uniform': glUniform4f,
|
||||
'arraytype': GLcharArray
|
||||
}
|
||||
def use_raw_shaders(self):
|
||||
self.funcs = {
|
||||
'create': raw.GL.glCreateShader,
|
||||
'source': raw.GL.glShaderSource,
|
||||
'compile': raw.GL.glCompileShader,
|
||||
'program': raw.GL.glCreateProgram,
|
||||
'attach': raw.GL.glAttachShader,
|
||||
'link': raw.GL.glLinkProgram,
|
||||
'use': raw.GL.glUseProgram,
|
||||
'param': raw.GL.glGetShaderiv
|
||||
}
|
||||
|
||||
def use_arb_shaders(self):
|
||||
from OpenGL.GL.ARB import shader_objects
|
||||
if not shader_objects.glInitShaderObjectsARB():
|
||||
raise RuntimeError("ARB Shaders failed to initialize")
|
||||
|
||||
self.funcs = {
|
||||
'create': shader_objects.glCreateShaderObjectARB,
|
||||
'source': shader_objects.glShaderSourceARB,
|
||||
'compile': shader_objects.glCompileShaderARB,
|
||||
'program': shader_objects.glCreateProgramObjectARB,
|
||||
'attach': shader_objects.glAttachObjectARB,
|
||||
'link': shader_objects.glLinkProgramARB,
|
||||
'use': shader_objects.glUseProgramObjectARB,
|
||||
'uniform': shader_objects.glUniform4fARB,
|
||||
'param': shader_objects.glGetObjectParameterivARB
|
||||
}
|
||||
def use_arb_new_shaders(self):
|
||||
from OpenGL.GL.ARB import shader_objects_new
|
||||
shader_objects = shader_objects_new
|
||||
if not shader_objects.glInitShaderObjectsARB():
|
||||
raise RuntimeError("ARB New Shaders failed to initialize")
|
||||
|
||||
self.funcs = {
|
||||
'create': shader_objects.glCreateShaderObjectARB,
|
||||
'source': shader_objects.base_glShaderSourceARB,
|
||||
'compile': shader_objects.glCompileShaderARB,
|
||||
'program': shader_objects.glCreateProgramObjectARB,
|
||||
'attach': shader_objects.glAttachObjectARB,
|
||||
'link': shader_objects.glLinkProgramARB,
|
||||
'use': shader_objects.glUseProgramObjectARB,
|
||||
'param': shader_objects.glGetObjectParameterivARB,
|
||||
'arraytype': GLcharARBArray
|
||||
}
|
||||
|
||||
def init_gl(self):
|
||||
if self.initialized:
|
||||
return
|
||||
|
||||
self.initialized = True
|
||||
import files
|
||||
#print glGetString(GL_EXTENSIONS)
|
||||
if True:
|
||||
self.use_gl2_shaders()
|
||||
else:
|
||||
self.use_arb_shaders()
|
||||
#self.use_gl2_shaders()
|
||||
|
||||
for name, vertex, fragment in self.initshadersources:
|
||||
vf = files.mgr.open('shaders/%s.vert' % (vertex,))
|
||||
ff = files.mgr.open('shaders/%s.frag' % (fragment,))
|
||||
vs = self.funcs['create'](GL_VERTEX_SHADER)
|
||||
fs = self.funcs['create'](GL_FRAGMENT_SHADER)
|
||||
self.funcs['source'](vs, vf.read())
|
||||
self.funcs['source'](fs, ff.read())
|
||||
rv = self.funcs['compile'](vs)
|
||||
rv = self.funcs['compile'](fs)
|
||||
sp = self.funcs['program']()
|
||||
self.funcs['attach'](sp, vs)
|
||||
self.funcs['attach'](sp, fs)
|
||||
rv = self.funcs['link'](sp)
|
||||
self.shaderlib[name] = sp
|
||||
self.shaderprograms[name] = (vs, fs)
|
||||
|
||||
def detect(self):
|
||||
shaderlist = [
|
||||
('GL2', self.use_gl2_shaders),
|
||||
('ARB', self.use_arb_shaders),
|
||||
('ARBNEW', self.use_arb_new_shaders),
|
||||
('RAW', self.use_raw_shaders)
|
||||
]
|
||||
|
||||
workable_shaders = []
|
||||
|
||||
for shadername, shaderinit in shaderlist:
|
||||
try:
|
||||
shaderinit()
|
||||
except:
|
||||
print "Shader type %s failed to initialize" % (shadername,)
|
||||
continue
|
||||
try:
|
||||
self.select("ffp")
|
||||
except:
|
||||
print "Shader type %s failed to access the fixed function pipeline" % (shadername,)
|
||||
continue
|
||||
try:
|
||||
self.select("standard")
|
||||
except:
|
||||
print "Shader type %s failed to load the \"standard\" vertex and fragment shaders" % (shadername,)
|
||||
continue
|
||||
|
||||
workable_shaders.append(shadername)
|
||||
|
||||
return workable_shaders
|
||||
|
||||
def autoinit(self):
|
||||
shadertypes = self.detect()
|
||||
|
||||
if not shadertypes:
|
||||
raise ValueError, "No working shaders detected"
|
||||
|
||||
self.init_shadertype(shadertypes[0])
|
||||
|
||||
def init_shadertype(self, shadertype):
|
||||
if shadertype == "GL2":
|
||||
self.use_gl2_shaders()
|
||||
elif shadertype == "ARB":
|
||||
self.use_arb_shaders()
|
||||
elif shadertype == "ARBNEW":
|
||||
self.use_arb_new_shaders()
|
||||
elif shadertype == "RAW":
|
||||
self.use_raw_shaders()
|
||||
|
||||
|
||||
|
||||
def select(self, shader):
|
||||
if self.initshadersources:
|
||||
self.init_gl()
|
||||
self.initshadersources = []
|
||||
if not shader in self.shaderlib:
|
||||
self.funcs['use'](0)
|
||||
return True
|
||||
try:
|
||||
self.funcs['use'](self.shaderlib[shader])
|
||||
except GLError:
|
||||
p = self.shaderlib[shader]
|
||||
v, f = self.shaderprograms[shader]
|
||||
print "Shader failed to execute: %s" % (shader,)
|
||||
print "Vertex shader log:"
|
||||
lenarr = GLintArray.zeros(1)
|
||||
glGetShaderiv(v, GL_INFO_LOG_LENGTH, lenarr)
|
||||
infoarr = GLcharArray.zeros(lenarr[0])
|
||||
outsize = GLsizeiArray.zeros(1)
|
||||
glGetShaderInfoLog(v, lenarr[0], outsize, infoarr)
|
||||
print ''.join([chr(x) for x in infoarr[:outsize[0]]])
|
||||
print "Fragment shader log:"
|
||||
lenarr = GLintArray.zeros(1)
|
||||
glGetShaderiv(f, GL_INFO_LOG_LENGTH, lenarr)
|
||||
infoarr = GLcharArray.zeros(lenarr[0])
|
||||
outsize = GLsizeiArray.zeros(1)
|
||||
glGetShaderInfoLog(f, lenarr[0], outsize, infoarr)
|
||||
print ''.join([chr(x) for x in infoarr[:outsize[0]]])
|
||||
print "Program info log:"
|
||||
lenarr = GLintArray.zeros(1)
|
||||
glGetProgramiv(p, GL_INFO_LOG_LENGTH, lenarr)
|
||||
infoarr = GLcharArray.zeros(lenarr[0])
|
||||
outsize = GLsizeiArray.zeros(1)
|
||||
glGetProgramInfoLog(p, lenarr[0], outsize, infoarr)
|
||||
print ''.join([chr(x) for x in infoarr[:outsize[0]]])
|
||||
glDeleteShader(v)
|
||||
glDeleteShader(f)
|
||||
glDeleteProgram(p)
|
||||
del self.shaderprograms[shader]
|
||||
del self.shaderlib[shader]
|
||||
glUseProgram(0)
|
||||
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def load(self):
|
||||
shader_data = gamedata.get('shaders')
|
||||
self.load_shaders(shader_data)
|
||||
|
||||
def load_shaders(self, shaders):
|
||||
for shader in shaders.shader:
|
||||
self.initshadersources.append((shader['id'], shader['vertex'], shader['fragment']))
|
||||
|
||||
def init():
|
||||
global mgr
|
||||
mgr = shader_manager()
|
||||
|
||||
mgr = None
|
||||
import ctypes
|
||||
from OpenGL.GL import *
|
||||
try:
|
||||
import OpenGL.raw.GL
|
||||
raw = OpenGL.raw
|
||||
except ImportError:
|
||||
pass
|
||||
from OpenGL.arrays import GLintArray, GLcharArray, GLsizeiArray, GLcharARBArray
|
||||
import sys
|
||||
import gamedata
|
||||
|
||||
|
||||
class shader_manager(object):
|
||||
def __init__(self):
|
||||
# Fixed Pipeline is always zero
|
||||
self.shaderlib = {'ffp': 0}
|
||||
self.shaderprograms = {}
|
||||
|
||||
self.initshadersources = []
|
||||
self.initmode = 'auto'
|
||||
self.initialized = False
|
||||
|
||||
def use_gl2_shaders(self):
|
||||
self.funcs = {
|
||||
'create': glCreateShader,
|
||||
'source': glShaderSource,
|
||||
'compile': glCompileShader,
|
||||
'program': glCreateProgram,
|
||||
'attach': glAttachShader,
|
||||
'link': glLinkProgram,
|
||||
'use': glUseProgram,
|
||||
'param': glGetShaderiv,
|
||||
'uniform': glUniform4f,
|
||||
'arraytype': GLcharArray
|
||||
}
|
||||
def use_raw_shaders(self):
|
||||
self.funcs = {
|
||||
'create': raw.GL.glCreateShader,
|
||||
'source': raw.GL.glShaderSource,
|
||||
'compile': raw.GL.glCompileShader,
|
||||
'program': raw.GL.glCreateProgram,
|
||||
'attach': raw.GL.glAttachShader,
|
||||
'link': raw.GL.glLinkProgram,
|
||||
'use': raw.GL.glUseProgram,
|
||||
'param': raw.GL.glGetShaderiv
|
||||
}
|
||||
|
||||
def use_arb_shaders(self):
|
||||
from OpenGL.GL.ARB import shader_objects
|
||||
if not shader_objects.glInitShaderObjectsARB():
|
||||
raise RuntimeError("ARB Shaders failed to initialize")
|
||||
|
||||
self.funcs = {
|
||||
'create': shader_objects.glCreateShaderObjectARB,
|
||||
'source': shader_objects.glShaderSourceARB,
|
||||
'compile': shader_objects.glCompileShaderARB,
|
||||
'program': shader_objects.glCreateProgramObjectARB,
|
||||
'attach': shader_objects.glAttachObjectARB,
|
||||
'link': shader_objects.glLinkProgramARB,
|
||||
'use': shader_objects.glUseProgramObjectARB,
|
||||
'uniform': shader_objects.glUniform4fARB,
|
||||
'param': shader_objects.glGetObjectParameterivARB
|
||||
}
|
||||
def use_arb_new_shaders(self):
|
||||
from OpenGL.GL.ARB import shader_objects_new
|
||||
shader_objects = shader_objects_new
|
||||
if not shader_objects.glInitShaderObjectsARB():
|
||||
raise RuntimeError("ARB New Shaders failed to initialize")
|
||||
|
||||
self.funcs = {
|
||||
'create': shader_objects.glCreateShaderObjectARB,
|
||||
'source': shader_objects.base_glShaderSourceARB,
|
||||
'compile': shader_objects.glCompileShaderARB,
|
||||
'program': shader_objects.glCreateProgramObjectARB,
|
||||
'attach': shader_objects.glAttachObjectARB,
|
||||
'link': shader_objects.glLinkProgramARB,
|
||||
'use': shader_objects.glUseProgramObjectARB,
|
||||
'param': shader_objects.glGetObjectParameterivARB,
|
||||
'arraytype': GLcharARBArray
|
||||
}
|
||||
|
||||
def init_gl(self):
|
||||
if self.initialized:
|
||||
return
|
||||
|
||||
self.initialized = True
|
||||
import files
|
||||
#print glGetString(GL_EXTENSIONS)
|
||||
if True:
|
||||
self.use_gl2_shaders()
|
||||
else:
|
||||
self.use_arb_shaders()
|
||||
#self.use_gl2_shaders()
|
||||
|
||||
for name, vertex, fragment in self.initshadersources:
|
||||
vf = files.mgr.open('shaders/%s.vert' % (vertex,))
|
||||
ff = files.mgr.open('shaders/%s.frag' % (fragment,))
|
||||
vs = self.funcs['create'](GL_VERTEX_SHADER)
|
||||
fs = self.funcs['create'](GL_FRAGMENT_SHADER)
|
||||
self.funcs['source'](vs, vf.read())
|
||||
self.funcs['source'](fs, ff.read())
|
||||
rv = self.funcs['compile'](vs)
|
||||
rv = self.funcs['compile'](fs)
|
||||
sp = self.funcs['program']()
|
||||
self.funcs['attach'](sp, vs)
|
||||
self.funcs['attach'](sp, fs)
|
||||
rv = self.funcs['link'](sp)
|
||||
self.shaderlib[name] = sp
|
||||
self.shaderprograms[name] = (vs, fs)
|
||||
|
||||
def detect(self):
|
||||
shaderlist = [
|
||||
('GL2', self.use_gl2_shaders),
|
||||
('ARB', self.use_arb_shaders),
|
||||
('ARBNEW', self.use_arb_new_shaders),
|
||||
('RAW', self.use_raw_shaders)
|
||||
]
|
||||
|
||||
workable_shaders = []
|
||||
|
||||
for shadername, shaderinit in shaderlist:
|
||||
try:
|
||||
shaderinit()
|
||||
except:
|
||||
print("Shader type %s failed to initialize" % (shadername,))
|
||||
continue
|
||||
try:
|
||||
self.select("ffp")
|
||||
except:
|
||||
print("Shader type %s failed to access the fixed function pipeline" % (shadername,))
|
||||
continue
|
||||
try:
|
||||
self.select("standard")
|
||||
except:
|
||||
print("Shader type %s failed to load the \"standard\" vertex and fragment shaders" % (shadername,))
|
||||
continue
|
||||
|
||||
workable_shaders.append(shadername)
|
||||
|
||||
return workable_shaders
|
||||
|
||||
def autoinit(self):
|
||||
shadertypes = self.detect()
|
||||
|
||||
if not shadertypes:
|
||||
raise ValueError("No working shaders detected")
|
||||
|
||||
self.init_shadertype(shadertypes[0])
|
||||
|
||||
def init_shadertype(self, shadertype):
|
||||
if shadertype == "GL2":
|
||||
self.use_gl2_shaders()
|
||||
elif shadertype == "ARB":
|
||||
self.use_arb_shaders()
|
||||
elif shadertype == "ARBNEW":
|
||||
self.use_arb_new_shaders()
|
||||
elif shadertype == "RAW":
|
||||
self.use_raw_shaders()
|
||||
|
||||
|
||||
|
||||
def select(self, shader):
|
||||
if self.initshadersources:
|
||||
self.init_gl()
|
||||
self.initshadersources = []
|
||||
if not shader in self.shaderlib:
|
||||
self.funcs['use'](0)
|
||||
return True
|
||||
try:
|
||||
self.funcs['use'](self.shaderlib[shader])
|
||||
except GLError:
|
||||
p = self.shaderlib[shader]
|
||||
v, f = self.shaderprograms[shader]
|
||||
print("Shader failed to execute: %s" % (shader,))
|
||||
print("Vertex shader log:")
|
||||
lenarr = GLintArray.zeros(1)
|
||||
glGetShaderiv(v, GL_INFO_LOG_LENGTH, lenarr)
|
||||
infoarr = GLcharArray.zeros(lenarr[0])
|
||||
outsize = GLsizeiArray.zeros(1)
|
||||
glGetShaderInfoLog(v, lenarr[0], outsize, infoarr)
|
||||
print(''.join([chr(x) for x in infoarr[:outsize[0]]]))
|
||||
print("Fragment shader log:")
|
||||
lenarr = GLintArray.zeros(1)
|
||||
glGetShaderiv(f, GL_INFO_LOG_LENGTH, lenarr)
|
||||
infoarr = GLcharArray.zeros(lenarr[0])
|
||||
outsize = GLsizeiArray.zeros(1)
|
||||
glGetShaderInfoLog(f, lenarr[0], outsize, infoarr)
|
||||
print(''.join([chr(x) for x in infoarr[:outsize[0]]]))
|
||||
print("Program info log:")
|
||||
lenarr = GLintArray.zeros(1)
|
||||
glGetProgramiv(p, GL_INFO_LOG_LENGTH, lenarr)
|
||||
infoarr = GLcharArray.zeros(lenarr[0])
|
||||
outsize = GLsizeiArray.zeros(1)
|
||||
glGetProgramInfoLog(p, lenarr[0], outsize, infoarr)
|
||||
print(''.join([chr(x) for x in infoarr[:outsize[0]]]))
|
||||
glDeleteShader(v)
|
||||
glDeleteShader(f)
|
||||
glDeleteProgram(p)
|
||||
del self.shaderprograms[shader]
|
||||
del self.shaderlib[shader]
|
||||
glUseProgram(0)
|
||||
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def load(self):
|
||||
shader_data = gamedata.get('shaders')
|
||||
self.load_shaders(shader_data)
|
||||
|
||||
def load_shaders(self, shaders):
|
||||
for shader in shaders.shader:
|
||||
self.initshadersources.append((shader['id'], shader['vertex'], shader['fragment']))
|
||||
|
||||
def init():
|
||||
global mgr
|
||||
mgr = shader_manager()
|
||||
print("initiated shader mgr: %s" % (mgr,))
|
||||
|
||||
mgr = None
|
||||
|
|
|
@ -1,93 +1,93 @@
|
|||
import os
|
||||
import pygame
|
||||
import sys
|
||||
import math
|
||||
|
||||
pygame.init()
|
||||
pygame.font.init()
|
||||
|
||||
assert pygame.font.get_init()
|
||||
|
||||
fmod = pygame.font
|
||||
Font = pygame.font.Font
|
||||
|
||||
fontname, fontsize = sys.argv[1:]
|
||||
|
||||
if '/' in fontname:
|
||||
ffile = fontname
|
||||
fontname = os.path.splitext(os.path.split(fontname)[1])[0].lower()
|
||||
else:
|
||||
ffile = fmod.match_font(fontname)
|
||||
|
||||
if not ffile:
|
||||
print "Unable to find font... here is a list of fonts:\n"
|
||||
for x in sorted(fmod.get_fonts()):
|
||||
print x
|
||||
sys.exit(0)
|
||||
|
||||
fontsize = int(fontsize)
|
||||
fontname = "%s%s" % (fontname, fontsize)
|
||||
|
||||
f = Font(ffile, fontsize)
|
||||
|
||||
start = 32
|
||||
end = 128
|
||||
images = []
|
||||
imsizes = []
|
||||
maxwidth = 0
|
||||
maxheight = 0
|
||||
for char in xrange(start, end):
|
||||
letter = chr(char)
|
||||
sz = f.size(letter)
|
||||
maxwidth = max(maxwidth, sz[0])
|
||||
maxheight = max(maxheight, sz[1])
|
||||
im = f.render(letter, True, (255, 255, 255))
|
||||
images.append(im)
|
||||
imsizes.append(sz)
|
||||
|
||||
print len(images)
|
||||
maxwidth += 1
|
||||
maxheight += 1
|
||||
|
||||
ratio = float(maxwidth) / float(maxheight)
|
||||
print "Ratio %s" % (ratio,)
|
||||
reqwidth = maxwidth * len(images)
|
||||
|
||||
ratioheight = int(math.ceil(math.sqrt(len(images) * ratio)))
|
||||
ratiowidth = int(math.ceil(len(images) / math.sqrt(len(images) * ratio)))
|
||||
|
||||
print [ratioheight, ratiowidth]
|
||||
|
||||
reqwidth = maxwidth * ratiowidth
|
||||
reqheight = maxheight * ratioheight
|
||||
|
||||
print [reqheight, reqwidth]
|
||||
|
||||
texsize = 16
|
||||
|
||||
while texsize < reqheight or texsize < reqwidth:
|
||||
texsize *= 2
|
||||
|
||||
print texsize
|
||||
|
||||
tex = pygame.Surface((texsize, texsize), pygame.SRCALPHA, 32)
|
||||
tex.fill((0, 0, 0, 0))
|
||||
|
||||
for i, im in enumerate(images):
|
||||
tex.blit(im, (((i % ratiowidth) * maxwidth), ((i // ratiowidth) * maxheight)))
|
||||
|
||||
pygame.image.save(tex, "%s.png" % (fontname,))
|
||||
|
||||
datf = open("%s.tfd" % (fontname,), "w")
|
||||
datf.write("fontheader\n")
|
||||
datf.write("%s,%s\n" % (start, end))
|
||||
datf.write("%s,%s\n" % (maxwidth, maxheight))
|
||||
datf.write("%s,%s\n" % (ratiowidth, ratioheight))
|
||||
datf.write("%s,%s\n" % (texsize, texsize))
|
||||
datf.write("charsizes\n")
|
||||
for i, sz in enumerate(imsizes):
|
||||
datf.write("%s,%s\n" % (sz[0], sz[1]))
|
||||
|
||||
datf.close()
|
||||
|
||||
|
||||
import os
|
||||
import pygame
|
||||
import sys
|
||||
import math
|
||||
|
||||
pygame.init()
|
||||
pygame.font.init()
|
||||
|
||||
assert pygame.font.get_init()
|
||||
|
||||
fmod = pygame.font
|
||||
Font = pygame.font.Font
|
||||
|
||||
fontname, fontsize = sys.argv[1:]
|
||||
|
||||
if '/' in fontname:
|
||||
ffile = fontname
|
||||
fontname = os.path.splitext(os.path.split(fontname)[1])[0].lower()
|
||||
else:
|
||||
ffile = fmod.match_font(fontname)
|
||||
|
||||
if not ffile:
|
||||
print("Unable to find font... here is a list of fonts:\n")
|
||||
for x in sorted(fmod.get_fonts()):
|
||||
print(x)
|
||||
sys.exit(0)
|
||||
|
||||
fontsize = int(fontsize)
|
||||
fontname = "%s%s" % (fontname, fontsize)
|
||||
|
||||
f = Font(ffile, fontsize)
|
||||
|
||||
start = 32
|
||||
end = 128
|
||||
images = []
|
||||
imsizes = []
|
||||
maxwidth = 0
|
||||
maxheight = 0
|
||||
for char in range(start, end):
|
||||
letter = chr(char)
|
||||
sz = f.size(letter)
|
||||
maxwidth = max(maxwidth, sz[0])
|
||||
maxheight = max(maxheight, sz[1])
|
||||
im = f.render(letter, True, (255, 255, 255))
|
||||
images.append(im)
|
||||
imsizes.append(sz)
|
||||
|
||||
print(len(images))
|
||||
maxwidth += 1
|
||||
maxheight += 1
|
||||
|
||||
ratio = float(maxwidth) / float(maxheight)
|
||||
print("Ratio %s" % (ratio,))
|
||||
reqwidth = maxwidth * len(images)
|
||||
|
||||
ratioheight = int(math.ceil(math.sqrt(len(images) * ratio)))
|
||||
ratiowidth = int(math.ceil(len(images) / math.sqrt(len(images) * ratio)))
|
||||
|
||||
print([ratioheight, ratiowidth])
|
||||
|
||||
reqwidth = maxwidth * ratiowidth
|
||||
reqheight = maxheight * ratioheight
|
||||
|
||||
print([reqheight, reqwidth])
|
||||
|
||||
texsize = 16
|
||||
|
||||
while texsize < reqheight or texsize < reqwidth:
|
||||
texsize *= 2
|
||||
|
||||
print(texsize)
|
||||
|
||||
tex = pygame.Surface((texsize, texsize), pygame.SRCALPHA, 32)
|
||||
tex.fill((0, 0, 0, 0))
|
||||
|
||||
for i, im in enumerate(images):
|
||||
tex.blit(im, (((i % ratiowidth) * maxwidth), ((i // ratiowidth) * maxheight)))
|
||||
|
||||
pygame.image.save(tex, "%s.png" % (fontname,))
|
||||
|
||||
datf = open("%s.tfd" % (fontname,), "w")
|
||||
datf.write("fontheader\n")
|
||||
datf.write("%s,%s\n" % (start, end))
|
||||
datf.write("%s,%s\n" % (maxwidth, maxheight))
|
||||
datf.write("%s,%s\n" % (ratiowidth, ratioheight))
|
||||
datf.write("%s,%s\n" % (texsize, texsize))
|
||||
datf.write("charsizes\n")
|
||||
for i, sz in enumerate(imsizes):
|
||||
datf.write("%s,%s\n" % (sz[0], sz[1]))
|
||||
|
||||
datf.close()
|
||||
|
||||
|
||||
|
|
5
video.py
|
@ -18,7 +18,8 @@ def enable_vsync():
|
|||
|
||||
def skipping_next_frame():
|
||||
return False
|
||||
def set_res((width_in, height_in)):
|
||||
def set_res(xxx_todo_changeme):
|
||||
(width_in, height_in) = xxx_todo_changeme
|
||||
global height, width, hwnd
|
||||
|
||||
load_window_pos()
|
||||
|
@ -85,7 +86,7 @@ def init2d():
|
|||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
|
||||
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (0.3, 0.3, 0.3, 1.0))
|
||||
|
||||
|
||||
shader.mgr.load()
|
||||
shader.mgr.init_gl()
|
||||
shader.mgr.select("ffp")
|
||||
|
|