Cellular automata in GLSL+PyQT. Various rulesets can be found by checking out individual commits. http://hut.pm/cellmade_gallery.html
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

150 lines
5.1 KiB

from cellmade.lib.glhelper import *
from cellmade.lib.openstruct import OpenStruct
import random
class Simulation(object):
def __init__(self, ctrl):
self.ctrl = ctrl
self.conf = ctrl.conf
self.textureSize = (self.conf.window.height,
self.conf.window.width)
self.zoomLevel = 1
self.doStep = False
self.doReset = False
self.pause = True
self.flip = False
self.t = 0
self.offsetx = 0
self.offsety = 0
self.zoom = 0
def initializeGraphics(self):
self.pause = self.conf.general.pause
glClearColor(1, 1, 0, 0)
glEnable(GL_DEPTH_TEST)
self.recompileShaders()
self.bufferTexture = createTexture(*self.textureSize)
self.resultTexture = createTexture(*self.textureSize)
self._initializeBufferTexture()
def recompileShaders(self, stepfrag=None, renderfrag=None):
def uniforms(tex, t, texwidth, texheight, hsvactive, b1, b2, diffH,
diffV, p1, p2):
glUniform1i(tex, 0)
glUniform1i(t, self.t)
glUniform1i(texwidth, self.conf.window.width)
glUniform1i(texheight, self.conf.window.height)
glUniform1f(p1, self.ctrl.params.p1)
glUniform1f(p2, self.ctrl.params.p2)
for boolean in 'hsvactive', 'b1', 'b2', 'diffH', 'diffV':
glUniform1i(locals()[boolean], self.ctrl.params[boolean])
stepShader = Shader("step.vert", "step.frag", uniforms,
frag_override=stepfrag)
def uniformsPost(offsetx, offsety, zoom, tex, texwidth, texheight,
hsvshift, hsvactive, b1, b2, diffH, diffV):
glUniform1f(offsetx, self.offsetx)
glUniform1f(offsety, self.offsety)
glUniform1f(zoom, self.zoomLevel)
glUniform1i(tex, 0)
glUniform1i(texwidth, self.conf.window.width)
glUniform1i(texheight, self.conf.window.height)
glUniform1f(hsvshift, self.ctrl.params.hsvshift)
for boolean in 'hsvactive', 'b1', 'b2', 'diffH', 'diffV':
glUniform1i(locals()[boolean], self.ctrl.params[boolean])
renderShader = Shader("render.vert", "render.frag", uniformsPost,
frag_override=renderfrag)
self.shader = stepShader
self.shaderPost = renderShader
def draw(self):
if self.doReset:
self._initializeBufferTexture()
self.flip = False
self.doReset = False
self.t = 0
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslate(0, 0, -2.0)
for i in range(int(self.ctrl.params.frameskip)):
if not self.pause or self.doStep:
self.t += 1
glBindTexture(GL_TEXTURE_2D, 2 if self.flip else 1)
self._generateTexture()
self.flip ^= True
self.doStep = False
glBindTexture(GL_TEXTURE_2D, 2 if self.flip else 1)
self._drawTexture()
def getStatusBarText(self):
return "Simulating Cellular Automaton Stuff"
def simReset(self):
self.doReset = True
def simPause(self):
self.pause ^= True
def simStep(self):
self.doStep = True
def simStepBack(self):
pass
def cameraReset(self):
self.offsetx = 0
self.offsety = 0
self.zoomLevel = 1
def cameraMove(self, x, y):
self.offsetx += x * self.zoomLevel
self.offsety += y * self.zoomLevel
def cameraZoom(self, factor, absolute=False):
self.zoomLevel = min(2**24, max(0.01, self.zoomLevel * factor))
self.ctrl.updateZoomSlider()
def _initializeBufferTexture(self):
Shader.disable()
glBindTexture(GL_TEXTURE_2D, 0)
ystep = 2.0 / self.ctrl.conf.window.height
xstep = 2.0 / self.ctrl.conf.window.width
def putPixel(color, x, y):
draw2DSquare(color, x * xstep, y * ystep, (x+1) * xstep, (y+1) * ystep)
with renderIntoTexture(self.bufferTexture, *self.textureSize):
glClearColor(0.0, 0.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
# rectsize = 5
# rectnum = 30
# for n in range(rectnum):
# dx, dy = random.randint(-200, 200), random.randint(-200, 200)
# for i in range(int(rectsize * (random.random() * 6 + 1))):
# for j in range(rectsize):
# putPixel((1, 1, 1, 1), i+dx, j+dy)
def _drawTexture(self):
self.shaderPost.updateParameters()
drawQuad((1,1,1,1), (-1, -1), (-1, 1), (1, 1), (1, -1))
def _generateTexture(self):
target = self.bufferTexture if self.flip else self.resultTexture
with renderIntoTexture(target, *self.textureSize):
glPushAttrib(GL_VIEWPORT_BIT)
try:
glViewport(0, 0, *self.textureSize)
self.shader.updateParameters()
drawQuad((0,1,1,1), (-1, -1), (-1, 1), (1, 1), (1, -1))
finally:
glPopAttrib()