New Python bindings via Cython

This commit is contained in:
Hector Martin 2011-03-20 08:42:48 +01:00
parent 8c23610b0f
commit 2b24b889db
8 changed files with 815 additions and 2 deletions

View file

@ -30,6 +30,7 @@ endif()
find_package(Threads REQUIRED)
find_package(JACK REQUIRED)
find_package(PythonInterp REQUIRED)
find_package(Qt4)
find_package(FFmpeg)
find_package(OpenGL)
@ -46,4 +47,5 @@ add_definitions(-Wall)
add_subdirectory (libol)
add_subdirectory (output)
add_subdirectory (tools)
add_subdirectory (python)
add_subdirectory (examples)

View file

@ -35,7 +35,7 @@ if(CURSES_FOUND AND FFMPEG_FOUND)
DEPENDS ${CMAKE_SOURCE_DIR}/tools/svg2ild.py
MAIN_DEPENDENCY ${NAME}.svg
DEPENDS ${NAME}.svg ${NAME}.cfg
COMMAND python ${CMAKE_SOURCE_DIR}/tools/svg2ild.py -q ${ARGN} -cfg ${CMAKE_CURRENT_SOURCE_DIR}/${NAME}.cfg ${CMAKE_CURRENT_SOURCE_DIR}/${NAME}.svg ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.ild)
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/svg2ild.py -q ${ARGN} -cfg ${CMAKE_CURRENT_SOURCE_DIR}/${NAME}.cfg ${CMAKE_CURRENT_SOURCE_DIR}/${NAME}.svg ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.ild)
endfunction()
svg2ild(openlase-logo -noopt)

185
examples/harp2.py Normal file
View file

