def __init__(self, width, height, scale=2): """ width, height: size of the window in pixels. scale: the size of the texture is (width//scale) x (height//scale). """ pyglet.window.Window.__init__(self, width, height, caption='GrayScott Simulation', visible=False, vsync=False) self.reaction_shader = Shader('./glsl/default.vert', './glsl/reaction.frag') self.render_shader = Shader('./glsl/default.vert', './glsl/render.frag') self.pattern = DEFAULT_PATTERN self.palette = DEFAULT_PALETTE self.tex_width = width // scale self.tex_height = height // scale self.uv_texture = create_uv_texture(width//scale, height//scale) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(self.uv_texture.target, self.uv_texture.id) # use an invisible buffer to do the computation. with FrameBuffer() as self.fbo: self.fbo.attach_texture(self.uv_texture) # why do we need this? the reason is in the 'on_mouse_drag' function. self.mouse_down = False # put all patterns in a list for iterating over them. self._species = list(SPECIES.keys()) # set the uniforms and attributes in the two shaders. self.init_reaction_shader() self.init_render_shader()
def __init__(self, use_lut=False, lighted=False, gridsize=(0.0,0.0,0.0), elevation=0.0): self._lighted = lighted self._gridsize = gridsize self._gridwidth = (1.0,1.0,1.0) self._elevation = elevation interpolation = read_shader('bicubic.txt') light = read_shader('phong.txt') lut = read_shader('lut.txt') vertex = read_shader('vertex_bicubic.txt') fragment = read_shader('fragment_bicubic.txt') lut_code = light_code = grid_code = height_code = '' if use_lut: lut_code = 'color = texture1D_lut(lut, color.a);' if lighted: light_code = read_shader('light_bicubic.txt') if self._gridsize[0] or self._gridsize[1] or self._gridsize[2]: grid_code = read_shader('grid.txt') if self._elevation: height_code = read_shader('height_bicubic.txt') fragment = fragment % (lut_code,grid_code,light_code) vertex = vertex % (height_code) Shader.__init__(self, vert = [interpolation] + [vertex], frag = [interpolation] + [light] + [lut] + [fragment]) self.kernel = build_kernel()
def getShader( frag, seed ): with open ("shaders/basicvert.glsl", "r") as vertfile: vert = vertfile.read() with open ("shaders/noise.glsl", "r") as noisefile: noise = noisefile.read() with open ("shaders/utils.glsl", "r") as utilsfile: utils = utilsfile.read() with open ("shaders/header.glsl", "r") as headerfile: header = headerfile.read() fullfrag = header + noise + utils + frag with open( "Output/" + str( seed ) + "/" + str( seed ) + ".glsl", "w") as text_file: text_file.write( frag ) with open( "Output/" + str( seed ) + "/" + str( seed ) + "full.glsl", "w") as text_file: text_file.write( fullfrag ) shader = Shader( vert, fullfrag ) shader.bind() shader.uniformf( "iResolution", x, y ) return shader
class W(pyglet.window.Window): def __init__(self, sprite): super(W, self).__init__() self.mouse = [0,0] self.sprite = sprite self.shader = Shader(open('pass.vert').read(), open('RGB2Lab.glsl').read()) def on_draw(self): x, y = self.mouse # glEnable(GL_LINE_SMOOTH) # glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) # glMatrixMode(GL_PROJECTION) # glLoadIdentity() # glOrtho(-1., 1., 1., -1., 0., 1.) # glMatrixMode(GL_MODELVIEW) # glLoadIdentity() self.shader.bind() self.sprite.draw() #self.shader.uniformf('C', *self.C) self.shader.unbind() def on_mouse_motion(self, x, y, dx, dy): self.mouse = [x, y] def on_mouse_press(self, x, y, buttons, modifiers): # capture window contents to buffer buf = pyglet.image.get_buffer_manager().get_color_buffer() image = pyglet_to_pil(buf) image.show()
def loadShader(self): self.gridShader = None with open("shaders/heightGrid.vs") as vsf: with open("shaders/heightGrid.fs") as fsf: self.gridShader = Shader(vs=vsf.read(), fs=fsf.read()) with open("shaders/water.vs") as vsf: with open("shaders/water.fs") as fsf: self.waterShader = Shader(vs=vsf.read(), fs=fsf.read())
class FloorSpots: def __init__(self, floor_color, background_color, y=0): self._floor_color = floor_color self._y = y self._display_list_id = None self._shader = Shader( radius = FLOOR_SPOT_RADIUS * 2 * FLOOR_GRID_SIZE * 1.5, background_color = background_color) def render(self, center_x, center_z, camera_x, camera_z): self._draw_floor_spots( center_x, center_z) self._shader.render( x=-camera_x, y=0, z=-camera_z) def _draw_floor_spots(self, center_x, center_z): cell_size = FLOOR_SPOT_RADIUS * 2 quantified_center_x = int(center_x / cell_size / 2) * cell_size * 2 quantified_center_z = int(center_z / cell_size) * cell_size for nx in range(FLOOR_GRID_SIZE): x = quantified_center_x + (nx - float(FLOOR_GRID_SIZE)/2 + 0.5) * cell_size if nx % 2 == 0: offset_z = 0 else: offset_z = FLOOR_SPOT_RADIUS for nz in range(FLOOR_GRID_SIZE): z = offset_z + quantified_center_z + (nz - float(FLOOR_GRID_SIZE)/2 + 0.5) * cell_size self._draw_floor_spot(x=x, z=z) def _draw_floor_spot(self, x, z, y=0): if self._display_list_id is None: self._create_floor_spot_display_list() glPushMatrix() glTranslatef(x, y, z) glCallList(self._display_list_id) glPopMatrix() def _create_floor_spot_display_list(self, resolution=15): color_r, color_g, color_b, color_a = self._floor_color angle_increment = (float) (2 * math.pi / resolution); self._display_list_id = glGenLists(1) glNewList(self._display_list_id, GL_COMPILE) glBegin(GL_TRIANGLE_FAN) glColor4f(*self._floor_color) glVertex3f(0, 0, 0) glColor4f(color_r, color_g, color_b, 0) for i in range(resolution): angle1 = angle_increment * i angle2 = angle_increment * (i+1) glVertex3f(math.cos(angle1) * FLOOR_SPOT_RADIUS, 0, math.sin(angle1) * FLOOR_SPOT_RADIUS) glVertex3f(math.cos(angle2) * FLOOR_SPOT_RADIUS, 0, math.sin(angle2) * FLOOR_SPOT_RADIUS) glEnd() glEndList()
def draw(self): model = Matrix.identity() # translate model[3,0] = self.pos.x + (self.dir == -1 and 1.0 or 0.0) model[3,1] = self.pos.y model[0,0] = self.dir Shader.upload_model(model) self.texture.texture_bind() self.vbo.draw()
class uiShaderGroup(uiGroup): def __init__(self, order, window, vertex_shader, fragment_shader, **kwargs): super(uiShaderGroup, self).__init__(order, window, **kwargs) self.shader = Shader(vertex_shader, fragment_shader) def set_state(self): self.shader.bind() #self.shader.uniform_matrixf('projection', camera.matrix * m) def unset_state(self): self.shader.unbind()
def __init__(self, floor_color, background_color, y=0): self._floor_color = floor_color self._y = y self._display_list_id = None self._shader = Shader( radius = FLOOR_SPOT_RADIUS * 2 * FLOOR_GRID_SIZE * 1.5, background_color = background_color)
def __init__(self): super(JuliaWindow, self).__init__(caption = 'julia', width = 512, height = 512) self.C = (-0.70176, -0.3842) shader_path = 'julia' self.shader = Shader(''.join(open('%s.v.glsl' % shader_path)), ''.join(open('%s.f.glsl' % shader_path)))
def bind(self, texture, lut=None): ''' Bind the program, i.e. use it. ''' Shader.bind(self) if lut is not None: gl.glActiveTexture(gl.GL_TEXTURE1) gl.glBindTexture(lut.target, lut.id) self.uniformi('lut', 1) gl.glEnable(texture.target) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(texture.target, texture.id) self.uniformi('texture', 0) self.uniformf('elevation', self._elevation) self.uniformf('pixel', 1.0/texture.width, 1.0/texture.height) self.uniformf('gridsize', *self._gridsize) self.uniformf('gridwidth', *self._gridwidth) self.uniformi('lighted', self._lighted)
class FloorGrid: def __init__(self, num_cells, size, floor_color, background_color, y=0): self._num_cells = num_cells self._size = size self._floor_color = floor_color self._y = y self._cell_size = float(self._size) / self._num_cells self._hypotenuse = math.sqrt(self._cell_size * self._cell_size * 2) self._shader = Shader( radius = math.sqrt(self._size * self._size * 2), background_color = background_color) def render(self, center_x, center_z, camera_x, camera_z): self._draw_grid(center_x, center_z) self._shader.render(-camera_x, 0, -camera_z) def _draw_grid(self, center_x, center_z): z1 = - self._size/2 z2 = + self._size/2 x1 = - self._size/2 x2 = + self._size/2 glColor4f(*self._floor_color) glLineWidth(1.4) quantified_center_x = int(center_x / self._hypotenuse) * self._hypotenuse quantified_center_z = int(center_z / self._hypotenuse) * self._hypotenuse glPushMatrix() glTranslatef(quantified_center_x, 0, quantified_center_z) glRotatef(45, 0, 1, 0) for n in range(self._num_cells): glBegin(GL_LINES) x = x1 + float(n) * self._cell_size glVertex3f(x, self._y, z1) glVertex3f(x, self._y, z2) glEnd() for n in range(self._num_cells): glBegin(GL_LINES) z = z1 + float(n) * self._cell_size glVertex3f(x1, self._y, z) glVertex3f(x2, self._y, z) glEnd() glPopMatrix()
def __init__(self, num_cells, size, floor_color, background_color, y=0): self._num_cells = num_cells self._size = size self._floor_color = floor_color self._y = y self._cell_size = float(self._size) / self._num_cells self._hypotenuse = math.sqrt(self._cell_size * self._cell_size * 2) self._shader = Shader( radius = math.sqrt(self._size * self._size * 2), background_color = background_color)
def __init__(self): # Setup the GLSL program with open('molgl.vert','r') as f: vert = f.readlines() with open('molgl.frag','r') as f: frag = f.readlines() self.shader = Shader(vert=vert, frag=frag) # Some parameters glEnable(GL_DEPTH_TEST) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
def __init__(self, width, height, pattern, scale=2): ''' width, height: size of the window in pixels. scale: the size of the texture is (width//scale) x (height//scale). pattern: a name in dict 'species'. ''' pyglet.window.Window.__init__(self, width, height, caption='GrayScott Simulation', visible=False, vsync=False) # we will need two shaders, one for computing the reaction and diffusion, # and one for coloring the uv_texture. self.reaction_shader = Shader.from_files('default.vert', 'reaction.frag') self.render_shader = Shader.from_files('default.vert', 'render.frag') self.pattern = pattern self.palette = GrayScott.palette_default self.tex_width = width // scale self.tex_height = height // scale self.uv_texture = create_uv_texture(width // scale, height // scale) # the texture is bind to unit '0'. gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(self.uv_texture.target, self.uv_texture.id) # set the uniforms and attributes in the two shaders. self.init_reaction_shader() self.init_render_shader() # we need a framebuffer to do the offscreen rendering. # once we finished computing the reaction-diffusion step with the reaction_shader, # we render the result to this 'invisible' buffer since we do not want to show it. # the final image is further colored and will be rendered to the window. with FrameBuffer() as self.fbo: self.fbo.attach_texture(self.uv_texture) # why do we need this? # the reason is in the 'on_mouse_drag' function. self.mouse_down = False
class JuliaWindow(pyglet.window.Window): def __init__(self): super(JuliaWindow, self).__init__(caption = 'julia', width = 512, height = 512) self.C = (-0.70176, -0.3842) shader_path = 'julia' self.shader = Shader(''.join(open('%s.v.glsl' % shader_path)), ''.join(open('%s.f.glsl' % shader_path))) def on_mouse_motion(self, x, y, dx, dy): self.C = (6. * ((float(x) / window.width) - .5), 6 * ((float(y) / window.height) - .5)) def on_draw(self): glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(-1., 1., 1., -1., 0., 1.) glMatrixMode(GL_MODELVIEW) glLoadIdentity() self.shader.bind() self.shader.uniformf('C', *self.C) glBegin(GL_QUADS) glVertex2i(-1, -1) glTexCoord2i(-2, -2) glVertex2f(1, -1) glTexCoord2i(2, -2) glVertex2i(1, 1) glTexCoord2i(2, 2) glVertex2i(-1, 1) glTexCoord2i(-2, 2) glEnd() self.shader.unbind()
def __init__(self): # Create the shader. self.shader = Shader(vertex_shader, fragment_shader) # Set the texture unit. self.shader.bind() self.shader.uniformi('tex0', 0) self.shader.unbind() # Create a quad geometry to fit the whole window that will be the target of our drawing. self.batch = pyglet.graphics.Batch() self.batch.add(4, GL_QUADS, None, ('v2i', (0,0, 1,0, 1,1, 0,1)), ('t2f', (0,0, 1,0, 1,1, 0,1)))
def __init__(self, num_cells, size, floor_color, background_color, board_color1, board_color2, y=0): self._num_cells = num_cells self._size = size self._board_color1 = board_color1 self._board_color2 = board_color2 self._y = y self._cell_size = float(self._size) / self._num_cells self._hypotenuse = math.sqrt(self._cell_size * self._cell_size * 2) self._shader = Shader( radius = math.sqrt(self._size * self._size * 2) * 0.55, background_color = background_color) self._grid_display_list_id = None
def draw_gl_points(points,size=20,color=(1.,0.5,0.5,.5)): global simple_pt_shader # we cache the shader because we only create it the first time we call this fn. if not simple_pt_shader: # we just draw single points, a VBO is much slower than this. But this is a little bit hacked. #someday we should replace all legacy fn with vbo's and shaders... # shader defines VERT_SHADER = """ #version 120 varying vec4 f_color; void main () { gl_Position = gl_ModelViewProjectionMatrix*vec4(gl_Vertex.xy,1.,1.); gl_PointSize = gl_Vertex.z; //this needs to be used on some hardware we cheat and use the z coord f_color = gl_Color; } """ FRAG_SHADER = """ #version 120 varying vec4 f_color; void main() { float dist = distance(gl_PointCoord, vec2(0.5, 0.5)); gl_FragColor = mix(f_color, vec4(f_color.rgb,0.0), smoothstep(0.35, 0.5, dist)); } """ #shader link and compile simple_pt_shader = Shader(VERT_SHADER,FRAG_SHADER) simple_pt_shader.bind() glColor4f(*color) glBegin(GL_POINTS) for pt in points: glVertex3f(pt[0],pt[1],size) glEnd() simple_pt_shader.unbind()
def load_shader(name, attributes = (), **defaults): vert = open('./shaders/%s.vert' % name, 'rb').read() frag = open('./shaders/%s.frag' % name, 'rb').read() shader = Shader([vert], [frag]) shader.initialize() for (index, name) in attributes: glBindAttribLocationARB(shader.handle, index, name) shader.link() shader.bind() for k, v in defaults.iteritems(): try: v = tuple(v) except TypeError: v = (v,) if isinstance(v[0], float): func = shader.uniformf elif isinstance(v[0], int): func = shader.uniformi func(k, *v) shader.unbind() return shader
def __init__(self, **kwargs): config = pyglet.gl.Config(sample_buffers=1, samples=4) pyglet.window.Window.__init__(self, width=1000, height=700, resizable=True, config=self.config, **kwargs) self.fps = pyglet.clock.ClockDisplay() self.shader = Shader(vertex_shader, fragment_shader) self.center = np.array([0.0,0.0]) self.show_fps = False self.screen_size = np.array([self.width, self.height]) self.view_size = np.array([3.0, 2.0]) self.col_scale = 4000.0 self.draw()
def __init__(self, camera, window): super(Render, self).__init__() self.scene_batch = pyglet.graphics.Batch() self.static_batch = pyglet.graphics.Batch() self.camera = camera self.window = window # scaling factors self.scale = vec2(window.width / 1360., window.height / 765.) self.players = {} #for rendering self.fbo = FBO(window.width, window.height) self.lighting = Shader('lighting') self.lighting.set('mvp', Matrix.orthographic( 0., window.width, 0., window.height, 0, 1)) self.lighting.set('lightPos', vector((-20., 20, 10))) self.screen = TexQuad( 0, 0, window.width, window.height, self.fbo.textures[0].tex_coords)
def draw_gl_checkerboards(points,size=60,color=(1.,0.5,0.5,.5), grid=[7.0,7.0]): global simple_checkerboard_shader # we cache the shader because we only create it the first time we call this fn. if not simple_checkerboard_shader: grid = np.array(grid) # step = size/grid # in this example the step would be 10 # we just draw single points, a VBO is much slower than this. But this is a little bit hacked. #someday we should replace all legacy fn with vbo's and shaders... # shader defines VERT_SHADER = """ #version 120 varying vec4 f_color; void main () { gl_Position = gl_ModelViewProjectionMatrix*vec4(gl_Vertex.xy,1.,1.); gl_PointSize = gl_Vertex.z; //this needs to be used on some hardware we cheat and use the z coord f_color = gl_Color; } """ FRAG_SHADER = """ #version 120 varying vec4 f_color; uniform vec2 grid; void main() { // get the lowest integer value for the grid float total = floor(gl_PointCoord.x*grid.x) + floor(gl_PointCoord.y*grid.y); // make the checkerboard by alternating colors bool isEven = mod(total,2.0)==0.0; vec4 col1 = vec4(0.0,0.0,0.0,1.0); vec4 col2 = vec4(1.0,1.0,1.0,1.0); gl_FragColor = (isEven)? col1:col2; } """ #shader link and compile simple_checkerboard_shader = Shader(VERT_SHADER,FRAG_SHADER) simple_checkerboard_shader.bind() simple_checkerboard_shader.uniformf('grid', *grid) glColor4f(*color) glBegin(GL_POINTS) for pt in points: glVertex3f(pt[0],pt[1],size) glEnd() simple_checkerboard_shader.unbind()
def __init__(self): self.objects = [] self.camera = None self.playback = Parameter(default=self.PAUSED, enum=[('Play',self.PLAYING),('Pause',self.PAUSED)]) #self.playback = self.PLAYING self.fps = 24.0 self.time = 0 # in seconds? self.frame = Parameter(default=1, vmin=0, vmax=100, title='Frame', update=self.update_time) self.sframe = Parameter(default=1, vmin=0, vmax=100, title='Start Frame') self.eframe = Parameter(default=100, vmin=0, vmax=100, title='End Frame') self.ui3d_shader = Shader(self.vertex_shader) self.ui3d_batch = pyglet.graphics.Batch() self.grid = Grid(10, 10, self.ui3d_batch ) self.axes = Axes(0.5, self.ui3d_batch ) self.bbmin = None self.bbmax = None
def __init__(self, filename, scale): super(Model, self).__init__() p_data = parsedae.parse_dae(filename, scale) verts, norms, facedata, jd, js, skn, anm, fsc = p_data self.maxtime = max(anm[0][0]) _anim = AnimatedModel(*p_data) self.anim = AnimationUpdater(anm, _anim) self.meshes = [] self.batch = pyglet.graphics.Batch() for faces in facedata: color = faces[0] facearr = [(vert, faces[2][i]) for i, vert in enumerate(faces[1])] self.meshes.append(Mesh(verts, facearr, norms, color, skn)) self.tarr = [[None for j in range(len(facedata[i][1])*3)] for i in range(len(facedata))] self.add(self.batch) self.quats, self.vecs = _anim.get_bindpose() self.shader = Shader('skinning') self.shader.set('quats', self.quats) self.shader.set('vecs', self.vecs) self.shader.set('scale', fsc)
def __init__(self, shader_path): self.w = 512 self.h = 512 # Scaling values self.x = -5.4 self.y = -5.4 self.z = 0.0 self.zoom = 0.02 self.octives = 9 self.freq = 0.73 self.windowSize = (float(self.w), float(self.h)) super(ShaderWindow, self).__init__(caption = 'Shader', width=self.w, height=self.h) self.shader = Shader( ' '.join(open('%s.v.glsl' % shader_path)), ' '.join(open('%s.f.glsl' % shader_path)) ) self.p = [] permutation = self.getPermutation() for i in range(512): self.p.append(permutation[i % len(permutation)])
def __init__(self): self.feather = 0.4 self.shader = Shader([''' #version 120 attribute vec2 width; varying vec4 color; varying vec2 offset; void main() { // transform the vertex position vec2 dir = gl_Normal.xy * width.xy; offset = dir; gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex + vec4(offset, 0.0, 0.0); color = gl_Color; } '''], [''' #version 120 varying vec4 color; varying vec2 offset; uniform float feather; uniform float width; void main() { vec4 newColor = color; //if (length(offset) >= width * 0.9) { // newColor = vec4(1.0, 0.0, 0.0, 1.0); //} float alpha = 1.0 - smoothstep(-width * feather, width * feather, length(offset) - width); newColor = vec4(color.r * alpha, color.g * alpha, color.b * alpha, alpha); gl_FragColor = newColor; } '''])
def loadShader(self): self.gridShader = None with open("shaders/cube.vs") as vsf: with open("shaders/cube.fs") as fsf: self.cubeShader = Shader(vs=vsf.read(), fs=fsf.read())
def __init__(self, width, height): """---------Create Camera--------""" camera = Camera() self.camera = camera """-------Create Matricies-------""" model = glm.mat4() view = camera.getViewMatrix() projection = glm.perspective(glm.radians(45.0), width/height, 0.1, 100.0) """--------------Compile Shaders--------------""" shader = Shader(fullpath("shaderPC.vs"), fullpath("shaderPC.fs")) shader.use() shader.setMatrix("view", view) shader.setMatrix("projection", projection) shader.setMatrix("model", model) # for drawing position and color - data self.shaderPC = shader shader = Shader(fullpath("shaderPT.vs"), fullpath("shaderPT.fs")) shader.use() shader.setMatrix("view", view) shader.setMatrix("projection", projection) shader.setMatrix("model", model) # for drawing position and texture - data self.shaderPT = shader shader = Shader(fullpath("shaderPCT.vs"), fullpath("shaderPCT.fs")) shader.use() shader.setMatrix("view", view) shader.setMatrix("projection", projection) shader.setMatrix("model", model) # for drawing position, color and texture - data self.shaderPCT = shader shader = Shader(fullpath("GUIshader.vs"), fullpath("GUIshader.fs")) # for drawing GUI elements self.GUIshader = shader
class GrayScott(pyglet.window.Window): """ ---------------------------------------------------------- | This simulation uses mouse and keyboard to control the | | patterns and colors. At any time you may click or drag | | your mouse to draw on the screen. | | | | Keyboard control: | | 1. press 'space' to clear the window to blank. | | 2. press 'p' to change to a random palette. | | 3. press 's' to change to another species. | | 4. press 'Ctrl + s' to save current config. | | 5. press 'Ctrl + o' to load a config from the file. | | 6. press 'Enter' to take screenshots. | | 7. press 'Ctrl + v' to start saving the animation to | | the video and press 'Ctrl + v' again to stop. | | 8. press 'Esc' to exit. | ---------------------------------------------------------- """ def __init__(self, width, height, scale=1.5, conf=1, mask=None, flip=False, video=False, sample_rate=None, frame_rate=None): """ INPUTS: - `width`, `height`: size of the window in pixels. - `scale`: level of scaling of the texture. - `conf`: line number of the config in the file (`config.txt`). - `mask`: a user-specified image that is used to control the growth of the pattern. - `flip`: flip the white/black pixels in the mask image, only meaningful is there is a mask image. - `video`: whether the video is turned on or off. - `sample_rate`: sample a frame from the animation every these frames. - `frame_rate`: number of frames per second to render to the video. """ pyglet.window.Window.__init__(self, width, height, caption='GrayScott Simulation', resizable=True, visible=False, vsync=False) # use two shaders, one for doing the computations and one for rendering to the screen. self.reaction_shader = Shader(['./glsl/reaction.vert'], ['./glsl/reaction.frag']) self.render_shader = Shader(['./glsl/render.vert'], ['./glsl/render.frag']) self.tex_width, self.tex_height = int(width / scale), int(height / scale) try: self.species, self.palette = self.load_config(conf) print('> Current species: ' + self.species + '\n') except: conf = 'unstable: #00000000 #00FF0033 #FFFF0035 #FF000066 #FFFFFF99' self.species, self.palette = parse(conf) print('> Failed to load the config, using the default one.\n') self.species_list = list(all_species.keys()) # create the uv_texture uv_grid = np.zeros((self.tex_height, self.tex_width, 4), dtype=np.float32) uv_grid[:, :, 0] = 1.0 rand_rows = np.random.choice(range(self.tex_height), 5) rand_cols = np.random.choice(range(self.tex_width), 5) uv_grid[rand_rows, rand_cols, 1] = 1.0 self.uv_texture = create_texture_from_ndarray(uv_grid) # create the mask_texture mask_grid = np.ones_like(uv_grid) if mask is not None: img = Image.open(mask).convert('L').resize( (self.tex_width, self.tex_height)) img = (np.asarray(img) / 255.0).astype(np.float32) if flip: img = 1.0 - img mask_grid[:, :, 0] = img[::-1] self.mask_texture = create_texture_from_ndarray(mask_grid) # bind the two textures gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(self.uv_texture.target, self.uv_texture.id) gl.glActiveTexture(gl.GL_TEXTURE1) gl.glBindTexture(self.mask_texture.target, self.mask_texture.id) # use an invisible buffer to do the computations. with FrameBuffer() as self.fbo: self.fbo.attach_texture(self.uv_texture) # we need this because the program samples the position of the mouse in discrete times. self.mouse_down = False # initialize the two shaders with self.reaction_shader: self.reaction_shader.vertex_attrib('position', [-1, -1, 1, -1, -1, 1, 1, 1]) self.reaction_shader.vertex_attrib('texcoord', [0, 0, 1, 0, 0, 1, 1, 1]) self.reaction_shader.uniformi('uv_texture', 0) self.reaction_shader.uniformi('mask_texture', 1) self.reaction_shader.uniformf('u_resolution', self.tex_width, self.tex_height) self.reaction_shader.uniformf('u_mouse', -1, -1) self.reaction_shader.uniformf('params', *all_species[self.species]) with self.render_shader: self.render_shader.vertex_attrib('position', [-1, -1, 1, -1, -1, 1, 1, 1]) self.render_shader.vertex_attrib('texcoord', [0, 0, 1, 0, 0, 1, 1, 1]) self.render_shader.uniformi('uv_texture', 0) self.render_shader.uniformfv('palette', 5, self.palette) self.video_on = video self.buffer = pyglet.image.get_buffer_manager().get_color_buffer() self.sample_rate = sample_rate self.frame_rate = frame_rate self.frame_count = 0 if video: self.ffmpeg_pipe = self.create_new_pipe() self.start_time = time.time() def on_draw(self): gl.glClearColor(0.0, 0.0, 0.0, 0.0) self.clear() if time.time() - self.start_time > 0.1: gl.glViewport(0, 0, self.tex_width, self.tex_height) with self.fbo: with self.reaction_shader: gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) gl.glViewport(0, 0, self.width, self.height) with self.render_shader: gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) if self.video_on and (self.frame_count % self.sample_rate == 0): self.write_video_frame() self.frame_count += 1 def on_key_press(self, symbol, modifiers): if symbol == key.ENTER: self.save_screenshot() if symbol == key.ESCAPE: pyglet.app.exit() if symbol == key.SPACE: self.clear_blank_window() if symbol == key.P: self.use_random_palette() if symbol == key.S and not modifiers: self.use_next_species() if symbol == key.S and (modifiers & key.LCTRL): self.save_config() if symbol == key.O and (modifiers & key.LCTRL): self.require_config_input() if symbol == key.V and (modifiers & key.LCTRL): self.switch_video() def update_species(self, species): self.species = species with self.reaction_shader: self.reaction_shader.uniformf('params', *all_species[species]) def update_palette(self, palette): self.palette = palette with self.render_shader: self.render_shader.uniformfv('palette', 5, palette) def update_mouse(self, x, y): with self.fbo: with self.reaction_shader: self.reaction_shader.uniformf('u_mouse', x, y) def save_screenshot(self): self.buffer.save( '-'.join(['screenshot', timestamp(), self.species]) + '.png') def save_config(self): with open('config.txt', 'a+') as f: f.write(self.species + ': ' + ' '.join(rgb_to_htmlcolors(self.palette)) + '\n') print('> Config saved.\n') def load_config(self, k): with open('config.txt', 'r') as f: for i, line in enumerate(f.readlines()): if k == i: return parse(line) print('> Config does not exist.\n') def require_config_input(self): try: k = int( input('> Enter the line number in the config file: ').strip()) except ValueError: print('> Invalid input.\n') return try: species, palette = self.load_config(k) self.update_species(species) self.update_palette(palette) print('> Config loaded. Current species: ' + self.species) except: return def write_video_frame(self): data = self.buffer.get_image_data().get_data('RGBA', -4 * self.width) self.ffmpeg_pipe.write(data) def on_mouse_press(self, x, y, button, modifiers): self.mouse_down = True self.update_mouse(x / self.width, y / self.height) def on_mouse_release(self, x, y, button, modifiers): self.mouse_down = False self.update_mouse(-1, -1) def on_mouse_drag(self, x, y, dx, dy, button, modifiers): if self.mouse_down: self.update_mouse(x / self.width, y / self.height) def clear_blank_window(self): self.update_mouse(-10, -10) def use_random_palette(self): new_palette = [0.0] * 3 + [np.random.random() for _ in range(17)] self.update_palette(new_palette) def use_next_species(self): index = self.species_list.index(self.species) new_species = self.species_list[(index + 1) % len(self.species_list)] self.update_species(new_species) print('> Current species: ' + self.species + '\n') def switch_video(self): self.video_on = not self.video_on if self.video_on: self.ffmpeg_pipe = self.create_new_pipe() print('> Writing to video...\n') else: self.ffmpeg_pipe.close() print('> The video is closed.\n') def create_new_pipe(self): ffmpeg = subprocess.Popen( (FFMPEG_EXE, '-threads', '0', '-loglevel', 'panic', '-r', '%d' % self.frame_rate, '-f', 'rawvideo', '-pix_fmt', 'rgba', '-s', '%dx%d' % (self.width, self.height), '-i', '-', '-c:v', 'libx264', '-crf', '20', '-y', self.species + timestamp() + '.mp4'), stdin=subprocess.PIPE) return ffmpeg.stdin def run(self, fps=None): self.set_visible(True) if fps is None: pyglet.clock.schedule(lambda dt: None) else: pyglet.clock.schedule_interval(lambda dt: None, 1.0 / fps) pyglet.app.run()
class Scene(object): PAUSED = 0 PLAYING = 1 vertex_shader = ''' uniform mat4 modelview; uniform mat4 projection; void main() { gl_FrontColor = gl_Color; vec4 modelSpacePos = modelview * gl_Vertex; gl_Position = projection * modelSpacePos; } ''' def __init__(self): self.objects = [] self.camera = None self.playback = Parameter(default=self.PAUSED, enum=[('Play',self.PLAYING),('Pause',self.PAUSED)]) #self.playback = self.PLAYING self.fps = 24.0 self.time = 0 # in seconds? self.frame = Parameter(default=1, vmin=0, vmax=100, title='Frame', update=self.update_time) self.sframe = Parameter(default=1, vmin=0, vmax=100, title='Start Frame') self.eframe = Parameter(default=100, vmin=0, vmax=100, title='End Frame') self.ui3d_shader = Shader(self.vertex_shader) self.ui3d_batch = pyglet.graphics.Batch() self.grid = Grid(10, 10, self.ui3d_batch ) self.axes = Axes(0.5, self.ui3d_batch ) self.bbmin = None self.bbmax = None def calculate_bounds(self): self.bbmin = None self.bbmax = None for ob in self.objects: if hasattr(ob, "bbmin") and hasattr(ob, "bbmax"): if self.bbmin is None and self.bbmax is None: self.bbmin = ob.bbmin self.bbmax = ob.bbmax else: self.bbmin.x = min(ob.bbmin.x, self.bbmin.x) self.bbmin.y = min(ob.bbmin.y, self.bbmin.y) self.bbmin.z = min(ob.bbmin.z, self.bbmin.z) self.bbmax.x = max(ob.bbmax.x, self.bbmax.x) self.bbmax.y = max(ob.bbmax.y, self.bbmax.y) self.bbmax.z = max(ob.bbmax.z, self.bbmax.z) self.grid.delete() del self.grid diam = self.bbmax - self.bbmin center = self.bbmin + diam*0.5 self.grid = Grid(10, 10, self.ui3d_batch, center=center[:]) def on_key_press(self, symbol, modifiers): if symbol == pyglet.window.key.H: self.calculate_bounds() self.camera.focus(self) if symbol == pyglet.window.key.RIGHT: self.frame.value += 1 if symbol == pyglet.window.key.LEFT: self.frame.value -= 1 def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): if not (modifiers & pyglet.window.key.MOD_ALT or \ modifiers & pyglet.window.key.MOD_CTRL or \ modifiers & pyglet.window.key.MOD_SHIFT or \ keys[pyglet.window.key.SPACE]): if buttons & mouse.MIDDLE: self.frame.value += dx*0.05 return pyglet.event.EVENT_HANDLED def on_draw(self): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # 3D Geometry for ob in self.objects: ob.draw(time=self.time, camera=self.camera) # 3D UI elements glEnable(GL_LINE_SMOOTH) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); self.ui3d_shader.bind() self.ui3d_shader.uniform_matrixf('modelview', self.camera.matrixinv) self.ui3d_shader.uniform_matrixf('projection', self.camera.persp_matrix) self.ui3d_batch.draw() self.ui3d_shader.unbind() glDisable(GL_LINE_SMOOTH) def update_time(self): for ob in self.objects: ob.update(self.time, self.frame.value) def update(self, dt): if self.playback.value == self.PLAYING: #self.time += dt # loop playback #frame = self.time * self.fps frame = self.frame.value + 1 if frame > self.eframe.value: frame = self.sframe.value self.frame.value = frame self.update_time()
class Mobius(pyglet.window.Window): """ Keyboard control: 1. Press 1 to toggle on/off applying the transformation. 2. Press 2 to toggle on/off applying the hyperbolic scaling. 3. Press 3 to toggle on/off applying the elliptic rotation. 4. Press Ctrl + v to toggle on/off saving the video. 5. Press Enter to save screenshot. """ def __init__( self, width, height, scene, video, sample_rate, video_rate, antialiasing ): pyglet.window.Window.__init__( self, width, height, caption="Mobius transformation in hyperbolic 3-space", resizable=True, visible=False, vsync=False, ) self._start_time = time.clock() self.shader = Shader(["./glsl/mobius.vert"], ["./glsl/mobius.frag"]) self.apply, self.elliptic, self.hyperbolic = [ int(x) for x in bin(scene)[2:].zfill(3) ] self.video_on = video self.buffer = pyglet.image.get_buffer_manager().get_color_buffer() self.sample_rate = sample_rate self.video_rate = video_rate self.frame_count = 0 if self.video_on: self.ffmpeg_pipe = self.create_new_pipe() with self.shader: self.shader.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shader.uniformf("iResolution", width, height, 0.0) self.shader.uniformf("iTime", 0.0) self.shader.uniformi("iApply", self.apply) self.shader.uniformi("iElliptic", self.elliptic) self.shader.uniformi("iHyperbolic", self.hyperbolic) self.shader.uniformf("iMobius.A", -1, 0.0) self.shader.uniformf("iMobius.B", 1, 0.0) self.shader.uniformf("iMobius.C", -1, 0.0) self.shader.uniformf("iMobius.D", -1, 0.0) self.shader.uniformi("AA", antialiasing) def on_draw(self): gl.glClearColor(0, 0, 0, 0) self.clear() gl.glViewport(0, 0, self.width, self.height) with self.shader: self.shader.uniformf("iTime", time.clock() - self._start_time) gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) if self.video_on and (self.frame_count % self.sample_rate == 0): self.write_video_frame() self.frame_count += 1 def on_key_press(self, symbol, modifiers): if symbol == key._1: self.apply = not self.apply with self.shader: self.shader.uniformi("iApply", self.apply) if symbol == key._2: self.hyperbolic = not self.hyperbolic with self.shader: self.shader.uniformi("iHyperbolic", self.hyperbolic) if symbol == key._3: self.elliptic = not self.elliptic with self.shader: self.shader.uniformi("iElliptic", self.elliptic) if symbol == key.V and (modifiers & key.LCTRL): self.switch_video() if symbol == key.ENTER: self.save_screenshot() if symbol == key.ESCAPE: pyglet.app.exit() def scene_info(self): parabolic = not (self.elliptic or self.hyperbolic) loxodromic = self.elliptic and self.hyperbolic info = "" if parabolic: if self.apply: info += "parabolic-translation-horosphere" else: info += "parabolic-translation-horoplane" elif loxodromic: if self.apply: info += "loxodromic-Dupin-cyclide" else: info += "loxodromic-cone" elif self.elliptic: if self.apply: info += "elliptic-roatation-Dupin-cyclide" else: info += "elliptic-rotation-cone" else: if self.apply: info += "hyperbolic-scaling-Dupin-cyclide" else: info += "hyperbolic-scaling-cone" return info def save_screenshot(self): self.buffer.save(self.scene_info() + ".png") def switch_video(self): self.video_on = not self.video_on if self.video_on: self.ffmpeg_pipe = self.create_new_pipe() print("> Writing to video...\n") else: self.ffmpeg_pipe.close() print("> The video is closed.\n") def write_video_frame(self): data = self.buffer.get_image_data().get_data("RGBA", -4 * self.width) self.ffmpeg_pipe.write(data) def create_new_pipe(self): ffmpeg = subprocess.Popen( ( FFMPEG_EXE, "-threads", "0", "-loglevel", "panic", "-r", "%d" % self.video_rate, "-f", "rawvideo", "-pix_fmt", "rgba", "-s", "%dx%d" % (self.width, self.height), "-i", "-", "-c:v", "libx264", "-crf", "20", "-y", self.scene_info() + ".mp4", ), stdin=subprocess.PIPE, ) return ffmpeg.stdin def run(self, fps=None): self.set_visible(True) if fps is None: pyglet.clock.schedule(lambda dt: None) else: pyglet.clock.schedule_interval(lambda dt: None, 1.0 / fps) pyglet.app.run()
class Engine: def __init__(self, width, height): # pygame Stuff pygame.init() self.window = Window(width, height) self.screen = pygame.display.set_mode(self.window.screen_size, pygame.DOUBLEBUF | pygame.OPENGL) # Engine Stuff self._tps_target = None self._tps = 0 self._spt_target = 0 self._fps_target = None self._fps = 0 self._spf_target = 0 self._start_time = -1 self._running = False self._event_handlers = {} self.game_objects = [] # Render Stuff self.background = Color(0.15, a=1.) self.shader = Shader('vert.glsl', 'frag.glsl') # Event Stuff self._keys = {} self._buttons = {} self._mouse_pos = Vector([0, 0]) self._mouse_pos_prev = Vector([0, 0]) self._scroll_dir = Vector([0, 0]) self._scroll_dir_prev = Vector([0, 0]) GL.glEnable(GL.GL_DEPTH_TEST) GL.glEnable(GL.GL_CULL_FACE) GL.glEnable(GL.GL_BLEND) GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA) # Engine Stuff @property def tps(self): return self._tps @tps.setter def tps(self, tps): self._tps_target = tps self._spt_target = 0 if tps is None or tps < 1 else int(1e9 / tps) @property def fps(self): return self._fps @fps.setter def fps(self, fps): self._fps_target = fps self._spf_target = 0 if fps is None or fps < 1 else int(1e9 / fps) @property def start_time(self): return self._start_time @property def time(self): if self._start_time < 0: return 0 return time.perf_counter_ns() - self._start_time @property def running(self): return self._running def start(self): try: self._init() self._start_time = time.perf_counter_ns() self._running = True tick_count, frame_count = 0, 0 last_tick = self.time last_frame = self.time last_sec = self.time while self._running: self._events() t = self.time dt = t - last_tick if dt >= self._spt_target: tick_count += 1 last_tick = t t, dt = t / 1e9, dt / 1e9 for game_object in self.game_objects: game_object.update(t, dt) t = self.time dt = t - last_frame if dt >= self._spf_target: frame_count += 1 last_frame = t self._render(t / 1e9, dt / 1e9) t = self.time dt = t - last_sec if dt >= 1e9: last_sec = t self._tps, self._fps = tick_count, frame_count tick_count, frame_count = 0, 0 except Exception: # print(e) raise finally: self._shutdown() def stop(self): self._running = False def _render(self, t, dt): GL.glClearColor(*self.background) GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT) # if self.debug: # GL.glPolygonMode( # GL.GL_FRONT_AND_BACK, # GL.GL_LINE # ) # self.lights.generateShadows(self.models.draw) # Reset Viewpoint GL.glViewport(0, 0, *self.window.screen_size) GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) self.shader.use() self.shader.set_floatm('projection', self.window.projection.data) self.shader.set_floatm('view', self.window.view.data) # self.shader.setVec3f("viewPos", self.window.position) # self.lights.bind(self.shader) for game_object in self.game_objects: game_object.render(self.shader, t, dt) GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT) # self.lights.unbind() # deltaTimeText = str(self.deltaTime / 1000) # self.font.draw(deltaTimeText, 5, 40) # for i in range(len(self.drawTextOnScreenMethods)): # self.drawTextOnScreenMethods[i](self.font) pygame.display.flip() def _init(self): for handler in self._init_handlers: handler() def _events(self): for e in self._get_events(): if e.type == QUIT: self.stop() if e.type == VIDEO_RESIZE: self.screen = pygame.display.set_mode((e.w, e.h), self._flags) for e_type in (None, e.type): if e_type in self._event_handlers.keys(): for handler in self._event_handlers[e_type]: handler(e) def _update(self, t, dt): for handler in self._update_handlers: handler(t, dt) def _render(self, t, dt): for handler in self._render_handlers: handler(t, dt) pygame.display.flip() def _shutdown(self): for handler in self._shutdown_handlers: handler() pygame.quit() def on_init(self, func): self._init_handlers.add(func) return func # Event Stuff def on_event(self, func=None, *, event=None): def decorator(func): try: self._event_handlers[event].add(func) except KeyError: self._event_handlers[event] = set() self._event_handlers[event].add(func) return func return decorator if func is None else decorator(func) def on_update(self, func): self._update_handlers.add(func) return func def on_render(self, func): self._render_handlers.add(func) return func def on_shutdown(self, func): self._shutdown_handlers.add(func) return func @property def mouse_pos(self): return self._mouse_pos.copy() @property def scroll_dir(self): return self._scroll_dir.copy() def key_down(self, key): return key in self._keys.keys() def button_down(self, button): return button in self._buttons.keys() def _get_events(self): events = [] now = time.perf_counter_ns() for e in pygame.event.get(): if e.type == pygame.KEYDOWN: k = e.key if k not in self._keys: self._keys[k] = _KeyData(now, e.mod, e.unicode, e.scancode) elif e.type == pygame.KEYUP: k = e.key try: self._keys[k].up = True except KeyError: pass elif e.type == pygame.MOUSEBUTTONDOWN: b = e.button if b not in self._buttons: self._buttons[b] = _ButtonData(now, e.pos) elif e.type == pygame.MOUSEBUTTONUP: b = e.button try: self._buttons[b].up = True except KeyError: pass elif e.type == pygame.MOUSEMOTION: self._mouse_pos = Vector(e.pos) else: events.append( _Event(pygame.event.event_name(e.type), now, **e.__dict__)) for k, d in self._keys.copy().items(): if d.down: events.append(_Event(KEY_DOWN, now, key=k, mod=d.mod)) self._keys[k].down = False else: events.append(_Event(KEY_HOLD, now, key=k, mod=d.mod)) if d.up: if now - d.time < 1e9 / 5: events.append(_Event(KEY_PRESSED, now, key=k, mod=d.mod)) events.append(_Event(KEY_UP, now, key=k, mod=d.mod)) del self._keys[k] for b, d in self._buttons.copy().items(): if self._mouse_pos != self._mouse_pos_prev: events.append( _Event(MOUSE_DRAGGED, now, button=b, pos=self._mouse_pos, rel=self._mouse_pos - self._mouse_pos_prev)) if d.down: events.append( _Event(MOUSE_BUTTON_DOWN, now, button=b, pos=Vector(d.pos))) self._buttons[b].down = False else: events.append( _Event(MOUSE_BUTTON_HOLD, now, button=b, pos=Vector(d.pos))) if d.up: if now - d.time < 1e9 / 5: events.append( _Event(MOUSE_BUTTON_PRESSED, now, button=b, pos=Vector(d.pos))) events.append( _Event(MOUSE_BUTTON_UP, now, button=b, pos=Vector(d.pos))) del self._buttons[b] if self._mouse_pos != self._mouse_pos_prev: events.append( _Event(MOUSE_MOTION, now, pos=self._mouse_pos, rel=self._mouse_pos - self._mouse_pos_prev)) self._mouse_pos_prev = self._mouse_pos.copy() if self._scroll_dir != self._scroll_dir_prev: events.append( _Event(MOUSE_SCROLL, now, pos=self._scroll_dir, rel=self._scroll_dir - self._scroll_dir_prev)) self._scroll_dir_prev = self._scroll_dir.copy() return events
def __init__(self, t): Shader.__init__(self, t) self.fragCoord = GlslVariable(g.vec2, piping=IN) self.zoom = Uniform(float) self.zoom_pos = Uniform(g.vec2)
# the error will say that pygame.init() width = 1200 height = 600 pygame.display.set_mode((width, height), flags=DOUBLEBUF | OPENGL) # OpenGL initialization: glViewport(0, 0, width, height) glEnable(GL_DEPTH_TEST) glClearColor(1.0, 1.0, 1.0, 1.0) glEnable(GL_LINE_SMOOTH) glLineWidth(4) glPointSize(8) # create the shader program to run on the gpu: shader = Shader("shader.vs", "shader.fs") shader.use() # set the uniform color to black (the corresponding shader must be in use): shader.setVector("outlineColor", 0.0, 0.0, 0.0) camera = Camera() view = camera.getViewMatrix() shader.setMatrix("view", view) projection = glm.perspective(glm.radians(45.0), width / height, 0.1, 100.0) shader.setMatrix("projection", projection) # initialize the last_frame_time: last_frame_time = time.time()
def __init__(self, width, height, aa=1, video_rate=16, sample_rate=4): """ :param width and height: size of the window in pixels. :param aa: antialiasing level, a higher value will give better result but also slow down the animation. (aa=2 is recommended) """ pyglet.window.Window.__init__( self, width, height, caption="Wythoff Explorer", resizable=True, visible=False, vsync=False, ) self.video_rate = video_rate self.video_on = False self.sample_rate = sample_rate self._start_time = time.clock() self._frame_count = 0 # count number of frames rendered so far self._speed = 4 # control speed of the animation self.aa = aa # shader A draws the UI self.shaderA = Shader( ["./glsl/wythoff.vert"], ["./glsl/common.frag", "./glsl/BufferA.frag"] ) # shadwr B draws the polyhedra self.shaderB = Shader( ["./glsl/wythoff.vert"], ["./glsl/common.frag", "./glsl/BufferB.frag"] ) # shader C puts them together self.shaderC = Shader( ["./glsl/wythoff.vert"], ["./glsl/common.frag", "./glsl/main.frag"] ) self.font_texture = create_image_texture(FONT_TEXTURE) self.iChannel0 = pyglet.image.Texture.create_for_size( gl.GL_TEXTURE_2D, width, height, gl.GL_RGBA32F_ARB ) self.iChannel1 = pyglet.image.Texture.create_for_size( gl.GL_TEXTURE_2D, width, height, gl.GL_RGBA32F_ARB ) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(self.iChannel0.target, self.iChannel0.id) gl.glActiveTexture(gl.GL_TEXTURE1) gl.glBindTexture(self.iChannel1.target, self.iChannel1.id) gl.glActiveTexture(gl.GL_TEXTURE2) gl.glBindTexture(gl.GL_TEXTURE_2D, self.font_texture) # frame buffer A renders the UI to texture iChannel0 with FrameBuffer() as self.bufferA: self.bufferA.attach_texture(self.iChannel0) # frame buffer B render the polyhedra to texture iChannel1 with FrameBuffer() as self.bufferB: self.bufferB.attach_texture(self.iChannel1) # initialize the shaders with self.shaderA: self.shaderA.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shaderA.uniformf("iResolution", width, height, 0.0) self.shaderA.uniformf("iTime", 0.0) self.shaderA.uniformf("iMouse", 0.0, 0.0, 0.0, 0.0) self.shaderA.uniformi("iChannel0", 0) self.shaderA.uniformi("iFrame", 0) with self.shaderB: self.shaderB.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shaderB.uniformf("iResolution", width, height, 0.0) self.shaderB.uniformf("iTime", 0.0) self.shaderB.uniformf("iMouse", 0.0, 0.0, 0.0, 0.0) self.shaderB.uniformi("iChannel0", 0) self.shaderB.uniformi("AA", self.aa) with self.shaderC: self.shaderC.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shaderC.uniformf("iResolution", width, height, 0.0) self.shaderC.uniformf("iTime", 0.0) self.shaderC.uniformf("iMouse", 0.0, 0.0, 0.0, 0.0) self.shaderC.uniformi("iChannel0", 0) self.shaderC.uniformi("iChannel1", 1) self.shaderC.uniformi("iTexture", 2)
def on_reshape( width, height ): gl.glViewport( 0, 0, width, height ) gl.glMatrixMode( gl.GL_PROJECTION ) gl.glLoadIdentity( ) gl.glOrtho( 0, width, 0, height, -1, 1 ) gl.glMatrixMode( gl.GL_MODELVIEW ) gl.glLoadIdentity( ) def on_keyboard( key, x, y ): if key == '\033': sys.exit( ) if key == ' ': fbo.save(on_display, "gl-polygon.png") if __name__ == '__main__': import sys glut.glutInit( sys.argv ) glut.glutInitDisplayMode( glut.GLUT_DOUBLE | glut.GLUT_RGB | glut.GLUT_DEPTH ) glut.glutCreateWindow( sys.argv[0] ) glut.glutReshapeWindow( 512, 512+32 ) glut.glutDisplayFunc( on_display ) glut.glutReshapeFunc( on_reshape ) glut.glutKeyboardFunc( on_keyboard ) shader = Shader(vert,frag) glut.glutMainLoop( )
def __init__(self, width=640, height=480, name="Window"): glfw.window_hint(glfw.RESIZABLE, True) glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) self.width, self.height = width, height self.win = glfw.create_window(width, height, name, None, None) if not self.win: glfw.terminate() exit() glfw.make_context_current(self.win) glfw.set_key_callback(self.win, self.on_key) glfw.set_window_size_callback(self.win, self.window_resize) # glfw.set_input_mode(self.win, glfw.CURSOR, glfw.CURSOR_NORMAL) glfw.set_cursor_pos_callback(self.win, self.on_mouse) glfw.set_scroll_callback(self.win, self.on_scroll) glfw.set_mouse_button_callback(self.win, self.on_mouse_button) print('OpenGL', glGetString(GL_VERSION).decode() + ', GLSL', glGetString(GL_SHADING_LANGUAGE_VERSION).decode() + ', Renderer', glGetString(GL_RENDERER).decode(), '\n') glClearColor(0, 0, 0, 1) glEnable(GL_CULL_FACE) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_DEPTH_TEST) # glEnable(GL_ALPHA_TEST) glDepthFunc(GL_LEQUAL) # glDepthMask(GL_FALSE) self.elements = list() self.colored_elements = list() # self.colored_elements.append(Pyramid()) self.camera = Camera(self.win) self.trackball = Trackball() winsize = glfw.get_window_size(self.win) self.projection = self.trackball.projection_matrix(winsize) self.mouse_picker = MousePicker(self.camera, self.projection) self.texture_shader = Shader("res/shaders/basicShader") self.color_shader = Shader("res/shaders/grid") self.shaders = { "color": self.color_shader, "texture": self.texture_shader } self.map_pointer = None self.keys = { "e": False } self.clicks = {} self.delta_time = 0 self.last_frame = 0 self.last_x = 400 self .last_y = 300 self.first_mouse = True self.move_x = 0 self.move_y = 0 self.map = BasicMap(5) main_planet = MainPlanet(1.0) main_planet_pos = (0, 0) self.map.set_entity(main_planet_pos, main_planet) # Trying to enter the main planet at the launch # self.map.selected_tile = self.map.get_tile(main_planet_pos) # self.map_pointer = main_planet self.elements.append(self.map) self.elements.extend(( Background(1, 20), Background(2, 20), Background(3, 20))) self.pyramid = Pyramid()
def __init__(self, attributes, index=None): super().__init__(attributes, index) self.shader = Shader(LAMBERTIAN_VERT, LAMBERTIAN_FRAG)
def __init__(self, attributes, color, index=None): super().__init__(attributes, index) self.shader = Shader(COLOR_VERT, COLOR_FRAG) self.color = color
class Unwrapper: """ This unwrapper takes an image path and a parsed frame and fulfills the operations required to draw the unwrapped image. The draw operations MUST be called inside of the "on_draw" callback passed to "start_unwrap_window" in order to be fulfilled. This class cannot function without an OpenGL window. """ def __init__(self): # Create the shader. self.shader = Shader(vertex_shader, fragment_shader) # Set the texture unit. self.shader.bind() self.shader.uniformi('tex0', 0) self.shader.unbind() # Create a quad geometry to fit the whole window that will be the target of our drawing. self.batch = pyglet.graphics.Batch() self.batch.add(4, GL_QUADS, None, ('v2i', (0,0, 1,0, 1,1, 0,1)), ('t2f', (0,0, 1,0, 1,1, 0,1))) def update(self, img_path, frame): """ Update the texture to the given image path, and update the shaders with the new frame information to unwrap the given image correctly. """ # Recalculate the variables required to unwrap the new image. projector = PolygonProjector(frame.center_point, frame.center_vertices) angle_bounds = [v.angle for v in projector.vertices] radii = [p.center_dist for p in projector.projectors] angles = [p.center_angle for p in projector.projectors] # Load the new image, and update the size variables. self.texture = pyglet.image.load(img_path).get_texture() region_w, region_h = self.texture.width, self.texture.height actual_w, actual_h = self.texture.owner.width, self.texture.owner.height # Update the shader variables. self.shader.bind() self.shader.uniformf('region_size', region_w, region_h) self.shader.uniformf('actual_size', actual_w, actual_h) self.shader.uniformfv('angle_bounds', 1, angle_bounds) self.shader.uniformfv('radii', 1, radii) self.shader.uniformfv('angles', 1, angles) self.shader.uniformi('count', len(radii)) self.shader.unbind() def draw(self): """Draw the unwrapped image to the window.""" glBindTexture(self.texture.target, self.texture.id) self.shader.bind() self.batch.draw() self.shader.unbind() glBindTexture(self.texture.target, 0) def save_image(self, filename): """Save the current window image to the given filename.""" pyglet.image.get_buffer_manager().get_color_buffer().save(filename) def get_fps(self): """Get the current framerate in frames per second.""" return pyglet.clock.get_fps()
def main(): if not glfw.init(): return window = glfw.create_window(WIDTH, HEIGHT, "Hello World", None, None) glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) glfw.window_hint(glfw.RESIZABLE, GL_FALSE) if not window: glfw.terminate() return -1 glfw.make_context_current(window) (width, height) = glfw.get_framebuffer_size(window) glViewport(0, 0, width, height) glfw.set_key_callback(window, key_callback) glClearColor(0.2, 0.3, 0.2, 1.0) quad = [ # coords # colors # texture -0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, -0.5, 0.5, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0 ] quad = numpy.array(quad, dtype=numpy.float32) indexes = [0, 1, 2, 0, 2, 3] indexes = numpy.array(indexes, dtype=numpy.uint32) ourShader = Shader('vertex_shader.vs', 'fragment_shader.frag') VAO = glGenVertexArrays(1) VBO = glGenBuffers(1) EBO = glGenBuffers(1) glBindVertexArray(VAO) glBindBuffer(GL_ARRAY_BUFFER, VBO) glBufferData(GL_ARRAY_BUFFER, quad.itemsize * len(quad), quad, GL_STATIC_DRAW) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO) glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexes.itemsize * len(indexes), indexes, GL_STATIC_DRAW) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12)) glEnableVertexAttribArray(1) glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24)) glEnableVertexAttribArray(2) glBindVertexArray(0) texture = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, texture) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) image = Image.open('../textures/wall.jpg') img_data = numpy.array(list(image.getdata()), numpy.uint8) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data) glGenerateMipmap(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, 0) while not glfw.window_should_close(window): glfw.poll_events() glClear(GL_COLOR_BUFFER_BIT) ourShader.Use() glActiveTexture(GL_TEXTURE0) glBindTexture(GL_TEXTURE_2D, texture) glBindVertexArray(VAO) glDrawElements(GL_TRIANGLES, len(indexes), GL_UNSIGNED_INT, None) glBindVertexArray(0) glfw.swap_buffers(window) glfw.terminate()
def __init__(self, t): Shader.__init__(self, t)
class GrayScott(pyglet.window.Window): """ ---------------------------------------------------------- | This simulation uses mouse and keyboard to control the | | patterns and colors. At any time you may click or drag | | your mouse to draw on the screen. | | | | Keyboad control: | | 1. press 'space' to clear the window to blank. | | 2. press 'p' to change to a random palette. | | 3. press 's' to change to another pattern. | | 4. press 'Ctrl + r' to reset to default. | | 5. press 'Ctrl + s' to save current config. | | 6. press 'Ctrl + o' to load config from json file. | | 7. press 'Enter' to take screenshots. | | 8. press 'Esc' to exit. | ---------------------------------------------------------- """ def __init__(self, width, height, scale=2): """ width, height: size of the window in pixels. scale: the size of the texture is (width//scale) x (height//scale). """ pyglet.window.Window.__init__(self, width, height, caption='GrayScott Simulation', visible=False, vsync=False) self.reaction_shader = Shader('./glsl/default.vert', './glsl/reaction.frag') self.render_shader = Shader('./glsl/default.vert', './glsl/render.frag') self.pattern = DEFAULT_PATTERN self.palette = DEFAULT_PALETTE self.tex_width = width // scale self.tex_height = height // scale self.uv_texture = create_uv_texture(width // scale, height // scale) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(self.uv_texture.target, self.uv_texture.id) # use an invisible buffer to do the computation. with FrameBuffer() as self.fbo: self.fbo.attach_texture(self.uv_texture) # why do we need this? the reason is in the 'on_mouse_drag' function. self.mouse_down = False # put all patterns in a list for iterating over them. self._species = list(SPECIES.keys()) # set the uniforms and attributes in the two shaders. self.init_reaction_shader() self.init_render_shader() def set_viewport(self, width, height): gl.glViewport(0, 0, width, height) gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() gl.glOrtho(0, 1, 0, 1, -1, 1) gl.glMatrixMode(gl.GL_MODELVIEW) def on_draw(self): gl.glClearColor(0, 0, 0, 0) self.clear() # since we are rendering to the invisible framebuffer, # the size is the texture's size. self.set_viewport(self.tex_width, self.tex_height) with self.fbo: with self.reaction_shader: gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) # now we render to the actual window, hence the size is window's size. self.set_viewport(self.width, self.height) with self.render_shader: gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) def use_pattern(self, pattern): self.pattern = pattern rU, rV, feed, kill = SPECIES[pattern] with self.reaction_shader: self.reaction_shader.set_uniformf('feed', feed) self.reaction_shader.set_uniformf('kill', kill) self.reaction_shader.set_uniformf('rU', rU) self.reaction_shader.set_uniformf('rV', rV) def use_palette(self, palette): self.palette = palette color1, color2, color3, color4, color5 = palette with self.render_shader: self.render_shader.set_uniformf('color1', *color1) self.render_shader.set_uniformf('color2', *color2) self.render_shader.set_uniformf('color3', *color3) self.render_shader.set_uniformf('color4', *color4) self.render_shader.set_uniformf('color5', *color5) def init_reaction_shader(self): with self.reaction_shader: self.reaction_shader.set_uniformi('uv_texture', 0) self.reaction_shader.set_uniformf('dx', 1.0 / self.tex_width) self.reaction_shader.set_uniformf('dy', 1.0 / self.tex_height) # the order of the vertices and texcoords matters, # since we will call 'GL_TRIANGLE_STRIP' to draw them. self.reaction_shader.set_vertex_attrib('position', [(-1, -1), (1, -1), ( -1, 1, ), (1, 1)]) self.reaction_shader.set_vertex_attrib('texcoord', [(0, 0), (1, 0), (0, 1), (1, 1)]) self.reaction_shader.set_uniformf('u_mouse', -1, -1) self.use_pattern(self.pattern) def init_render_shader(self): with self.render_shader: self.render_shader.set_uniformi('uv_texture', 0) self.render_shader.set_vertex_attrib('position', [(-1, -1), (1, -1), (-1, 1), (1, 1)]) self.render_shader.set_vertex_attrib('texcoord', [(0, 0), (1, 0), (0, 1), (1, 1)]) self.use_palette(self.palette) def update_mouse(self, *u_mouse): self.set_viewport(self.tex_width, self.tex_height) with self.fbo: with self.reaction_shader: self.reaction_shader.set_uniformf('u_mouse', *u_mouse) def on_mouse_press(self, x, y, button, modifiers): self.mouse_down = True bx = x / float(self.width) by = y / float(self.height) self.update_mouse(bx, by) def on_mouse_release(self, x, y, button, modifiers): self.mouse_down = False self.update_mouse(-1, -1) def on_mouse_drag(self, x, y, dx, dy, button, modifiers): if self.mouse_down: bx = x / float(self.width) by = y / float(self.height) self.update_mouse(bx, by) def on_key_press(self, symbol, modifiers): if symbol == pyglet.window.key.ENTER: self.save_screenshot() if symbol == pyglet.window.key.ESCAPE: pyglet.app.exit() # clear to blank window if symbol == pyglet.window.key.SPACE: self.update_mouse(-10, -10) if symbol == pyglet.window.key.S: if modifiers != pyglet.window.key.LCTRL: self.change_pattern() if symbol == pyglet.window.key.P: self.change_palette() if symbol == pyglet.window.key.R: if modifiers & pyglet.window.key.LCTRL: self.restore_default() if symbol == pyglet.window.key.S: if modifiers & pyglet.window.key.LCTRL: self.save_config() if symbol == pyglet.window.key.O: if modifiers & pyglet.window.key.LCTRL: self.load_config() def save_screenshot(self): index = np.random.randint(0, 1000) img = pyglet.image.get_buffer_manager().get_color_buffer() img.save('screenshot{:03d}.png'.format(index)) def restore_default(self): self.use_palette(DEFAULT_PALETTE) self.use_pattern(DEFAULT_PATTERN) print('> Using default config.\n') def save_config(self): """Save current config to the json file.""" with open('palette.json', 'a+') as f: data = json.dumps({self.pattern: self.palette.tolist()}) f.write(data + '\n') print('> Config saved.\n') def load_config(self): """Load a config from the json file.""" try: num = int(input('> Enter the line number in json file: ')) except ValueError: print('> Invalid input.\n') return with open('palette.json', 'r') as f: lines = f.readlines() if 1 <= num <= len(lines): (pattern, palette), = json.loads(lines[num - 1]).items() self.use_pattern(pattern) self.use_palette(palette) print('> Config loaded. Current config: ' + self.pattern + '. Draw on it!\n') else: print('> Config does not exist in json file.\n') def change_palette(self): """Use a random palette.""" alphas = sorted(np.random.random(5)) palette = np.random.random((5, 4)) # the first row is set to 0 to make the background black. palette[0] = 0.0 palette[:, -1] = alphas palette = palette.round(3) self.use_palette(palette) print('> Current palette: ') print(palette) print('\n') def change_pattern(self): """Use the next pattern in the list `self._species`.""" index = self._species.index(self.pattern) next_pattern = self._species[(index + 1) % len(self._species)] self.use_pattern(next_pattern) print('> Current pattern: ' + self.pattern + '. If the screen is blank, draw on it!\n') def run(self): self.set_visible(True) pyglet.clock.schedule(lambda dt: None) pyglet.app.run()
def main(): glfw.init() glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) window = glfw.create_window(800, 600, "LearnOpenGL", None, None) if not window: print("Window Creation failed!") glfw.terminate() glfw.make_context_current(window) glfw.set_window_size_callback(window, on_resize) shader = Shader(CURDIR / 'shaders/3.4.shader.vs', CURDIR / 'shaders/3.4.shader.fs') data = [ -0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 1.0, ] data = (c_float * len(data))(*data) vao = gl.glGenVertexArrays(1) gl.glBindVertexArray(vao) vbo = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(data), data, gl.GL_STATIC_DRAW) # -- vertices gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 6 * sizeof(c_float), c_void_p(0)) gl.glEnableVertexAttribArray(0) # -- color gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 6 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) gl.glEnableVertexAttribArray(1) while not glfw.window_should_close(window): process_input(window) gl.glClearColor(.2, .3, .3, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT) shader.use() gl.glBindVertexArray(vao) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) glfw.poll_events() glfw.swap_buffers(window) gl.glDeleteVertexArrays(1, id(vao)) gl.glDeleteBuffers(1, id(vbo)) glfw.terminate()
def main(): global delta_time, last_frame glfw.init() glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) window = glfw.create_window(SRC_WIDTH, SRC_HEIGHT, "learnOpenGL", None, None) if not window: glfw.terminate() raise ValueError("Failed to create window") glfw.make_context_current(window) glfw.set_framebuffer_size_callback(window, framebuffer_size_callback) glfw.set_cursor_pos_callback(window, mouse_callback) glfw.set_scroll_callback(window, scroll_callback) glfw.set_input_mode(window, glfw.CURSOR, glfw.CURSOR_DISABLED) gl.glEnable(gl.GL_DEPTH_TEST) lamp_shader = Shader(CURDIR / "shaders/1.lamp.vs", CURDIR / "shaders/1.lamp.fs") lighting_shader = Shader(CURDIR / "shaders/5.2.light_casters.vs", CURDIR / "shaders/5.2.light_casters.fs") vertices = [ # positions normals texture coords -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 0.0, 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 0.0, 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 1.0, 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 1.0, -0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 0.0, -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 0.0, 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 1.0, 0.0, -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 1.0, 1.0, -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 0.0, 1.0, -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 0.0, 1.0, -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 0.0, 0.0, -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 1.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 1.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 0.0, -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 0.0, 1.0, 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 1.0, 0.0, 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 1.0, 0.0, -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 0.0, 0.0, -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 0.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 0.0, -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 0.0, -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0 ] vertices = (c_float * len(vertices))(*vertices) cube_positions = [(0.0, 0.0, 0.0), (2.0, 5.0, -15.0), (-1.5, -2.2, -2.5), (-3.8, -2.0, -12.3), (2.4, -0.4, -3.5), (-1.7, 3.0, -7.5), (1.3, -2.0, -2.5), (1.5, 2.0, -2.5), (1.5, 0.2, -1.5), (-1.3, 1.0, -1.5)] cube_vao = gl.glGenVertexArrays(1) vbo = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) gl.glBindVertexArray(cube_vao) # -- position attribute gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(0)) gl.glEnableVertexAttribArray(0) # -- normal attribute gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) gl.glEnableVertexAttribArray(1) # -- texture coordinate gl.glVertexAttribPointer(2, 2, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(6 * sizeof(c_float))) gl.glEnableVertexAttribArray(2) # -- second configure light vao (vbo is the same) light_vao = gl.glGenVertexArrays(1) gl.glBindVertexArray(light_vao) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(0)) gl.glEnableVertexAttribArray(0) # -- load texture diffuse_map = load_texture("container2.png") specular_map = load_texture("container2_specular.png") # -- shader configuration lighting_shader.use() lighting_shader.set_int("material.diffuse", 0) lighting_shader.set_int("material.specular", 1) while not glfw.window_should_close(window): # -- time logic current_frame = glfw.get_time() delta_time = current_frame - last_frame last_frame = current_frame # -- input process_input(window) # -- render gl.glClearColor(0.1, 0.1, 0.1, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) lighting_shader.use() lighting_shader.set_vec3("light.position", light_pos) lighting_shader.set_vec3("viewPos", camera.position) # -- light properties lighting_shader.set_vec3("light.ambient", Vector3([0.2, 0.2, 0.2])) lighting_shader.set_vec3("light.diffuse", Vector3([0.5, 0.5, 0.5])) lighting_shader.set_vec3("light.specular", Vector3([1.0, 1.0, 1.0])) lighting_shader.set_float("light.constant", 1.0) lighting_shader.set_float("light.linear", 0.09) lighting_shader.set_float("light.quadratic", 0.032) # -- material properties lighting_shader.set_float("material.shininess", 32.0) # -- view.projection transformations projection = Matrix44.perspective_projection(camera.zoom, SRC_WIDTH / SRC_HEIGHT, 0.1, 100.0) view = camera.get_view_matrix() lighting_shader.set_mat4("projection", projection) lighting_shader.set_mat4("view", view) # -- world transformation model = Matrix44.identity() lighting_shader.set_mat4("model", model) # -- bind diffuse map gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(gl.GL_TEXTURE_2D, diffuse_map) # -- bind specular map gl.glActiveTexture(gl.GL_TEXTURE1) gl.glBindTexture(gl.GL_TEXTURE_2D, specular_map) # -- render continers gl.glBindVertexArray(cube_vao) for idx, position in enumerate(cube_positions): angle = 20.0 * idx rotation = matrix44.create_from_axis_rotation([1.0, 0.3, 0.5], math.radians(angle)) translation = Matrix44.from_translation(position) model = translation * rotation lighting_shader.set_mat4('model', model) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 36) # -- draw lamp object lamp_shader.use() lamp_shader.set_mat4("projection", projection) lamp_shader.set_mat4("view", view) model = Matrix44.identity() model *= Matrix44.from_translation(light_pos) model *= Matrix44.from_scale(Vector3([.2, .2, .2])) lamp_shader.set_mat4("model", model) gl.glBindVertexArray(light_vao) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 36) glfw.swap_buffers(window) glfw.poll_events() gl.glDeleteVertexArrays(1, id(cube_vao)) gl.glDeleteVertexArrays(1, id(light_vao)) gl.glDeleteBuffers(1, id(vbo)) glfw.terminate()
class UI: def __init__(self, view): self.logger = logging.getLogger(type(self).__name__) self.view = view self.enabled = True self.init_opengl() self.elements = { 'time_label':Text((.01, .99)), 'fps_label':Text((.71, .99)), 'camera_label':Text((.01, .04)) } self.composition_overlay_enabled = True self.overlay_shader = Shader({GL_VERTEX_SHADER:'shaders/shader.vert', GL_GEOMETRY_SHADER:'shaders/shader.geom', GL_FRAGMENT_SHADER:'shaders/composition.frag'}) self.overlay_shader.create() self.logger.debug('Initialized UI') def init_opengl(self): glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) glEnable(GL_BLEND) glEnable(GL_COLOR_MATERIAL) glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glEnable(GL_TEXTURE_2D) def toggle_visibility(self): self.enabled = not self.enabled def toggle_composition_overlay(self): self.composition_overlay_enabled = not self.composition_overlay_enabled def draw_composition_overlay(self): self.overlay_shader.bind() self.overlay_shader.set_uniforms( { 'resolution':self.view.resolution, 'time':0., } ) glDrawArrays(GL_POINTS, 0, 1) # dummy vbo self.overlay_shader.unbind() def draw(self, values_dict): if not self.enabled: return ar = self.view.resolution[0]/self.view.resolution[1] glPushMatrix() glTranslatef(-1,-1,0) glScale(2,2,1) # -> [0,1]x[0,1] for name, elem in self.elements.items(): glPushMatrix() glTranslatef(*elem.position, 0) #glScale(1/self.view.resolution[0], 1/self.view.resolution[1], 1) glScale(1/2000, 1/2000*ar, 1) elem.draw(values_dict[name]) glPopMatrix() if self.composition_overlay_enabled: self.draw_composition_overlay() glPopMatrix()
class Wythoff(pyglet.window.Window): def __init__(self, width, height): """ :param width and height: size of the window in pixels. """ pyglet.window.Window.__init__(self, width, height, caption="Wythoff Explorer", resizable=True, visible=False, vsync=False) self._start_time = time.clock() self._last = self._now = self._start_time self._frame_count = 0 # count number of frames rendered so far self.shaderA = Shader(["./glsl/wythoff.vert"], ["./glsl/common.frag", "./glsl/BufferA.frag"]) self.shaderB = Shader(["./glsl/wythoff.vert"], ["./glsl/common.frag", "./glsl/main.frag"]) self.font_texture = create_image_texture(FONT_TEXTURE) self.noise_texture = create_image_texture(NOISE_TEXTURE) self.iChannel0 = pyglet.image.Texture.create_for_size( gl.GL_TEXTURE_2D, width, height, gl.GL_RGBA32F_ARB) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(self.iChannel0.target, self.iChannel0.id) gl.glActiveTexture(gl.GL_TEXTURE1) gl.glBindTexture(gl.GL_TEXTURE_2D, self.font_texture) gl.glActiveTexture(gl.GL_TEXTURE2) gl.glBindTexture(gl.GL_TEXTURE_2D, self.noise_texture) with FrameBuffer() as self.bufferA: self.bufferA.attach_texture(self.iChannel0) # initialize the shaders with self.shaderA: self.shaderA.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shaderA.uniformf("iResolution", width, height, 0.0) self.shaderA.uniformf("iTime", 0.0) self.shaderA.uniformf("iMouse", 0.0, 0.0, 0.0, 0.0) self.shaderA.uniformi("iChannel0", 0) self.shaderA.uniformi("iChannel1", 1) self.shaderA.uniformi("iChannel2", 2) self.shaderA.uniformf("iDate", *get_idate()) self.shaderA.uniformf("iTimeDelta", 0) with self.shaderB: self.shaderB.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shaderB.uniformf("iResolution", width, height, 0.0) self.shaderB.uniformf("iTime", 0.0) self.shaderB.uniformf("iMouse", 0.0, 0.0, 0.0, 0.0) self.shaderB.uniformi("iChannel0", 0) self.shaderB.uniformi("iChannel1", 1) self.shaderB.uniformi("iChannel2", 2) self.shaderB.uniformf("iDate", *get_idate()) self.shaderA.uniformf("iTimeDelta", 0) def on_draw(self): gl.glClearColor(0, 0, 0, 0) self.clear() gl.glViewport(0, 0, self.width, self.height) self._last = self._now self._now = time.clock() itime = self._now - self._start_time idate = get_idate() delta = self._now - self._last with self.bufferA: with self.shaderA: self.shaderA.uniformf("iTime", itime) self.shaderA.uniformf("iDate", *idate) self.shaderA.uniformf("iTimeDelta", delta) gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) with self.shaderB: self.shaderB.uniformf("iTime", itime) self.shaderB.uniformf("iDate", *idate) self.shaderB.uniformf("iTimeDelta", delta) gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) self._frame_count += 1 def on_key_press(self, symbol, modifiers): """Keyboard interface. """ if symbol == key.ENTER: self.save_screenshot() if symbol == key.ESCAPE: pyglet.app.exit() def on_mouse_press(self, x, y, button, modifiers): if button & pyglet.window.mouse.LEFT: with self.shaderA: self.shaderA.uniformf("iMouse", x, y, x, y) def on_mouse_release(self, x, y, button, modifiers): """Don't forget reset 'iMouse' when mouse is released. """ with self.shaderA: self.shaderA.uniformf("iMouse", 0, 0, 0, 0) def on_mouse_drag(self, x, y, dx, dy, button, modifiers): if button & pyglet.window.mouse.LEFT: with self.shaderA: x += dx y += dy x = max(min(x, self.width), 0) y = max(min(y, self.height), 0) self.shaderA.uniformf("iMouse", x, y, x, y) def save_screenshot(self): image_buffer = pyglet.image.get_buffer_manager().get_color_buffer() image_buffer.save("screenshoot.png") def run(self, fps=None): self.set_visible(True) if fps is None: pyglet.clock.schedule(lambda dt: None) else: pyglet.clock.schedule_interval(lambda dt: None, 1.0 / fps) pyglet.app.run()
class MainWindow(pyglet.window.Window): def __init__(self, width, height, aa): pyglet.window.Window.__init__(self, width, height, caption="Loxodromic transformation", resizable=True, visible=False, vsync=False) self._start_time = time.clock() self.shader = Shader(["./glsl/loxodrome.vert"], ["./glsl/loxodrome.frag"]) self.buffer = pyglet.image.get_buffer_manager().get_color_buffer() texture = create_image_texture(WOOD_TEXTURE) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(gl.GL_TEXTURE_2D, texture) with self.shader: self.shader.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shader.uniformf("iResolution", width, height, 0.0) self.shader.uniformf("iTime", 0.0) self.shader.uniformi("iTexture", 0) self.shader.uniformi("AA", aa) def on_draw(self): gl.glClearColor(0, 0, 0, 0) self.clear() gl.glViewport(0, 0, self.width, self.height) now = time.clock() - self._start_time now *= 20 with self.shader: self.shader.uniformf("iTime", now) gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) def on_key_press(self, symbol, modifiers): if symbol == key.ENTER: self.save_screenshot() if symbol == key.ESCAPE: pyglet.app.exit() def save_screenshot(self): self.buffer.save("loxodrome-screenshot.png") def on_mouse_press(self, x, y, button, modifiers): if button & mouse.LEFT: with self.shader: self.shader.uniformf("iMouse", x, y, x, y) def on_mouse_drag(self, x, y, dx, dy, button, modifiers): if button & mouse.LEFT: with self.shader: x += dx y += dy x = max(min(x, self.width), 0) y = max(min(y, self.height), 0) self.shader.uniformf("iMouse", x, y, x, y) def run(self, fps=None): self.set_visible(True) if fps is None: pyglet.clock.schedule(lambda dt: None) else: pyglet.clock.schedule_interval(lambda dt: None, 1.0 / fps) pyglet.app.run()
def __init__(self, width, height, scale=1.5, conf=1, mask=None, flip=False, video=False, sample_rate=None, video_rate=None): """ Parameters ---------- :width & height: size of the window in pixels. :scale: scaling factor of the texture. :conf: line number of the config in the file (`config.txt`). :mask: a user-specified image that is used to control the growth of the pattern. :flip: flip the white/black pixels in the mask image, only meaningful if there is a mask image. :video: whether the video is turned on or off. :sample_rate: sample a frame from the animation every these frames. :video_rate: frames per second of the video. """ pyglet.window.Window.__init__(self, width, height, caption="GrayScott Simulation", resizable=True, visible=False, vsync=False) # use two shaders, one for doing the computations and one for rendering to the screen. self.reaction_shader = Shader(["./glsl/reaction.vert"], ["./glsl/reaction.frag"]) self.render_shader = Shader(["./glsl/render.vert"], ["./glsl/render.frag"]) self.tex_width, self.tex_height = int(width / scale), int(height / scale) try: self.species, self.palette = self.load_config(conf) print("> Current species: " + self.species + "\n") except: conf = "unstable: #00000000 #00FF0033 #FFFF0035 #FF000066 #FFFFFF99" self.species, self.palette = parse(conf) print("> Failed to load the config, using the default one.\n") self.species_list = list(ALL_SPECIES.keys()) # create the uv_texture uv_grid = np.zeros((self.tex_height, self.tex_width, 4), dtype=np.float32) uv_grid[:, :, 0] = 1.0 rand_rows = np.random.choice(range(self.tex_height), 5) rand_cols = np.random.choice(range(self.tex_width), 5) uv_grid[rand_rows, rand_cols, 1] = 1.0 self.uv_texture = create_texture_from_ndarray(uv_grid) # create the mask_texture mask_grid = np.ones_like(uv_grid) if mask is not None: img = Image.open(mask).convert("L").resize( (self.tex_width, self.tex_height)) img = (np.asarray(img) / 255.0).astype(np.float32) if flip: img = 1.0 - img mask_grid[:, :, 0] = img[::-1] self.mask_texture = create_texture_from_ndarray(mask_grid) # bind the two textures gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(self.uv_texture.target, self.uv_texture.id) gl.glActiveTexture(gl.GL_TEXTURE1) gl.glBindTexture(self.mask_texture.target, self.mask_texture.id) # use an invisible buffer to do the computations. with FrameBuffer() as self.fbo: self.fbo.attach_texture(self.uv_texture) # we need this because the program samples the position of the mouse in discrete times. self.mouse_down = False # initialize the two shaders with self.reaction_shader: self.reaction_shader.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.reaction_shader.vertex_attrib("texcoord", [0, 0, 1, 0, 0, 1, 1, 1]) self.reaction_shader.uniformi("uv_texture", 0) self.reaction_shader.uniformi("mask_texture", 1) self.reaction_shader.uniformf("u_resolution", self.tex_width, self.tex_height) self.reaction_shader.uniformf("u_mouse", -1, -1) self.reaction_shader.uniformf("params", *ALL_SPECIES[self.species]) with self.render_shader: self.render_shader.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.render_shader.vertex_attrib("texcoord", [0, 0, 1, 0, 0, 1, 1, 1]) self.render_shader.uniformi("uv_texture", 0) self.render_shader.uniformfv("palette", 5, self.palette) self.video_on = video self.buffer = pyglet.image.get_buffer_manager().get_color_buffer() self.sample_rate = sample_rate self.video_rate = video_rate self.frame_count = 0 if video: self.ffmpeg_pipe = self.create_new_pipe() self.start_time = time.time()
def __init__(self): if not glfw.init(): return glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 2) glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE) window = glfw.create_window(self.WIDTH, self.HEIGHT, self.TITLE, None, None) glfw.set_window_size_limits(window, 320, 480, glfw.DONT_CARE, glfw.DONT_CARE) if not window: glfw.terminate() return glfw.make_context_current(window) glfw.set_key_callback(window, self.key_callback) glfw.set_window_size_callback(window, self.reshape) width, height = glfw.get_framebuffer_size(window) glViewport(0, 0, width, height) aspect_ratio = width / height glClearColor(0.2, 0.3, 0.2, 1.0) glEnable(GL_DEPTH_TEST) self.ball = Ball(TEXTILE_TEXTURE) ball_shader = Shader(BASE_VS, BASE_FS) self.ball.prep(ball_shader, aspect_ratio, 0.5, 85) self.platform = Platform(BUCKET_TEXTURE) shader = Shader(BASE_VS, BASE_FS) self.platform.prep(shader, aspect_ratio, 1.0, 85) self.Vidass = [] for i in range(0, self.MAX_FAIL): Vidas = LiveVidas([-3.0 + i * 0.5, 5.5, 0.0]) Vidas_shader = Shader(Vidas_VS, Vidas_FS) Vidas.prep(Vidas_shader, aspect_ratio, 0.3, 85) self.Vidass.append(Vidas) self.bg = Background(WOOD_TEXTURE) bg_shader = Shader(BASE_VS, BASE_FS) self.bg.prep(bg_shader, aspect_ratio, 11.0, 85) while not glfw.window_should_close(window): glClearColor(0.0, 0.3, 0.3, 1.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glDisable(GL_DEPTH_TEST) self.bg.draw() glEnable(GL_DEPTH_TEST) self.platform.draw(self.game_status_play) self.ball.draw(self.game_status_play) if self.collision_detect(): if self.fails == self.MAX_FAIL: self.game_status_play = False for Vidas in self.Vidass: Vidas.draw() glfw.swap_buffers(window) glfw.poll_events() glfw.terminate()
class GrayScott(pyglet.window.Window): """ ---------------------------------------------------------- | This simulation uses mouse and keyboard to control the | | patterns and colors. At any time you may click or drag | | your mouse to draw on the screen. | | | | Keyboard control: | | 1. press "space" to clear the window to blank. | | 2. press "p" to change to a random palette. | | 3. press "s" to change to another species. | | 4. press "Ctrl + s" to save current config. | | 5. press "Ctrl + o" to load a config from the file. | | 6. press "Enter" to take screenshots. | | 7. press "Ctrl + v" to start saving the animation to | | the video and press "Ctrl + v" again to stop. | | 8. press "Esc" to exit. | ---------------------------------------------------------- """ def __init__(self, width, height, scale=1.5, conf=1, mask=None, flip=False, video=False, sample_rate=None, video_rate=None): """ Parameters ---------- :width & height: size of the window in pixels. :scale: scaling factor of the texture. :conf: line number of the config in the file (`config.txt`). :mask: a user-specified image that is used to control the growth of the pattern. :flip: flip the white/black pixels in the mask image, only meaningful if there is a mask image. :video: whether the video is turned on or off. :sample_rate: sample a frame from the animation every these frames. :video_rate: frames per second of the video. """ pyglet.window.Window.__init__(self, width, height, caption="GrayScott Simulation", resizable=True, visible=False, vsync=False) # use two shaders, one for doing the computations and one for rendering to the screen. self.reaction_shader = Shader(["./glsl/reaction.vert"], ["./glsl/reaction.frag"]) self.render_shader = Shader(["./glsl/render.vert"], ["./glsl/render.frag"]) self.tex_width, self.tex_height = int(width / scale), int(height / scale) try: self.species, self.palette = self.load_config(conf) print("> Current species: " + self.species + "\n") except: conf = "unstable: #00000000 #00FF0033 #FFFF0035 #FF000066 #FFFFFF99" self.species, self.palette = parse(conf) print("> Failed to load the config, using the default one.\n") self.species_list = list(ALL_SPECIES.keys()) # create the uv_texture uv_grid = np.zeros((self.tex_height, self.tex_width, 4), dtype=np.float32) uv_grid[:, :, 0] = 1.0 rand_rows = np.random.choice(range(self.tex_height), 5) rand_cols = np.random.choice(range(self.tex_width), 5) uv_grid[rand_rows, rand_cols, 1] = 1.0 self.uv_texture = create_texture_from_ndarray(uv_grid) # create the mask_texture mask_grid = np.ones_like(uv_grid) if mask is not None: img = Image.open(mask).convert("L").resize( (self.tex_width, self.tex_height)) img = (np.asarray(img) / 255.0).astype(np.float32) if flip: img = 1.0 - img mask_grid[:, :, 0] = img[::-1] self.mask_texture = create_texture_from_ndarray(mask_grid) # bind the two textures gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(self.uv_texture.target, self.uv_texture.id) gl.glActiveTexture(gl.GL_TEXTURE1) gl.glBindTexture(self.mask_texture.target, self.mask_texture.id) # use an invisible buffer to do the computations. with FrameBuffer() as self.fbo: self.fbo.attach_texture(self.uv_texture) # we need this because the program samples the position of the mouse in discrete times. self.mouse_down = False # initialize the two shaders with self.reaction_shader: self.reaction_shader.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.reaction_shader.vertex_attrib("texcoord", [0, 0, 1, 0, 0, 1, 1, 1]) self.reaction_shader.uniformi("uv_texture", 0) self.reaction_shader.uniformi("mask_texture", 1) self.reaction_shader.uniformf("u_resolution", self.tex_width, self.tex_height) self.reaction_shader.uniformf("u_mouse", -1, -1) self.reaction_shader.uniformf("params", *ALL_SPECIES[self.species]) with self.render_shader: self.render_shader.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.render_shader.vertex_attrib("texcoord", [0, 0, 1, 0, 0, 1, 1, 1]) self.render_shader.uniformi("uv_texture", 0) self.render_shader.uniformfv("palette", 5, self.palette) self.video_on = video self.buffer = pyglet.image.get_buffer_manager().get_color_buffer() self.sample_rate = sample_rate self.video_rate = video_rate self.frame_count = 0 if video: self.ffmpeg_pipe = self.create_new_pipe() self.start_time = time.time() def on_draw(self): gl.glClearColor(0.0, 0.0, 0.0, 0.0) self.clear() if time.time() - self.start_time > 0.1: gl.glViewport(0, 0, self.tex_width, self.tex_height) with self.fbo: with self.reaction_shader: gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) gl.glViewport(0, 0, self.width, self.height) with self.render_shader: gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) if self.video_on and (self.frame_count % self.sample_rate == 0): self.write_video_frame() self.frame_count += 1 def on_key_press(self, symbol, modifiers): """Keyboard interface. """ if symbol == key.ENTER: self.save_screenshot() if symbol == key.ESCAPE: pyglet.app.exit() if symbol == key.SPACE: self.clear_blank_window() if symbol == key.P: self.use_random_palette() if symbol == key.S and not modifiers: self.use_next_species() if symbol == key.S and (modifiers & key.LCTRL): self.save_config() if symbol == key.O and (modifiers & key.LCTRL): self.require_config_input() if symbol == key.V and (modifiers & key.LCTRL): self.switch_video() def update_species(self, species): self.species = species with self.reaction_shader: self.reaction_shader.uniformf("params", *ALL_SPECIES[species]) def update_palette(self, palette): self.palette = palette with self.render_shader: self.render_shader.uniformfv("palette", 5, palette) def update_mouse(self, x, y): with self.fbo: with self.reaction_shader: self.reaction_shader.uniformf("u_mouse", x, y) def save_screenshot(self): self.buffer.save("screenshot-" + self.species + ".png") def save_config(self): with open("config.txt", "a+") as f: f.write(self.species + ": " + " ".join(rgba_to_htmlcolors(self.palette)) + "\n") print("> Config saved.\n") def load_config(self, k): with open("config.txt", "r") as f: for i, line in enumerate(f.readlines()): if k == i: return parse(line) print("> Config does not exist.\n") def require_config_input(self): try: k = int( input("> Enter the line number in the config file: ").strip()) except ValueError: print("> Invalid input.\n") return try: species, palette = self.load_config(k) self.update_species(species) self.update_palette(palette) print("> Config loaded. Current species: " + self.species) except: return def write_video_frame(self): """Read frame data from buffer and write it to the video. """ data = self.buffer.get_image_data().get_data("RGBA", -4 * self.width) self.ffmpeg_pipe.write(data) def on_mouse_press(self, x, y, button, modifiers): self.mouse_down = True self.update_mouse(x / self.width, y / self.height) def on_mouse_release(self, x, y, button, modifiers): self.mouse_down = False self.update_mouse(-1, -1) def on_mouse_drag(self, x, y, dx, dy, button, modifiers): if self.mouse_down: self.update_mouse(x / self.width, y / self.height) def clear_blank_window(self): self.update_mouse(-10, -10) def use_random_palette(self): new_palette = np.random.random(20) new_palette[[3, 7, 11, 15, 19]] = sorted(np.random.random(5)) new_palette[:3] = 0 self.update_palette(new_palette) def use_next_species(self): index = self.species_list.index(self.species) new_species = self.species_list[(index + 1) % len(self.species_list)] self.update_species(new_species) print("> Current species: " + self.species + "\n") def switch_video(self): self.video_on = not self.video_on if self.video_on: self.ffmpeg_pipe = self.create_new_pipe() print("> Writing to video...\n") else: self.ffmpeg_pipe.close() print("> The video is closed.\n") def create_new_pipe(self): ffmpeg = subprocess.Popen( (FFMPEG_EXE, "-threads", "0", "-loglevel", "panic", "-r", "%d" % self.video_rate, "-f", "rawvideo", "-pix_fmt", "rgba", "-s", "%dx%d" % (self.width, self.height), "-i", "-", "-c:v", "libx264", "-crf", "20", "-y", self.species + ".mp4"), stdin=subprocess.PIPE) return ffmpeg.stdin def run(self, fps=None): self.set_visible(True) if fps is None: pyglet.clock.schedule(lambda dt: None) else: pyglet.clock.schedule_interval(lambda dt: None, 1.0 / fps) pyglet.app.run()
shader = Shader([ ''' void main() { // transform the vertex position gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; // pass through the texture coordinate gl_TexCoord[0] = gl_MultiTexCoord0; } ''' ], [ ''' uniform sampler2D tex0; uniform vec2 pixel; void main() { // retrieve the texture coordinate vec2 c = gl_TexCoord[0].xy; // and the current pixel vec3 current = texture2D(tex0, c).rgb; // count the neightbouring pixels with a value greater than zero vec3 neighbours = vec3(0.0); neighbours += vec3(greaterThan(texture2D(tex0, c + pixel*vec2(-1,-1)).rgb, vec3(0.0))); neighbours += vec3(greaterThan(texture2D(tex0, c + pixel*vec2(-1, 0)).rgb, vec3(0.0))); neighbours += vec3(greaterThan(texture2D(tex0, c + pixel*vec2(-1, 1)).rgb, vec3(0.0))); neighbours += vec3(greaterThan(texture2D(tex0, c + pixel*vec2( 0,-1)).rgb, vec3(0.0))); neighbours += vec3(greaterThan(texture2D(tex0, c + pixel*vec2( 0, 1)).rgb, vec3(0.0))); neighbours += vec3(greaterThan(texture2D(tex0, c + pixel*vec2( 1,-1)).rgb, vec3(0.0))); neighbours += vec3(greaterThan(texture2D(tex0, c + pixel*vec2( 1, 0)).rgb, vec3(0.0))); neighbours += vec3(greaterThan(texture2D(tex0, c + pixel*vec2( 1, 1)).rgb, vec3(0.0))); // check if the current pixel is alive vec3 live = vec3(greaterThan(current, vec3(0.0))); // resurect if we are not live, and have 3 live neighrbours current += (1.0-live) * vec3(equal(neighbours, vec3(3.0))); // kill if we do not have either 3 or 2 neighbours current *= vec3(equal(neighbours, vec3(2.0))) + vec3(equal(neighbours, vec3(3.0))); // fade the current pixel as it ages current -= vec3(greaterThan(current, vec3(0.4)))*0.05; // write out the pixel gl_FragColor = vec4(current, 1.0); } ''' ])
class Window(Window): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # glEnable(GL_DEPTH_TEST) self.shader = Shader('vs.glsl', 'fs.glsl') self.chunk = Chunk((0, 0, 0)) self.camera = Camera() self.shader.use() self.shader.set_uniform("light.direction", pyrr.Vector3([-0.5, -1.0, -0.0])) self.shader.set_uniform("viewPos", self.camera.position) self.shader.set_uniform("light.ambient", pyrr.Vector3([0.2, 0.2, 0.2])) self.shader.set_uniform("light.diffuse", pyrr.Vector3([0.5, 0.5, 0.5])) self.shader.set_uniform("light.specular", pyrr.Vector3([1.0, 1.0, 1.0])) self.shader.set_uniform("material.shininess", 32.0) def on_key_press(self, symbol, modifiers): pass def on_key_release(self, symbol, modifiers): pass def on_draw(self): glClearColor(0.1, 0.1, 0.1, 1.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) self.projection = pyrr.matrix44.create_perspective_projection( radians(self.camera.zoom), self.width / self.height, 0.1, 1000.0) self.view = self.camera.get_view_matrix() self.shader.set_uniform("projection", self.projection) self.shader.set_uniform("view", self.view) # Draw! glBindVertexArray(self.chunk.vao) # Normally we'd translate before drawing a chunk model = pyrr.Matrix44() self.shader.set_uniform("model", model) glDrawArrays(GL_TRIANGLES, 0, len(self.chunk.vertices) // 3) # swap buffers - may not be necessary with pyglet # self.flip() def on_mouse_motion(self, x, y, dx, dy): pass def on_resize(self, width, height): glViewport(0, 0, width, height)
class ShaderWindow(pyglet.window.Window): def __init__(self, shader_path): self.w = 512 self.h = 512 # Scaling values self.x = -5.4 self.y = -5.4 self.z = 0.0 self.zoom = 0.02 self.octives = 9 self.freq = 0.73 self.windowSize = (float(self.w), float(self.h)) super(ShaderWindow, self).__init__(caption = 'Shader', width=self.w, height=self.h) self.shader = Shader( ' '.join(open('%s.v.glsl' % shader_path)), ' '.join(open('%s.f.glsl' % shader_path)) ) self.p = [] permutation = self.getPermutation() for i in range(512): self.p.append(permutation[i % len(permutation)]) def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): self.x -= dx * self.zoom; self.y -= dy * self.zoom; def on_mouse_release(self, x, y, button, modifiers): print "x: {}, y: {}, z: {}, zoom: {}, octs: {}, freq: {}".format(self.x, self.y, self.z, self.zoom, self.octives, self.freq) def on_mouse_scroll(self, x, y, scroll_x, scroll_y): self.zoom -= scroll_y * 0.0025; print "x: {}, y: {}, z: {}, zoom: {}, octs: {}, freq: {}".format(self.x, self.y, self.z, self.zoom, self.octives, self.freq) def on_key_release(self, symbol, modifiers): if symbol == pyglet.window.key.F2: self.saveFromShader() elif symbol == pyglet.window.key.Q: self.x += 0.1; elif symbol == pyglet.window.key.A: self.x -= 0.1; elif symbol == pyglet.window.key.W: self.y += 0.1; elif symbol == pyglet.window.key.S: self.y -= 0.1; elif symbol == pyglet.window.key.E: self.z += 0.01; elif symbol == pyglet.window.key.D: self.z -= 0.01; elif symbol == pyglet.window.key.R: self.zoom += 0.0025; elif symbol == pyglet.window.key.F: self.zoom -= 0.0025; elif symbol == pyglet.window.key.T: self.octives += 1; elif symbol == pyglet.window.key.G: self.octives -= 1; elif symbol == pyglet.window.key.Y: self.freq += 0.01; elif symbol == pyglet.window.key.H: self.freq -= 0.01; print "x: {}, y: {}, z: {}, zoom: {}, octs: {}, freq: {}".format(self.x, self.y, self.z, self.zoom, self.octives, self.freq) def saveFromShader(self): a = (GLubyte * (4 * self.w * self.h))(0) glReadPixels(0, 0, self.w, self.h, GL_RGBA, GL_UNSIGNED_BYTE, a) image = pyglet.image.ImageData(self.w, self.h, 'RGBA', a) scriptPath = os.path.dirname(os.path.realpath(__file__)) filePath = scriptPath + "/TESTSAVE_" + time.strftime("%Y%m%d_%H%M%S") + ".png" print "save to {}".format(filePath) image.save(filePath) def getPermutation(self): return [ 151,160,137, 91, 90, 15,131, 13,201, 95, 96, 53,194,233, 7,225, 140, 36,103, 30, 69,142, 8, 99, 37,240, 21, 10, 23,190, 6,148, 247,120,234, 75, 0, 26,197, 62, 94,252,219,203,117, 35, 11, 32, 57,177, 33, 88,237,149, 56, 87,174, 20,125,136,171,168, 68,175, 74,165, 71,134,139, 48, 27,166, 77,146,158,231, 83,111,229,122, 60,211,133,230,220,105, 92, 41, 55, 46,245, 40,244,102,143, 54, 65, 25, 63,161, 1,216, 80, 73,209, 76,132,187,208, 89, 18,169, 200,196,135,130,116,188,159, 86,164,100,109,198,173,186, 3, 64, 52,217,226,250,124,123, 5,202, 38,147,118,126,255, 82, 85,212, 207,206, 59,227, 47, 16, 58, 17,182,189, 28, 42,223,183,170,213, 119,248,152, 2, 44,154,163, 70,221,153,101,155,167, 43,172, 9, 129, 22, 39,253, 19, 98,108,110, 79,113,224,232,178,185,112,104, 218,246, 97,228,251, 34,242,193,238,210,144, 12,191,179,162,241, 81, 51,145,235,249, 14,239,107, 49,192,214, 31,181,199,106,157, 184, 84,204,176,115,121, 50, 45,127, 4,150,254,138,236,205, 93, 222,114, 67, 29, 24, 72,243,141,128,195, 78, 66,215, 61,156,180, ] def on_draw(self): glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(-1., 1., 1., -1., 0., 1.) glMatrixMode(GL_MODELVIEW) glLoadIdentity() self.shader.bind() self.shader.uniformi('p', *self.p) self.shader.uniformf('x', *[self.x]) self.shader.uniformf('y', *[self.y]) self.shader.uniformf('z', *[self.z]) self.shader.uniformf('zoom', *[self.zoom]) self.shader.uniformi('octives', *[self.octives]) self.shader.uniformf('freq', *[self.freq]) glBegin(GL_QUADS) glVertex2i(-1, -1) glTexCoord2i(-2, -2) glVertex2f(1, -1) glTexCoord2i(2, -2) glVertex2i(1, 1) glTexCoord2i(2, 2) glVertex2i(-1, 1) glTexCoord2i(-2, 2) glEnd() self.shader.unbind()
def OnInit(): try: # Start with writing relevant info to the debug dump in case stuff goes # wrong at a later time debugdump.dump.appendGL() debugdump.dump.appendMessage( "GL.VENDOR: " + str(glGetString(GL_VENDOR), encoding='UTF-8')) debugdump.dump.appendMessage( "GL.RENDERER: " + str(glGetString(GL_RENDERER), encoding='UTF-8')) debugdump.dump.appendMessage( "GL.VERSION: " + str(glGetString(GL_VERSION), encoding='UTF-8')) debugdump.dump.appendMessage( "GLSL.VERSION: " + str(Shader.glslVersionStr(), encoding='UTF-8')) except Exception as e: log.error("Failed to write GL debug info to debug dump: %s", format(str(e))) global have_multisample if G.args.get('nomultisampling', False): have_multisample = False else: have_multisample = glInitMultisampleARB() try: # Number of samples is setup in the QGLWidget context nb_samples = glGetInteger(OpenGL.GL.ARB.multisample.GL_SAMPLES_ARB) debugdump.dump.appendMessage( "GL.EXTENSION: GL_ARB_multisample %s (%sx samples)" % ("enabled" if have_multisample else "not available", nb_samples)) except Exception as e: log.error("Failed to write GL debug info to debug dump: %s", format(str(e))) global have_activeTexture have_activeTexture = bool(glActiveTexture) global MAX_TEXTURE_UNITS if have_activeTexture: MAX_TEXTURE_UNITS = glGetInteger(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS) else: MAX_TEXTURE_UNITS = 1 # Set global scene ambient glLightModelfv(GL_LIGHT_MODEL_AMBIENT, A(0.0, 0.0, 0.0, 1.0)) # Lights and materials lightPos = A(-10.99, 20.0, 20.0, 1.0) # Light - Position ambientLight = A(0.0, 0.0, 0.0, 1.0) # Light - Ambient Values diffuseLight = A(1.0, 1.0, 1.0, 1.0) # Light - Diffuse Values specularLight = A(1.0, 1.0, 1.0, 1.0) # Light - Specular Values MatAmb = A(0.11, 0.11, 0.11, 1.0) # Material - Ambient Values MatDif = A(1.0, 1.0, 1.0, 1.0) # Material - Diffuse Values MatSpc = A(0.2, 0.2, 0.2, 1.0) # Material - Specular Values MatShn = A(10.0, ) # Material - Shininess MatEms = A(0.0, 0.0, 0.0, 1.0) # Material - Emission Values glEnable(GL_DEPTH_TEST) # Hidden surface removal # glEnable(GL_CULL_FACE) # Inside face removal # glEnable(GL_ALPHA_TEST) # glAlphaFunc(GL_GREATER, 0.0) glDisable(GL_DITHER) glEnable(GL_LIGHTING) # Enable lighting # TODO set light properties based on selected scene glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight) glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight) glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight) glLightfv(GL_LIGHT0, GL_POSITION, lightPos) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR ) # If we enable this, we have stronger specular highlights glMaterialfv(GL_FRONT, GL_AMBIENT, MatAmb) # Set Material Ambience glMaterialfv(GL_FRONT, GL_DIFFUSE, MatDif) # Set Material Diffuse glMaterialfv(GL_FRONT, GL_SPECULAR, MatSpc) # Set Material Specular glMaterialfv(GL_FRONT, GL_SHININESS, MatShn) # Set Material Shininess glMaterialfv(GL_FRONT, GL_EMISSION, MatEms) # Set Material Emission glEnable(GL_LIGHT0) glEnable(GL_COLOR_MATERIAL ) # Vertex colors affect materials (lighting is enabled) glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE ) # Vertex colors affect ambient and diffuse of material # glEnable(GL_TEXTURE_2D) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) # Activate and specify pointers to vertex and normal array glEnableClientState(GL_NORMAL_ARRAY) glEnableClientState(GL_COLOR_ARRAY) glEnableClientState(GL_VERTEX_ARRAY) if have_multisample: glEnable(GL_MULTISAMPLE) #glSampleCoverage(1.0, GL_FALSE) # TODO probably not needed, is used for GL_SAMPLE_COVERAGE, which we do not use (do not confuse with GL_SAMPLE_ALPHA_TO_COVERAGE) #glSampleCoverageARB(1.0, GL_FALSE) # TODO flip mask each time global TEX_NOT_FOUND TEX_NOT_FOUND = getTexture(NOTFOUND_TEXTURE) if TEX_NOT_FOUND in (None, False): log.error('Unable to load texture %s, this might cause errors.', NOTFOUND_TEXTURE)
def drawMesh(obj): if not obj.visibility: return if G.args.get('fullloggingopengl', False): log.debug("Rendering mesh %s", obj.name) glDepthFunc(GL_LEQUAL) # Transform the current object glPushMatrix() transformObject(obj) glColor3f(1.0, 1.0, 1.0) useShader = obj.shader and obj.solid and not obj.shadeless if not useShader: if obj.isTextured and obj.texture and obj.solid: # Bind texture for fixed function shading if have_activeTexture: glActiveTexture(GL_TEXTURE0) glEnable(GL_TEXTURE_2D) tex = getTexture(obj.texture) if tex not in (False, None): glBindTexture(GL_TEXTURE_2D, tex.textureId) else: glBindTexture(GL_TEXTURE_2D, TEX_NOT_FOUND.textureId) if have_activeTexture: for gl_tex_idx in range(GL_TEXTURE0 + 1, GL_TEXTURE0 + MAX_TEXTURE_UNITS): glActiveTexture(gl_tex_idx) glBindTexture(GL_TEXTURE_2D, 0) glDisable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_1D, 0) glDisable(GL_TEXTURE_1D) else: # Disable all textures (when in fixed function textureless shading mode) for gl_tex_idx in range(GL_TEXTURE0, GL_TEXTURE0 + MAX_TEXTURE_UNITS): if have_activeTexture: glActiveTexture(gl_tex_idx) glBindTexture(GL_TEXTURE_2D, 0) glDisable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_1D, 0) glDisable(GL_TEXTURE_1D) if obj.nTransparentPrimitives: # TODO not needed for alpha-to-coverage rendering (it's face order independent) # TODO for other pipelines/older harware better to statically sort faces of hair meshes around BBox center #obj.sortFaces() pass # Fill the array pointers with object mesh data if obj.hasUVs: glEnableClientState(GL_TEXTURE_COORD_ARRAY) glTexCoordPointer(2, GL_FLOAT, 0, obj.UVs) glEnableClientState(GL_VERTEX_ARRAY) glVertexPointer(3, GL_FLOAT, 0, obj.verts) glEnableClientState(GL_NORMAL_ARRAY) glNormalPointer(GL_FLOAT, 0, obj.norms) glEnableClientState(GL_COLOR_ARRAY) if not useShader and obj.solid: # Vertex colors should be multiplied with the diffuse material value, also for fixed function # (with the exception of wireframe rendering) glColorPointer(4, GL_UNSIGNED_BYTE, 0, obj.color_diff) else: glColorPointer(4, GL_UNSIGNED_BYTE, 0, obj.color) # Disable lighting if the object is shadeless if obj.shadeless: glDisable(GL_LIGHTING) else: glEnable(GL_LIGHTING) if obj.cull: glEnable(GL_CULL_FACE) glCullFace(GL_BACK if obj.cull > 0 else GL_FRONT) else: glDisable(GL_CULL_FACE) if obj.solid: # Set material properties mat = obj.material MatAmb = A(mat.ambientColor.values, 1.0) # Material - Ambient MatDif = A(mat.diffuseColor.values, mat.opacity) # Material - Diffuse MatSpc = A(mat.specularColor.values, 1.0) # Material - Specular MatShn = A(128 * mat.shininess) # Material - Shininess MatEms = A(mat.emissiveColor.values, 1.0) # Material - Emission else: # Wireframe # Set some default material properties MatAmb = A(0.11, 0.11, 0.11, 1.0) # Material - Ambient Values MatDif = A(1.0, 1.0, 1.0, 1.0) # Material - Diffuse Values MatSpc = A(0.2, 0.2, 0.2, 1.0) # Material - Specular Values MatShn = A(10.0, ) # Material - Shininess MatEms = A(0.0, 0.0, 0.0, 1.0) # Material - Emission Values glMaterialfv(GL_FRONT, GL_AMBIENT, MatAmb) # Set Material Ambience glMaterialfv(GL_FRONT, GL_DIFFUSE, MatDif) # Set Material Diffuse glMaterialfv(GL_FRONT, GL_SPECULAR, MatSpc) # Set Material Specular glMaterialfv(GL_FRONT, GL_SHININESS, MatShn) # Set Material Shininess glMaterialfv(GL_FRONT, GL_EMISSION, MatEms) # Set Material Emission if obj.useVertexColors: # Vertex colors affect materials (lighting is enabled) glEnable(GL_COLOR_MATERIAL) # Vertex colors affect diffuse of material glColorMaterial(GL_FRONT, GL_DIFFUSE) else: glDisable(GL_COLOR_MATERIAL) # Enable the shader if the driver supports it and there is a shader assigned if useShader: glUseProgram(obj.shader) # Set custom attributes if obj.shaderObj.requiresVertexTangent(): glVertexAttribPointer(obj.shaderObj.vertexTangentAttrId, 4, GL_FLOAT, GL_FALSE, 0, obj.tangents) glEnableVertexAttribArray(obj.shaderObj.vertexTangentAttrId) # TODO # This should be optimized, since we only need to do it when it's changed # Validation should also only be done when it is set obj.shaderObj.setUniforms(obj.shaderParameters) elif Shader.supported(): glUseProgram(0) # draw the mesh if not obj.solid: # Wireframe drawing glEnable(GL_COLOR_MATERIAL) glDisableClientState(GL_COLOR_ARRAY) glColor3f(0.0, 0.0, 0.0) glDisable(GL_LIGHTING) glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ) # Vertex colors affect ambient and diffuse of material glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glDrawElements(g_primitiveMap[obj.vertsPerPrimitive - 1], obj.primitives.size, GL_UNSIGNED_INT, obj.primitives) glEnableClientState(GL_COLOR_ARRAY) glEnable(GL_LIGHTING) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glEnable(GL_POLYGON_OFFSET_FILL) glPolygonOffset(1.0, 1.0) glDrawElements(g_primitiveMap[obj.vertsPerPrimitive - 1], obj.primitives.size, GL_UNSIGNED_INT, obj.primitives) glDisable(GL_POLYGON_OFFSET_FILL) glDisable(GL_COLOR_MATERIAL) elif obj.nTransparentPrimitives: if have_multisample and obj.alphaToCoverage: # Enable alpha-to-coverage (also called CSAA) # using the multisample buffer for alpha to coverage disables its use for MSAA (anti-aliasing) glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) #glEnable(GL_SAMPLE_ALPHA_TO_ONE) # Enable this if transparent objects are too transparent glDisable(GL_BLEND) # Disable alpha blending else: glDepthMask(GL_FALSE) glEnable(GL_ALPHA_TEST) glAlphaFunc(GL_GREATER, 0.0) glDrawElements(g_primitiveMap[obj.vertsPerPrimitive - 1], obj.primitives.size, GL_UNSIGNED_INT, obj.primitives) glDisable(GL_ALPHA_TEST) if have_multisample and obj.alphaToCoverage: glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE) glEnable(GL_BLEND) else: glDepthMask(GL_TRUE) elif obj.depthless: glDepthMask(GL_FALSE) glDisable(GL_DEPTH_TEST) glDrawElements(g_primitiveMap[obj.vertsPerPrimitive - 1], obj.primitives.size, GL_UNSIGNED_INT, obj.primitives) glEnable(GL_DEPTH_TEST) glDepthMask(GL_TRUE) else: glDrawElements(g_primitiveMap[obj.vertsPerPrimitive - 1], obj.primitives.size, GL_UNSIGNED_INT, obj.primitives) if obj.solid and not obj.nTransparentPrimitives: glDisableClientState(GL_COLOR_ARRAY) for i, (start, count) in enumerate(obj.groups): color = obj.gcolor(i) if color is None or np.all(color[:3] == 255): continue glColor4ub(*color) indices = obj.primitives[start:start + count, :] glDrawElements(g_primitiveMap[obj.vertsPerPrimitive - 1], indices.size, GL_UNSIGNED_INT, indices) glEnableClientState(GL_COLOR_ARRAY) # Disable the shader if the driver supports it and there is a shader assigned if useShader: glUseProgram(0) # Restore state defaults if have_activeTexture: glActiveTexture(GL_TEXTURE0) glDisable(GL_CULL_FACE) glColor3f(1.0, 1.0, 1.0) glColorMaterial(GL_FRONT, GL_DIFFUSE) if obj.useVertexColors: glDisable(GL_COLOR_MATERIAL) # Disable custom vertex arrays again if useShader and obj.shaderObj.requiresVertexTangent(): glDisableVertexAttribArray(obj.shaderObj.vertexTangentAttrId) # Re-enable lighting if it was disabled glEnable(GL_LIGHTING) glColorMaterial(GL_FRONT, GL_DIFFUSE) if obj.isTextured and obj.texture and obj.solid: glDisable(GL_TEXTURE_2D) if obj.hasUVs: glDisableClientState(GL_TEXTURE_COORD_ARRAY) glPopMatrix()
shader = Shader( ''' #version 140 uniform mat4 ModelViewProjMat; in vec4 in_Position; in vec3 in_Normal; out vec3 v_Normal; void main(void) { gl_Position = ModelViewProjMat * in_Position; v_Normal = in_Normal; } ''', ''' #version 140 precision highp float; uniform vec4 DiffuseColor; in vec3 v_Normal; out vec4 out_Color; const vec3 lightDir = vec3(0.1,-0.8,0.4); void main(void) { float NdotL = dot(normalize(v_Normal), lightDir); vec3 lit = DiffuseColor.rgb * clamp(NdotL, 0.2, 1.0); out_Color = vec4(lit.rgb, DiffuseColor.a); } ''')
class Wythoff(pyglet.window.Window): """ User interface: 1. use mouse click to play with the ui. 2. press `Enter` to save screenshots. 3. press `Ctrl+v` to start saving video and `Ctrl+v` again to stop. 4. press `Esc` to exit. """ def __init__(self, width, height, aa=1, video_rate=16, sample_rate=4): """ :param width and height: size of the window in pixels. :param aa: antialiasing level, a higher value will give better result but also slow down the animation. (aa=2 is recommended) """ pyglet.window.Window.__init__( self, width, height, caption="Wythoff Explorer", resizable=True, visible=False, vsync=False, ) self.video_rate = video_rate self.video_on = False self.sample_rate = sample_rate self._start_time = time.clock() self._frame_count = 0 # count number of frames rendered so far self._speed = 4 # control speed of the animation self.aa = aa # shader A draws the UI self.shaderA = Shader( ["./glsl/wythoff.vert"], ["./glsl/common.frag", "./glsl/BufferA.frag"] ) # shadwr B draws the polyhedra self.shaderB = Shader( ["./glsl/wythoff.vert"], ["./glsl/common.frag", "./glsl/BufferB.frag"] ) # shader C puts them together self.shaderC = Shader( ["./glsl/wythoff.vert"], ["./glsl/common.frag", "./glsl/main.frag"] ) self.font_texture = create_image_texture(FONT_TEXTURE) self.iChannel0 = pyglet.image.Texture.create_for_size( gl.GL_TEXTURE_2D, width, height, gl.GL_RGBA32F_ARB ) self.iChannel1 = pyglet.image.Texture.create_for_size( gl.GL_TEXTURE_2D, width, height, gl.GL_RGBA32F_ARB ) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(self.iChannel0.target, self.iChannel0.id) gl.glActiveTexture(gl.GL_TEXTURE1) gl.glBindTexture(self.iChannel1.target, self.iChannel1.id) gl.glActiveTexture(gl.GL_TEXTURE2) gl.glBindTexture(gl.GL_TEXTURE_2D, self.font_texture) # frame buffer A renders the UI to texture iChannel0 with FrameBuffer() as self.bufferA: self.bufferA.attach_texture(self.iChannel0) # frame buffer B render the polyhedra to texture iChannel1 with FrameBuffer() as self.bufferB: self.bufferB.attach_texture(self.iChannel1) # initialize the shaders with self.shaderA: self.shaderA.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shaderA.uniformf("iResolution", width, height, 0.0) self.shaderA.uniformf("iTime", 0.0) self.shaderA.uniformf("iMouse", 0.0, 0.0, 0.0, 0.0) self.shaderA.uniformi("iChannel0", 0) self.shaderA.uniformi("iFrame", 0) with self.shaderB: self.shaderB.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shaderB.uniformf("iResolution", width, height, 0.0) self.shaderB.uniformf("iTime", 0.0) self.shaderB.uniformf("iMouse", 0.0, 0.0, 0.0, 0.0) self.shaderB.uniformi("iChannel0", 0) self.shaderB.uniformi("AA", self.aa) with self.shaderC: self.shaderC.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shaderC.uniformf("iResolution", width, height, 0.0) self.shaderC.uniformf("iTime", 0.0) self.shaderC.uniformf("iMouse", 0.0, 0.0, 0.0, 0.0) self.shaderC.uniformi("iChannel0", 0) self.shaderC.uniformi("iChannel1", 1) self.shaderC.uniformi("iTexture", 2) def on_draw(self): gl.glClearColor(0, 0, 0, 0) self.clear() gl.glViewport(0, 0, self.width, self.height) now = time.clock() - self._start_time now *= self._speed with self.bufferA: with self.shaderA: self.shaderA.uniformf("iTime", now) self.shaderA.uniformi("iFrame", self._frame_count) gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) with self.bufferB: with self.shaderB: self.shaderB.uniformf("iTime", now) gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) with self.shaderC: self.shaderC.uniformf("iTime", now) gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) if self.video_on and (self._frame_count % self.sample_rate == 0): self.write_video_frame() self._frame_count += 1 def on_key_press(self, symbol, modifiers): """ Keyboard interface. """ if symbol == key.ENTER: self.save_screenshot() if symbol == key.ESCAPE: pyglet.app.exit() if symbol == key.V and (modifiers & key.LCTRL): self.switch_video() def on_mouse_press(self, x, y, button, modifiers): if button & pyglet.window.mouse.LEFT: with self.shaderA: self.shaderA.uniformf("iMouse", x, y, x, y) def on_mouse_release(self, x, y, button, modifiers): """ Don't forget reset 'iMouse' when mouse is released. """ with self.shaderA: self.shaderA.uniformf("iMouse", 0, 0, 0, 0) def on_mouse_drag(self, x, y, dx, dy, button, modifiers): if button & pyglet.window.mouse.LEFT: with self.shaderA: x += dx y += dy x = max(min(x, self.width), 0) y = max(min(y, self.height), 0) self.shaderA.uniformf("iMouse", x, y, x, y) def save_screenshot(self): image_buffer = pyglet.image.get_buffer_manager().get_color_buffer() image_buffer.save("screenshot.png") def switch_video(self): self.video_on = not self.video_on if self.video_on: self.ffmpeg_pipe = self.create_new_pipe() print("> Writing to video...\n") else: self.ffmpeg_pipe.close() print("> The video is closed.\n") def write_video_frame(self): data = ( pyglet.image.get_buffer_manager() .get_color_buffer() .get_image_data() .get_data("RGBA", -4 * self.width) ) self.ffmpeg_pipe.write(data) def create_new_pipe(self): ffmpeg = subprocess.Popen( ( FFMPEG_EXE, "-threads", "0", "-loglevel", "panic", "-r", "%d" % self.video_rate, "-f", "rawvideo", "-pix_fmt", "rgba", "-s", "%dx%d" % (self.width, self.height), "-i", "-", "-c:v", "libx264", "-crf", "20", "-y", "test.mp4", ), stdin=subprocess.PIPE, ) return ffmpeg.stdin def run(self, fps=None): self.set_visible(True) if fps is None: pyglet.clock.schedule(lambda dt: None) else: pyglet.clock.schedule_interval(lambda dt: None, 1.0 / fps) pyglet.app.run()
def main(): glfw.init() glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) window = glfw.create_window(width, height, "LearnOpenGL", None, None) if not window: print("Window Creation failed!") glfw.terminate() glfw.make_context_current(window) glfw.set_window_size_callback(window, on_resize) gl.glEnable(gl.GL_DEPTH_TEST) shader = Shader(CURDIR / 'shaders/6.1.coordinate_systems.vs', CURDIR / 'shaders/6.1.coordinate_systems.fs') vertices = [ # positions tex_coords -0.5, -0.5, -0.5, 0.0, 0.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5, -0.5, 1.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 0.0, -0.5, -0.5, 0.5, 0.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 1.0, -0.5, 0.5, 0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, -0.5, 1.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, 0.5, 0.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 1.0, 1.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, 0.5, 0.0, 0.0, -0.5, 0.5, -0.5, 0.0, 1.0 ] vertices = (c_float * len(vertices))(*vertices) cube_positions = [(0.0, 0.0, 0.0), (2.0, 5.0, -15.0), (-1.5, -2.2, -2.5), (-3.8, -2.0, -12.3), (2.4, -0.4, -3.5), (-1.7, 3.0, -7.5), (1.3, -2.0, -2.5), (1.5, 2.0, -2.5), (1.5, 0.2, -1.5), (-1.3, 1.0, -1.5)] vao = gl.glGenVertexArrays(1) gl.glBindVertexArray(vao) vbo = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(0)) gl.glEnableVertexAttribArray(0) gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) gl.glEnableVertexAttribArray(1) # -- load texture 1 texture1 = gl.glGenTextures(1) gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) # -- texture wrapping gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) # -- texture filterting gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) gl.glGenerateMipmap(gl.GL_TEXTURE_2D) # -- load texture 2 texture2 = gl.glGenTextures(1) gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) # -- texture wrapping gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) # -- texture filterting gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) img = Image.open(Tex('awesomeface.png')) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) gl.glGenerateMipmap(gl.GL_TEXTURE_2D) shader.use() shader.set_int("texture1", 0) shader.set_int("texture2", 1) while not glfw.window_should_close(window): process_input(window) gl.glClearColor(.2, .3, .3, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) gl.glActiveTexture(gl.GL_TEXTURE1) gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) shader.use() view = Matrix44.from_translation([0, 0, -3]) projection = Matrix44.perspective_projection(45, width / height, 0.1, 100.0) shader.set_mat4('view', view) shader.set_mat4('projection', projection) gl.glBindVertexArray(vao) for idx, position in enumerate(cube_positions): angle = math.radians(20.0 * idx) if idx % 3 == 0: angle = glfw.get_time() rotation = matrix44.create_from_axis_rotation([1.0, 0.3, 0.5], angle) translation = Matrix44.from_translation(position) model = translation * rotation shader.set_mat4('model', model) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 36) glfw.poll_events() glfw.swap_buffers(window) gl.glDeleteVertexArrays(1, id(vao)) gl.glDeleteBuffers(1, id(vbo)) glfw.terminate()