Fix various bugs for 64-bit and Linux.

This commit is contained in:
Quantum 2018-08-22 16:22:08 -04:00
parent b4dce48fa7
commit ff78a2d8a7
5 changed files with 52 additions and 109 deletions

View file

@ -66,96 +66,31 @@ cpdef torus(float major_radius, float minor_radius, int n_major, int n_minor, tu
glPopAttrib() glPopAttrib()
@cython.cdivision(True) cpdef bytes bgr_to_rgb(bytes buffer, int width, int height, bint alpha=0):
cpdef normal_sphere(double r, int divide, GLuint tex, normal, bint lighting=True):
from texture import pil_load
print 'Loading normal map: %s...' % normal,
normal_map = pil_load(normal)
normal = normal_map.load()
print 'Loaded'
cdef int width, height
width, height = normal_map.size
cdef bint gray_scale = len(normal[0, 0]) == 1
glEnable(GL_TEXTURE_2D)
if lighting:
glDisable(GL_BLEND)
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [1, 1, 1, 0])
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [1, 1, 1, 0])
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 125)
else:
glDisable(GL_LIGHTING)
glBindTexture(GL_TEXTURE_2D, tex)
cdef double twopi_divide, pi_divide
cdef int i, j
cdef double phi1, phi2
cdef double theta, s, t
cdef int u, v
cdef double x, y, z
cdef double dx, dy, xz
cdef double nx, ny, nz
twopi_divide = TWOPI / divide
pi_divide = PI / divide
glBegin(GL_TRIANGLE_STRIP)
for j in xrange(divide + 1):
phi1 = j * twopi_divide
phi2 = (j + 1) * twopi_divide
for i in xrange(divide + 1):
theta = i * pi_divide
s = phi2 / TWOPI
u = min(<int>(s * width), width - 1)
t = theta / PI
v = min(<int>(t * height), height - 1)
if gray_scale:
x = y = z = normal[u, v]
else:
x, y, z = normal[u, v]
dx, dy, dz = sin(theta) * cos(phi2), sin(theta) * sin(phi2), cos(theta)
nx, ny, nz = x / 127.5 - 1, y / 127.5 - 1, z / 127.5 - 1 # Make into [-1, 1]
nx, nz = cos(theta) * nx + sin(theta) * nz, -sin(theta) * nx + cos(theta) * nz
nx, ny = cos(phi2) * nx - sin(phi2) * ny, sin(phi2) * nx + cos(phi2) * ny
glNormal3f(nx, ny, nz)
glTexCoord2f(s, 1 - t) # GL is bottom up
glVertex3f(r * dx, r * dy, r * dz)
s = phi1 / TWOPI # x
u = min(<int>(s * width), width - 1)
if gray_scale:
x = y = z = normal[u, v]
else:
x, y, z = normal[u, v]
dx, dy = sin(theta) * cos(phi1), sin(theta) * sin(phi1)
nx, ny, nz = x / 127.5 - 1, y / 127.5 - 1, z / 127.5 - 1
nx, nz = cos(theta) * nx + sin(theta) * nz, -sin(theta) * nx + cos(theta) * nz
nx, ny = cos(phi1) * nx - sin(phi1) * ny, sin(phi1) * nx + cos(phi1) * ny
glNormal3f(nx, ny, nz)
glTexCoord2f(s, 1 - t)
glVertex3f(r * dx, r * dy, r * dz)
glEnd()
glDisable(GL_TEXTURE_2D)
glEnable(GL_LIGHTING)
glEnable(GL_BLEND)
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 length = len(buffer)
cdef int depth = length / (width * height) cdef int depth = length / (width * height)
cdef int depth2 = depth - alpha cdef int depth2 = depth - alpha
cdef object final = PyBytes_FromStringAndSize(NULL, length) cdef object final = PyBytes_FromStringAndSize(NULL, length)
cdef char *result = PyBytes_AsString(final) cdef char *result = PyBytes_AsString(final)
cdef const char *source = PyBytes_AsString(buffer) cdef const char *source = PyBytes_AsString(buffer)
cdef int x, y, ioffset, ooffset, i, row = width * depth cdef int x, y, offset, i, row = width * depth
for y in xrange(height): for y in xrange(height):
for x in xrange(width): for x in xrange(width):
ioffset = y * width * depth + x * depth offset = y * row + x * depth
ooffset = (height - y - 1 if bottom_up else y) * row + x * depth
for i in xrange(depth2): for i in xrange(depth2):
result[ooffset+i] = source[ioffset+depth2-i-1] result[offset+i] = source[offset+depth2-i-1]
if alpha: if alpha:
result[ooffset+depth2] = source[ioffset+depth2] result[offset+depth2] = source[offset+depth2]
return final
cpdef bytes flip_vertical(bytes buffer, int width, int height):
cdef int length = len(buffer)
cdef object final = PyBytes_FromStringAndSize(NULL, length)
cdef char *result = PyBytes_AsString(final)
cdef const char *source = PyBytes_AsString(buffer)
cdef int y1, y2, row = length / height
for y1 in xrange(height):
y2 = height - y1 - 1
memcpy(result + y1 * row, source + y2 * row, row)
return final return final

