[oden] Text is mildly functional
This commit is contained in:
parent
8914b1795f
commit
ecce7b64eb
5 changed files with 204 additions and 114 deletions
15
game/log.ts
Normal file
15
game/log.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { print } from "./graphics";
|
||||
|
||||
const lines: string[] = [];
|
||||
|
||||
export function log(...args: unknown[]) {
|
||||
// const line = args.join(" ");
|
||||
lines.push(args.join(" "));
|
||||
}
|
||||
|
||||
export function draw_log() {
|
||||
for (const line of lines) {
|
||||
print(line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
16
game/main.ts
16
game/main.ts
|
|
@ -1,4 +1,4 @@
|
|||
import { cls, print } from "./graphics";
|
||||
import { cls } from "./graphics";
|
||||
import { since_start } from "./time";
|
||||
import { new_v2 } from "./vector";
|
||||
import { load_world, World, Level, draw_level } from "./level";
|
||||
|
|
@ -10,6 +10,7 @@ import {
|
|||
is_actor_type,
|
||||
spawn_actor,
|
||||
} from "./actor";
|
||||
import { log, draw_log } from "./log";
|
||||
|
||||
/// A nice looping frame counter.
|
||||
let clock = 0;
|
||||
|
|
@ -25,7 +26,7 @@ let actors: Actor[] = [];
|
|||
function start_load_assets() {
|
||||
// Start this load, but then...
|
||||
load_world("./overworld.ldtk").then((w) => {
|
||||
print("World loaded at", since_start());
|
||||
log("World loaded at", since_start());
|
||||
world = w;
|
||||
|
||||
// Assume we start at 0,0
|
||||
|
|
@ -43,7 +44,7 @@ function start_load_assets() {
|
|||
const props = new_actor_props(entity.id, new_v2(x, y), w);
|
||||
actors.push(spawn_actor(entity.type, props));
|
||||
} else {
|
||||
print("WARNING: Ignoring entity of type", entity.type);
|
||||
log("WARNING: Ignoring entity of type", entity.type);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -52,7 +53,7 @@ function start_load_assets() {
|
|||
// TODO: Build a system whereby the signatures of the fundamental functions can be checked.
|
||||
|
||||
export function init() {
|
||||
print("Hello world!");
|
||||
log("Hello world!");
|
||||
start_load_assets();
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +63,7 @@ interface Snapshot {
|
|||
}
|
||||
|
||||
export function suspend(): Snapshot {
|
||||
print("Suspend! ", actors.length, "actors");
|
||||
log("Suspend! ", actors.length, "actors");
|
||||
return {
|
||||
clock,
|
||||
actors: actors.map((a) => {
|
||||
|
|
@ -75,7 +76,7 @@ export function resume(snapshot: Snapshot | undefined) {
|
|||
if (snapshot) {
|
||||
clock = snapshot.clock || 0;
|
||||
actors = snapshot.actors.map((s) => spawn_actor(s.type, s.props));
|
||||
print("Resume! ", actors.length, "actors");
|
||||
log("Resume! ", actors.length, "actors");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,5 +110,6 @@ export function draw() {
|
|||
actor.draw(clock);
|
||||
}
|
||||
|
||||
// print("FRAME TIME:", since_last_frame());
|
||||
// log("FRAME TIME:", since_last_frame());
|
||||
draw_log();
|
||||
}
|
||||
|
|
|
|||
199
src/lib.rs
199
src/lib.rs
|
|
@ -629,7 +629,7 @@ impl State {
|
|||
binding: 0,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
multisampled: true,
|
||||
multisampled: false,
|
||||
view_dimension: wgpu::TextureViewDimension::D2,
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: false },
|
||||
},
|
||||
|
|
@ -695,7 +695,7 @@ impl State {
|
|||
});
|
||||
|
||||
let inconsolata = include_bytes!("./Inconsolata-Regular.ttf") as &[u8];
|
||||
let inconsolata = text::FontCache::new(&device, inconsolata, 16.0);
|
||||
let inconsolata = text::FontCache::new(&device, inconsolata, 32.0);
|
||||
|
||||
let mut font_textures = HashMap::new();
|
||||
{
|
||||
|
|
@ -787,6 +787,7 @@ impl State {
|
|||
// Reset instance buffers.
|
||||
self.sprite_instance_buffers.clear();
|
||||
self.circle_instance_buffers.clear();
|
||||
self.text_instance_buffers.clear();
|
||||
|
||||
let mut builder = FrameBuilder::new(self)?;
|
||||
for command in commands {
|
||||
|
|
@ -871,18 +872,25 @@ impl State {
|
|||
.copy_instance_buffers(&self.queue);
|
||||
self.circle_instance_buffers
|
||||
.copy_instance_buffers(&self.queue);
|
||||
self.text_instance_buffers
|
||||
.copy_instance_buffers(&self.queue);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
enum DrawMode {
|
||||
Sprites,
|
||||
None,
|
||||
Sprites(u32),
|
||||
Circles,
|
||||
Text,
|
||||
Text(u32),
|
||||
}
|
||||
|
||||
trait DrawModeInstance: Sized {
|
||||
const MODE: DrawMode;
|
||||
// const MODE: DrawMode;
|
||||
|
||||
fn assert_compatible_mode(mode: DrawMode);
|
||||
|
||||
fn new_vertex_buffer(state: &mut State) -> (u32, VertexBufferHandle);
|
||||
|
||||
fn get_vertex_buffer<'a>(
|
||||
state: &'a mut State,
|
||||
|
|
@ -891,7 +899,19 @@ trait DrawModeInstance: Sized {
|
|||
}
|
||||
|
||||
impl DrawModeInstance for SpriteInstance {
|
||||
const MODE: DrawMode = DrawMode::Sprites;
|
||||
// const MODE: DrawMode = DrawMode::Sprites;
|
||||
|
||||
fn assert_compatible_mode(mode: DrawMode) {
|
||||
let compat = match mode {
|
||||
DrawMode::Sprites(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
assert!(compat, "{mode:?} is not compatible with SpriteInstance");
|
||||
}
|
||||
|
||||
fn new_vertex_buffer(state: &mut State) -> (u32, VertexBufferHandle) {
|
||||
state.sprite_instance_buffers.get_a_buffer(&state.device)
|
||||
}
|
||||
|
||||
fn get_vertex_buffer<'a>(
|
||||
state: &'a mut State,
|
||||
|
|
@ -902,7 +922,19 @@ impl DrawModeInstance for SpriteInstance {
|
|||
}
|
||||
|
||||
impl DrawModeInstance for CircleInstance {
|
||||
const MODE: DrawMode = DrawMode::Circles;
|
||||
// const MODE: DrawMode = DrawMode::Circles;
|
||||
|
||||
fn assert_compatible_mode(mode: DrawMode) {
|
||||
let compat = match mode {
|
||||
DrawMode::Circles => true,
|
||||
_ => false,
|
||||
};
|
||||
assert!(compat, "{mode:?} is not compatible with CircleInstance");
|
||||
}
|
||||
|
||||
fn new_vertex_buffer(state: &mut State) -> (u32, VertexBufferHandle) {
|
||||
state.circle_instance_buffers.get_a_buffer(&state.device)
|
||||
}
|
||||
|
||||
fn get_vertex_buffer<'a>(
|
||||
state: &'a mut State,
|
||||
|
|
@ -913,7 +945,19 @@ impl DrawModeInstance for CircleInstance {
|
|||
}
|
||||
|
||||
impl DrawModeInstance for GlyphInstance {
|
||||
const MODE: DrawMode = DrawMode::Text;
|
||||
// const MODE: DrawMode = DrawMode::Text;
|
||||
|
||||
fn assert_compatible_mode(mode: DrawMode) {
|
||||
let compat = match mode {
|
||||
DrawMode::Text(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
assert!(compat, "{mode:?} is not compatible with GlyphInstance");
|
||||
}
|
||||
|
||||
fn new_vertex_buffer(state: &mut State) -> (u32, VertexBufferHandle) {
|
||||
state.text_instance_buffers.get_a_buffer(&state.device)
|
||||
}
|
||||
|
||||
fn get_vertex_buffer<'a>(
|
||||
state: &'a mut State,
|
||||
|
|
@ -926,7 +970,6 @@ impl DrawModeInstance for GlyphInstance {
|
|||
#[derive(Debug)]
|
||||
struct DrawCall {
|
||||
mode: DrawMode,
|
||||
texture_id: Option<u32>,
|
||||
vertex_buffer: VertexBufferHandle,
|
||||
draw_start: u32,
|
||||
draw_end: u32,
|
||||
|
|
@ -936,7 +979,6 @@ impl DrawCall {
|
|||
pub fn new(mode: DrawMode, vertex_buffer: VertexBufferHandle, draw_start: u32) -> Self {
|
||||
DrawCall {
|
||||
mode,
|
||||
texture_id: None,
|
||||
vertex_buffer,
|
||||
draw_start,
|
||||
draw_end: draw_start,
|
||||
|
|
@ -947,16 +989,6 @@ impl DrawCall {
|
|||
DrawCall::new(self.mode, self.vertex_buffer.clone(), self.draw_end)
|
||||
}
|
||||
|
||||
pub fn switch_textures(&self, id: u32) -> DrawCall {
|
||||
let mut next = self.new_at_buffer_tail();
|
||||
next.texture_id = Some(id);
|
||||
next
|
||||
}
|
||||
|
||||
pub fn empty(&self) -> bool {
|
||||
self.draw_start == self.draw_end
|
||||
}
|
||||
|
||||
pub fn allocate_capacity(&mut self, capacity: u32) -> Option<VertexBufferHandle> {
|
||||
// TODO: FIX: CAPACITY == 1 ALWAYS??
|
||||
if self.vertex_buffer.capacity >= (self.draw_end + capacity) as usize {
|
||||
|
|
@ -970,14 +1002,13 @@ impl DrawCall {
|
|||
pub fn draw<'a>(&self, state: &'a State, pass: &mut wgpu::RenderPass<'a>) {
|
||||
if self.draw_end > self.draw_start {
|
||||
let vb = match self.mode {
|
||||
DrawMode::Sprites => {
|
||||
match self.texture_id {
|
||||
Some(id) => {
|
||||
let bind_group = state.sprite_textures.get(&id).unwrap();
|
||||
pass.set_bind_group(1, bind_group, &[]);
|
||||
}
|
||||
None => (),
|
||||
};
|
||||
DrawMode::None => return,
|
||||
DrawMode::Sprites(id) => {
|
||||
let bind_group = state
|
||||
.sprite_textures
|
||||
.get(&id)
|
||||
.expect("sprite mode has unknown sprite texture");
|
||||
pass.set_bind_group(1, bind_group, &[]);
|
||||
|
||||
&state
|
||||
.sprite_instance_buffers
|
||||
|
|
@ -985,14 +1016,13 @@ impl DrawCall {
|
|||
.buffer
|
||||
}
|
||||
|
||||
DrawMode::Text => {
|
||||
match self.texture_id {
|
||||
Some(id) => {
|
||||
let bind_group = state.font_textures.get(&id).unwrap();
|
||||
pass.set_bind_group(1, bind_group, &[]);
|
||||
}
|
||||
None => (),
|
||||
}
|
||||
DrawMode::Text(id) => {
|
||||
let bind_group = state
|
||||
.font_textures
|
||||
.get(&id)
|
||||
.expect("text mode has unknown font texture");
|
||||
pass.set_bind_group(1, bind_group, &[]);
|
||||
|
||||
&state.text_instance_buffers.get(&self.vertex_buffer).buffer
|
||||
}
|
||||
|
||||
|
|
@ -1023,6 +1053,7 @@ struct FrameBuilder<'a> {
|
|||
output: wgpu::SurfaceTexture,
|
||||
|
||||
mode: DrawMode,
|
||||
last_texture: Option<u32>,
|
||||
fill_color: [f32; 4],
|
||||
stroke_color: [f32; 4],
|
||||
target: Rc<wgpu::TextureView>,
|
||||
|
|
@ -1054,7 +1085,8 @@ impl<'a> FrameBuilder<'a> {
|
|||
encoder,
|
||||
output,
|
||||
|
||||
mode: DrawMode::Sprites,
|
||||
mode: DrawMode::None,
|
||||
last_texture: None,
|
||||
stroke_color: [0.0, 0.0, 0.0, 1.0],
|
||||
fill_color: [1.0, 1.0, 1.0, 1.0],
|
||||
target: last_view,
|
||||
|
|
@ -1152,59 +1184,16 @@ impl<'a> FrameBuilder<'a> {
|
|||
}
|
||||
|
||||
fn use_texture(&mut self, texture_id: u32) {
|
||||
match self.draw_calls.last_mut() {
|
||||
Some(call) => match call.texture_id {
|
||||
Some(id) => {
|
||||
if id == texture_id {
|
||||
return;
|
||||
} else if call.empty() {
|
||||
call.texture_id = Some(texture_id);
|
||||
} else {
|
||||
let next = call.switch_textures(texture_id);
|
||||
self.draw_calls.push(next);
|
||||
return;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
call.texture_id = Some(texture_id);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
let (draw_start, buffer) = self.new_instance_buffer();
|
||||
let mut call = DrawCall::new(self.mode, buffer, draw_start);
|
||||
call.texture_id = Some(texture_id);
|
||||
self.draw_calls.push(call);
|
||||
}
|
||||
}
|
||||
self.last_texture = Some(texture_id);
|
||||
}
|
||||
|
||||
fn new_instance_buffer(&mut self) -> (u32, VertexBufferHandle) {
|
||||
match self.mode {
|
||||
DrawMode::Sprites => self
|
||||
.state
|
||||
.sprite_instance_buffers
|
||||
.get_a_buffer(&self.state.device),
|
||||
fn get_instance_buffer<T: DrawModeInstance>(&mut self, mode: DrawMode) -> &mut VertexBuffer<T> {
|
||||
T::assert_compatible_mode(mode);
|
||||
|
||||
DrawMode::Circles => self
|
||||
.state
|
||||
.circle_instance_buffers
|
||||
.get_a_buffer(&self.state.device),
|
||||
|
||||
DrawMode::Text => self
|
||||
.state
|
||||
.text_instance_buffers
|
||||
.get_a_buffer(&self.state.device),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_instance_buffer<T: DrawModeInstance>(&mut self) -> &mut VertexBuffer<T> {
|
||||
// TODO: Re-work the mode shuffle. Keep the most recent vertex buffer
|
||||
// around from the
|
||||
|
||||
self.mode = T::MODE;
|
||||
self.mode = mode;
|
||||
match self.draw_calls.last_mut() {
|
||||
Some(call) => {
|
||||
if call.mode == T::MODE {
|
||||
if call.mode == self.mode {
|
||||
match call.allocate_capacity(1) {
|
||||
Some(vb) => return T::get_vertex_buffer(self.state, &vb),
|
||||
None => {}
|
||||
|
|
@ -1214,7 +1203,7 @@ impl<'a> FrameBuilder<'a> {
|
|||
None => {}
|
||||
};
|
||||
|
||||
let (draw_start, buffer) = self.new_instance_buffer();
|
||||
let (draw_start, buffer) = T::new_vertex_buffer(self.state);
|
||||
let mut call = DrawCall::new(self.mode, buffer, draw_start);
|
||||
let vb = call.allocate_capacity(1).unwrap();
|
||||
self.draw_calls.push(call);
|
||||
|
|
@ -1222,15 +1211,19 @@ impl<'a> FrameBuilder<'a> {
|
|||
}
|
||||
|
||||
fn push_sprite(&mut self, si: SpriteInstance) {
|
||||
let vertex_buffer = self.get_instance_buffer();
|
||||
vertex_buffer.vec.push(si);
|
||||
if let Some(id) = self.last_texture {
|
||||
let vertex_buffer = self.get_instance_buffer(DrawMode::Sprites(id));
|
||||
vertex_buffer.vec.push(si);
|
||||
} else {
|
||||
eprintln!("WARNING: sprite drawn with no active texture");
|
||||
}
|
||||
}
|
||||
|
||||
fn push_circle(&mut self, cc: script::graphics::CircleCommand) {
|
||||
let stroke_color = self.stroke_color.clone();
|
||||
let fill_color = self.fill_color.clone();
|
||||
|
||||
let vertex_buffer = self.get_instance_buffer();
|
||||
let vertex_buffer = self.get_instance_buffer(DrawMode::Circles);
|
||||
vertex_buffer.vec.push(CircleInstance {
|
||||
center: cc.center,
|
||||
radius: cc.radius,
|
||||
|
|
@ -1241,14 +1234,14 @@ impl<'a> FrameBuilder<'a> {
|
|||
}
|
||||
|
||||
fn push_text(&mut self, pc: script::graphics::PrintCommand) {
|
||||
println!("{}", pc.text);
|
||||
// println!("{}", pc.text);
|
||||
let mut cursor_x = 0.0;
|
||||
let cursor_y = 0.0;
|
||||
|
||||
self.mode = DrawMode::Text; // ?
|
||||
self.use_texture(0); // ?
|
||||
|
||||
let font_id: u32 = 0;
|
||||
|
||||
// self.mode = ; // ?
|
||||
|
||||
let font = self.state.fonts.get_mut(&font_id).unwrap();
|
||||
let mut glyphs = vec![];
|
||||
for char in pc.text.chars() {
|
||||
|
|
@ -1257,17 +1250,22 @@ impl<'a> FrameBuilder<'a> {
|
|||
glyphs.push(GlyphInstance {
|
||||
src_top_left: [glyph.x, glyph.y],
|
||||
src_dims: [glyph.w, glyph.h],
|
||||
dest_top_left: [cursor_x, cursor_y],
|
||||
dest_dims: [glyph.w, glyph.h],
|
||||
dest_top_left: [
|
||||
cursor_x + (glyph.adjust_x / 2.0),
|
||||
cursor_y + (glyph.adjust_y / 2.0),
|
||||
],
|
||||
dest_dims: [glyph.w / 2.0, glyph.h / 2.0],
|
||||
color,
|
||||
});
|
||||
cursor_x += glyph.w;
|
||||
cursor_x += glyph.advance_width / 2.0;
|
||||
}
|
||||
|
||||
for glyph in glyphs {
|
||||
// TODO: Get new instance buffer when we don't have space for
|
||||
// this glyph instead of doing this over and over.
|
||||
self.get_instance_buffer().vec.push(glyph);
|
||||
self.get_instance_buffer(DrawMode::Text(font_id))
|
||||
.vec
|
||||
.push(glyph);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1303,9 +1301,12 @@ impl<'a> FrameBuilder<'a> {
|
|||
};
|
||||
if need_set_pipeline {
|
||||
match call.mode {
|
||||
DrawMode::Sprites => pass.set_pipeline(&self.state.sprite_pipeline),
|
||||
DrawMode::None => {
|
||||
continue; // Skip this draw call I guess.
|
||||
}
|
||||
DrawMode::Sprites(_) => pass.set_pipeline(&self.state.sprite_pipeline),
|
||||
DrawMode::Circles => pass.set_pipeline(&self.state.circle_pipeline),
|
||||
DrawMode::Text => pass.set_pipeline(&self.state.text_pipeline),
|
||||
DrawMode::Text(_) => pass.set_pipeline(&self.state.text_pipeline),
|
||||
}
|
||||
last_mode = Some(call.mode);
|
||||
}
|
||||
|
|
|
|||
74
src/text.rs
74
src/text.rs
|
|
@ -46,6 +46,8 @@ pub struct FontCache {
|
|||
font: Font,
|
||||
size: f32,
|
||||
texture: wgpu::Texture,
|
||||
cell_width: u16,
|
||||
cell_height: u16,
|
||||
pub view: wgpu::TextureView,
|
||||
pub sampler: wgpu::Sampler,
|
||||
|
||||
|
|
@ -69,8 +71,11 @@ struct GlyphCell {
|
|||
pub struct Glyph {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
pub adjust_x: f32,
|
||||
pub adjust_y: f32,
|
||||
pub w: f32,
|
||||
pub h: f32,
|
||||
pub advance_width: f32,
|
||||
}
|
||||
|
||||
impl FontCache {
|
||||
|
|
@ -90,7 +95,7 @@ impl FontCache {
|
|||
depth_or_array_layers: 1,
|
||||
},
|
||||
mip_level_count: 1,
|
||||
sample_count: 4,
|
||||
sample_count: 1, // 4 for multisample?
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::R8Unorm,
|
||||
usage: wgpu::TextureUsages::TEXTURE_BINDING
|
||||
|
|
@ -124,6 +129,8 @@ impl FontCache {
|
|||
char_width = metrics.width.max(char_width);
|
||||
char_height = metrics.height.max(char_height);
|
||||
|
||||
eprintln!("For this font, width={char_width} height={char_height}");
|
||||
|
||||
// Allocate the individual cells in the texture atlas; this records
|
||||
// the state of what's in the cell and whatnot.
|
||||
let mut cells = vec![];
|
||||
|
|
@ -151,6 +158,9 @@ impl FontCache {
|
|||
font,
|
||||
size,
|
||||
texture,
|
||||
cell_width: char_width.try_into().unwrap(),
|
||||
cell_height: char_height.try_into().unwrap(),
|
||||
|
||||
view,
|
||||
sampler,
|
||||
cells,
|
||||
|
|
@ -182,9 +192,33 @@ impl FontCache {
|
|||
SlotState::Empty => {
|
||||
let (metrics, bitmap) = self.font.rasterize_indexed(index, self.size);
|
||||
|
||||
// eprintln!("Rasterizing '{c}' (index {index}): {metrics:?}");
|
||||
// For a good time, call
|
||||
// {
|
||||
// eprintln!();
|
||||
// let mut i = 0;
|
||||
// for _ in (0..metrics.height) {
|
||||
// for _ in (0..metrics.width) {
|
||||
// let bv = bitmap[i];
|
||||
// let rc = if bv == 0 {
|
||||
// ' '
|
||||
// } else if bv < 25 {
|
||||
// '.'
|
||||
// } else {
|
||||
// 'X'
|
||||
// };
|
||||
// eprint!("{rc}");
|
||||
// i += 1;
|
||||
// }
|
||||
// eprintln!();
|
||||
// }
|
||||
// eprintln!();
|
||||
// }
|
||||
|
||||
let mut texture = self.texture.as_image_copy();
|
||||
texture.origin.x = cell.x.into();
|
||||
texture.origin.y = cell.y.into();
|
||||
// eprintln!(" Rendering to {}, {}", texture.origin.x, texture.origin.y);
|
||||
|
||||
queue.write_texture(
|
||||
texture,
|
||||
|
|
@ -207,14 +241,44 @@ impl FontCache {
|
|||
};
|
||||
|
||||
Glyph {
|
||||
x: cell.x as f32 + metrics.bounds.xmin,
|
||||
y: cell.y as f32 + metrics.bounds.ymin,
|
||||
w: metrics.bounds.width,
|
||||
h: metrics.bounds.height,
|
||||
x: cell.x as f32,
|
||||
y: cell.y as f32,
|
||||
adjust_x: metrics.xmin as f32,
|
||||
adjust_y: (self.cell_height as f32)
|
||||
+ floor(-metrics.bounds.height - metrics.bounds.ymin), // PositiveYDown,
|
||||
w: self.cell_width as f32,
|
||||
h: self.cell_height as f32,
|
||||
advance_width: metrics.advance_width,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn floor(x: f32) -> f32 {
|
||||
let mut ui = x.to_bits();
|
||||
let e = (((ui >> 23) as i32) & 0xff) - 0x7f;
|
||||
|
||||
if e >= 23 {
|
||||
return x;
|
||||
}
|
||||
if e >= 0 {
|
||||
let m: u32 = 0x007fffff >> e;
|
||||
if (ui & m) == 0 {
|
||||
return x;
|
||||
}
|
||||
if ui >> 31 != 0 {
|
||||
ui += m;
|
||||
}
|
||||
ui &= !m;
|
||||
} else {
|
||||
if ui >> 31 == 0 {
|
||||
ui = 0;
|
||||
} else if ui << 1 != 0 {
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
f32::from_bits(ui)
|
||||
}
|
||||
|
||||
// pub fn inconsolata() {
|
||||
// let font = include_bytes!("./Inconsolata-Regular.ttf") as &[u8];
|
||||
// let font = fontdue::Font::from_bytes(font, fontdue::FontSettings::default()).unwrap();
|
||||
|
|
|
|||
|
|
@ -34,13 +34,21 @@ struct VertexOutput {
|
|||
// Fragment shader
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@group(1) @binding(0) var t_diffuse : texture_multisampled_2d<f32>;
|
||||
@group(1) @binding(0) var t_diffuse : texture_2d<f32>;
|
||||
@group(1) @binding(1) var s_diffuse : sampler;
|
||||
|
||||
@fragment fn fs_main(in : VertexOutput)->@location(0) vec4<f32> {
|
||||
// TODO: Should we be sampling here for the shader?
|
||||
let tc = vec2(u32(in.tex_coords.x), u32(in.tex_coords.y));
|
||||
return textureLoad(t_diffuse, tc, 0);
|
||||
|
||||
// let tc = vec2(u32(in.tex_coords.x), u32(in.tex_coords.y));
|
||||
// let c = textureLoad(t_diffuse, tc, 0);
|
||||
|
||||
let tc = in.tex_coords / vec2<f32>(textureDimensions(t_diffuse));
|
||||
let c = textureSample(t_diffuse, s_diffuse, tc);
|
||||
|
||||
|
||||
return vec4<f32>(c.r,c.r,c.r,c.r);
|
||||
//return vec4<f32>(1.0,1.0,1.0,1.0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue