punyverse/punyverse/_glgeom.pyx
Quantum 355f156295 Initial version.
Signed-off-by: Xiaomao Chen <xiaomao5@live.com>
2013-10-22 20:38:37 -04:00

84 lines
2.7 KiB
Cython

from libc.math cimport sin, cos, sqrt
from libc.stdlib cimport malloc, free
from libc.string cimport memcpy
cimport cython
include "_cyopengl.pxi"
cdef float PI = 3.1415926535897932324626
cdef float TWOPI = PI * 2
cdef extern from "Python.h":
object PyBytes_FromStringAndSize(const char *s, Py_ssize_t len)
const char* PyBytes_AsString(bytes o)
@cython.cdivision(True)
cpdef torus(float major_radius, float minor_radius, int n_major, int n_minor, tuple material, int shininess=125):
'''
Torus function from the OpenGL red book.
'''
glPushAttrib(GL_CURRENT_BIT)
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [material[0], material[1], material[2], material[3]])
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [1, 1, 1, 1])
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess)
assert n_major > 0 and n_minor > 0
assert minor_radius > 0 and major_radius > 0
cdef float major_s, minor_s
major_s = TWOPI / n_major
minor_s = TWOPI / n_minor
cdef float a0, a1, x0, y0, x1, y1, b, c, r, z, m, x, y, z2
cdef int i, j
for i in xrange(n_major):
a0 = i * major_s
a1 = a0 + major_s
x0 = cos(a0)
y0 = sin(a0)
x1 = cos(a1)
y1 = sin(a1)
glBegin(GL_TRIANGLE_STRIP)
for j in xrange(n_minor + 1):
b = j * minor_s
c = cos(b)
r = minor_radius * c + major_radius
z = minor_radius * sin(b)
x = x0 * c
y = y0 * c
z2 = z / minor_radius
m = 1.0 / sqrt(x * x + y * y + z2 * z2)
glNormal3f(x * m, y * z, z2 * m)
glVertex3f(x0 * r, y0 * r, z)
x = x1 * c
y = y1 * c
m = 1.0 / sqrt(x * x + y * y + z2 * z2)
glNormal3f(x * m, y * z, z2 * m)
glVertex3f(x1 * r, y1 * r, z)
glEnd()
glPopAttrib()
cpdef bytes bgr_to_rgb(bytes buffer, int width, int height, bint alpha=0, bint bottom_up=1):
cdef int length = len(buffer)
cdef int depth = length / (width * height)
cdef int depth2 = depth - alpha
cdef char *result = <char*>malloc(length)
cdef const char *source = PyBytes_AsString(buffer)
cdef int x, y, ioffset, ooffset, i, row = width * depth
for y in xrange(height):
for x in xrange(width):
ioffset = y * width * depth + x * depth
ooffset = (height - y - 1 if bottom_up else y) * row + x * depth
for i in xrange(depth2):
result[ooffset+i] = source[ioffset+depth2-i-1]
if alpha:
result[ooffset+depth2] = source[ioffset+depth2]
cdef object final = PyBytes_FromStringAndSize(result, length)
free(result)
return final