@ -0,0 +1,185 @@
# OpenLase - a realtime laser graphics toolkit
#
# Copyright (C) 2009-2011 Hector Martin "marcan" <hector@marcansoft.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 or version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# This is the laser harp sensing portion, which has nothing to do with OpenLase.
# You need OpenCV (2.2.0) and PyALSA installed
# Pass the destination ALSA MIDI client:port pair as an argument.
# You may need to edit some constants here
THRESHOLD=60
WIDTH=320
HEIGHT=240
VELOCITY=90
import sys, math
import cv
from pyalsa import alsaseq
import pylase as ol
import threading, time
class LaserThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.die = False
self.dots = []
def run(self):
ol.init()
params = ol.RenderParams()
params.render_flags = ol.RENDER_NOREORDER | ol.RENDER_GRAYSCALE
ol.setRenderParams(params)
while not self.die:
ol.loadIdentity()
for x,y in self.dots:
ol.dot((x,y), 30, ol.C_WHITE)
ol.renderFrame(100)
ol.shutdown()
seq = alsaseq.Sequencer(name="default", clientname=sys.argv[0], streams = alsaseq.SEQ_OPEN_DUPLEX, mode = alsaseq.SEQ_NONBLOCK)
port = seq.create_simple_port(
name='out',
type = alsaseq.SEQ_PORT_TYPE_MIDI_GENERIC | alsaseq.SEQ_PORT_TYPE_APPLICATION,
caps = alsaseq.SEQ_PORT_CAP_READ | alsaseq.SEQ_PORT_CAP_SUBS_READ)
def note(n, state=False):
if state:
etype = alsaseq.SEQ_EVENT_NOTEON
else:
etype = alsaseq.SEQ_EVENT_NOTEOFF
event = alsaseq.SeqEvent(type=etype)
event.set_data({'note.channel': 0, 'note.note': n, 'note.velocity': 90})
seq.output_event(event)
seq.drain_output()
if len(sys.argv) > 1:
toport = seq.parse_address(sys.argv[1])
seq.connect_ports((seq.client_id, port), toport)
def getpoints(image):
points = []
cv.CvtColor(image, grey, cv.CV_RGB2GRAY)
cv.Threshold(grey, grey, THRESHOLD, 255, cv.CV_THRESH_BINARY)
cv.Copy(grey, grey2)
storage = cv.CreateMemStorage(0)
contour = cv.FindContours(grey, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE)
while contour:
bound_rect = cv.BoundingRect(list(contour))
contour = contour.h_next()
pt = (bound_rect[0] + bound_rect[2]/2, bound_rect[1] + bound_rect[3]/2)
#cv.Circle(image, pt, 2, cv.CV_RGB(255,0,0), 1)
points.append(pt)
return points
def near(p1, p2, d):
x,y = (p1[0]-p2[0],p1[1]-p2[1])
dist = math.sqrt(x**2+y**2)
return dist < d
oldstate = None
olt = LaserThread()
print "Starting thread"
v_off = -0.1
n_start = 47
n_end = 47 + 25
n_off = 0
offsets = [0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0]
xpos = [0, 0.5, 1, 1.5, 2, 3, 3.5, 4, 4.5, 5, 5.5, 6]
def gxpos(x):
o = x // 12
v = x % 12
return xpos[v] + o * 7
dots = []
xstart = gxpos(n_start)
xend = gxpos(n_end)
for n in range(n_start, n_end+1):
ld = (n + n_off) % len(offsets)
off = offsets[ld] * v_off
x = 2 * (gxpos(n + n_off) - xstart) / float(xend - xstart)
x -= 1.0
x *= 0.99
dots.append((-x, off))
olt.dots = dots
time.sleep(1)
camera = cv.CreateCameraCapture(0)
cv.SetCaptureProperty(camera, cv.CV_CAP_PROP_FRAME_WIDTH, WIDTH)
cv.SetCaptureProperty(camera, cv.CV_CAP_PROP_FRAME_HEIGHT, HEIGHT)
cv.SetCaptureProperty(camera, cv.CV_CAP_PROP_BRIGHTNESS, 0)
image = cv.QueryFrame(camera)
image = cv.QueryFrame(camera)
image = cv.QueryFrame(camera)
grey = cv.CreateImage(cv.GetSize(image), cv.IPL_DEPTH_8U, 1)
grey2 = cv.CreateImage(cv.GetSize(image), cv.IPL_DEPTH_8U, 1)
olt.start()
print "Thread running"
try:
for i in range(30):
image = cv.QueryFrame(camera)
refpoints = getpoints(image)
refpoints.sort(key=lambda x: -x[0])
print len(refpoints), n_end - n_start + 1
while True:
image = cv.QueryFrame(camera)
cpoints = getpoints(image)
state = [False]*len(refpoints)
for i, rp in enumerate(refpoints):
for cp in cpoints:
if near(rp,cp,4):
break
else:
state[i] = True
if oldstate is not None:
for i,(j,k) in enumerate(zip(oldstate, state)):
if j != k:
note(n_start+len(oldstate)-i, k)
if k:
print "PRESSED: %d"%i
else:
print "RELEASED: %d"%i
oldstate = state
cv.ShowImage("thresholded", grey2)
if cv.WaitKey(10)&0xfff == 27:
break
except:
olt.die = True
olt.join()
raise

44
examples/showtext.py Normal file
View file

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# OpenLase - a realtime laser graphics toolkit
#
# Copyright (C) 2009-2011 Hector Martin "marcan" <hector@marcansoft.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 or version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import pylase as ol
import sys
if ol.init(10) < 0:
sys.exit(1)
params = ol.RenderParams()
params.render_flags = ol.RENDER_NOREORDER | ol.RENDER_GRAYSCALE
params.on_speed = 2/120.0
params.off_speed = 2/30.0
params.flatness = 0.000001
ol.setRenderParams(params)
lines = sys.argv[1:]
while True:
lc = len(lines)
font = ol.getDefaultFont()
yoff = (lc/2.0) * 0.3
for i,line in enumerate(lines):
w = ol.getStringWidth(font, 0.3, line)
ol.drawString(font, (-w/2,yoff-i*0.3), 0.3, ol.C_WHITE, line)
ftime = ol.renderFrame(60)

