first try with render thread
This commit is contained in:
parent
8382993eaf
commit
1e452ca41e
40
field.py
40
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())
|
||||
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
Normal file
121
glField.py
Normal file
@ -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
Normal file
24
glMain.py
Normal file
@ -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
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…
Reference in New Issue
Block a user