Skip to content

Commit

Permalink
Merge branch 'develop' v2.20
Browse files Browse the repository at this point in the history
  • Loading branch information
paddywwoof committed Jul 27, 2017
2 parents 0ced85e + 4030971 commit 97f460e
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 56 deletions.
5 changes: 5 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Tim Skillman, Patrick Gaunt, Tom Ritchford

Date Amends

v2.20
2017-07-27 Bug fixes: Removed use of numpy functions not yet available
in numpypy (pypy version). Some corrections of Log. Removal
of ctypes.byref() where passing an array (as already a pointer).
Some out of memory checking in Buffer.
v2.19
2017-04-20 Improvements: Multiple Textures can be used for ElevationMap,
Texture flip can do vertical, horizontal or both.
Expand Down
9 changes: 7 additions & 2 deletions pi3d/Buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ctypes, itertools
import numpy as np
import logging

from ctypes import c_float, c_int, c_short

Expand All @@ -12,6 +13,8 @@
from pi3d.util.Loadable import Loadable
from pi3d.util.Ctypes import c_floats, c_shorts

LOGGER = logging.getLogger(__name__)

class Buffer(Loadable):
"""Holds the vertex, normals, incices and tex_coords for each part of
a Shape that needs to be rendered with a different material or texture
Expand Down Expand Up @@ -182,6 +185,8 @@ def _load_opengl(self):
self.element_array_buffer.nbytes,
self.element_array_buffer.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
GL_STATIC_DRAW)
if opengles.glGetError() == GL_OUT_OF_MEMORY:
LOGGER.critical('Out of GPU memory')


def _unload_opengl(self):
Expand Down Expand Up @@ -265,7 +270,7 @@ def draw(self, shape=None, M=None, unif=None, shader=None,
opengles.glUniformMatrix4fv(shader.unif_modelviewmatrix, 3,
ctypes.c_ubyte(0), M.ctypes.data)

opengles.glUniform3fv(shader.unif_unif, 20, ctypes.byref(unif))
opengles.glUniform3fv(shader.unif_unif, 20, unif)
textures = textures or self.textures
if ntl is not None:
self.unib[0] = ntl
Expand Down Expand Up @@ -306,7 +311,7 @@ def draw(self, shape=None, M=None, unif=None, shader=None,

self.disp.last_shader = shader

opengles.glUniform3fv(shader.unif_unib, 4, ctypes.byref(self.unib))
opengles.glUniform3fv(shader.unif_unib, 4, self.unib)

opengles.glEnable(GL_DEPTH_TEST) # TODO find somewhere more efficient to do this

Expand Down
8 changes: 4 additions & 4 deletions pi3d/Shader.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
def _opengl_log(shader, function, caption):
log = c_chars(MAX_LOG_SIZE)
loglen = ctypes.c_int()
function(shader, MAX_LOG_SIZE, ctypes.byref(loglen), ctypes.byref(log))
function(shader, MAX_LOG_SIZE, ctypes.byref(loglen), log)
LOGGER.info('%s: %s', caption, log.value)

class Shader(DefaultInstance):
Expand Down Expand Up @@ -92,7 +92,7 @@ def make_shader(src, suffix, shader_type):
characters = ctypes.c_char_p(src)
shader = opengles.glCreateShader(shader_type)
src_len = ctypes.c_int(len(src))
opengles.glShaderSource(shader, 1, ctypes.byref(characters), ctypes.byref(src_len))
opengles.glShaderSource(shader, 1, characters, ctypes.byref(src_len))
opengles.glCompileShader(shader)
self.showshaderlog(shader, src)
opengles.glAttachShader(self.program, shader)
Expand Down Expand Up @@ -148,7 +148,7 @@ def showshaderlog(self, shader, src):
log = (ctypes.c_char * N)()
loglen = ctypes.c_int()
opengles.glGetShaderInfoLog(
shader, N, ctypes.byref(loglen), ctypes.byref(log))
shader, N, ctypes.byref(loglen), log)
if len(log.value) > 0:
LOGGER.info('shader(%s) %s, %s', shader, self.shfile, log.value)

Expand All @@ -158,7 +158,7 @@ def showprogramlog(self, shader):
log = (ctypes.c_char * N)()
loglen = ctypes.c_int()
opengles.glGetProgramInfoLog(
shader, N, ctypes.byref(loglen), ctypes.byref(log))
shader, N, ctypes.byref(loglen), log)

def _load_shader(self, sfile):
''' takes a file name as string, tries to find it then returns the
Expand Down
40 changes: 20 additions & 20 deletions pi3d/Shape.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import ctypes

from numpy import array, dot, savez, load, zeros
import numpy as np
from math import radians, pi, sin, cos

from pi3d.constants import *
Expand Down Expand Up @@ -96,37 +96,37 @@ def __init_matrices(self):
Shape holds matrices that are updated each time it is moved or rotated
this saves time recalculating them each frame as the Shape is drawn
"""
self.tr1 = array([[1.0, 0.0, 0.0, 0.0],
self.tr1 = np.array([[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[self.unif[0] - self.unif[9], self.unif[1] - self.unif[10], self.unif[2] - self.unif[11], 1.0]])
"""translate to position - offset"""

s, c = sin(radians(self.unif[3])), cos(radians(self.unif[3]))
self.rox = array([[1.0, 0.0, 0.0, 0.0],
self.rox = np.array([[1.0, 0.0, 0.0, 0.0],
[0.0, c, s, 0.0],
[0.0, -s, c, 0.0],
[0.0, 0.0, 0.0, 1.0]])
self.roxflg = True if self.unif[3] != 0.0 else False
"""rotate about x axis"""

s, c = sin(radians(self.unif[4])), cos(radians(self.unif[4]))
self.roy = array([[c, 0.0, -s, 0.0],
self.roy = np.array([[c, 0.0, -s, 0.0],
[0.0, 1.0, 0.0, 0.0],
[s, 0.0, c, 0.0],
[0.0, 0.0, 0.0, 1.0]])
self.royflg = True if self.unif[4] != 0.0 else False
"""rotate about y axis"""

s, c = sin(radians(self.unif[5])), cos(radians(self.unif[5]))
self.roz = array([[c, s, 0.0, 0.0],
self.roz = np.array([[c, s, 0.0, 0.0],
[-s, c, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0]])
self.rozflg = True if self.unif[5] != 0.0 else False
"""rotate about z axis"""

self.scl = array([[self.unif[6], 0.0, 0.0, 0.0],
self.scl = np.array([[self.unif[6], 0.0, 0.0, 0.0],
[0.0, self.unif[7], 0.0, 0.0],
[0.0, 0.0, self.unif[8], 0.0],
[0.0, 0.0, 0.0, 1.0]])
Expand All @@ -136,7 +136,7 @@ def __init_matrices(self):
self.sclflg = False
"""scale"""

self.tr2 = array([[1.0, 0.0, 0.0, 0.0],
self.tr2 = np.array([[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[self.unif[9], self.unif[10], self.unif[11], 1.0]])
Expand All @@ -147,8 +147,8 @@ def __init_matrices(self):
"""translate to offset"""

self.MFlg = True
#self.M = zeros(32, dtype="float32").reshape(2,4,4)
self.M = zeros(48, dtype="float32").reshape(3,4,4) # 3rd matrix added for casting shadows v2.7
#self.M = np.zeros(32, dtype="float32").reshape(2,4,4)
self.M = np.zeros(48, dtype="float32").reshape(3,4,4) # 3rd matrix added for casting shadows v2.7


def draw(self, shader=None, txtrs=None, ntl=None, shny=None, camera=None, mlist=[], light_camera=None):
Expand All @@ -170,15 +170,15 @@ def draw(self, shader=None, txtrs=None, ntl=None, shny=None, camera=None, mlist=
# Calculate rotation and translation matrix for this model using numpy.
self.MRaw = self.tr1
if self.rozflg:
self.MRaw = dot(self.roz, self.MRaw)
self.MRaw = np.dot(self.roz, self.MRaw)
if self.roxflg:
self.MRaw = dot(self.rox, self.MRaw)
self.MRaw = np.dot(self.rox, self.MRaw)
if self.royflg:
self.MRaw = dot(self.roy, self.MRaw)
self.MRaw = np.dot(self.roy, self.MRaw)
if self.sclflg:
self.MRaw = dot(self.scl, self.MRaw)
self.MRaw = np.dot(self.scl, self.MRaw)
if self.tr2flg:
self.MRaw = dot(self.tr2, self.MRaw)
self.MRaw = np.dot(self.tr2, self.MRaw)

# child drawing addition #############
newmlist = [m for m in mlist]
Expand All @@ -187,21 +187,21 @@ def draw(self, shader=None, txtrs=None, ntl=None, shny=None, camera=None, mlist=
for c in self.children:
c.draw(shader, txtrs, ntl, shny, camera, newmlist, light_camera) # TODO issues where child doesn't use same shader
for m in mlist[-1::-1]:
self.MRaw = dot(self.MRaw, m)
self.MRaw = np.dot(self.MRaw, m)
######################################
self.M[0,:,:] = self.MRaw[:,:]
#self.M[0:16] = c_floats(self.MRaw.reshape(-1).tolist()) #pypy version
self.M[1,:,:] = dot(self.MRaw, camera.mtrx)[:,:]
#self.M[16:32] = c_floats(dot(self.MRaw, camera.mtrx).reshape(-1).tolist()) #pypy
self.M[1,:,:] = np.dot(self.MRaw, camera.mtrx)[:,:]
#self.M[16:32] = c_floats(np.dot(self.MRaw, camera.mtrx).reshape(-1).tolist()) #pypy
if light_camera is not None:
self.M[2,:,:] = dot(self.MRaw, light_camera.mtrx)[:,:]
self.M[2,:,:] = np.dot(self.MRaw, light_camera.mtrx)[:,:]
self.MFlg = False

elif camera.was_moved:
# Only do this if it's not done because model moved.
self.M[1,:,:] = dot(self.MRaw, camera.mtrx)[:,:]
self.M[1,:,:] = np.dot(self.MRaw, camera.mtrx)[:,:]
if light_camera is not None:
self.M[2,:,:] = dot(self.MRaw, light_camera.mtrx)[:,:]
self.M[2,:,:] = np.dot(self.MRaw, light_camera.mtrx)[:,:]

if camera.was_moved:
self.unif[18:21] = camera.eye[0:3]
Expand Down
2 changes: 2 additions & 0 deletions pi3d/Texture.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ def update_ndarray(self, new_array=None):
opengles.glTexImage2D(GL_TEXTURE_2D, 0, iformat, self.ix, self.iy, 0, iformat,
GL_UNSIGNED_BYTE,
self.image.ctypes.data_as(ctypes.POINTER(ctypes.c_ubyte)))
if opengles.glGetError() == GL_OUT_OF_MEMORY:
LOGGER.critical('Out of GPU memory')
opengles.glEnable(GL_TEXTURE_2D)
if self.mipmap:
opengles.glGenerateMipmap(GL_TEXTURE_2D)
Expand Down
2 changes: 1 addition & 1 deletion pi3d/constants/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""
import time

__version__ = '2.19'
__version__ = '2.20'
year = time.localtime().tm_year

STARTUP_MESSAGE = """
Expand Down
12 changes: 6 additions & 6 deletions pi3d/util/DisplayOpenGL.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ def create_display(self, x=0, y=0, w=0, h=0, depth=24, samples=4, layer=0, displ
numconfig = c_int()
self.config = ctypes.c_void_p()
r = openegl.eglChooseConfig(self.display,
ctypes.byref(attribute_list),
attribute_list,
ctypes.byref(self.config), 1,
ctypes.byref(numconfig))

context_attribs = c_ints((EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE))
self.context = openegl.eglCreateContext(self.display, self.config,
EGL_NO_CONTEXT, ctypes.byref(context_attribs) )
EGL_NO_CONTEXT, context_attribs)
if self.context != EGL_NO_CONTEXT:
break
assert self.context != EGL_NO_CONTEXT
Expand Down Expand Up @@ -123,10 +123,10 @@ def create_surface(self, x=0, y=0, w=0, h=0, layer=0):
self.dispman_element = bcm.vc_dispmanx_element_add(
self.dispman_update,
self.dispman_display,
layer, ctypes.byref(dst_rect),
0, ctypes.byref(src_rect),
layer, dst_rect,
0, src_rect,
DISPMANX_PROTECTION_NONE,
ctypes.byref(alpha), 0, 0)
alpha, 0, 0)

nativewindow = c_ints((self.dispman_element, w, h + 1))
bcm.vc_dispmanx_update_submit_sync(self.dispman_update)
Expand Down Expand Up @@ -172,7 +172,7 @@ def create_surface(self, x=0, y=0, w=0, h=0, layer=0):
#self.window.set_wm_icon_name('pi3d')
#self.window.set_wm_class('draw', 'XlibExample')

xlib.XSetWMProtocols(self.d, self.window, ctypes.byref(self.WM_DELETE_WINDOW), 1)
xlib.XSetWMProtocols(self.d, self.window, self.WM_DELETE_WINDOW, 1)
#self.window.set_wm_hints(flags = Xutil.StateHint,
# initial_state = Xutil.NormalState)

Expand Down
8 changes: 7 additions & 1 deletion pi3d/util/FixedString.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,13 @@ def __init__(self, font, string, camera=None, color=(255,255,255,255),
self._render_text(lines, justify, margin, imgfont, maxwid, height, shadow, draw)
self.im = self.im.filter(ImageFilter.GaussianBlur(radius=shadow_radius))
if background_color == None:
self.im = Image.fromarray(self._force_color(np.array(self.im), shadow))
im_arr = self._force_color(np.array(self.im), shadow)
try: # numpy not quite working fully in pypy so have to convert tobytes
self.im = Image.fromarray(im_arr)
except:
h, w, c = im_arr.shape
rgb = 'RGB' if c == 3 else 'RGBA'
self.im = Image.frombytes(rgb, (w, h), im_arr.tobytes())

draw = ImageDraw.Draw(self.im)

Expand Down
7 changes: 6 additions & 1 deletion pi3d/util/Font.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,12 @@ def _force_color(self, img, color):
from PIL import ImageColor
color = ImageColor.getrgb(color)
img[:,:,:3] = color[:3]
return Image.fromarray(img)
try: # numpy not quite working fully in pypy so have to convert tobytes
return Image.fromarray(img)
except:
h, w, c = img.shape
rgb = 'RGB' if c == 3 else 'RGBA'
return Image.frombytes(rgb, (w, h), img.tobytes())

def _load_disk(self):
"""
Expand Down
7 changes: 4 additions & 3 deletions pi3d/util/Log.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def __init__(self, name=None, level='WARNING', file=None, format=None):
At the top of the file is typically:
LOGGER = pi3d.Log(__name__, level='INFO')
LOGGER = pi3d.Log(level='INFO', file='error.log')
and then later on you can do things like:
Expand All @@ -28,12 +28,13 @@ def __init__(self, name=None, level='WARNING', file=None, format=None):
message if it isn't going to be displayed.)
***N.B. if name is not passed as an argument then this will set the root
logger properties (and all the pi3d module logging will also be logged.)***
logger properties (and all the pi3d module logging will also be logged,
which is what you usually want.)***
The level, file, format arguments are passed on to set_logs() see below.
'''
self.logger = logging.getLogger(name) # NB overriding default None will stop module logging!

self.logger = logging.getLogger(name)
self.debug = self.logger.debug # to reference methods to those of the logger instance
self.info = self.logger.info
self.warning = self.logger.warning
Expand Down
Loading

0 comments on commit 97f460e

Please sign in to comment.