mirror of https://github.com/kivy/kivy.git
add some new ContextInstruction usefull for 3D rendering:
- PushState, ChangeState, PopState (like PushMatrix etc. but for any state/uniform) - ScaleXYZ (non uniform scale on all 3 axis) - UpdateNormalMatrix (set uniform 'normal_mat' based on current modelview_mat) - ApplyContextMatrix (multiply a current matrix by one from another matrix stack in context) - LoadIdentity (loads identity matrix) - all Matrixinstructions now als have 'stack' property to allow using multiple different kind of matrices.
This commit is contained in:
parent
e4c15b0443
commit
83ea2e07de
|
@ -77,8 +77,9 @@ from kivy.graphics.instructions import Callback, Canvas, CanvasBase, \
|
|||
ContextInstruction, Instruction, InstructionGroup, RenderContext, \
|
||||
VertexInstruction
|
||||
from kivy.graphics.context_instructions import BindTexture, Color, \
|
||||
MatrixInstruction, PopMatrix, PushMatrix, Rotate, Scale, \
|
||||
Translate, gl_init_resources
|
||||
PushState, ChangeState, PopState, MatrixInstruction, ApplyContextMatrix, \
|
||||
PopMatrix, PushMatrix, Rotate, Scale, ScaleXYZ, Translate, LoadIdentity, \
|
||||
UpdateNormalMatrix, gl_init_resources
|
||||
from kivy.graphics.vertex_instructions import Bezier, BorderImage, Ellipse, \
|
||||
GraphicException, Line, Mesh, Point, Quad, Rectangle, Triangle
|
||||
from kivy.graphics.stencil_instructions import StencilPop, StencilPush, \
|
||||
|
@ -98,5 +99,7 @@ __all__ = (Bezier.__name__, BindTexture.__name__, BorderImage.__name__,
|
|||
StencilPush.__name__, StencilUse.__name__, StencilUnUse.__name__,
|
||||
Translate.__name__, Triangle.__name__, VertexInstruction.__name__,
|
||||
ClearColor.__name__, ClearBuffers.__name__,
|
||||
gl_init_resources.__name__)
|
||||
gl_init_resources.__name__, PushState.__name__, ChangeState.__name__,
|
||||
PopState.__name__, ApplyContextMatrix.__name__, ScaleXYZ.__name__,
|
||||
UpdateNormalMatrix.__name__,LoadIdentity.__name__)
|
||||
|
||||
|
|
|
@ -6,6 +6,15 @@ from transformation cimport Matrix
|
|||
from instructions cimport ContextInstruction
|
||||
from texture cimport Texture
|
||||
|
||||
cdef class PushState(ContextInstruction):
|
||||
pass
|
||||
|
||||
cdef class ChangeState(ContextInstruction):
|
||||
pass
|
||||
|
||||
cdef class PopState(ContextInstruction):
|
||||
pass
|
||||
|
||||
cdef class LineWidth(ContextInstruction):
|
||||
cdef void apply(self)
|
||||
|
||||
|
@ -18,13 +27,26 @@ cdef class BindTexture(ContextInstruction):
|
|||
cdef Texture _texture
|
||||
cdef void apply(self)
|
||||
|
||||
|
||||
cdef class LoadIdentity(ContextInstruction):
|
||||
pass
|
||||
|
||||
cdef class PushMatrix(ContextInstruction):
|
||||
cdef void apply(self)
|
||||
|
||||
cdef class PopMatrix(ContextInstruction):
|
||||
cdef void apply(self)
|
||||
|
||||
cdef class ApplyContextMatrix(ContextInstruction):
|
||||
cdef object _target_stack
|
||||
cdef object _source_stack
|
||||
cdef void apply(self)
|
||||
|
||||
cdef class UpdateNormalMatrix(ContextInstruction):
|
||||
cdef void apply(self)
|
||||
|
||||
cdef class MatrixInstruction(ContextInstruction):
|
||||
cdef object _stack
|
||||
cdef Matrix _matrix
|
||||
cdef void apply(self)
|
||||
|
||||
|
@ -34,7 +56,6 @@ cdef class Transform(MatrixInstruction):
|
|||
cpdef rotate(self, float angle, float ax, float ay, float az)
|
||||
cpdef scale(self, float s)
|
||||
cpdef identity(self)
|
||||
cdef void apply(self)
|
||||
|
||||
cdef class Rotate(Transform):
|
||||
cdef float _angle
|
||||
|
@ -45,6 +66,11 @@ cdef class Scale(Transform):
|
|||
cdef float s
|
||||
cdef void apply(self)
|
||||
|
||||
cdef class ScaleXYZ(Transform):
|
||||
cdef float _x, _y, _z
|
||||
cdef void apply(self)
|
||||
cdef set_scale(self, double x, double y, double z)
|
||||
|
||||
cdef class Translate(Transform):
|
||||
cdef double _x, _y, _z
|
||||
cdef void apply(self)
|
||||
|
|
|
@ -100,6 +100,63 @@ cdef tuple hsv_to_rgb(float h, float s, float v):
|
|||
# Cannot get here
|
||||
|
||||
|
||||
cdef class PushState(ContextInstruction):
|
||||
'''Instruction that pushes arbitrary states/uniforms on the context
|
||||
state stack.
|
||||
'''
|
||||
def __init__(self, *args, **kwargs):
|
||||
ContextInstruction.__init__(self, **kwargs)
|
||||
self.context_push = list(args)
|
||||
|
||||
property state:
|
||||
def __get__(self):
|
||||
return ','.join(self.context_push)
|
||||
def __set__(self, value):
|
||||
self.context_push = value.split(',')
|
||||
|
||||
property states:
|
||||
def __get__(self):
|
||||
return self.context_push
|
||||
def __set__(self, value):
|
||||
self.context_push = list(value)
|
||||
|
||||
|
||||
cdef class ChangeState(ContextInstruction):
|
||||
'''Instruction that changes the values of arbitrary states/uniforms on the
|
||||
current render context.
|
||||
'''
|
||||
def __init__(self, **kwargs):
|
||||
ContextInstruction.__init__(self, **kwargs)
|
||||
self.context_state.update(**kwargs)
|
||||
|
||||
property changes:
|
||||
def __get__(self):
|
||||
return self.context_state
|
||||
def __set__(self, value):
|
||||
self.context_state = dict(value)
|
||||
|
||||
|
||||
cdef class PopState(ContextInstruction):
|
||||
'''Instruction that pops arbitrary states/uniforms on the context
|
||||
state stack.
|
||||
'''
|
||||
def __init__(self, *args, **kwargs):
|
||||
ContextInstruction.__init__(self, **kwargs)
|
||||
self.context_pop = list(args)
|
||||
|
||||
property state:
|
||||
def __get__(self):
|
||||
return ','.join(self.context_pop)
|
||||
def __set__(self, value):
|
||||
self.context_pop = value.split(',')
|
||||
|
||||
property states:
|
||||
def __get__(self):
|
||||
return self.context_pop
|
||||
def __set__(self, value):
|
||||
self.context_pop = list(value)
|
||||
|
||||
|
||||
cdef class Color(ContextInstruction):
|
||||
'''Instruction to set the color state for any vertices being drawn after it.
|
||||
All the values passed are between 0 and 1, not 0 and 255.
|
||||
|
@ -108,7 +165,7 @@ cdef class Color(ContextInstruction):
|
|||
|
||||
from kivy.graphics import Color
|
||||
|
||||
# create red color
|
||||
# create red v
|
||||
c = Color(1, 0, 0)
|
||||
# create blue color
|
||||
c = Color(0, 1, 0)
|
||||
|
@ -301,19 +358,75 @@ cdef class BindTexture(ContextInstruction):
|
|||
cdef double radians(double degrees):
|
||||
return degrees * (3.14159265 / 180.)
|
||||
|
||||
|
||||
cdef class LoadIdentity(ContextInstruction):
|
||||
'''Load identity Matrix into the matrix stack sepcified by
|
||||
the instructions stack property (default='modelview_mat')
|
||||
'''
|
||||
def __init__(self, **kwargs):
|
||||
self.context_state = kwargs.get("stack", "modelview_mat")
|
||||
|
||||
property stack:
|
||||
def __get__(self):
|
||||
return self.context_state.keys()[0]
|
||||
def __set__(self, value):
|
||||
self.context_state = {value: Matrix()}
|
||||
|
||||
|
||||
cdef class PushMatrix(ContextInstruction):
|
||||
'''PushMatrix on context's matrix stack
|
||||
'''
|
||||
def __init__(self, *args, **kwargs):
|
||||
ContextInstruction.__init__(self, **kwargs)
|
||||
self.context_push = ['modelview_mat']
|
||||
self.stack = kwargs.get("stack", "modelview_mat")
|
||||
|
||||
property stack:
|
||||
def __get__(self):
|
||||
return self.context_push[0]
|
||||
def __set__(self, value):
|
||||
value = value or "modelview_mat"
|
||||
self.context_push = [value]
|
||||
|
||||
|
||||
cdef class PopMatrix(ContextInstruction):
|
||||
'''Pop Matrix from context's matrix stack onto model view
|
||||
'''
|
||||
def __init__(self, *args, **kwargs):
|
||||
ContextInstruction.__init__(self, **kwargs)
|
||||
self.context_pop = ['modelview_mat']
|
||||
self.stack = kwargs.get("stack", "modelview_mat")
|
||||
|
||||
property stack:
|
||||
def __get__(self):
|
||||
return self.context_push[0]
|
||||
def __set__(self, value):
|
||||
value = value or "modelview_mat"
|
||||
self.context_pop = [value]
|
||||
|
||||
|
||||
cdef class ApplyContextMatrix(ContextInstruction):
|
||||
'''pre-multiply the matrix at the top of the stack specified by
|
||||
`target_stack` by the matrix at the top of the 'source_stack'
|
||||
'''
|
||||
def __init__(self, **kwargs):
|
||||
self._target_stack = kwargs.get('target_stack', 'modelview_mat')
|
||||
self._source_stack = kwargs.get('target_stack', 'modelview_mat')
|
||||
|
||||
cdef void apply(self):
|
||||
cdef RenderContext context = self.get_context()
|
||||
m = context.get_state(self._target_stack)
|
||||
m = m.multiply(context.get_state(self._source_stack))
|
||||
context.set_state(self._target_stack, m)
|
||||
|
||||
|
||||
cdef class UpdateNormalMatrix(ContextInstruction):
|
||||
'''Update the normal matrix 'normal_mat' based on the current
|
||||
modelview matrix. will compute 'normal_mat' uniform as:
|
||||
`inverse( transpose( mat3(mvm) ) )`
|
||||
'''
|
||||
cdef void apply(self):
|
||||
cdef RenderContext context = self.get_context()
|
||||
mvm = context.get_state('modelview_mat')
|
||||
context.set_state('normal_mat', mvm.normal_matrix())
|
||||
|
||||
|
||||
cdef class MatrixInstruction(ContextInstruction):
|
||||
|
@ -322,6 +435,7 @@ cdef class MatrixInstruction(ContextInstruction):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
ContextInstruction.__init__(self, **kwargs)
|
||||
self._stack = kwargs.get("stack", "modelview_mat")
|
||||
self._matrix = None
|
||||
|
||||
cdef void apply(self):
|
||||
|
@ -330,8 +444,8 @@ cdef class MatrixInstruction(ContextInstruction):
|
|||
'''
|
||||
cdef RenderContext context = self.get_context()
|
||||
cdef Matrix mvm
|
||||
mvm = context.get_state('modelview_mat')
|
||||
context.set_state('modelview_mat', mvm.multiply(self.matrix))
|
||||
mvm = context.get_state(self._stack)
|
||||
context.set_state(self._stack, mvm.multiply(self.matrix))
|
||||
|
||||
property matrix:
|
||||
''' Matrix property. Numpy matrix from transformation module
|
||||
|
@ -346,10 +460,21 @@ cdef class MatrixInstruction(ContextInstruction):
|
|||
self._matrix = x
|
||||
self.flag_update()
|
||||
|
||||
property stack:
|
||||
def __get__(self):
|
||||
return self._stack
|
||||
def __set__(self, value):
|
||||
value = value or "modelview_mat"
|
||||
self._stack = value
|
||||
|
||||
cdef class Transform(MatrixInstruction):
|
||||
'''Transform class. A matrix instruction class which
|
||||
has function to modify the transformation matrix
|
||||
'''
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
MatrixInstruction.__init__(self, **kwargs)
|
||||
|
||||
cpdef transform(self, Matrix trans):
|
||||
'''Multiply the instructions matrix by trans
|
||||
'''
|
||||
|
@ -377,7 +502,6 @@ cdef class Transform(MatrixInstruction):
|
|||
self.matrix = Matrix()
|
||||
|
||||
|
||||
|
||||
cdef class Rotate(Transform):
|
||||
'''Rotate the coordinate space by applying a rotation transformation
|
||||
on the modelview matrix. You can set the properties of the instructions
|
||||
|
@ -387,8 +511,8 @@ cdef class Rotate(Transform):
|
|||
rot.axis = (0,0,1)
|
||||
'''
|
||||
|
||||
def __init__(self, *args):
|
||||
Transform.__init__(self)
|
||||
def __init__(self, *args, **kwargs):
|
||||
Transform.__init__(self, **kwargs)
|
||||
if len(args) == 4:
|
||||
self.set(args[0], args[1], args[2], args[3])
|
||||
else:
|
||||
|
@ -425,9 +549,9 @@ cdef class Rotate(Transform):
|
|||
cdef class Scale(Transform):
|
||||
'''Instruction to perform a uniform scale transformation
|
||||
'''
|
||||
def __init__(self, *args):
|
||||
def __init__(self, *args, **kwargs):
|
||||
cdef double s
|
||||
Transform.__init__(self)
|
||||
Transform.__init__(self, **kwargs)
|
||||
if len(args) == 1:
|
||||
self.s = s = args[0]
|
||||
self.matrix = Matrix().scale(s, s, s)
|
||||
|
@ -443,13 +567,69 @@ cdef class Scale(Transform):
|
|||
self.s = s
|
||||
self.matrix = Matrix().scale(s, s, s)
|
||||
|
||||
cdef class ScaleXYZ(Transform):
|
||||
'''Instruction to create a non uniform scale transformation
|
||||
'''
|
||||
def __init__(self, *args, **kwargs):
|
||||
cdef double x, y, z
|
||||
Transform.__init__(self, **kwargs)
|
||||
if len(args) == 3:
|
||||
x, y, z = args
|
||||
self.set_scale(x, y, z)
|
||||
|
||||
cdef set_scale(self, double x, double y, double z):
|
||||
self._x = x
|
||||
self._y = y
|
||||
self._z = z
|
||||
self.matrix = Matrix().scale(x, y, z)
|
||||
|
||||
property x:
|
||||
'''Property for getting/setting the scale on X axis
|
||||
'''
|
||||
def __get__(self):
|
||||
return self._x
|
||||
def __set__(self, double x):
|
||||
self.set_scale(x, self._y, self._z)
|
||||
|
||||
property y:
|
||||
'''Property for getting/setting the scale on Y axis
|
||||
'''
|
||||
def __get__(self):
|
||||
return self._y
|
||||
def __set__(self, double y):
|
||||
self.set_scale(self._x, y, self._z)
|
||||
|
||||
property z:
|
||||
'''Property for getting/setting the scale on Z axis
|
||||
'''
|
||||
def __get__(self):
|
||||
return self._z
|
||||
def __set__(self, double z):
|
||||
self.set_scale(self._x, self._y, z)
|
||||
|
||||
property xy:
|
||||
'''2 tuple with scale vector in 2D for x and y axis
|
||||
'''
|
||||
def __get__(self):
|
||||
return self._x, self._y
|
||||
def __set__(self, c):
|
||||
self.set_scale(c[0], c[1], self._z)
|
||||
|
||||
property xyz:
|
||||
'''3 tuple scale vector in 3D in x, y, and z axis
|
||||
'''
|
||||
def __get__(self):
|
||||
return self._x, self._y, self._z
|
||||
def __set__(self, c):
|
||||
self.set_scale(c[0], c[1], c[2])
|
||||
|
||||
|
||||
cdef class Translate(Transform):
|
||||
'''Instruction to create a translation of the model view coordinate space
|
||||
'''
|
||||
def __init__(self, *args):
|
||||
def __init__(self, *args, **kwargs):
|
||||
cdef double x, y, z
|
||||
Transform.__init__(self)
|
||||
Transform.__init__(self, **kwargs)
|
||||
if len(args) == 3:
|
||||
x, y, z = args
|
||||
self.set_translate(x, y, z)
|
||||
|
@ -500,3 +680,4 @@ cdef class Translate(Transform):
|
|||
def __set__(self, c):
|
||||
self.set_translate(c[0], c[1], c[2])
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue