Skip to content

Commit

Permalink
Added flag initialiser, wip preference flags for opengl renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
Frimkron committed May 16, 2011
1 parent 44acc71 commit 6becb67
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 38 deletions.
28 changes: 20 additions & 8 deletions src/mrf/structs.py
Expand Up @@ -302,15 +302,17 @@ def dispatch(self,comm,*args,**kargs):
continue
return f(comm, *args,**kargs)
raise DispatchLookupError("Couldn't find function to dispatch to")



def type_dispatch(obj,args,kargs,handler,prefix="_handle_"):
for t in type(obj).__mro__:
try:
f = getattr(handler,prefix+t.__name__)
except AttributeError:
continue
return f(*args,**kargs)
class FlagInitialiser(object):
def __init__(self):
self.val = 0
def __iter__(self):
return self
def next(self):
f = 1 << self.val
self.val += 1
return f


# -- Testing -----------------------------
Expand Down Expand Up @@ -565,6 +567,16 @@ def __str__(self):
self.assertEquals(2, len(calls))
self.assertEquals("ba", calls[1])

class TestFlagInitialiser(unittest.TestCase):

def testIterator(self):
flags = []
for i,f in enumerate(FlagInitialiser()):
if i >= 8:
break
flags.append(f)
self.assertEquals([1,2,4,8,16,32,64,128], flags)

unittest.main()


Expand Down
102 changes: 72 additions & 30 deletions src/mrf/vectorgfx.py
Expand Up @@ -38,18 +38,22 @@
RENDERER_PYGAME = "pygame"
RENDERER_OPENGL = "opengl"

CAP_STROKE = (1<<0)
CAP_FILL = (1<<1)
CAP_SCALE = (1<<2)
CAP_ROTATION = (1<<3)
CAP_STROKE_ALPHA = (1<<4)
CAP_FILL_ALPHA = (1<<5)
CAP_MULTI_STROKE_COL = (1<<6)
CAP_MULTI_STROKE_WIDTH = (1<<7)
CAP_MULTI_FILL_COL = (1<<8)
f = FlagInitialiser()
CAP_POSITION = f.next()
CAP_SCALE = f.next()
CAP_ROTATION = f.next()
CAP_IMG_STROKE_COLOUR = f.next()
CAP_IMG_STROKE_ALPHA = f.next()
CAP_IMG_STROKE_WIDTH = f.next()
CAP_IMG_FILL_COLOUR = f.next()
CAP_IMG_FILL_ALPHA = f.next()
CAP_OVR_STROKE_COL = f.next()
CAP_OVR_STROKE_ALPHA = f.next()
CAP_OVR_STROKE_WID = f.next()
CAP_OVR_FILL_COLOUR = f.next()
CAP_OVR_FILL_ALPHA = f.next()
CAP_ALL = (1<<32)-1


# Command objects:

class Inherited(object): pass
Expand Down Expand Up @@ -1352,12 +1356,18 @@ def _colour(self,val):

class OpenGLRenderer(object):

def __init__(self,capabilities):
def __init__(self,img_stroke_colour,img_stroke_width,translate_transform,
rotate_transform,scale_transform):
# import opengl
import OpenGL.GL as GL
self._cache = {}
self.img_stroke_colour = img_stroke_colour
self.img_stroke_width = img_stroke_width
self.translate_transform = translate_transform
self.rotate_transform = rotate_transform
self.scale_transform = scale_transform

def render(self, target, img, pos, scale=1.0, rotation=0.0, stroke_colour=None, fill_colour=None):
def render(self,target,img,pos,scale=1.0,rotation=0.0,stroke_colour=None,stroke_width=None,fill_colour=None):
"""
Renders the given vector image. It is assumed that an OpenGL context has been established.
Expand All @@ -1367,7 +1377,8 @@ def render(self, target, img, pos, scale=1.0, rotation=0.0, stroke_colour=None,
pos 2-tuple containing the x and y to draw at
scale Float indicating the scale factor
rotation Rotation to draw at, in radians
stroke_colour The colour to draw the image in
stroke_colour Overriding stroke colour
stroke_width Overriding stroke width
fill_colour Not used
"""

