Browse Source

first try with render thread

master
Jonas Weinz 5 years ago
parent
commit
1e452ca41e
  1. 42
      field.py
  2. 121
      glField.py
  3. 24
      glMain.py
  4. 9
      rule.py

42
field.py

@ -1,19 +1,33 @@
import numpy as np
import rule
import time
class Field(object):
def __init__(self, shape = (32,32)):
self.resize(shape)
self.a_to_b = True
self.rule = rule.Rule(0)
self.updatedValues = [] # tuple (i,j, newValue)
def setRule(self, rule):
self.rule = rule
def resize(self, shape):
self.shape = shape
self.matrix_a = np.matrix(np.zeros(shape, int))
self.matrix_b = np.matrix(np.zeros(shape, int))
self.matrix_a = []
self.matrix_b = []
for i in range(shape[0]):
row_a = []
row_b = []
for j in range(shape[1]):
row_a.append(0)
row_b.append(0)
self.matrix_a.append(row_a)
self.matrix_b.append(row_b)
def getUpdatedValues(self):
return self.updatedValues
def update(self):
self.a_to_b = False if self.a_to_b else True
@ -24,14 +38,17 @@ class Field(object):
h, w = self.shape
for i in range(h):
for j in range(w):
b[i,j] = self.rule.applyRule(a, i, j)
#b[i,j] = self.rule.applyRule(a, i, j)
b[i][j] = self.rule.applyRule(a, self.shape, i, j)
if a[i][j] != b[i][j]:
self.updatedValues.append((i,j,b[i][j]))
def getField(self):
return self.matrix_b if self.a_to_b else self.matrix_a
def setValue(self, y, x, val):
self.matrix_a[y,x] = val
self.matrix_b[y,x] = val
self.matrix_a[y][x] = val
self.matrix_b[y][x] = val
# some testing
if __name__ == "__main__":
@ -40,6 +57,13 @@ if __name__ == "__main__":
f.setRule(r)
f.setValue(2,2,1)
for i in range(10):
print(f.getField())
f.update()
steps = 10
t_start = time.time()
for i in range(steps):
#print(f.getField())
f.update()
t_end = time.time()
print("average time per update: " + str((t_end - t_start) / steps) )

121
glField.py

@ -0,0 +1,121 @@
import pygame
from OpenGL.GL import *
from pygame.locals import *
import threading
class GLField(threading.Thread):
def __init__(self, w, h, win_w, win_h, fullscreen = False):
super(GLField, self).__init__()
self.input = []
self.changed_values = []
self.inputLock = threading.Lock()
self.queue = []
self.fullscreen = fullscreen
self.w = w
self.h = h
self.win_w = win_w
self.win_h = win_h
self.rect_w = self.win_w / self.w
self.rect_h = self.win_h / self.h
self.colors = []
self.FPS = 30
self.drawBuffer = []
def initFieldColors(self):
for i in range(self.w):
self.colors.append([])
for j in range(self.h):
rgba = [float(j) / float(self.h), float(self.w - j) / float(self.w),
float(i) / float(self.h), 0.15]
self.colors[i].append(rgba)
def resize(self):
glViewport(0,0, self.win_w, self.win_h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0.0, self.w * self.rect_w, self.h * self.rect_h, 0.0, -6.0, 0.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glClearColor(0.0, 0.0, 0.0, 0.0)
def drawQuadInternally(self, pX, pY):
r,g,b,a = self.colors[pY][pX]
glColor4f(a*r, a*g, a*b, 1.0)
y = pY * self.rect_w
x = pX * self.rect_h
glVertex3f(x,y,0.0)
glVertex3f(x + self.rect_w - 1.0, y, 0.0)
glVertex3f(x + self.rect_w - 1.0, y + self.rect_h - 1.0, 0.0)
glVertex3f(x, y + self.rect_h - 1.0, 0.0)
def appendChanges(self, changes):
self.inputLock.acquire()
self.changed_values += changes
self.inputLock.release()
def draw(self):
self.inputLock.acquire()
for c in self.changed_values:
i,j,v = c
self.colors[i][j][3] = v
self.queue.append((i,j))
self.inputLock.release()
glBegin(GL_QUADS)
for i,j in self.queue + self.drawBuffer:
self.drawQuadInternally(j,i)
glEnd()
self.drawBuffer = self.queue
self.queue = []
self.changed_values = []
def run(self):
pygame.init()
video_flags = OPENGL | HWSURFACE | DOUBLEBUF | FULLSCREEN if self.fullscreen else OPENGL | HWSURFACE | DOUBLEBUF
dinfo = pygame.display.Info()
window_w = dinfo.current_w if self.fullscreen else self.win_w
window_h = dinfo.current_h if self.fullscreen else self.win_h
self.win_w = window_w
self.win_h = window_h
self.rect_w = self.win_w / self.w
self.rect_h = self.win_h / self.h
pygame.display.set_mode((self.win_w, self.win_h), video_flags)
self.initFieldColors()
self.resize()
clock = pygame.time.Clock()
counter = 0
while True:
print("render main #" + str(counter))
counter += 1
ticktime = clock.tick(self.FPS)
# print ticktime
event = pygame.event.poll()
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
break
self.draw()
pygame.display.flip()

24
glMain.py

@ -0,0 +1,24 @@
from field import *
from glField import *
def main():
f = Field((160, 90))
r = rule.Rule(2)
f.setRule(r)
f.setValue(2, 2, 1)
screen = GLField(160, 90, 800,600, False)
screen.start()
counter = 0
while screen.is_alive():
f.update()
c = f.getUpdatedValues()
screen.appendChanges(c)
print("master thread #" + str(counter))
counter += 1
if __name__ == '__main__':
main()

9
rule.py

@ -1,4 +1,3 @@
import numpy as np
class Rule(object):
@ -7,7 +6,7 @@ class Rule(object):
self.k = k
self.a = 2 * r + 1
self.a2 = self.a**2
self.rule_table = np.zeros(k**self.a2, int)
self.rule_table = k**self.a2 * [0]
self.setRule(rule_id)
def setRule(self, rule_id):
@ -19,18 +18,18 @@ class Rule(object):
self.rule_id = rule_id
self.generateRuleTable()
def applyRule(self, matrix_field, pos_y, pos_x):
def applyRule(self, matrix_field, shape, pos_y, pos_x):
e = 0
sum = 0
h, w = matrix_field.shape
h, w = shape
for i in range(pos_y - self.r, pos_y + self.r + 1):
for j in range(pos_x - self.r, pos_x + self.r + 1):
y = i if i < h else i - h
x = j if j < w else j - w
sum += matrix_field[y,x] * self.k**e
sum += matrix_field[y][x] * self.k**e
e += 1
return self.rule_table[sum]

Loading…
Cancel
Save