View file

@ -1,6 +1,6 @@
# Blender v2.68 (sub 0) OBJ File: '' # Blender v2.68 (sub 0) OBJ File: ''
# www.blender.org # www.blender.org
mtllib HST.mtl mtllib hst.mtl
v 0.325496 -2.594603 -0.788680 v 0.325496 -2.594603 -0.788680
v 0.472583 -2.594603 -0.710061 v 0.472583 -2.594603 -0.710061
v 0.601506 -2.594603 -0.604257 v 0.601506 -2.594603 -0.604257

View file

@ -144,10 +144,7 @@ def flare(rinner, router, res, prob, tex):
last_y = y last_y = y
def sphere(r, lats, longs, tex, lighting=True, fv4=GLfloat * 4, inside=False): def sphere(r, lats, longs, tex, lighting=True, inside=False, fv4=GLfloat * 4):
"""
Sphere function from the OpenGL red book.
"""
with glRestore(GL_ENABLE_BIT | GL_TEXTURE_BIT): with glRestore(GL_ENABLE_BIT | GL_TEXTURE_BIT):
sphere = gluNewQuadric() sphere = gluNewQuadric()
gluQuadricDrawStyle(sphere, GLU_FILL) gluQuadricDrawStyle(sphere, GLU_FILL)
@ -192,19 +189,19 @@ def colourball(r, lats, longs, colour, fv4=GLfloat * 4):
gluDeleteQuadric(sphere) gluDeleteQuadric(sphere)
def normal_sphere(r, divide, tex, normal, lighting=True, fv4=GLfloat * 4): def normal_sphere(r, divide, tex, normal, lighting=True, inside=False, fv4=GLfloat * 4):
if (not have_extension('GL_ARB_multitexture') or not if (not have_extension('GL_ARB_multitexture') or not
have_extension('GL_ARB_texture_env_combine') or not have_extension('GL_ARB_texture_env_combine') or not
have_extension('GL_EXT_texture_env_dot3')): have_extension('GL_EXT_texture_env_dot3')):
print('No hardware normal mapping support. No bumping for you.') print('No hardware normal mapping support. No bumping for you.')
return sphere(r, divide, divide, tex, lighting) return sphere(r, divide, divide, tex, lighting, inside)
from texture import load_texture from .texture import load_texture
normal = load_texture(normal) normal = load_texture(normal)
with glRestore(GL_ENABLE_BIT | GL_TEXTURE_BIT): with glRestore(GL_ENABLE_BIT | GL_TEXTURE_BIT):
glEnable(GL_CULL_FACE) glEnable(GL_CULL_FACE)
glCullFace(GL_BACK) glCullFace(GL_FRONT if inside else GL_BACK)
glActiveTextureARB(GL_TEXTURE0_ARB) glActiveTextureARB(GL_TEXTURE0_ARB)
glBindTexture(GL_TEXTURE_2D, normal) glBindTexture(GL_TEXTURE_2D, normal)

View file