Expand All @@ -1384,9 +1395,12 @@ def render(self, target, img, pos, scale=1.0, rotation=0.0, stroke_colour=None,
GL.glPushMatrix()

# build transform stack
GL.glTranslatef(pos[0], pos[1], 0.0)
GL.glRotatef(math.degrees(rotation), 0.0, 0.0, 1.0)
GL.glScalef(scale, scale, 1.0)
if self.translate_transform:
GL.glTranslatef(pos[0], pos[1], 0.0)
if self.rotate_transform:
GL.glRotatef(math.degrees(rotation), 0.0, 0.0, 1.0)
if self.scale_transform:
GL.glScalef(scale, scale, 1.0)

# set stroke colour
GL.glColor4f(stroke_colour[0], stroke_colour[1], stroke_colour[2], 1.0)
Expand All @@ -1398,18 +1412,21 @@ def render(self, target, img, pos, scale=1.0, rotation=0.0, stroke_colour=None,
GL.glPopMatrix()

def cache(self, img):
self._cache[img] = self._convert(img)
self._cache[img] = self._convert(img,self.img_stroke_colour,self.img_stroke_width)

def _convert(self, img):
def _convert(self, img, bake_stroke_colour,bake_stroke_width):

drawlist = GL.glGenLists(1)
GL.glNewList(drawlist, GL.GL_COMPILE)

for pmp in PointMatrixPolygon.convert(img):
if pmp.stroke_colour is not None and pmp.stroke_width > 0:

GL.glColor4f(*pmp.stroke_colour)
GL.glLineWidth(pmp.stroke_width)
if bake_stroke_colour:
GL.glColor4f(*pmp.stroke_colour)
if bake_stroke_width:
GL.glLineWidth(pmp.stroke_width)

GL.glBegin(GL.GL_LINE_LOOP if pmp.closed else GL.GL_LINE_STRIP)

for x,y in [(pmp.point_matrix[0][c],pmp.point_matrix[1][c])
Expand Down Expand Up @@ -1450,24 +1467,49 @@ def make_renderer(type, capabilities=None):
Use None for all available capabilites for the given type.
"""
if type == RENDERER_PYGAME:
if( capabilities is not None
and any([capabilities & c != 0 for c in (CAP_FILL_ALPHA,CAP_STROKE_ALPHA)]) ):
raise CapabilityError("CAP_FILL_ALPHA and CAP_STROKE_ALPHA not supported by RENDERER_PYGAME")
_incapable_check(capabilities,("CAP_IMG_FILL_ALPHA","CAP_IMG_STROKE_ALPHA",
"CAP_OVR_FILL_ALPHA","CAP_OVR_STROKE_ALPHA"))
return PygameRenderer()

elif type == RENDERER_OPENGL:

if( capabilities is not None
and any([capabilities & c != 0 for c in (CAP_FILL,CAP_FILL_ALPHA,CAP_MULTI_STROKE_COL,
CAP_MULTI_STROKE_WIDTH,CAP_MULTI_FILL_COL) ]) ):
raise CapabilityError("CAP_FILL, CAP_FILL_ALPHA, CAP_MULTI_STROKE_COL, "
+"CAP_MULTI_STROKE_WIDTH, CAP_MULTI_FILL_COL not supported by RENDERER_OPENGL")
return OpenGLRenderer(capabilities)
if capabilities is None:
capabilities = (CAP_POSITION|CAP_ROTATION|CAP_SCALE|CAP_IMG_STROKE_COLOUR
|CAP_IMG_STROKE_ALPHA|CAP_IMG_STROKE_WIDTH)
_incapable_check(capabilities,("CAP_IMG_FILL_COLOUR","CAP_IMG_FILL_ALPHA",
"CAP_OVR_FILL_COLOUR","CAP_OVR_FILL_ALPHA"))
_incapable_combination_check(capabilities,[
("CAP_IMG_STROKE_COLOUR","CAP_OVR_STROKE_COLOUR"),
("CAP_IMG_STROKE_ALPHA","CAP_OVR_STROKE_ALPHA"),
("CAP_IMG_STROKE_WIDTH","CAP_OVR_STROKE_WIDTH"),
("CAP_IMG_STROKE_COLOUR","CAP_OVR_STROKE_ALPHA"),
("CAP_OVR_STROKE_COLOUR","CAP_IMG_STROKE_ALPHA"),
])
img_stroke_colour = ( capabilities & (CAP_IMG_STROKE_COLOUR|CAP_IMG_STROKE_ALPHA) != 0
or capabilities & (CAP_OVR_STROKE_COLOUR|CAP_OVR_STROKE_ALPHA) == 0 )
img_stroke_width = ( capabilities & CAP_IMG_STROKE_WIDTH != 0
or capabilities & CAP_OVR_STROKE_WIDTH == 0 )
translate_transform = capabilities & CAP_POSITION != 0
rotate_transform = capabilities & CAP_ROTATE != 0
scale_transform = capabilities & CAP_SCALE != 0

return OpenGLRenderer(img_stroke_colour,img_stroke_width,
translate_transform,rotate_transform,scale_transform)

else:
raise ValueError("Unknown renderer type %s" % type)


def _incapable_check(requested,incap_names):
if( requested is not None
and any([requested & globals()[c] != 0 for c in incap_names]) ):
raise CapabilityError("%s not supported by this renderer" % ", ".join(incap_names))

def _incapable_combination_check(requested,incap_name_sets):
if requested is not None:
for nameset in incap_name_sets:
if all([requested & globals()[c] != 0 for c in nameset]):
raise CapabilityError("Use of %s together not supported by this renderer" % " and ".join(nameset))

if __name__ == "__main__":
import sys
import random
Expand Down

0 comments on commit 6becb67

Please sign in to comment.