77
examples/simple.py Normal file
View file

@ -0,0 +1,77 @@
# OpenLase - a realtime laser graphics toolkit
#
# Copyright (C) 2009-2011 Hector Martin "marcan" <hector@marcansoft.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 or version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import pylase as ol
from math import pi
ol.init()
time = 0
frames = 0
while True:
ol.loadIdentity3()
ol.loadIdentity()
font = ol.getDefaultFont()
s = "Hi!"
w = ol.getStringWidth(font, 0.2, s)
ol.drawString(font, (-w/2,0.1), 0.2, ol.C_WHITE, s)
ol.perspective(60, 1, 1, 100)
ol.translate3((0, 0, -3))
for i in range(2):
ol.scale3((0.6, 0.6, 0.6))
ol.rotate3Z(time * pi * 0.1)
ol.rotate3X(time * pi * 0.8)
ol.rotate3Y(time * pi * 0.73)
ol.begin(ol.LINESTRIP)
ol.vertex3((-1, -1, -1), ol.C_WHITE)
ol.vertex3(( 1, -1, -1), ol.C_WHITE)
ol.vertex3(( 1, 1, -1), ol.C_WHITE)
ol.vertex3((-1, 1, -1), ol.C_WHITE)
ol.vertex3((-1, -1, -1), ol.C_WHITE)
ol.vertex3((-1, -1, 1), ol.C_WHITE)
ol.end()
ol.begin(ol.LINESTRIP);
ol.vertex3(( 1, 1, 1), ol.C_WHITE)
ol.vertex3((-1, 1, 1), ol.C_WHITE)
ol.vertex3((-1, -1, 1), ol.C_WHITE)
ol.vertex3(( 1, -1, 1), ol.C_WHITE)
ol.vertex3(( 1, 1, 1), ol.C_WHITE)
ol.vertex3(( 1, 1, -1), ol.C_WHITE)
ol.end()
ol.begin(ol.LINESTRIP)
ol.vertex3(( 1, -1, -1), ol.C_WHITE)
ol.vertex3(( 1, -1, 1), ol.C_WHITE)
ol.end()
ol.begin(ol.LINESTRIP)
ol.vertex3((-1, 1, 1), ol.C_WHITE)
ol.vertex3((-1, 1, -1), ol.C_WHITE)
ol.end()
ftime = ol.renderFrame(60)
frames += 1
time += ftime
print "Frame time: %f, FPS:%f"%(ftime, frames/time)
ol.shutdown()

View file

@ -25,4 +25,4 @@ target_link_libraries (openlase ${CMAKE_THREAD_LIBS_INIT} m jack)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/fontdef.c
DEPENDS ${CMAKE_SOURCE_DIR}/tools/genfont.py
MAIN_DEPENDENCY laserfont.svg
COMMAND python ${CMAKE_SOURCE_DIR}/tools/genfont.py ${CMAKE_CURRENT_SOURCE_DIR}/laserfont.svg ${CMAKE_CURRENT_BINARY_DIR}/fontdef.c default_font)
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/genfont.py ${CMAKE_CURRENT_SOURCE_DIR}/laserfont.svg ${CMAKE_CURRENT_BINARY_DIR}/fontdef.c default_font)

23
python/CMakeLists.txt Normal file
View file

@ -0,0 +1,23 @@
find_package(PythonLibs)
find_program(CYTHON_EXECUTABLE cython)
if(CYTHON_EXECUTABLE MATCHES "NOTFOUND" OR NOT PYTHONLIBS_FOUND)
message(STATUS "Will NOT build python bindings (python libs or cython missing)")
else()
execute_process(COMMAND
${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
add_custom_command(OUTPUT pylase.c
MAIN_DEPENDENCY pylase.pyx
COMMAND ${CYTHON_EXECUTABLE} -I ${CMAKE_SOURCE_DIR}/include -o pylase.c "${CMAKE_CURRENT_SOURCE_DIR}/pylase.pyx")
list(APPEND ADDITIONAL_MAKE_CLEAN_FILES pylase.c)
include_directories(${PYTHON_INCLUDE_PATH} ${CMAKE_SOURCE_DIR}/include)
add_library(pylase MODULE pylase.c)
set_target_properties(pylase PROPERTIES
PREFIX ""
OUTPUT_NAME "pylase"
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(pylase openlase)
endif()

482
python/pylase.pyx Normal file
View file

@ -0,0 +1,482 @@
# OpenLase - a realtime laser graphics toolkit
#
# Copyright (C) 2009-2011 Hector Martin "marcan" <hector@marcansoft.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 or version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from libc.stdint cimport *
cdef extern from "libol.h":
enum:
OL_LINESTRIP
OL_BEZIERSTRIP
OL_POINTS
enum:
_RENDER_GRAYSCALE "RENDER_GRAYSCALE"
_RENDER_NOREORDER "RENDER_NOREORDER"
_RENDER_NOREVERSE "RENDER_NOREVERSE"
ctypedef struct OLRenderParams:
int rate
float on_speed
float off_speed
int start_wait
int start_dwell
int curve_dwell
int corner_dwell
int end_dwell
int end_wait
float curve_angle
float flatness
float snap
int render_flags
int min_length
int max_framelen
ctypedef struct OLFrameInfo "OLFrameInfo":
int objects
int points
int resampled_points
int resampled_blacks
int padding_points
int olInit(int buffer_count, int max_points)
void olSetRenderParams(OLRenderParams *params)
void olGetRenderParams(OLRenderParams *params)
ctypedef void (*AudioCallbackFunc)(float *leftbuf, float *rightbuf, int samples)
void olSetAudioCallback(AudioCallbackFunc f)
void olLoadIdentity()
void olPushMatrix()
void olPopMatrix()
void olMultMatrix(float m[9])
void olRotate(float theta)
void olTranslate(float x, float y)
void olScale(float sx, float sy)
void olLoadIdentity3()
void olPushMatrix3()
void olPopMatrix3()
void olMultMatrix3(float m[16])
void olRotate3X(float theta)
void olRotate3Y(float theta)
void olRotate3Z(float theta)
void olTranslate3(float x, float y, float z)
void olScale3(float sx, float sy, float sz)
void olFrustum (float left, float right, float bot, float ttop, float near, float far)
void olPerspective(float fovy, float aspect, float zNear, float zFar)
void olResetColor()
void olMultColor(uint32_t color)
void olPushColor()
void olPopColor()
void olBegin(int prim)
void olVertex(float x, float y, uint32_t color)
void olVertex3(float x, float y, float z, uint32_t color)
void olEnd()
void olTransformVertex3(float *x, float *y, float *z)
ctypedef void (*ShaderFunc)(float *x, float *y, uint32_t *color)
ctypedef void (*Shader3Func)(float *x, float *y, float *z, uint32_t *color)
void olSetVertexPreShader(ShaderFunc f)
void olSetVertexShader(ShaderFunc f)
void olSetVertex3Shader(Shader3Func f)
void olSetPixelShader(ShaderFunc f)
void olRect(float x1, float y1, float x2, float y2, uint32_t color)
void olLine(float x1, float y1, float x2, float y2, uint32_t color)
void olDot(float x, float y, int points, uint32_t color)
float olRenderFrame(int max_fps) nogil
void olGetFrameInfo(OLFrameInfo *info)
void olShutdown()
void olSetScissor (float x0, float y0, float x1, float y1)
void olLog(char *fmt, ...)
ctypedef char* const_char_ptr "const char*"
ctypedef void (*LogCallbackFunc)(char *msg)
void olSetLogCallback(LogCallbackFunc f)
LINESTRIP = OL_LINESTRIP
BEZIERSTRIP = OL_BEZIERSTRIP
POINTS = OL_POINTS
RENDER_GRAYSCALE = _RENDER_GRAYSCALE
RENDER_NOREORDER = _RENDER_NOREORDER
RENDER_NOREVERSE = _RENDER_NOREVERSE
C_RED = 0xff0000
C_GREEN = 0x00ff00
C_BLUE = 0x0000ff
C_WHITE = 0xffffff
cpdef uint32_t C_GREY(uint8_t x):
return 0x010101 * x
cdef class RenderParams:
cdef public int rate
cdef public float on_speed
cdef public float off_speed
cdef public int start_wait
cdef public int start_dwell
cdef public int curve_dwell
cdef public int corner_dwell
cdef public int end_dwell
cdef public int end_wait
cdef public float curve_angle
cdef public float flatness
cdef public float snap
cdef public int render_flags
cdef public int min_length
cdef public int max_framelen
def __init__(self):
self.rate = 48000
self.on_speed = 2/100.0
self.off_speed = 1/30.0
self.start_wait = 8
self.start_dwell = 3
self.curve_dwell = 0
self.corner_dwell = 6
self.end_dwell = 3
self.end_wait = 7
self.curve_angle = 0.866
self.flatness = 0.00001
self.snap = 0.00001
self.render_flags = RENDER_GRAYSCALE
self.min_length = 0
self.max_framelen = 0
cpdef setRenderParams(params):
cdef OLRenderParams cparams
cparams.rate = params.rate
cparams.on_speed = params.on_speed
cparams.off_speed = params.off_speed
cparams.start_wait = params.start_wait
cparams.start_dwell = params.start_dwell
cparams.curve_dwell = params.curve_dwell
cparams.corner_dwell = params.corner_dwell
cparams.end_dwell = params.end_dwell
cparams.end_wait = params.end_wait
cparams.curve_angle = params.curve_angle
cparams.flatness = params.flatness
cparams.snap = params.snap
cparams.render_flags = params.render_flags
cparams.min_length = params.min_length
cparams.max_framelen = params.max_framelen
olSetRenderParams(&cparams)
cpdef getRenderParams():
cdef OLRenderParams params
olGetRenderParams(&params)
pyparams = RenderParams()
pyparams.rate = params.rate
pyparams.on_speed = params.on_speed
pyparams.off_speed = params.off_speed
pyparams.start_wait = params.start_wait
pyparams.start_dwell = params.start_dwell
pyparams.curve_dwell = params.curve_dwell
pyparams.corner_dwell = params.corner_dwell
pyparams.end_dwell = params.end_dwell
pyparams.end_wait = params.end_wait
pyparams.curve_angle = params.curve_angle
pyparams.flatness = params.flatness
pyparams.snap = params.snap
pyparams.render_flags = params.render_flags
pyparams.min_length = params.min_length
pyparams.max_framelen = params.max_framelen
return pyparams
cpdef int init(int buffer_count=4, int max_points=30000):
cdef int ret = olInit(buffer_count, max_points)
if ret < 0:
return ret
setRenderParams(RenderParams())
return ret
cpdef loadIdentity(): olLoadIdentity()
cpdef pushMatrix(): olPushMatrix()
cpdef popMatrix(): olPopMatrix()
cpdef multMatrix(object m):
if len(m) == 3:
m = m[0] + m[1] + m[2]
cdef float cm[9]
for i in range(9):
cm[i] = m[i]
olMultMatrix(cm)
cpdef rotate(float theta): olRotate(theta)
cpdef translate(tuple coord):
x, y = coord
olTranslate(x, y)
cpdef scale(tuple coord):
x, y = coord
olScale(x, y)
_py_audiocb = None
cdef void _audiocb(float *l, float *r, int samples) with gil:
global _py_audiocb
if _py_audiocb is not None:
buf = _py_audiocb(samples)
for i in range(min(len(buf), samples)):
l[i], r[i] = buf[i]
if len(buf) < samples:
for i in range(len(buf), samples):
l[i] = r[i] = 0
cpdef setAudioCallback(object func):
global _py_audiocb
_py_audiocb = func
if func is not None:
olSetAudioCallback(_audiocb)
else:
olSetAudioCallback(NULL)
cpdef loadIdentity3(): olLoadIdentity3()
cpdef pushMatrix3(): olPushMatrix3()
cpdef popMatrix3(): olPopMatrix3()
cpdef multMatrix3(object m):
if len(m) == 4:
m = m[0] + m[1] + m[2] + m[3]
cdef float cm[16]
for i in range(16):
cm[i] = m[i]
olMultMatrix(cm)
cpdef rotate3X(float theta): olRotate3X(theta)
cpdef rotate3Y(float theta): olRotate3Y(theta)
cpdef rotate3Z(float theta): olRotate3Z(theta)
cpdef translate3(tuple coord):
x, y, z = coord
olTranslate3(x, y, z)
cpdef scale3(tuple coord):
x, y, z = coord
olScale3(x, y, z)
cpdef frustum(float left, float right, float bot, float top, float near, float far):
olFrustum(left, right, bot, top, near, far)
cpdef perspective(float fovy, float aspect, float zNear, float zFar):
olPerspective(fovy, aspect, zNear, zFar)
cpdef resetColor(): olResetColor()
cpdef multColor(uint32_t color): olMultColor(color)
cpdef pushColor(): olPushColor()
cpdef popColor(): olPopColor()
cpdef begin(int prim): olBegin(prim)
cpdef vertex(tuple coord, uint32_t color):
x, y = coord
olVertex(x, y, color)
cpdef vertex3(tuple coord, uint32_t color):
x, y, z = coord
olVertex3(x, y, z, color)
cpdef end(): olEnd()
cpdef tuple transformVertex3(float x, float y, float z):
olTransformVertex3(&x, &y, &z)
return x, y, z
_py_vpreshader = None
cdef void _vpreshader(float *x, float *y, uint32_t *color) with gil:
global _py_vpreshader
if _py_vpreshader is not None:
(x[0], y[0]), color[0] = _py_vpreshader((x[0], y[0]), color[0])
_py_vshader = None
cdef void _vshader(float *x, float *y, uint32_t *color) with gil:
global _py_vshader
if _py_vshader is not None:
(x[0], y[0]), color[0] = _py_vshader((x[0], y[0]), color[0])
_py_v3shader = None
cdef void _v3shader(float *x, float *y, float *z, uint32_t *color) with gil:
global _py_v3shader
if _py_v3shader is not None:
(x[0], y[0], z[0]), color[0] = _py_v3shader((x[0], y[0], z[0]), color[0])
_py_pshader = None
cdef void _pshader(float *x, float *y, uint32_t *color) with gil:
global _py_pshader
if _py_pshader is not None:
(x[0], y[0]), color[0] = _py_pshader((x[0], y[0]), color[0])
cpdef setVertexPreShader(object func):
global _py_vpreshader
_py_vpreshader = func
if func is not None:
olSetVertexPreShader(_vpreshader)
else:
olSetVertexPreShader(NULL)
cpdef setVertexShader(object func):
global _py_vshader
_py_vshader = func
if func is not None:
olSetVertexShader(_vshader)
else:
olSetVertexShader(NULL)
cpdef setVertex3Shader(object func):
global _py_v3shader
_py_v3shader = func
if func is not None:
olSetVertex3Shader(_v3shader)
else:
olSetVertex3Shader(NULL)
cpdef setPixelShader(object func):
global _py_pshader
_py_pshader = func
if func is not None:
olSetPixelShader(_pshader)
else:
olSetPixelShader(NULL)
cpdef rect(tuple start, tuple end, uint32_t color):
x1, y1 = start
x2, y2 = end
olRect(x1, y1, x2, y2, color)
cpdef line(tuple start, tuple end, uint32_t color):
x1, y1 = start
x2, y2 = end
olLine(x1, y1, x2, y2, color)
cpdef dot(tuple coord, int points, uint32_t color):
x, y = coord
olDot(x, y, points, color)
cpdef float renderFrame(int max_fps):
cdef float ret
with nogil:
ret = olRenderFrame(max_fps)
return ret
cdef class FrameInfo:
cdef readonly int objects
cdef readonly int points
cdef readonly int resampled_points
cdef readonly int resampled_blocks
cdef readonly int padding_points
cpdef getFrameInfo():
cdef OLFrameInfo info
olGetFrameInfo(&info)
pyinfo = FrameInfo()
pyinfo.objects = info.objects
pyinfo.points = info.points
pyinfo.resampled_points = info.resampled_points
pyinfo.resampled_blocks = info.resampled_blocks
pyinfo.padding_points = info.padding_points
return pyinfo
cpdef shutdown(): olShutdown()
cpdef setScissor(tuple start, tuple end):
x1, y1 = start
x2, y2 = end
olSetScissor(x1, y1, x2, y2)
_py_logcb = None
cdef void _logcb(const_char_ptr msg):
global _py_logcb
cdef bytes msg2 = msg
if _py_logcb is not None:
_py_logcb(msg2)
cpdef setLogCallback(object func):
global _py_logcb
_py_logcb = func
if func is not None:
olSetLogCallback(_logcb)
else:
olSetLogCallback(NULL)
cdef extern from "text.h":
ctypedef struct _Font "Font"
_Font *olGetDefaultFont()
float olGetCharWidth(_Font *fnt, char c)
float olGetStringWidth(_Font *fnt, float height, char *s)
float olGetCharOverlap(_Font *font, float height)
float olDrawChar(_Font *fnt, float x, float y, float height, uint32_t color, char c)
float olDrawString(_Font *fnt, float x, float y, float height, uint32_t color, char *s)
cdef class Font:
cdef _Font *font
cpdef getDefaultFont():
f = Font()
f.font = olGetDefaultFont()
return f
cpdef float getCharWidth(object font, char c):
cdef Font fnt = font
return olGetCharWidth(fnt.font, c)
cpdef float getStringWidth(object font, float height, char *s):
cdef Font fnt = font
return olGetStringWidth(fnt.font, height, s)
cpdef float getCharOverlap(object font, float height):
cdef Font fnt = font
return olGetCharOverlap(fnt.font, height)
cpdef float drawChar(object font, tuple coord, float height, uint32_t color, char c):
cdef Font fnt = font
x, y = coord
return olDrawChar(fnt.font, x, y, height, color, c)
cpdef float drawString(object font, tuple coord, float height, uint32_t color, char *s):
cdef Font fnt = font
x, y = coord
return olDrawString(fnt.font, x, y, height, color, s)
cdef extern from "ilda.h":
ctypedef struct _IldaFile "IldaFile"
_IldaFile *olLoadIlda(char *filename)
void olDrawIlda(_IldaFile *ild)
void olDrawIlda3D(_IldaFile *ild)
void olFreeIlda(_IldaFile *ild)
cdef class IldaFile:
cdef _IldaFile *ilda
def __del__(self):
olFreeIlda(self.ilda)
cpdef loadIlda(char *file):
f = IldaFile()
f.ilda = olLoadIlda(file)
return f
cpdef drawIlda(object ilda):
cdef IldaFile f = ilda
olDrawIlda(f.ilda)
cpdef drawIlda3D(object ilda):
cdef IldaFile f = ilda
olDrawIlda3D(f.ilda)