@ -2,7 +2,7 @@ from __future__ import print_function
from pyglet import image from pyglet import image
from pyglet.gl import * from pyglet.gl import *
from ctypes import c_int, byref, c_ulong from ctypes import c_int, byref, c_uint
import os.path import os.path
import struct import struct
import itertools import itertools
@ -12,7 +12,7 @@ import six
from six.moves import zip from six.moves import zip
try: try:
from punyverse._glgeom import bgr_to_rgb from punyverse._glgeom import bgr_to_rgb, flip_vertical
except ImportError: except ImportError:
import warnings import warnings
warnings.warn('Compile _glgeom.c, or double the start up time.') warnings.warn('Compile _glgeom.c, or double the start up time.')
@ -27,7 +27,7 @@ except ImportError:
from six.moves import range from six.moves import range
def bgr_to_rgb(source, width, height, alpha=False, bottom_up=True): def bgr_to_rgb(source, width, height, alpha=False):
length = len(source) length = len(source)
depth = length // (width * height) depth = length // (width * height)
depth2 = depth - alpha depth2 = depth - alpha
@ -35,13 +35,21 @@ except ImportError:
row = width * depth row = width * depth
for y in range(height): for y in range(height):
for x in range(width): for x in range(width):
ioffset = y * width * depth + x * depth offset = y * row + x * depth
ooffset = (height - y - 1 if bottom_up else y) * row + x * depth
for i in range(depth2): for i in range(depth2):
result[ooffset+i] = source[ioffset+depth2-i-1] result[offset+i] = source[offset+depth2-i-1]
if alpha: if alpha:
result[ooffset+depth2] = source[ioffset+depth2] result[offset+depth2] = source[offset+depth2]
return str(result) return six.binary_type(result)
def flip_vertical(source, width, height):
length = len(source)
row = length // height
result = bytearray(length)
for y1 in range(height):
y2 = height - y1 - 1
result[y1*row:y1*row+row] = source[y2*row:y2*row+row]
return six.binary_type(result)
else: else:
magick = False magick = False
@ -67,7 +75,7 @@ def init():
if badcard: if badcard:
import warnings import warnings
warnings.warn('Please update your graphics drivers if possible') warnings.warn('Please update your graphics drivers if possible')
# Currently, BGRA images are flipped.
#bgra = gl_info.have_extension('GL_EXT_bgra') #bgra = gl_info.have_extension('GL_EXT_bgra')
if power_of_two is None: if power_of_two is None:
@ -196,7 +204,7 @@ def load_image(file, path):
texture = raw.data texture = raw.data
else: else:
texture = raw.get_data('RGBA', width * 4) texture = raw.get_data('RGBA', width * 4)
return path, width, height, len(raw.format), mode, texture return path, width, height, len(raw.format), mode, flip_vertical(texture, width, height)
def load_texture(file): def load_texture(file):
@ -211,7 +219,7 @@ def load_texture(file):
path, width, height, depth, mode, texture = load_image(file, path) path, width, height, depth, mode, texture = load_image(file, path)
buffer = c_ulong() buffer = c_uint()
glGenTextures(1, byref(buffer)) glGenTextures(1, byref(buffer))
id = buffer.value id = buffer.value
@ -232,7 +240,7 @@ def load_texture(file):
def pil_load(file): def pil_load(file):
import Image from PIL import Image
return Image.open(os.path.join(os.path.dirname(__file__), 'assets', 'textures', file)) return Image.open(os.path.join(os.path.dirname(__file__), 'assets', 'textures', file))
@ -248,7 +256,7 @@ def load_clouds(file):
path, width, height, depth, mode, texture = load_image(file, path) path, width, height, depth, mode, texture = load_image(file, path)
buffer = c_ulong() buffer = c_uint()
glGenTextures(1, byref(buffer)) glGenTextures(1, byref(buffer))
id = buffer.value id = buffer.value

View file

@ -16,12 +16,15 @@ except ImportError:
sys.exit(1) sys.exit(1)
cythonize = lambda x: x cythonize = lambda x: x
if has_pyx: if has_pyx:
pyx_path = lambda x: x pyx_path = lambda x: x
else: else:
pyx_path = lambda x: x.replace('.pyx', '.c') pyx_path = lambda x: x.replace('.pyx', '.c')
if os.name == 'nt':
gl_libs = ['opengl32']
else:
gl_libs = ['GL']
with open(os.path.join(os.path.dirname(__file__), 'README.md')) as f: with open(os.path.join(os.path.dirname(__file__), 'README.md')) as f:
long_description = f.read() long_description = f.read()
@ -46,8 +49,8 @@ setup(
], ],
}, },
ext_modules=cythonize([ ext_modules=cythonize([
Extension('punyverse._glgeom', sources=[pyx_path('punyverse/_glgeom.pyx')], libraries=['opengl32']), Extension('punyverse._glgeom', sources=[pyx_path('punyverse/_glgeom.pyx')], libraries=gl_libs),
Extension('punyverse._model', sources=[pyx_path('punyverse/_model.pyx')], libraries=['opengl32']), Extension('punyverse._model', sources=[pyx_path('punyverse/_model.pyx')], libraries=gl_libs),
]), ]),
entry_points={ entry_points={