working textures!

completely overhauled models framework...
now loads Model, Mesh, Material, and Texture (plus TextureFile)

fixed a number of bugs/inflexibilities in gamedata xml parser

refactored the various modules to use "init" functions to better control when they get loaded (ie, before or after OpenGL init)
which it turns out is *very important*, because if the shaders and textures get loaded before OpenGL does, they don't work. go figure.
This commit is contained in:
cecilkorik 2011-06-17 19:54:49 -06:00
parent edd7630844
commit deaa55d535
14 changed files with 440 additions and 359 deletions

View file

@ -10,4 +10,8 @@ class asset_manager(object):
return go
mgr = asset_manager()
def init():
global mgr
mgr = asset_manager()
mgr = None

View file

@ -1,23 +1,37 @@
<xml_binary_packing name="models">
<datatag name="mesh" multiple="yes">
<attribute name="id" data="string"/>
<datatag name="file" data="string" default=""/>
<datatag name="sprite" data="bool" default=""/>
<datatag name="centered_sprite" data="bool" default=""/>
</datatag>
<datatag name="model" multiple="yes">
<attribute name="id" data="string"/>
<datatag name="render" multiple="yes">
<attribute name="layer" data="int"/>
<datatag name="model">
<datatag name="file" data="string" default=""/>
<datatag name="xaxis_index" data="int" default="0"/>
<datatag name="yaxis_index" data="int" default="1"/>
<datatag name="zaxis_index" data="int" default="2"/>
<datatag name="mesh">
<datatag name="ref" data="string" default=""/>
<datatag name="xaxis" data="int" default="0"/>
<datatag name="yaxis" data="int" default="1"/>
<datatag name="zaxis" data="int" default="2"/>
<datatag name="scale" data="float" default="1.0">
<attribute name="x" data="float" default="1.0"/>
<attribute name="y" data="float" default="1.0"/>
<attribute name="z" data="float" default="1.0"/>
</datatag>
</datatag>
<datatag name="texture" data="string" optional="yes" multiple="yes">
<attribute name="layer" data="int" default="0"/>
<datatag name="material">
<datatag name="ref" data="string"/>
<datatag name="color" optional="yes">
<attribute name="r" data="float" default="1.0"/>
<attribute name="g" data="float" default="1.0"/>
<attribute name="b" data="float" default="1.0"/>
<attribute name="a" data="float" default="1.0"/>
</datatag>
</datatag>
<datatag name="sprite" data="string" default=""/>
<datatag name="sprite_color" data="string" default=""/>
<datatag name="billboard" data="bool" default=""/>
<datatag name="beam_align" data="bool" default=""/>
<datatag name="particle" data="bool" default=""/>
<datatag name="scale" data="float" default="1.0"/>
</datatag>
<datatag name="light" multiple="yes">
<datatag name="color" optional="yes">

View file

@ -3,9 +3,16 @@
<attribute name="id" data="string"/>
<datatag name="file" data="string"/>
<datatag name="coords" optional="yes">
<attribute name="x" data="int" default="-1" optional="yes"/>
<attribute name="y" data="int" default="-1" optional="yes"/>
<attribute name="x1" data="int" default="-1"/>
<attribute name="y1" data="int" default="-1"/>
<attribute name="x2" data="int" default="-1"/>
<attribute name="y2" data="int" default="-1"/>
<attribute name="x" data="int" default="-1"/>
<attribute name="y" data="int" default="-1"/>
<attribute name="h" data="int" default="-1"/>
<attribute name="w" data="int" default="-1"/>
</datatag>
<datatag name="uniform" data="bool" default=""/>
</datatag>
<datatag name="material" multiple="yes">
<attribute name="id" data="string"/>

View file

@ -1,101 +1,14 @@
<models>
<model id="m_star_yellow">
<mesh id="mesh_sprite">
<sprite/>
</mesh>
<mesh id="mesh_centered_sprite">
<centered_sprite/>
</mesh>
<model id="m_test">
<render layer="0">
<sprite>star_sprite_washout</sprite>
<billboard/>
<sprite_color>1.0,1.0,0.5,1.0</sprite_color>
</render>
<render layer="1">
<sprite>star_sprite_main</sprite>
<billboard/>
<sprite_color>1.0,1.0,0.7,1.0</sprite_color>
</render>
<render layer="2">
<sprite>star_sprite_inner</sprite>
<billboard/>
<sprite_color>1.0,1.0,1.0,1.0</sprite_color>
</render>
<light>
<color r="1.0" g="0.95" b="0.8"/>
<sun/>
<basepower>1.0</basepower>
</light>
</model>
<model id="m_fi_kestrel">
<render layer="0">
<model><file>kestrel</file></model>
<texture>kestrel</texture>
</render>
</model>
<model id="m_bs_thor">
<render layer="0">
<model><file>thor</file></model>
</render>
<light>
<color r="1.0" g="0.0" b="0.0"/>
<basepower>0.5</basepower>
<attenuation quadratic="0.0001"/>
</light>
</model>
<model id="m_misc_navbuoy0">
<render layer="0">
<model><file>navbuoy</file></model>
</render>
<light>
<color r="0.0" g="1.0" b="0.0"/>
<basepower>1.0</basepower>
<attenuation quadratic="0.000001"/>
</light>
</model>
<model id="m_misc_navbuoy_test">
<render layer="0">
<model><file>navbuoy</file></model>
</render>
<light>
<color r="0.0" g="0.0" b="1.0"/>
<basepower>2.5</basepower>
<attenuation quadratic="0.00000001"/>
</light>
</model>
<model id="m_planet_bob">
<render layer="0">
<model><file>planet1</file></model>
<scale>100.0</scale>
</render>
</model>
<model id="p_soft">
<render layer="0">
<sprite>soft_particle</sprite>
<billboard/>
<particle/>
</render>
</model>
<model id="p_hard">
<render layer="0">
<sprite>hard_particle</sprite>
<billboard/>
<particle/>
</render>
</model>
<model id="p_medium">
<render layer="0">
<sprite>medium_particle</sprite>
<billboard/>
<particle/>
</render>
</model>
<model id="m_fr_spacetruck">
<render layer="0">
<model><file>kestrel</file></model>
<texture>kestrel</texture>
</render>
</model>
<model id="m_pl_bob">
<render layer="0">
<model><file>planet1</file></model>
<texture>planet1_earthy</texture>
<scale>1000.0</scale>
<mesh><ref>mesh_sprite</ref><scale x="200" y="200"/></mesh>
<material><ref>mat_test</ref></material>
</render>
</model>
</models>

View file

@ -1,16 +1,20 @@
<textures>
<texture id="t_black">
<file>tex/black.png</file>
<coords/>
<uniform/>
</texture>
<texture id="t_white">
<file>tex/white.png</file>
<uniform/>
</texture>
<texture id="tnm_flat">
<file>tex/nm_flat.png</file>
<uniform/>
</texture>
<material id="m_blank">
<material id="mat_blank">
<texture ref="t_white" type="diffuse"/>
<texture ref="tnm_black" type="normal"/>
<texture ref="tnm_flat" type="normal"/>
</material>
<texture id="t_test">
<file>tex/test1.png</file>
@ -21,7 +25,7 @@
<texture id="t_test_plasma2">
<file>tex/plasma2.png</file>
</texture>
<material id="m_test">
<texture ref="t_test">
<material id="mat_test">
<texture ref="t_test"/>
</material>
</textures>

View file

@ -1,16 +1,32 @@
class enum(object):
pass
def __len__(self):
return len([x for x in dir(self) if x[0] != '_'])
def __iter__(self):
for name in sequence(self):
yield getattr(self, name)
def index(enumobj, name):
return getattr(enumobj, name)
def reverse(enumobj, value):
for name in dir(enumobj):
if name[0] == '_':
continue
if value == eval("enumobj.%s" % (name,)):
if value == getattr(enumobj, name):
return name
return None
def sequence(enumobj):
retlist = []
for name in dir(enumobj):
if name[0] == '_':
continue
retlist.append((getattr(enumobj, name), name))
return [x[1] for x in sorted(retlist)]
# render types (for model.renderable_layer)
rt = enum()

View file

