From 822d85c78cd5b2b9d12a12a4bd18a5ab9b5ba78a Mon Sep 17 00:00:00 2001 From: Pebaz Date: Tue, 18 Feb 2020 16:40:52 -0500 Subject: [PATCH 1/2] Add camera example --- examples/blank.py | 30 ++++++++ examples/camera.py | 104 ++++++++++++++++++++++++++++ examples/camera.py.requirements.txt | 1 + 3 files changed, 135 insertions(+) create mode 100644 examples/blank.py create mode 100644 examples/camera.py create mode 100644 examples/camera.py.requirements.txt diff --git a/examples/blank.py b/examples/blank.py new file mode 100644 index 0000000..16cb8da --- /dev/null +++ b/examples/blank.py @@ -0,0 +1,30 @@ +from raylib.dynamic import raylib as rl, ffi +from raylib.colors import * +from camera import CameraFly + +rl.SetTraceLogLevel(rl.LOG_ERROR) +rl.SetConfigFlags(rl.FLAG_WINDOW_RESIZABLE) +rl.InitWindow(512, 256, b'Test') +rl.SetTargetFPS(60) +rl.DisableCursor() + +flycam = CameraFly() + + +while not rl.WindowShouldClose(): + flycam.update() + cam = flycam.get_camera() + + rl.BeginDrawing() + rl.ClearBackground((0, 200, 255, 255)) + rl.BeginMode3D(cam[0]) + + # NOTE(pebaz): For whatever reason, this can solve a percentage of artifacts + rl.DrawGizmo([100000000, 100000000, 100000000]) + + rl.DrawGrid(32, 1) + + rl.EndMode3D() + rl.EndDrawing() + +rl.CloseWindow() diff --git a/examples/camera.py b/examples/camera.py new file mode 100644 index 0000000..7352e1b --- /dev/null +++ b/examples/camera.py @@ -0,0 +1,104 @@ +from math import sin, cos +import glm +from raylib.dynamic import raylib as rl, ffi + + +class CameraFly: + def __init__(self, x=0, y=0, z=0, fov=70.0): + self.last_mouse = ffi.new("struct Vector2 *", [0, 0]) + self.fov = fov + self.yaw = -46.33 + self.pitch = 0.0 + self.front = glm.vec3() + self.up = glm.vec3() + self.right = glm.vec3() + self.position = glm.vec3(x, y, z) + self.world_up = glm.vec3(0, 1, 0) + self.fps_facing = glm.vec3() + self.movement_speed = 10 + self.mouse_sensitivity = 0.002 + self.last_time = rl.GetFrameTime() + + def get_camera(self): + return ffi.new( + "struct Camera3D *", + [ + self.get_ray_front(), + self.get_ray_position(), + self.get_ray_up(), + self.fov, + rl.CAMERA_PERSPECTIVE + ] + ) + + def get_ray_front(self): + return list(self.position + self.front) + + def get_ray_up(self): + return list(self.up) + + def get_ray_position(self): + return list(self.position) + + def update_keyboard(self): + boost = 4 if rl.IsKeyDown(rl.KEY_LEFT_SHIFT) else 1 + velocity = self.movement_speed * boost * rl.GetFrameTime() + + if rl.IsKeyDown(rl.KEY_W): + self.position = self.position - self.fps_facing * velocity + + if rl.IsKeyDown(rl.KEY_S): + self.position = self.position + self.fps_facing * velocity + + if rl.IsKeyDown(rl.KEY_D): + dirr = glm.normalize(glm.cross(self.fps_facing, self.world_up)) + self.position = self.position - dirr * velocity + + if rl.IsKeyDown(rl.KEY_A): + dirr = glm.normalize(glm.cross(self.fps_facing, self.world_up)) + self.position = self.position + dirr * velocity + + if rl.IsKeyDown(rl.KEY_SPACE): + self.position = self.position + self.world_up * velocity + + if rl.IsKeyDown(rl.KEY_LEFT_CONTROL) or rl.IsKeyDown(rl.KEY_RIGHT_CONTROL): + self.position = self.position - self.world_up * velocity + + def update_mouse(self): + pos = rl.GetMousePosition() + width = rl.GetScreenWidth() + height = rl.GetScreenHeight() + + mouse_coordinates = ffi.new("struct Vector2 *", [ + pos.x - self.last_mouse.x, + pos.y - self.last_mouse.y + ]) + + self.yaw += mouse_coordinates.x * self.mouse_sensitivity + self.pitch += (mouse_coordinates.y * self.mouse_sensitivity) + self.pitch = min(self.pitch, 1.5) + self.pitch = max(self.pitch, -1.5) + self.last_mouse = rl.GetMousePosition() + + def update(self): + # NOTE(pebaz): Comment out these lines to control them in a game loop + self.update_keyboard() + self.update_mouse() + + # Update all camera vectors to reflect changes + self.fps_facing = glm.vec3( + cos((self.yaw)) * cos((0)), + sin((0)), + sin((self.yaw)) * cos((0)) + ) + self.fps_facing = glm.normalize(self.fps_facing) + + front = glm.vec3( + cos((self.yaw)) * cos((self.pitch)), + sin((self.pitch)), + sin((self.yaw)) * cos((self.pitch)) + ) + + self.front = glm.normalize(front) + self.right = glm.normalize(glm.cross(self.front, self.world_up)) + self.up = glm.normalize(glm.cross(self.right, self.front)) diff --git a/examples/camera.py.requirements.txt b/examples/camera.py.requirements.txt new file mode 100644 index 0000000..7e01fea --- /dev/null +++ b/examples/camera.py.requirements.txt @@ -0,0 +1 @@ +glm \ No newline at end of file From 40387cefeda8a35e1e7a4608093d2c92bea8f3f6 Mon Sep 17 00:00:00 2001 From: Pebaz Date: Tue, 18 Feb 2020 16:53:12 -0500 Subject: [PATCH 2/2] added rendertexture example --- examples/camera.py.requirements.txt | 2 +- examples/flow-field.py | 140 ++++++++++++++++++++++++ examples/flow-field.py.requirements.txt | 1 + 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 examples/flow-field.py create mode 100644 examples/flow-field.py.requirements.txt diff --git a/examples/camera.py.requirements.txt b/examples/camera.py.requirements.txt index 7e01fea..0513c36 100644 --- a/examples/camera.py.requirements.txt +++ b/examples/camera.py.requirements.txt @@ -1 +1 @@ -glm \ No newline at end of file +pyglm \ No newline at end of file diff --git a/examples/flow-field.py b/examples/flow-field.py new file mode 100644 index 0000000..eff1588 --- /dev/null +++ b/examples/flow-field.py @@ -0,0 +1,140 @@ +""" +RenderTexture example + +Run with: + +python3 flow-field + flow-field bees +""" + +import sys, math, time, random +import glm +from raylib.dynamic import raylib as rl, ffi +from raylib.colors import * + +CTM = lambda: round(time.time() * 1000) + + + +BEES = bool(sys.argv[1:]) + + + + +rl.SetTraceLogLevel(rl.LOG_ERROR) +rl.SetConfigFlags(rl.FLAG_WINDOW_RESIZABLE) +rl.InitWindow(512, 512, b'Friendly Bees') +rl.SetTargetFPS(60) +#rl.DisableCursor() + +canvas = rl.LoadRenderTexture(rl.GetScreenWidth(), rl.GetScreenHeight()) +rl.SetTextureWrap(canvas.texture, rl.WRAP_MIRROR_REPEAT) + +def random_point_in_circle(center, radius): + a = random.random() * 2 * math.pi + r = radius * math.sqrt(random.random()) + x = r * math.cos(a) + z = r * math.sin(a) + return glm.vec3( + x + center.x, + center.y, + z + center.z + ) + +class Particle: + def __init__(self, pos): + self.pos = pos + self.scl = 16 if BEES else 2 + self.ang = math.radians(random.randint(0, 359)) + self.spd = random.randint(4, 10) + self.start = CTM() + self.clr = [255, 200, 0, 155] if BEES else [*(random.randint(55, 255) for i in range(3)), 55] + self.mem = (0, 0) + self.pre = glm.vec2(pos) + + def process(self): + if CTM() > self.start + 50: + self.ang = math.radians(glm.simplex(self.pos) * 360.0) + self.start = CTM() + + self.rot = glm.vec2( + glm.vec4(1) * glm.rotate(glm.mat4(), self.ang, [0, 0, 1]) + ) + self.pre = int(self.pos.x), int(self.pos.y) + self.pos += self.rot * rl.GetFrameTime() * 64 + rl.DrawLine( + int(self.pos.x), int(self.pos.y), *self.pre, self.clr + ) + + if self.pos.x < 0: self.pos.x = rl.GetScreenWidth() - 1 + if self.pos.y < 0: self.pos.y = rl.GetScreenHeight() - 1 + if self.pos.x >= rl.GetScreenWidth(): self.pos.x = 0 + if self.pos.y >= rl.GetScreenHeight(): self.pos.y = 0 + + hlf = self.scl // 2 + self.mem = int(self.pos.x) - hlf, int(self.pos.y) - hlf + rl.DrawRectangle( + *self.mem, + self.scl if not BEES else hlf, + self.scl, + self.clr + ) + if BEES: + rl.DrawRectangle( + self.mem[0] + hlf, self.mem[1], + hlf, + self.scl, + [0, 0, 0, 55] + ) + +dims = rl.GetScreenWidth(), rl.GetScreenHeight() +ini = False +parts = [ + Particle(glm.vec2(random_point_in_circle( + glm.vec3( + rl.GetScreenWidth() / 2, + rl.GetScreenHeight() / 2, + 0 + ), + 64 + ))) + for i in range(125) +] +while not rl.WindowShouldClose(): + if (rl.GetScreenWidth(), rl.GetScreenHeight()) != dims: + canvas = rl.LoadRenderTexture(rl.GetScreenWidth(), rl.GetScreenHeight()) + rl.SetTextureWrap(canvas.texture, rl.WRAP_MIRROR_REPEAT) + ini = False + dims = rl.GetScreenWidth(), rl.GetScreenHeight() + + rl.BeginDrawing() + + rl.BeginTextureMode(canvas) + if not ini: + rl.ClearBackground([200, 200, 0, 255] if BEES else WHITE) + if BEES: + rl.DrawRectangle( + 0, 0, + dims[0], dims[1] // 2, + (0, 200, 255, 255) + ) + rl.DrawCircle( + dims[0] - 72, 72, 32, [255, 200, 0, 255] + ) + else: + ini = True + + for part in parts: part.process() + + rl.EndTextureMode() + + tex = canvas.texture + rl.DrawTexturePro( + tex, [0.0, 0.0, tex.width, -tex.height], + [0, 0, tex.width, tex.height], + [0, 0], 0.0, WHITE + ) + + rl.EndDrawing() + +rl.CloseWindow() diff --git a/examples/flow-field.py.requirements.txt b/examples/flow-field.py.requirements.txt new file mode 100644 index 0000000..0513c36 --- /dev/null +++ b/examples/flow-field.py.requirements.txt @@ -0,0 +1 @@ +pyglm \ No newline at end of file