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.
 
 
 

113 lines
3.6 KiB

import os
import sys
import inspect
from OpenGL.GL import shaders
from OpenGL.GL import *
class Shader(object):
def __init__(self, vertex_shader_path, fragment_shader_path,
uniformFunction, frag_override=None):
self.program = self.compileShader(vertex_shader_path,
fragment_shader_path, frag_override=frag_override)
self.uniformFunction = uniformFunction
def use(self):
glUseProgram(self.program)
def updateParameters(self):
params = list(inspect.signature(self.uniformFunction).parameters)
keywordargs = dict()
self.use()
for param in params:
keywordargs[param] = glGetUniformLocation(self.program, param)
return self.uniformFunction(**keywordargs)
@staticmethod
def disable():
glUseProgram(0)
@staticmethod
def compileShader(vertexShader, fragmentShader, frag_override=None):
def getShader(filename):
fname = os.path.join(os.path.dirname(__file__), "..", "shader", filename)
with open(fname, "r") as f:
content = f.read()
return content
VERTEX_SHADER = shaders.compileShader(
getShader(vertexShader), GL_VERTEX_SHADER)
FRAGMENT_SHADER = shaders.compileShader(
frag_override or getShader(fragmentShader), GL_FRAGMENT_SHADER)
program = glCreateProgram()
glAttachShader(program, VERTEX_SHADER)
glAttachShader(program, FRAGMENT_SHADER)
glLinkProgram(program)
glUseProgram(program)
return program
def createTexture(width, height):
texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture)
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
GL_UNSIGNED_INT, None)
return texture
def drawQuad(color, p1, p2, p3, p4):
glBegin(GL_QUADS)
for x, y in (p1, p2, p3, p4):
#glTexCoord2f((x+1)/2, (y+1)/2)
glVertex3f(x, y, 0)
glEnd()
def draw2DSquare(color, x1, y1, x2, y2):
glColor4f(*color)
glBegin(GL_QUADS)
glVertex2f(x1, y1)
glVertex2f(x1, y2)
glVertex2f(x2, y2)
glVertex2f(x2, y1)
glEnd()
class renderIntoTexture(object):
def __init__(self, target, texwidth, texheight):
self.target = target
self.texwidth = texwidth
self.texheight = texheight
def __enter__(self):
# Bind to a new framebuffer
self.fbo = glGenFramebuffers(1)
glBindFramebuffer(GL_FRAMEBUFFER, self.fbo)
# Assign the given texture as the output of the framebuffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, self.target, 0)
# Save the old viewport
glPushAttrib(GL_VIEWPORT_BIT)
# Configure the viewport
glViewport(0, 0, self.texwidth, self.texheight)
glClearColor(0.0, 0.4, 0.0, 0.0)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
def __exit__(self, type, value, traceback):
glEnable(GL_TEXTURE_2D)
# Restore viewport
glPopAttrib()
# Bind to default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0)
glDeleteFramebuffers(1, [self.fbo])
glEnable(GL_TEXTURE_2D)
glEnable(GL_DEPTH_TEST)