@ -24,5 +24,12 @@ class filemanager(object):
def png(self, *args):
filename = self.path(*args)
return pygame.image.load(filename)
def canonize_path(self, path):
return path.lower()
mgr = filemanager()
def init():
global mgr
mgr = filemanager()
mgr = None

View file

@ -24,6 +24,8 @@ class GameDataTagDef(object):
class GameDataNode(object):
def __init__(self):
self.dict = {}
self.missing = False
def __setitem__(self, name, val):
self.dict[name] = val
def __getitem__(self, name):
@ -97,20 +99,24 @@ class XMLGameDataReader(object):
def create_attribute_def(self, tag):
return self.create_datatag_def(tag)
def construct_node(self, bin, xml):
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 type(xml) == MissingNode and df.opt:
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 type(xml) == MissingNode:
elif (node.missing or value == None) and not allow_missing:
raise ValueError, "Missing value for mandatory tag %s" % (bin.get('name'),)
elif df.type == 'bool':
# tag exists, and since it is a bool, that means it's True
value = True
elif (node.missing or value == None):
value = None
else:
value = self.value_as_type(value, df.type)
@ -121,8 +127,10 @@ class XMLGameDataReader(object):
value = xml.get(bin.get('name'))
if value == None and df.opt:
value = df.default
elif not value:
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)
@ -133,7 +141,7 @@ class XMLGameDataReader(object):
return node
def construct_recurse(self, bin, xml):
def construct_recurse(self, bin, xml, allow_missing=False):
xmldict = {}
tagdict = {}
attrdict = {}
@ -141,7 +149,7 @@ class XMLGameDataReader(object):
if bin.tag == 'xml_binary_packing':
node = GameDataNode()
else:
node = self.construct_node(bin, xml)
node = self.construct_node(bin, xml, allow_missing)
for child in bin.getchildren():
if child.tag == 'datatag':
@ -152,38 +160,41 @@ class XMLGameDataReader(object):
raise ValueError
xmlattrdict = {}
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)
if subnode._def.multi:
node.add_multi(k, subnode)
else:
node.add_single(k, subnode)
xmltagdict = {}
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)
if subnode._def.multi:
node.add_multi(child.tag, subnode)
else:
node.add_single(child.tag, subnode)
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_node(tagdict[k], missing)
subnode = self.construct_recurse(tagdict[k], missing, isinstance(xml, MissingNode))
if not subnode._def.multi:
node.add_single(k, subnode)
else:
@ -192,7 +203,7 @@ class XMLGameDataReader(object):
for k in attrdict.keys():
if not k in xmlattrdict:
# Missing attribute
subnode = self.construct_node(attrdict[k], missing)
subnode = self.construct_node(attrdict[k], missing, isinstance(xml, MissingNode))
if not subnode._def.multi:
node.add_single(k, subnode)
else:

344
models.py
View file

