From 8187c58845facae68c29eb0ec480d7cf957abc97 Mon Sep 17 00:00:00 2001 From: Szabolcs Dombi Date: Mon, 29 Jan 2024 23:47:24 +0200 Subject: [PATCH] basic examples --- examples/advanced/grass.py | 139 ------------------ .../game_of_life.py} | 30 ++-- examples/basic/grass.py | 132 +++++++++++++++++ examples/{advanced => basic}/viewports.py | 0 .../{advanced => basic}/wireframe_terrain.py | 0 examples/{advanced => basic}/zengl_logo.py | 0 6 files changed, 153 insertions(+), 148 deletions(-) delete mode 100644 examples/advanced/grass.py rename examples/{advanced/conways_game_of_life.py => basic/game_of_life.py} (72%) create mode 100644 examples/basic/grass.py rename examples/{advanced => basic}/viewports.py (100%) rename examples/{advanced => basic}/wireframe_terrain.py (100%) rename examples/{advanced => basic}/zengl_logo.py (100%) diff --git a/examples/advanced/grass.py b/examples/advanced/grass.py deleted file mode 100644 index 87c3f5ca..00000000 --- a/examples/advanced/grass.py +++ /dev/null @@ -1,139 +0,0 @@ -import math - -import glwindow -import zengl - - -def grass_mesh(): - verts = [] - for i in range(7): - u = i / 7 - v = math.sin(u * u * (math.pi - 1.0) + 1.0) - verts.append((-v * 0.03, u * u * 0.2, u)) - verts.append((v * 0.03, u * u * 0.2, u)) - verts.append((0.0, 0.2, 1.0)) - verts = ",".join("vec3(%.8f, %.8f, %.8f)" % x for x in verts) - return f"vec3 grass[15] = vec3[]({verts});" - - -class Grass: - def __init__(self, size, count, samples=4): - self.ctx = zengl.context() - self.image = self.ctx.image(size, "rgba8unorm", samples=samples) - self.depth = self.ctx.image(size, "depth24plus", samples=samples) - self.output = self.image if self.image.samples == 1 else self.ctx.image(size, "rgba8unorm") - - self.ubo_data = bytearray(64) - self.uniform_buffer = self.ctx.buffer(self.ubo_data, uniform=True) - self.pipeline = self.ctx.pipeline( - vertex_shader=""" - #version 300 es - precision highp float; - - #include "N" - #include "grass" - - vec4 hash41(float p) { - vec4 p4 = fract(vec4(p) * vec4(0.1031, 0.1030, 0.0973, 0.1099)); - p4 += dot(p4, p4.wzxy + 33.33); - return fract((p4.xxyz + p4.yzzw) * p4.zywx); - } - - float hash11(float p) { - p = fract(p * 0.1031); - p *= p + 33.33; - p *= p + p; - return fract(p); - } - - layout (std140) uniform Common { - mat4 mvp; - }; - - out vec2 v_data; - - void main() { - vec3 v = grass[gl_VertexID]; - vec4 data = hash41(float(gl_InstanceID)); - vec2 cell = vec2(float(gl_InstanceID % N), float(gl_InstanceID / N)); - float height = (sin(cell.x * 0.1) + cos(cell.y * 0.1)) * 0.2; - float scale = 0.9 + hash11(float(gl_InstanceID)) * 0.2; - data.xy = (data.xy + cell - float(N / 2)) * 0.1; - data.z *= 6.283184; - vec3 vert = vec3( - data.x + cos(data.z) * v.x + sin(data.z) * v.y, - data.y + cos(data.z) * v.y - sin(data.z) * v.x, - height + v.z - ); - vert *= scale; - gl_Position = mvp * vec4(vert, 1.0); - v_data = vec2(data.w, v.z); - } - """, - fragment_shader=""" - #version 300 es - precision highp float; - - in vec2 v_data; - - layout (location = 0) out vec4 out_color; - - void main() { - vec3 yl = vec3(0.63, 1.0, 0.3); - vec3 gn = vec3(0.15, 0.83, 0.3); - out_color = vec4((yl + (gn - yl) * v_data.x) * v_data.y, 1.0); - } - """, - includes={ - "N": f"const int N = {count};", - "grass": grass_mesh(), - }, - layout=[ - { - "name": "Common", - "binding": 0, - }, - ], - resources=[ - { - "type": "uniform_buffer", - "binding": 0, - "buffer": self.uniform_buffer, - }, - ], - framebuffer=[self.image, self.depth], - topology="triangle_strip", - instance_count=count * count, - vertex_count=15, - ) - - self.aspect = size[0] / size[1] - self.time = 0.0 - - def render(self): - self.time += 1.0 / 60.0 - eye = (math.cos(self.time * 0.2) * 12.0, math.sin(self.time * 0.2) * 12.0, 4.0) - self.ubo_data[:] = zengl.camera(eye, (0.0, 0.0, 0.0), aspect=self.aspect, fov=45.0) - self.uniform_buffer.write(self.ubo_data) - self.image.clear() - self.depth.clear() - self.pipeline.render() - if self.image != self.output: - self.image.blit(self.output) - - -class App: - def __init__(self): - self.wnd = glwindow.get_window() - self.ctx = zengl.context() - self.scene = Grass(self.wnd.size, 200) - - def update(self): - self.ctx.new_frame() - self.scene.render() - self.scene.output.blit() - self.ctx.end_frame() - - -if __name__ == "__main__": - glwindow.run(App) diff --git a/examples/advanced/conways_game_of_life.py b/examples/basic/game_of_life.py similarity index 72% rename from examples/advanced/conways_game_of_life.py rename to examples/basic/game_of_life.py index 57e7d629..ff7ba5fa 100644 --- a/examples/advanced/conways_game_of_life.py +++ b/examples/basic/game_of_life.py @@ -1,18 +1,20 @@ -import numpy as np +import os + +import pygame import zengl -from window import Window +pygame.init() +pygame.display.set_mode((800, 800), flags=pygame.OPENGL | pygame.DOUBLEBUF, vsync=True) -window = Window() -width, height = window.size ctx = zengl.context() -image = ctx.image(window.size, 'rgba8unorm') -temp = ctx.image(window.size, 'rgba8unorm') +size = pygame.display.get_window_size() +image = ctx.image(size, 'rgba8unorm') +temp = ctx.image(size, 'rgba8unorm') scene = ctx.pipeline( includes={ - 'size': f'ivec2 SIZE = ivec2({width}, {height});', + 'size': f'ivec2 SIZE = ivec2({size[0]}, {size[1]});', }, vertex_shader=''' #version 300 es @@ -31,6 +33,7 @@ fragment_shader=''' #version 300 es precision highp float; + precision highp sampler2D; uniform sampler2D Texture; @@ -72,11 +75,20 @@ vertex_count=3, ) -image.write((np.random.randint(0, 2, width * height, 'u1') * 255).repeat(4)) +image.write(os.urandom(size[0] * size[1] * 4)) + +while True: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + quit() + + now = pygame.time.get_ticks() / 1000.0 -while window.update(): ctx.new_frame() image.blit(temp) scene.render() temp.blit() ctx.end_frame() + + pygame.display.flip() diff --git a/examples/basic/grass.py b/examples/basic/grass.py new file mode 100644 index 00000000..397c76c2 --- /dev/null +++ b/examples/basic/grass.py @@ -0,0 +1,132 @@ +import math + +import pygame +import zengl + +pygame.init() +pygame.display.set_mode((1280, 720), flags=pygame.OPENGL | pygame.DOUBLEBUF, vsync=True) + +ctx = zengl.context() + + +def grass_mesh(): + verts = [] + for i in range(7): + u = i / 7 + v = math.sin(u * u * (math.pi - 1.0) + 1.0) + verts.append((-v * 0.03, u * u * 0.2, u)) + verts.append((v * 0.03, u * u * 0.2, u)) + verts.append((0.0, 0.2, 1.0)) + verts = ','.join('vec3(%.8f, %.8f, %.8f)' % x for x in verts) + return f'vec3 grass[15] = vec3[]({verts});' + + +size = pygame.display.get_window_size() +image = ctx.image(size, 'rgba8unorm', samples=4) +depth = ctx.image(size, 'depth24plus', samples=4) + +uniform_buffer = ctx.buffer(size=64, uniform=True) + +count = 200 + +pipeline = ctx.pipeline( + vertex_shader=''' + #version 300 es + precision highp float; + + #include "N" + #include "grass" + + vec4 hash41(float p) { + vec4 p4 = fract(vec4(p) * vec4(0.1031, 0.1030, 0.0973, 0.1099)); + p4 += dot(p4, p4.wzxy + 33.33); + return fract((p4.xxyz + p4.yzzw) * p4.zywx); + } + + float hash11(float p) { + p = fract(p * 0.1031); + p *= p + 33.33; + p *= p + p; + return fract(p); + } + + layout (std140) uniform Common { + mat4 mvp; + }; + + out vec2 v_data; + + void main() { + vec3 v = grass[gl_VertexID]; + vec4 data = hash41(float(gl_InstanceID)); + vec2 cell = vec2(float(gl_InstanceID % N), float(gl_InstanceID / N)); + float height = (sin(cell.x * 0.1) + cos(cell.y * 0.1)) * 0.2; + float scale = 0.9 + hash11(float(gl_InstanceID)) * 0.2; + data.xy = (data.xy + cell - float(N / 2)) * 0.1; + data.z *= 6.283184; + vec3 vert = vec3( + data.x + cos(data.z) * v.x + sin(data.z) * v.y, + data.y + cos(data.z) * v.y - sin(data.z) * v.x, + height + v.z + ); + vert *= scale; + gl_Position = mvp * vec4(vert, 1.0); + v_data = vec2(data.w, v.z); + } + ''', + fragment_shader=''' + #version 300 es + precision highp float; + + in vec2 v_data; + + layout (location = 0) out vec4 out_color; + + void main() { + vec3 yl = vec3(0.63, 1.0, 0.3); + vec3 gn = vec3(0.15, 0.83, 0.3); + out_color = vec4((yl + (gn - yl) * v_data.x) * v_data.y, 1.0); + } + ''', + includes={ + 'N': f'const int N = {count};', + 'grass': grass_mesh(), + }, + layout=[ + { + 'name': 'Common', + 'binding': 0, + }, + ], + resources=[ + { + 'type': 'uniform_buffer', + 'binding': 0, + 'buffer': uniform_buffer, + }, + ], + framebuffer=[image, depth], + topology='triangle_strip', + instance_count=count * count, + vertex_count=15, +) + + +while True: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + quit() + + now = pygame.time.get_ticks() / 1000.0 + + ctx.new_frame() + eye = (math.cos(now * 0.2) * 12.0, math.sin(now * 0.2) * 12.0, 4.0) + uniform_buffer.write(zengl.camera(eye, (0.0, 0.0, 0.0), aspect=1.777, fov=45.0)) + image.clear() + depth.clear() + pipeline.render() + image.blit() + ctx.end_frame() + + pygame.display.flip() diff --git a/examples/advanced/viewports.py b/examples/basic/viewports.py similarity index 100% rename from examples/advanced/viewports.py rename to examples/basic/viewports.py diff --git a/examples/advanced/wireframe_terrain.py b/examples/basic/wireframe_terrain.py similarity index 100% rename from examples/advanced/wireframe_terrain.py rename to examples/basic/wireframe_terrain.py diff --git a/examples/advanced/zengl_logo.py b/examples/basic/zengl_logo.py similarity index 100% rename from examples/advanced/zengl_logo.py rename to examples/basic/zengl_logo.py