summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/teleia/src/assets/shaders/bitmap/vert.glsl9
-rw-r--r--crates/teleia/src/font.rs21
-rw-r--r--crates/teleia/src/renderer.rs2
-rw-r--r--crates/teleia/src/script.rs87
-rw-r--r--crates/teleia/src/shader.rs11
-rw-r--r--crates/teleia/src/state.rs19
6 files changed, 131 insertions, 18 deletions
diff --git a/crates/teleia/src/assets/shaders/bitmap/vert.glsl b/crates/teleia/src/assets/shaders/bitmap/vert.glsl
index 192d4b0..6a9870a 100644
--- a/crates/teleia/src/assets/shaders/bitmap/vert.glsl
+++ b/crates/teleia/src/assets/shaders/bitmap/vert.glsl
@@ -1,11 +1,13 @@
#version 300 es
precision highp float;
-in vec2 vertex;
+in vec3 vertex;
in vec2 texcoord;
in vec3 color;
-uniform mat4 transform;
+uniform mat4 view;
+uniform mat4 position;
+uniform mat4 projection;
out vec2 vertex_texcoord;
out vec3 vertex_color;
@@ -13,5 +15,6 @@ out vec3 vertex_color;
void main() {
vertex_texcoord = texcoord;
vertex_color = color;
- gl_Position = transform * vec4(vertex, 0.0, 1.0);
+ vec3 pos = (position * vec4(vertex, 1.0)).xyz;
+ gl_Position = projection * view * vec4(pos, 1.0);
}
diff --git a/crates/teleia/src/font.rs b/crates/teleia/src/font.rs
index 2fe7423..2e90571 100644
--- a/crates/teleia/src/font.rs
+++ b/crates/teleia/src/font.rs
@@ -6,6 +6,15 @@ pub struct BitmapParams<'color> {
pub scale: glam::Vec2,
pub offset: glam::Vec2,
}
+impl<'color> Default for BitmapParams<'color> {
+ fn default() -> Self {
+ Self {
+ color: &[],
+ scale: glam::Vec2::ONE,
+ offset: glam::Vec2::ZERO,
+ }
+ }
+}
pub struct Bitmap {
pub char_width: i32,
pub char_height: i32,
@@ -170,4 +179,16 @@ impl Bitmap {
) {
self.render_text_helper(ctx, st, text, &[]);
}
+
+ pub fn render_text_at(&self,
+ ctx: &context::Context, st: &mut state::State,
+ pos: glam::Vec2, text: &str,
+ params: BitmapParams,
+ ) {
+ st.bind_2d(ctx, &st.shader_text_bitmap);
+ let dims = glam::Vec2::new(self.char_width as f32, self.char_height as f32);
+ let fpos = pos + glam::Vec2::new(-dims.x / 2.0, dims.y / 2.0);
+ st.shader_text_bitmap.set_position_text_bitmap(ctx, st, &self, &fpos);
+ self.render_text_parameterized(ctx, st, text, params);
+ }
}
diff --git a/crates/teleia/src/renderer.rs b/crates/teleia/src/renderer.rs
index 19dd8a0..5242eac 100644
--- a/crates/teleia/src/renderer.rs
+++ b/crates/teleia/src/renderer.rs
@@ -280,7 +280,7 @@ impl<A: Assets> Renderer<A> {
self.texture = BoundTexture::None;
self.bind_uber_2d(ctx, st, UberFlags::TEXTURE_COLOR | UberFlags::VERTEX_COLOR | UberFlags::FLIP_TEXTURE);
let dims = glam::Vec2::new(st.font_default.char_width as f32, st.font_default.char_height as f32);
- let fpos = (pos + glam::Vec2::new(-dims.x / 2.0, st.font_default.char_height as f32 / 2.0));
+ let fpos = pos + glam::Vec2::new(-dims.x / 2.0, dims.y / 2.0);
self.set_position_2d(ctx, st, fpos, dims);
st.font_default.render_text(ctx, st, s);
}
diff --git a/crates/teleia/src/script.rs b/crates/teleia/src/script.rs
index 8e27f31..8eaf85a 100644
--- a/crates/teleia/src/script.rs
+++ b/crates/teleia/src/script.rs
@@ -15,6 +15,19 @@ impl std::fmt::Display for Error {
}
impl std::error::Error for Error {}
+type PitNativeFunc = extern "C" fn(rt: *mut PitRuntime, args: PitValue, data: *mut PitNativeFuncData) -> PitValue;
+#[repr(C)]
+struct PitNativeFuncDataShim { _data: () }
+struct PitNativeFuncData {
+ f: Box<dyn FnMut(&mut Runtime, Value) -> Value>,
+}
+extern "C" fn unwrap_nativefunc(rt: *mut PitRuntime, args: PitValue, data: *mut PitNativeFuncData) -> PitValue {
+ unsafe {
+ let ret = ((*data).f)(&mut Runtime::from_shared(rt), Value { val: args });
+ ret.val
+ }
+}
+
#[repr(C)]
#[derive(Debug, Clone, Copy)]
struct PitValue { data: u64 }
@@ -57,7 +70,36 @@ unsafe extern "C" {
fn pit_parse(rt: *mut PitRuntime, parser: *mut PitParser, eof: *mut bool) -> PitValue;
fn pit_eval(rt: *mut PitRuntime, v: PitValue) -> PitValue;
fn pit_dump(rt: *mut PitRuntime, buf: *mut u8, len: i64, v: PitValue, readable: bool) -> i64;
- fn pit_eq(rt: *mut PitRuntime, x: PitValue, y: PitValue) -> bool;
+
+ fn pit_eq(x: PitValue, y: PitValue) -> bool;
+
+ fn pit_intern(rt: *mut PitRuntime, buf: *const u8, len: i64) -> PitValue;
+ fn pit_set(rt: *mut PitRuntime, sym: PitValue, v: PitValue);
+ fn pit_fset(rt: *mut PitRuntime, sym: PitValue, v: PitValue);
+ fn pit_get(rt: *mut PitRuntime, sym: PitValue) -> PitValue;
+ fn pit_fget(rt: *mut PitRuntime, sym: PitValue) -> PitValue;
+
+ fn pit_array_new(rt: *mut PitRuntime, len: i64) -> PitValue;
+ fn pit_array_from_buf(rt: *mut PitRuntime, xs: *const PitValue, len: i64) -> PitValue;
+ fn pit_array_len(rt: *mut PitRuntime, arr: PitValue) -> i64;
+ fn pit_array_get(rt: *mut PitRuntime, arr: PitValue, idx: i64) -> PitValue;
+ fn pit_array_set(rt: *mut PitRuntime, arr: PitValue, idx: i64, v: PitValue) -> PitValue;
+
+ fn pit_cons(rt: *mut PitRuntime, car: PitValue, cdr: PitValue) -> PitValue;
+ fn pit_list_len(rt: *mut PitRuntime, xs: PitValue) -> i64;
+ fn pit_car(rt: *mut PitRuntime, v: PitValue) -> PitValue;
+ fn pit_cdr(rt: *mut PitRuntime, v: PitValue) -> PitValue;
+ fn pit_setcar(rt: *mut PitRuntime, v: PitValue, x: PitValue);
+ fn pit_setcdr(rt: *mut PitRuntime, v: PitValue, x: PitValue);
+ fn pit_append(rt: *mut PitRuntime, xs: PitValue, ys: PitValue) -> PitValue;
+ fn pit_reverse(rt: *mut PitRuntime, xs: PitValue) -> PitValue;
+ fn pit_contains_eq(rt: *mut PitRuntime, needle: PitValue, haystack: PitValue) -> PitValue;
+ fn pit_contains_equal(rt: *mut PitRuntime, needle: PitValue, haystack: PitValue) -> PitValue;
+ fn pit_plist_get(rt: *mut PitRuntime, k: PitValue, vs: PitValue) -> PitValue;
+
+ fn pit_lambda(rt: *mut PitRuntime, args: PitValue, body: PitValue) -> PitValue;
+ fn pit_nativefunc_new_with_data(rt: *mut PitRuntime, f: PitNativeFunc, data: *mut PitNativeFuncDataShim) -> PitValue;
+ fn pit_apply(rt: *mut PitRuntime, f: PitValue, args: PitValue) -> PitValue;
}
pub struct Runtime {
@@ -65,6 +107,12 @@ pub struct Runtime {
rt: *mut PitRuntime,
}
impl Runtime {
+ fn from_shared(rt: *mut PitRuntime) -> Self {
+ Self {
+ _buf: Box::new([]),
+ rt,
+ }
+ }
pub fn new(sz: usize) -> Self {
let mut buf = Box::new_uninit_slice(sz);
let rt = unsafe {
@@ -84,15 +132,14 @@ impl Runtime {
let e = unsafe { pit_get_error(self.rt) };
let ve = Value { val: e };
if self.eq(ve, NIL) { return Ok(()) };
+ eprintln!("ve: {}", ve.val.data);
Err(Error { msg: self.dump(ve).unwrap_or("<unable to dump>".to_owned()) }.into())
}
pub fn parse(&mut self, s: &str) -> utils::Erm<Value> {
- let mut rt = Runtime::new(1024 * 1024 * 1024);
let lexer = Lexer::from_bytes(s.as_bytes());
let mut parser = Parser::from_lexer(lexer);
- let expr = parser.parse(&mut rt)?.ok_or(Error { msg: "end of file".to_string() })?;
- let res = rt.eval(expr)?;
- Ok(res)
+ let expr = parser.parse(self)?.ok_or(Error { msg: "end of file".to_string() })?;
+ Ok(expr)
}
pub fn eval(&mut self, v: Value) -> utils::Erm<Value> {
unsafe {
@@ -108,8 +155,34 @@ impl Runtime {
Ok(str::from_utf8(&buf[0..len]).map(|s| s.to_owned())?)
}
}
- pub fn eq(&mut self, x: Value, y: Value) -> bool {
- unsafe { pit_eq(self.rt, x.val, y.val) }
+ pub fn eq(&self, x: Value, y: Value) -> bool {
+ unsafe { pit_eq(x.val, y.val) }
+ }
+ pub fn intern(&mut self, nm: &str) -> utils::Erm<Value> {
+ unsafe {
+ let bs = nm.as_bytes();
+ let sym = pit_intern(self.rt, bs.as_ptr(), bs.len() as i64);
+ self.error()?;
+ Ok(Value { val: sym })
+ }
+ }
+ pub fn fset(&mut self, sym: Value, f: Value) -> utils::Erm<()> {
+ unsafe {
+ pit_fset(self.rt, sym.val, f.val);
+ self.error()?;
+ Ok(())
+ }
+ }
+ pub fn nativefunc_new<F>(&mut self, f: F) -> utils::Erm<Value>
+ where F: FnMut(&mut Runtime, Value) -> Value + 'static {
+ unsafe {
+ let data = Box::leak(Box::new(PitNativeFuncData {
+ f: Box::new(f),
+ }));
+ let ret = pit_nativefunc_new_with_data(self.rt, unwrap_nativefunc, data as *mut PitNativeFuncData as *mut _);
+ self.error()?;
+ Ok(Value { val: ret })
+ }
}
}
diff --git a/crates/teleia/src/shader.rs b/crates/teleia/src/shader.rs
index b45e31e..d707416 100644
--- a/crates/teleia/src/shader.rs
+++ b/crates/teleia/src/shader.rs
@@ -2,7 +2,7 @@ use std::collections::HashMap;
use glow::HasContext;
-use crate::{context, state, mesh};
+use crate::{context, font, mesh, state};
const COMMON_VERT: &'static str = include_str!("assets/shaders/common/vert.glsl");
const COMMON_FRAG: &'static str = include_str!("assets/shaders/common/frag.glsl");
@@ -239,6 +239,15 @@ impl Shader {
self.set_position_2d_helper(ctx, st, pos, dims, &glam::Quat::IDENTITY)
}
+ pub fn set_position_text_bitmap(&self,
+ ctx: &context::Context, st: &state::State,
+ font: &font::Bitmap,
+ pos: &glam::Vec2
+ ) {
+ let dims = glam::Vec2::new(font.char_width as f32, font.char_height as f32);
+ self.set_position_2d_helper(ctx, st, pos, &dims, &glam::Quat::IDENTITY)
+ }
+
pub fn bind(&self, ctx: &context::Context) {
unsafe {
ctx.gl.use_program(Some(self.program));
diff --git a/crates/teleia/src/state.rs b/crates/teleia/src/state.rs
index f5b6313..9ac617e 100644
--- a/crates/teleia/src/state.rs
+++ b/crates/teleia/src/state.rs
@@ -175,6 +175,7 @@ pub struct State {
pub render_framebuffer: framebuffer::Framebuffer,
pub render_dims: glam::Vec2,
pub shader_upscale: shader::Shader,
+ pub shader_text_bitmap: shader::Shader,
pub mesh_square: mesh::Mesh,
pub font_default: font::Bitmap,
pub font_small: font::Bitmap,
@@ -250,6 +251,11 @@ impl State {
include_str!("assets/shaders/scale/vert.glsl"),
include_str!("assets/shaders/scale/frag.glsl"),
);
+ let shader_text_bitmap = shader::Shader::new_nolib(
+ ctx,
+ include_str!("assets/shaders/bitmap/vert.glsl"),
+ include_str!("assets/shaders/bitmap/frag.glsl"),
+ );
let mesh_square = mesh::Mesh::from_obj(ctx, include_bytes!("assets/meshes/square.obj"));
let nextframe = now(ctx);
@@ -272,6 +278,7 @@ impl State {
render_framebuffer,
render_dims: glam::Vec2::new(ctx.render_width, ctx.render_height),
shader_upscale,
+ shader_text_bitmap,
mesh_square,
font_default: font::Bitmap::default(ctx),
font_small: font::Bitmap::small(ctx),
@@ -369,7 +376,7 @@ impl State {
)
}
- pub fn bind_3d_helper(&mut self, ctx: &context::Context, shader: &shader::Shader, plc: usize, orth: bool) {
+ pub fn bind_3d_helper(&self, ctx: &context::Context, shader: &shader::Shader, plc: usize, orth: bool) {
shader.bind(ctx);
shader.set_mat4(ctx, "projection", if orth { &self.projection_orth } else { &self.projection });
shader.set_mat4(ctx, "view", &self.view());
@@ -391,11 +398,11 @@ impl State {
);
}
- pub fn bind_3d_no_point_lights(&mut self, ctx: &context::Context, shader: &shader::Shader) {
+ pub fn bind_3d_no_point_lights(&self, ctx: &context::Context, shader: &shader::Shader) {
self.bind_3d_helper(ctx, shader, 0, false);
}
- pub fn bind_3d_with_point_lights(&mut self, ctx: &context::Context, shader: &shader::Shader, orth: bool) {
+ pub fn bind_3d_with_point_lights(&self, ctx: &context::Context, shader: &shader::Shader, orth: bool) {
let plc = self.point_lights.len().min(5);
self.bind_3d_helper(ctx, shader, plc, orth);
if plc > 0 {
@@ -417,15 +424,15 @@ impl State {
}
}
- pub fn bind_3d(&mut self, ctx: &context::Context, shader: &shader::Shader) {
+ pub fn bind_3d(&self, ctx: &context::Context, shader: &shader::Shader) {
self.bind_3d_with_point_lights(ctx, shader, false)
}
- pub fn bind_3d_orth(&mut self, ctx: &context::Context, shader: &shader::Shader) {
+ pub fn bind_3d_orth(&self, ctx: &context::Context, shader: &shader::Shader) {
self.bind_3d_with_point_lights(ctx, shader, true)
}
- pub fn bind_2d(&mut self, ctx: &context::Context, shader: &shader::Shader) {
+ pub fn bind_2d(&self, ctx: &context::Context, shader: &shader::Shader) {
shader.bind(ctx);
shader.set_mat4(&ctx, "projection", &glam::Mat4::IDENTITY);
shader.set_mat4(