@ -1,4 +1,9 @@
import enums
import files
import gamedata
import pygame
from OpenGL.GL import *
from py3dutil import vect
class Vertex(object):
__slots__ = [
@ -7,39 +12,99 @@ class Vertex(object):
't', # texture coordinates
'c', # color
]
def __init__(self, v, n, t, c):
self.v = v
self.n = n
self.t = t
self.c = c
class Model_Manager(object):
def __init__(self):
self.load_textypes()
self.load_textures()
self.load_materials()
self.load_models()
def load_textypes():
self.textypes = {}
self.textypes[enums.tt.diffuse] = TextureType(GL_TEXTURE0, GL_TEXTURE_2D, GL_CLAMP, GL_CLAMP, GL_NEAREST, GL_NEAREST)
self.textypes[enums.tt.dark] = TextureType(GL_TEXTURE1, GL_TEXTURE_2D)
self.textypes[enums.tt.specular] = TextureType(GL_TEXTURE2, GL_TEXTURE_2D)
self.textypes[enums.tt.normal] = TextureType(GL_TEXTURE3, GL_TEXTURE_2D)
pass
def create(self, mname):
return self.models[mname].instance()
def get_textype(self, textype):
if isinstance(textype, TextureType):
return textype
return self.textypes[textype]
def load_textures(self):
gamedata.get('textures')
def load_textures(self):
gamedata.get('materials')
def load_textures(self):
gamedata.get('models')
def load(self):
self.load_textypes()
self.load_textures()
self.load_materials()
self.load_models()
mgr = Model_Manager()
def load_textypes(self):
self.textypes = {}
self.textypes[enums.tt.diffuse] = TextureType(GL_TEXTURE0, GL_TEXTURE_2D, GL_CLAMP, GL_CLAMP, GL_NEAREST, GL_NEAREST)
self.textypes[enums.tt.emissive] = TextureType(GL_TEXTURE1, GL_TEXTURE_2D)
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():
tt.initialize()
def load_textures(self):
texdata = gamedata.get('textures')
self.texture_files = {}
self.texture_ids = {}
self.textures = {}
self.materials = {}
for texd in texdata.texture:
fp = files.mgr.canonize_path(texd['file'])
if not fp in self.texture_files:
tf = TextureFile()
tf.load(fp)
self.texture_files[fp] = tf
self.texture_ids[tf.id] = tf
else:
tf = self.texture_files[fp]
to = Texture()
to.load(texd, tf)
self.textures[to.id] = to
for matd in texdata.material:
mo = Material()
mo.load(matd)
self.materials[mo.id] = mo
def load_meshes(self):
"ignored!!! meshes are contained in models.xml for now"
return
gamedata.get('meshes')
def load_materials(self):
"ignored!!! materials are contained in textures.xml for now"
return
gamedata.get('materials')
def load_models(self):
mdldata = gamedata.get('models')
self.meshes = {}
self.models = {}
for meshdata in mdldata.mesh:
if meshdata['sprite']:
mesh = SpriteMesh.singleton()
elif meshdata['centered_sprite']:
mesh = SpriteMeshCentered.singleton()
else:
mesh = Mesh.factory(meshdata)
mgr.meshes[meshdata['id']] = mesh
for modeldata in mdldata.model:
model = Model()
model.load(modeldata)
mgr.models[modeldata['id']] = model
class TextureType(object):
def __init__(self, texunit, texdim, wrap_s=GL_CLAMP, wrap_t=GL_CLAMP, mag=GL_LINEAR, min=GL_LINEAR)
def __init__(self, texunit, texdim, wrap_s=GL_CLAMP, wrap_t=GL_CLAMP, mag=GL_LINEAR, min=GL_LINEAR):
self.texunit = texunit
self.texdim = texdim
self.wrap_s = wrap_s
@ -64,32 +129,126 @@ class TextureType(object):
class Material(object):
def __init__(self):
pass
def attach_texture(self, textype, texid):
textype = mgr.get_textype(textype)
textype.activate()
self.id = None
self.textures = {}
self.texcoords = self.texcoords_notimpl
self.texcoords_uniform = self.texcoords_notimpl
def texcoords_notimpl(self, u, v):
raise NotImplementedError("No textures were associated with this material.")
def bind(self):
for tt in enums.tt:
if tt in self.textures:
tto = mgr.get_textype(tt)
tto.initialize()
tex = self.textures[tt]
tex.bind()
def load(self, data):
self.id = data['id']
prevtex = None
for tex in data.texture:
try:
texobj = mgr.textures[tex['ref']]
except KeyError:
raise KeyError("""Material "%s" references invalid %s texture "%s".""" % (self.id, tex['type'], tex['ref']))
typeidx = enums.index(enums.tt, tex['type'])
self.textures[typeidx] = texobj
if texobj.uniform:
if self.texcoords_uniform == self.texcoords_notimpl:
self.texcoords_uniform = texobj.texcoords
else:
if prevtex:
assert texobj.texcoords(0.0, 0.0) == prevtex.texcoords(0.0, 0.0) and texobj.texcoords(1.0, 1.0) == prevtex.texcoords(1.0, 1.0)
if self.texcoords == self.texcoords_notimpl:
self.texcoords = texobj.texcoords
prevtex = texobj
print self.textures
self.texid
class Texture(object):
def __init__(self):
pass
def load(self, file):
img = files.mgr.png(file)
texid, = glGenTextures(1)
self.id = None
self.texid = None
self.uniform = False
self.x = None
self.y = None
self.h = None
self.w = None
def texcoords_subset(self, u, v):
tf = mgr.texture_ids[self.texid]
dest_x = float(self.x) / float(tf.w)
dest_w = (float(self.x + self.w) / float(tf.w)) - dest_x
dest_y = float(self.y) / float(tf.h)
dest_h = (float(self.y + self.h) / float(tf.h)) - dest_y
return (dest_x + (u * dest_w), dest_y + (v * dest_h))
def texcoords_direct(self, u, v):
return (u, v)
def load(self, data, tf):
self.id = data['id']
self.texid = tf.id
self.uniform = data['uniform']
c = data.coords
if c['x'] != -1 and c['y'] != -1 and c['h'] != -1 and c['w'] != -1:
self.x = c['x']
self.y = c['y']
self.w = c['w']
self.h = c['h']
assert self.x < tf.w and self.w < tf.w and self.y < tf.h and self.h < tf.h
self.texcoords = self.texcoords_subset
elif c['x1'] != -1 and c['y1'] != -1 and c['x2'] != -1 and c['y2'] != -1:
self.x = c['x1']
self.y = c['y1']
self.w = c['x2'] - self.x
self.h = c['y2'] - self.y
assert self.x < tf.w and self.w < tf.w and self.y < tf.h and self.h < tf.h
self.texcoords = self.texcoords_subset
else:
self.x = 0
self.y = 0
self.w = tf.w
self.h = tf.h
self.texcoords = self.texcoords_direct
def bind(self):
glBindTexture(GL_TEXTURE_2D, self.texid)
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 = files.mgr.png(filename)
texid = glGenTextures(1)
print "Generated 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
glBindTexture(textype.get_dimension(), texid)
glTexImage2D(textype.get_dimension(), 0, GL_RGBA8, imgr.w, imgr.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgdata)
glBindTexture(textype.get_dimension(), 0)
dimension = GL_TEXTURE_2D
glBindTexture(dimension, texid)
glTexImage2D(dimension, 0, GL_RGBA8, imgr.w, imgr.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgdata)
glBindTexture(dimension, 0)
class Model(object):
class Mesh(object):
def __init__(self):
self.vertexes = []
@ -101,26 +260,105 @@ class Model(object):
def unset_rotation(self):
glPopMatrix()
def bind_textures(self):
glBindTexture(GL_TEXTURE_2D
def unbind_textures(self):
def draw(self):
self.bind_textures()
def draw(self, texcoord):
glBegin(GL_TRIANGLES)
for v in self.vertexes:
self.draw_vertex(v)
glEnd(GL_TRIANGLES)
self.unbind_textures()
self.draw_vertex(v, texcoord)
glEnd()
def draw_vertex(self, v):
def draw_vertex(self, v, texcoord):
glColor3f(v.c[0], v.c[1], v.c[2])
glNormal3f(v.n.x, v.n.y, v.n.z)
glTexCoord2f(v.t[0], v.t[1])
glTexCoord2f(*texcoord(v.t[0], v.t[1]))
glVertex3f(v.v.x, v.v.y, v.v.z)
class SpriteMesh(Mesh):
_SINGLETON = None
def __init__(self):
Mesh.__init__(self)
self.vertexes = [
Vertex(vect(0.0, 0.0, 0.0), vect(0.0, 0.0, 1.0), (0.0, 0.0), (1.0, 1.0, 1.0)),
Vertex(vect(0.0, 1.0, 0.0), vect(0.0, 0.0, 1.0), (0.0, 1.0), (1.0, 1.0, 1.0)),
Vertex(vect(1.0, 0.0, 0.0), vect(0.0, 0.0, 1.0), (1.0, 0.0), (1.0, 1.0, 1.0)),
Vertex(vect(1.0, 0.0, 0.0), vect(0.0, 0.0, 1.0), (1.0, 0.0), (1.0, 1.0, 1.0)),
Vertex(vect(0.0, 1.0, 0.0), vect(0.0, 0.0, 1.0), (0.0, 1.0), (1.0, 1.0, 1.0)),
Vertex(vect(1.0, 1.0, 0.0), vect(0.0, 0.0, 1.0), (1.0, 1.0), (1.0, 1.0, 1.0)),
]
@classmethod
def return_singleton(cls):
return cls._SINGLETON
@classmethod
def singleton(cls):
cls._SINGLETON = cls()
cls.singleton = cls.return_singleton
return cls._SINGLETON
class SpriteMeshCentered(SpriteMesh):
def __init__(self):
SpriteMesh.__init__(self)
self.vertexes = [
Vertex(vect(-0.5, -0.5, 0.0), vect(0.0, 0.0, 1.0), (0.0, 0.0), (1.0, 1.0, 1.0)),
Vertex(vect( 0.5, -0.5, 0.0), vect(0.0, 0.0, 1.0), (1.0, 0.0), (1.0, 1.0, 1.0)),
Vertex(vect(-0.5, 0.5, 0.0), vect(0.0, 0.0, 1.0), (0.0, 1.0), (1.0, 1.0, 1.0)),
Vertex(vect( 0.5, -0.5, 0.0), vect(0.0, 0.0, 1.0), (1.0, 0.0), (1.0, 1.0, 1.0)),
Vertex(vect(-0.5, 0.5, 0.0), vect(0.0, 0.0, 1.0), (0.0, 1.0), (1.0, 1.0, 1.0)),
Vertex(vect( 0.5, 0.5, 0.0), vect(0.0, 0.0, 1.0), (1.0, 1.0), (1.0, 1.0, 1.0)),
]
class Model(object):
def __init__(self):
self.layers = []
def load(self, data):
tmplayers = []
for rend in data.render:
layernum = rend['layer']
rl = RenderLayer(layernum)
rl.load(rend)
tmplayers.append((layernum, rl))
for ln, rl in sorted(tmplayers):
self.layers.append(rl)
def instance(self):
return self
def render(self):
for layer in self.layers:
layer.render()
class RenderLayer(object):
def __init__(self, layernum):
self.id = layernum
self.mesh = None
self.material = None
self.color = [1.0, 1.0, 1.0, 1.0]
self.scale = [1.0, 1.0, 1.0]
def load(self, layerdata):
meshdata = layerdata.mesh
matdata = layerdata.material
self.mesh = mgr.meshes[meshdata['ref']]
self.material = mgr.materials[matdata['ref']]
self.color = [matdata.color['r'], matdata.color['g'], matdata.color['b'], matdata.color['a']]
self.scale = [meshdata.scale['x'], meshdata.scale['y'], meshdata.scale['z']]
self.scale = [x * meshdata['scale'] for x in self.scale]
def render(self):
self.material.bind()
glPushMatrix()
glTranslatef(500.0, 300.0, 0.0)
glScalef(*self.scale)
self.mesh.draw(self.material.texcoords)
glPopMatrix()
class Sprite(object):
def __init__(self):
@ -143,4 +381,12 @@ class Sprite(object):
self.corners = vl
self.vertexes = [tl, bl, tr, bl, tr, br]
def set_texture(
def set_texture(self):
pass
def init():
global mgr
mgr = Model_Manager()
mgr.load()
mgr = None

72
roc.py
View file

@ -1,11 +1,9 @@
import pygame
from pygame.locals import *
import gamedata
import gametimer
import files
import video
import shader
import inputs
from OpenGL.GL import *
import models
import roc_main
def init2d():
@ -16,6 +14,8 @@ def init3d():
def init(videoinit):
pygame.init()
files.init()
shader.init()
size = width, height = (1600,1200)
size = width, height = (1024,768)
@ -23,64 +23,8 @@ def init(videoinit):
video.set_res(size)
videoinit()
video.enable_vsync()
def test_frame():
from PIL import Image
# pink triangle
glBegin(GL_TRIANGLE_STRIP)
glNormal3f(0.0, 0.0, 1.0)
glColor4f(1.0, 0.0, 0.5, 1.0)
glVertex3f( 20.0, 50.0, 1.0)
glVertex3f( 20.0, 600.0, 1.0)
glVertex3f( 400.0, 50.0, 1.0)
glEnd()
# yellow square
glBegin(GL_TRIANGLE_STRIP)
glNormal3f(0.0, 0.0, 1.0)
glColor4f(1.0, 1.0, 0.0, 1.0)
glVertex3f( 150.0, 20.0, -50.0)
glVertex3f( 150.0, 400.0, -50.0)
glVertex3f( 360.0, 20.0, -50.0)
glVertex3f( 360.0, 400.0, -50.0)
glEnd()
# texture test
glBegin(GL_TRIANGLE_STRIP)
glNormal3f(0.0, 0.0, 1.0)
glColor4f(1.0, 1.0, 1.0, 1.0)
glVertex3f( 500.0, 300.0, 5.0)
glVertex3f( 500.0, 500.0, 5.0)
glVertex3f( 700.0, 300.0, 5.0)
glVertex3f( 700.0, 500.0, 5.0)
glEnd()
def main():
gametimer.start_loop()
while True:
events = pygame.event.get()
gametimer.next_frame()
pygame.event.pump()
for ev in events:
if ev.type == QUIT:
inputs.add_command('exit')
break
elif ev.type == KEYUP:
inputs.keyup(ev.key)
elif ev.type == KEYDOWN:
inputs.keydown(ev.key)
#elif ev.type == VIDEOEXPOSE:
# video.force_redraw()
elif ev.type in (MOUSEBUTTONDOWN, MOUSEBUTTONUP):
pass
if 'exit' in inputs.commands:
break
video.predraw()
models.init()
test_frame()
video.next_frame()
def main():
roc_main.mainloop()

View file

@ -211,5 +211,9 @@ class shader_manager(object):
def load_shaders(self, shaders):
for shader in shaders.shader:
self.initshadersources.append((shader['id'], shader['vertex'], shader['fragment']))
mgr = shader_manager()
def init():
global mgr
mgr = shader_manager()
mgr = None

View file

@ -1,69 +0,0 @@
import files
import os
from OpenGL.GL import *
from py3ds.example.gltexture import Texture
class renderable_sprite(object):
"""
Internal class to create a textured quad for a sprite to live on.
Multiple sprites can use the same sprite_tex if the graphic they want to
display is the same.
"""
def __init__(self):
self.gltex = None
self.gllist = None
self.texfile = None
self.scale = 1.0
def load_name(self, name):
self.texfile = files.mgr.open(os.path.join('sprite', name + '.png'))
def set_file(self, fileobj):
self.texfile = fileobj
def update(self):
pass
def render(self):
if self.gltex == None:
self.gltex = Texture(self.texfile)
self.texfile.close()
self.texfile = None
if self.gllist == None:
glPushMatrix()
#glLoadIdentity()
dl = glGenLists(1)
if dl == 0:
raise GLError, "cannot allocate display list"
glNewList(dl, GL_COMPILE)
glEnable(GL_BLEND)
glEnable(GL_DEPTH_TEST)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
self.gltex.enable()
self.gltex.bind()
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
glBegin(GL_TRIANGLE_STRIP)
glNormal3f(1.0, 0.0, 0.0)
glTexCoord2f(1.0, 1.0); glVertex3f( 0.0, 1.0, 1.0)
glTexCoord2f(0.0, 1.0); glVertex3f( 0.0, 1.0, -1.0)
glTexCoord2f(1.0, 0.0); glVertex3f(-0.0, -1.0, 1.0)
glTexCoord2f(0.0, 0.0); glVertex3f(-0.0, -1.0, -1.0)
glEnd()
self.gltex.disable()
glDisable(GL_BLEND)
glEndList()
self.gllist = dl
glPopMatrix()
glCallList(self.gllist)
class sprite_manager(object):
def __init__(self):
self.sprite_cache = {}
def get(self, name):
if name in self.sprite_cache:
return self.sprite_cache[name]
s = renderable_sprite()
s.load_name(name)
self.sprite_cache[name] = s
return s
mgr = sprite_manager()

View file

@ -1,21 +0,0 @@
class texture_wrapper(object):
def __init__(self):
pass
def load_name(self, name):
pass
class texture_manager(object):
def __init__(self):
self.texture_cache = {}
def get(self, name):
if name in self.texture_cache:
return self.texture_cache[name]
t = texture_wrapper()
t.load_name(name)
self.texture_cache[name] = t
return t
mgr = texture_manager()

View file

@ -70,7 +70,8 @@ def init2d():
glDepthFunc(GL_GEQUAL)
glEnable(GL_BLEND)
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")