mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 07:14:46 +00:00
Render a triangle underneath the text
This commit is contained in:
parent
289070ef0f
commit
4972e03405
8 changed files with 190 additions and 37 deletions
45
Cargo.lock
generated
45
Cargo.lock
generated
|
@ -69,6 +69,12 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c"
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.3.2"
|
||||
|
@ -329,6 +335,15 @@ dependencies = [
|
|||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e56268c17a6248366d66d4a47a3381369d068cce8409bb1716ed77ea32163bb"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cocoa"
|
||||
version = "0.20.2"
|
||||
|
@ -1016,6 +1031,12 @@ version = "0.22.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "glyph_brush"
|
||||
version = "0.7.0"
|
||||
|
@ -2374,9 +2395,12 @@ dependencies = [
|
|||
name = "roc_editor"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bumpalo",
|
||||
"env_logger 0.7.1",
|
||||
"fs_extra",
|
||||
"futures",
|
||||
"glob",
|
||||
"glyph_brush",
|
||||
"im",
|
||||
"im-rc",
|
||||
|
@ -2404,6 +2428,7 @@ dependencies = [
|
|||
"roc_types",
|
||||
"roc_unify",
|
||||
"roc_uniq",
|
||||
"shaderc",
|
||||
"target-lexicon",
|
||||
"tokio",
|
||||
"wgpu",
|
||||
|
@ -2855,6 +2880,26 @@ dependencies = [
|
|||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shaderc"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50b8aeaae10b9bda5cba66736a7e265f67698e912e1cc6a4678acba286e22be9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"shaderc-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shaderc-sys"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b12d7c62d6732884c9dfab587503fa3a795b108df152415a89da23812d4737e"
|
||||
dependencies = [
|
||||
"cmake",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.2.1"
|
||||
|
|
|
@ -63,3 +63,9 @@ maplit = "1.0.1"
|
|||
indoc = "0.3.3"
|
||||
quickcheck = "0.8"
|
||||
quickcheck_macros = "0.8"
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1.0"
|
||||
fs_extra = "1.1"
|
||||
glob = "0.3"
|
||||
shaderc = "0.6"
|
81
editor/build.rs
Normal file
81
editor/build.rs
Normal file
|
@ -0,0 +1,81 @@
|
|||
use anyhow::*;
|
||||
use glob::glob;
|
||||
use std::fs::{read_to_string, write};
|
||||
use std::path::PathBuf;
|
||||
|
||||
// Build script for shaders used from:
|
||||
// https://sotrh.github.io/learn-wgpu/beginner/tutorial3-pipeline/#compiling-shaders-and-include-spirv
|
||||
|
||||
struct ShaderData {
|
||||
src: String,
|
||||
src_path: PathBuf,
|
||||
spv_path: PathBuf,
|
||||
kind: shaderc::ShaderKind,
|
||||
}
|
||||
|
||||
impl ShaderData {
|
||||
pub fn load(src_path: PathBuf) -> Result<Self> {
|
||||
let extension = src_path
|
||||
.extension()
|
||||
.context("File has no extension")?
|
||||
.to_str()
|
||||
.context("Extension cannot be converted to &str")?;
|
||||
let kind = match extension {
|
||||
"vert" => shaderc::ShaderKind::Vertex,
|
||||
"frag" => shaderc::ShaderKind::Fragment,
|
||||
"comp" => shaderc::ShaderKind::Compute,
|
||||
_ => bail!("Unsupported shader: {}", src_path.display()),
|
||||
};
|
||||
|
||||
let src = read_to_string(src_path.clone())?;
|
||||
let spv_path = src_path.with_extension(format!("{}.spv", extension));
|
||||
|
||||
Ok(Self {
|
||||
src,
|
||||
src_path,
|
||||
spv_path,
|
||||
kind,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// Collect all shaders recursively within /src/
|
||||
let mut shader_paths = [
|
||||
glob("./src/**/*.vert")?,
|
||||
glob("./src/**/*.frag")?,
|
||||
glob("./src/**/*.comp")?,
|
||||
];
|
||||
|
||||
// This could be parallelized
|
||||
let shaders = shader_paths
|
||||
.iter_mut()
|
||||
.flatten()
|
||||
.map(|glob_result| ShaderData::load(glob_result?))
|
||||
.collect::<Vec<Result<_>>>()
|
||||
.into_iter()
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
let mut compiler = shaderc::Compiler::new().context("Unable to create shader compiler")?;
|
||||
|
||||
// This can't be parallelized. The [shaderc::Compiler] is not
|
||||
// thread safe. Also, it creates a lot of resources. You could
|
||||
// spawn multiple processes to handle this, but it would probably
|
||||
// be better just to only compile shaders that have been changed
|
||||
// recently.
|
||||
for shader in shaders {
|
||||
// This tells cargo to rerun this script if something in /src/ changes.
|
||||
println!("cargo:rerun-if-changed={:?}", shader.src_path);
|
||||
|
||||
let compiled = compiler.compile_into_spirv(
|
||||
&shader.src,
|
||||
shader.kind,
|
||||
&shader.src_path.to_str().unwrap(),
|
||||
"main",
|
||||
None,
|
||||
)?;
|
||||
write(shader.spv_path, compiled.as_binary_u8())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
layout(location = 0) in vec4 vertex_color;
|
||||
|
||||
layout(location = 0) out vec4 fragment_color;
|
||||
|
||||
void main() {
|
||||
fragment_color = vertex_color;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
vec4 color;
|
||||
vec2 pos;
|
||||
vec2 scale;
|
||||
} push_constants;
|
||||
|
||||
layout(location = 0) out vec4 vertex_color;
|
||||
|
||||
void main() {
|
||||
vec2 position;
|
||||
if (gl_VertexIndex == 0) {
|
||||
position = vec2(0.0, -0.5);
|
||||
} else if (gl_VertexIndex == 1) {
|
||||
position = vec2(-0.5, 0.5);
|
||||
} else if (gl_VertexIndex == 2) {
|
||||
position = vec2(0.5, 0.5);
|
||||
}
|
||||
|
||||
vec2 pos = position * push_constants.scale;
|
||||
vertex_color = push_constants.color;
|
||||
gl_Position = vec4((pos + push_constants.pos), 0.0, 1.0);
|
||||
}
|
|
@ -76,7 +76,6 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
|||
// Prepare swap chain
|
||||
let render_format = wgpu::TextureFormat::Bgra8UnormSrgb;
|
||||
let mut size = window.inner_size();
|
||||
|
||||
let mut swap_chain = device.create_swap_chain(
|
||||
&surface,
|
||||
&wgpu::SwapChainDescriptor {
|
||||
|
@ -88,6 +87,43 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
|||
},
|
||||
);
|
||||
|
||||
// Prepare Triangle Pipeline
|
||||
let triangle_vs_module =
|
||||
device.create_shader_module(wgpu::include_spirv!("shaders/rect.vert.spv"));
|
||||
let triangle_fs_module =
|
||||
device.create_shader_module(wgpu::include_spirv!("shaders/rect.frag.spv"));
|
||||
|
||||
let triangle_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: None,
|
||||
bind_group_layouts: &[],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
let triangle_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: None,
|
||||
layout: Some(&triangle_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: &triangle_vs_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: &triangle_fs_module,
|
||||
entry_point: "main",
|
||||
}),
|
||||
// Use the default rasterizer state: no culling, no depth bias
|
||||
rasterization_state: None,
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[wgpu::TextureFormat::Bgra8UnormSrgb.into()],
|
||||
depth_stencil_state: None,
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[],
|
||||
},
|
||||
sample_count: 1,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
// Prepare glyph_brush
|
||||
let inconsolata =
|
||||
ab_glyph::FontArc::try_from_slice(include_bytes!("../Inconsolata-Regular.ttf"))?;
|
||||
|
@ -182,7 +218,7 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
|||
|
||||
// Clear frame
|
||||
{
|
||||
let _ = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||
attachment: &frame.view,
|
||||
resolve_target: None,
|
||||
|
@ -198,6 +234,9 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
|||
}],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
|
||||
render_pass.set_pipeline(&triangle_pipeline);
|
||||
render_pass.draw(0..3, 0..1);
|
||||
}
|
||||
|
||||
glyph_brush.queue(Section {
|
||||
|
|
7
editor/src/shaders/rect.frag
Normal file
7
editor/src/shaders/rect.frag
Normal file
|
@ -0,0 +1,7 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
void main() {
|
||||
outColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
10
editor/src/shaders/rect.vert
Normal file
10
editor/src/shaders/rect.vert
Normal file
|
@ -0,0 +1,10 @@
|
|||
#version 450
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
void main() {
|
||||
vec2 position = vec2(gl_VertexIndex, (gl_VertexIndex & 1) * 2) - 1;
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue