From 45ade674be36ab04452003ea6910cf6a26c29405 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 28 Feb 2017 12:29:42 -0800 Subject: [PATCH] Refactor `lorem-ipsum` --- examples/lorem-ipsum.rs | 498 +++++++++--------- .../examples/lorem-ipsum/composite.fs.glsl | 16 + .../examples/lorem-ipsum/composite.vs.glsl | 15 + resources/examples/lorem-ipsum/default.txt | 34 ++ .../examples/lorem-ipsum/solid_color.fs.glsl | 10 + .../examples/lorem-ipsum/solid_color.vs.glsl | 8 + 6 files changed, 330 insertions(+), 251 deletions(-) create mode 100644 resources/examples/lorem-ipsum/composite.fs.glsl create mode 100644 resources/examples/lorem-ipsum/composite.vs.glsl create mode 100644 resources/examples/lorem-ipsum/default.txt create mode 100644 resources/examples/lorem-ipsum/solid_color.fs.glsl create mode 100644 resources/examples/lorem-ipsum/solid_color.vs.glsl diff --git a/examples/lorem-ipsum.rs b/examples/lorem-ipsum.rs index cecea023..28dec868 100644 --- a/examples/lorem-ipsum.rs +++ b/examples/lorem-ipsum.rs @@ -16,8 +16,8 @@ use compute_shader::image::{Color, ExternalImage, Format, Image}; use compute_shader::instance::{Instance, ShadingLanguage}; use euclid::{Point2D, Rect, Size2D}; use gl::types::{GLchar, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid}; -use glfw::{Action, Context, Key, OpenGlProfileHint, SwapInterval, WindowEvent}; -use glfw::{WindowHint, WindowMode}; +use glfw::{Action, Context, Key, OpenGlProfileHint, SwapInterval, Window, WindowEvent}; +use glfw::{Glfw, WindowHint, WindowMode}; use memmap::{Mmap, Protection}; use pathfinder::atlas::{AtlasBuilder, AtlasOptions, GlyphRasterizationOptions}; use pathfinder::charmap::CodepointRanges; @@ -34,6 +34,7 @@ use std::io::Read; use std::mem; use std::os::raw::c_void; use std::path::{Path, PathBuf}; +use std::sync::mpsc::Receiver; const ATLAS_SIZE: u32 = 2048; const WIDTH: u32 = 640; @@ -50,7 +51,9 @@ const MAX_POINT_SIZE: f32 = 512.0; const FPS_DISPLAY_POINT_SIZE: f32 = 24.0; const FPS_PADDING: i32 = 6; -static SHADER_PATH: &'static str = "resources/shaders/"; +static PATHFINDER_SHADER_PATH: &'static str = "resources/shaders/"; +static EXAMPLE_SHADER_PATH: &'static str = "resources/examples/lorem-ipsum/"; +static DEFAULT_TEXT_PATH: &'static str = "resources/examples/lorem-ipsum/default.txt"; static FPS_BACKGROUND_COLOR: [f32; 3] = [0.3, 0.3, 0.3]; static FPS_FOREGROUND_COLOR: [f32; 3] = [1.0, 1.0, 1.0]; @@ -59,176 +62,256 @@ static TEXT_COLOR: [f32; 3] = [0.0, 0.0, 0.0]; static ATLAS_DUMP_FILENAME: &'static str = "lorem-ipsum-atlas.png"; +static RECT_INDICES: [u16; 6] = [0, 1, 3, 1, 2, 3]; + fn main() { - let index_arg = Arg::with_name("index").short("i") - .long("index") - .help("Select an index within a font collection") - .takes_value(true); - let subpixel_antialiasing_arg = - Arg::with_name("subpixel-aa").short("s") - .long("subpixel-aa") - .help("Enable subpixel antialiasing"); - let font_arg = Arg::with_name("FONT-FILE").help("Select the font file (`.ttf`, `.otf`, etc.)") - .required(true) - .index(1); - let text_arg = Arg::with_name("TEXT-FILE").help("Select a file containing text to display") - .index(2); - let matches = App::new("lorem-ipsum").arg(index_arg) - .arg(subpixel_antialiasing_arg) - .arg(font_arg) - .arg(text_arg) - .get_matches(); + DemoApp::new(AppOptions::parse()).run() +} - let mut glfw = glfw::init(glfw::LOG_ERRORS).unwrap(); - glfw.window_hint(WindowHint::ContextVersion(3, 3)); - glfw.window_hint(WindowHint::OpenGlForwardCompat(true)); - glfw.window_hint(WindowHint::OpenGlProfile(OpenGlProfileHint::Core)); - let context = glfw.create_window(WIDTH, HEIGHT, "lorem-ipsum", WindowMode::Windowed); +struct DemoApp { + options: AppOptions, + renderer: Renderer, + glfw: Glfw, + window: Window, + events: Receiver<(f64, WindowEvent)>, + point_size: f32, + translation: Point2D, + device_pixel_size: Size2D, +} - let (mut window, events) = context.expect("Couldn't create a window!"); - window.make_current(); - window.set_key_polling(true); - window.set_scroll_polling(true); - window.set_size_polling(true); - window.set_framebuffer_size_polling(true); - glfw.set_swap_interval(SwapInterval::Sync(1)); +impl DemoApp { + fn new(options: AppOptions) -> DemoApp { + let mut glfw = glfw::init(glfw::LOG_ERRORS).unwrap(); + glfw.window_hint(WindowHint::ContextVersion(3, 3)); + glfw.window_hint(WindowHint::OpenGlForwardCompat(true)); + glfw.window_hint(WindowHint::OpenGlProfile(OpenGlProfileHint::Core)); + let context = glfw.create_window(WIDTH, HEIGHT, "lorem-ipsum", WindowMode::Windowed); - gl::load_with(|symbol| window.get_proc_address(symbol) as *const c_void); + let (mut window, events) = context.expect("Couldn't create a window!"); + window.make_current(); + window.set_key_polling(true); + window.set_scroll_polling(true); + window.set_size_polling(true); + window.set_framebuffer_size_polling(true); + glfw.set_swap_interval(SwapInterval::Sync(1)); - let (width, height) = window.get_framebuffer_size(); - let mut device_pixel_size = Size2D::new(width as u32, height as u32); + gl::load_with(|symbol| window.get_proc_address(symbol) as *const c_void); - let mut text = "".to_string(); - match matches.value_of("TEXT-FILE") { - Some(path) => drop(File::open(path).unwrap().read_to_string(&mut text).unwrap()), - None => text.push_str(TEXT), + let (width, height) = window.get_framebuffer_size(); + let device_pixel_size = Size2D::new(width as u32, height as u32); + + let renderer = Renderer::new(options.subpixel_aa); + + DemoApp { + renderer: renderer, + glfw: glfw, + window: window, + events: events, + device_pixel_size: device_pixel_size, + point_size: INITIAL_POINT_SIZE, + translation: Point2D::zero(), + options: options, + } } - text = text.replace(&['\n', '\r', '\t'][..], " "); - let font_index = match matches.value_of("index") { - Some(index) => index.parse().unwrap(), - None => 0, - }; + fn run(&mut self) { + let file = Mmap::open_path(&self.options.font_path, Protection::Read).unwrap(); + let mut buffer = vec![]; + let font = unsafe { + Font::from_collection_index(file.as_slice(), + self.options.font_index, + &mut buffer).unwrap() + }; - let subpixel_aa = matches.is_present("subpixel-aa"); + let page_width = self.device_pixel_size.width as f32 * + font.units_per_em() as f32 / INITIAL_POINT_SIZE; - let file = Mmap::open_path(matches.value_of("FONT-FILE").unwrap(), Protection::Read).unwrap(); - let mut buffer = vec![]; - let font = unsafe { - Font::from_collection_index(file.as_slice(), font_index, &mut buffer).unwrap() - }; + let mut typesetter = Typesetter::new(page_width, &font, font.units_per_em() as f32); + typesetter.add_text(&font, font.units_per_em() as f32, &self.options.text); - let units_per_em = font.units_per_em() as f32; - let page_width = device_pixel_size.width as f32 * units_per_em / INITIAL_POINT_SIZE; - let mut typesetter = Typesetter::new(page_width, &font, units_per_em); - typesetter.add_text(&font, font.units_per_em() as f32, &text); + let glyph_stores = GlyphStores::new(&typesetter, &font); - let renderer = Renderer::new(subpixel_aa); - let mut point_size = INITIAL_POINT_SIZE; - let mut translation = Point2D::new(0, 0); - let mut dirty = true; - - let glyph_store = typesetter.create_glyph_store(&font).unwrap(); - - // Set up the FPS glyph store. - let mut fps_chars: Vec = vec![]; - fps_chars.extend(" ./,:()".chars()); - fps_chars.extend(('A' as u32..('Z' as u32 + 1)).flat_map(char::from_u32)); - fps_chars.extend(('a' as u32..('z' as u32 + 1)).flat_map(char::from_u32)); - fps_chars.extend(('0' as u32..('9' as u32 + 1)).flat_map(char::from_u32)); - fps_chars.sort(); - let fps_codepoint_ranges = CodepointRanges::from_sorted_chars(&fps_chars); - let fps_glyph_store = GlyphStore::from_codepoints(&fps_codepoint_ranges, &font).unwrap(); - - while !window.should_close() { - if dirty { - let redraw_result = renderer.redraw(point_size, - &font, - &glyph_store, - &typesetter, - &device_pixel_size, - &translation); - - let (draw_time, accum_time); - match redraw_result.events { - Some(events) => { - let mut draw_nanos = 0u64; - unsafe { - gl::Flush(); - gl::GetQueryObjectui64v(events.draw, gl::QUERY_RESULT, &mut draw_nanos); - } - - draw_time = draw_nanos as f64; - accum_time = events.accum.time_elapsed().unwrap() as f64; - } - None => { - draw_time = 0.0; - accum_time = 0.0; - } + let mut dirty = true; + while !self.window.should_close() { + if dirty { + self.redraw(&glyph_stores, &typesetter, &font); + dirty = false } - let timing = renderer.get_timing_in_ms(); + self.glfw.wait_events(); + let events: Vec<_> = glfw::flush_messages(&self.events).map(|(_, e)| e).collect(); + for event in events { + dirty = self.handle_window_event(event) || dirty + } + } + } - renderer.draw_fps(&font, - &fps_glyph_store, - &device_pixel_size, - draw_time, - accum_time, - timing, - redraw_result.glyphs_drawn); + fn redraw(&mut self, glyph_stores: &GlyphStores, typesetter: &Typesetter, font: &Font) { + let redraw_result = self.renderer.redraw(self.point_size, + &font, + &glyph_stores.main, + typesetter, + &self.device_pixel_size, + &self.translation); - window.swap_buffers(); + let (draw_time, accum_time); + match redraw_result.events { + Some(events) => { + let mut draw_nanos = 0u64; + unsafe { + gl::Flush(); + gl::GetQueryObjectui64v(events.draw, gl::QUERY_RESULT, &mut draw_nanos); + } - dirty = false + draw_time = draw_nanos as f64; + accum_time = events.accum.time_elapsed().unwrap() as f64; + } + None => { + draw_time = 0.0; + accum_time = 0.0; + } } + let timing = self.renderer.get_timing_in_ms(); - glfw.wait_events(); - for (_, event) in glfw::flush_messages(&events) { - match event { - WindowEvent::Key(Key::Escape, _, Action::Press, _) => { - window.set_should_close(true) - } - WindowEvent::Key(Key::S, _, Action::Press, _) => { - renderer.take_screenshot(); - println!("wrote screenshot to: {}", ATLAS_DUMP_FILENAME); - } - WindowEvent::Scroll(x, y) => { - if window.get_key(Key::LeftAlt) == Action::Press || - window.get_key(Key::RightAlt) == Action::Press { - let old_point_size = point_size; - point_size = old_point_size + y as f32; + self.renderer.draw_fps(&font, + &glyph_stores.fps, + &self.device_pixel_size, + draw_time, + accum_time, + timing, + redraw_result.glyphs_drawn); - if point_size < MIN_POINT_SIZE { - point_size = MIN_POINT_SIZE - } else if point_size > MAX_POINT_SIZE { - point_size = MAX_POINT_SIZE - } + self.window.swap_buffers(); + } - let mut center = Point2D::new( - translation.x as f32 - device_pixel_size.width as f32 * 0.5, - translation.y as f32 - device_pixel_size.height as f32 * 0.5); - center.x = center.x * point_size / old_point_size; - center.y = center.y * point_size / old_point_size; + // Returns true if the window needs to be redrawn. + fn handle_window_event(&mut self, event: WindowEvent) -> bool { + match event { + WindowEvent::Key(Key::Escape, _, Action::Press, _) => { + self.window.set_should_close(true); + false + } + WindowEvent::Key(Key::S, _, Action::Press, _) => { + self.renderer.take_screenshot(); + println!("wrote screenshot to: {}", ATLAS_DUMP_FILENAME); + false + } + WindowEvent::Scroll(x, y) => { + if self.window.get_key(Key::LeftAlt) == Action::Press || + self.window.get_key(Key::RightAlt) == Action::Press { + let old_point_size = self.point_size; + self.point_size = old_point_size + y as f32; - translation.x = (center.x + device_pixel_size.width as f32 * 0.5).round() - as i32; - translation.y = (center.y + device_pixel_size.height as f32 * 0.5).round() - as i32; - } else { - translation.x += (x * SCROLL_SPEED).round() as i32; - translation.y += (y * SCROLL_SPEED).round() as i32; + if self.point_size < MIN_POINT_SIZE { + self.point_size = MIN_POINT_SIZE + } else if self.point_size > MAX_POINT_SIZE { + self.point_size = MAX_POINT_SIZE } - dirty = true + let mut center = + Point2D::new(self.translation.x as f32 - + self.device_pixel_size.width as f32 * + 0.5, + self.translation.y as f32 - + self.device_pixel_size.height as f32 * + 0.5); + center.x = center.x * self.point_size / old_point_size; + center.y = center.y * self.point_size / old_point_size; + + self.translation.x = + (center.x + self.device_pixel_size.width as f32 * 0.5).round() as i32; + self.translation.y = + (center.y + self.device_pixel_size.height as f32 * 0.5).round() as i32; + } else { + self.translation.x += (x * SCROLL_SPEED).round() as i32; + self.translation.y += (y * SCROLL_SPEED).round() as i32; } - WindowEvent::Size(_, _) | WindowEvent::FramebufferSize(_, _) => { - let (width, height) = window.get_framebuffer_size(); - device_pixel_size = Size2D::new(width as u32, height as u32); - dirty = true - } - _ => {} + + true } + WindowEvent::Size(_, _) | WindowEvent::FramebufferSize(_, _) => { + let (width, height) = self.window.get_framebuffer_size(); + self.device_pixel_size = Size2D::new(width as u32, height as u32); + true + } + _ => false, + } + } +} + +struct AppOptions { + font_path: String, + font_index: u32, + text: String, + subpixel_aa: bool, +} + +impl AppOptions { + fn parse() -> AppOptions { + let index_arg = Arg::with_name("index").short("i") + .long("index") + .help("Select an index within a font collection") + .takes_value(true); + let subpixel_antialiasing_arg = + Arg::with_name("subpixel-aa").short("s") + .long("subpixel-aa") + .help("Enable subpixel antialiasing"); + let font_arg = + Arg::with_name("FONT-FILE").help("Select the font file (`.ttf`, `.otf`, etc.)") + .required(true) + .index(1); + let text_arg = Arg::with_name("TEXT-FILE").help("Select a file containing text to display") + .index(2); + let matches = App::new("lorem-ipsum").arg(index_arg) + .arg(subpixel_antialiasing_arg) + .arg(font_arg) + .arg(text_arg) + .get_matches(); + + let mut text = "".to_string(); + let path = matches.value_of("TEXT-FILE").unwrap_or(DEFAULT_TEXT_PATH); + File::open(path).unwrap().read_to_string(&mut text).unwrap(); + text = text.replace(&['\n', '\r', '\t'][..], " "); + + let font_index = match matches.value_of("index") { + Some(index) => index.parse().unwrap(), + None => 0, + }; + + let font_path = matches.value_of("FONT-FILE").unwrap(); + let subpixel_aa = matches.is_present("subpixel-aa"); + + AppOptions { + text: text, + font_index: font_index, + font_path: font_path.to_string(), + subpixel_aa: subpixel_aa, + } + } +} + +struct GlyphStores { + main: GlyphStore, + fps: GlyphStore, +} + +impl GlyphStores { + fn new(typesetter: &Typesetter, font: &Font) -> GlyphStores { + let main_glyph_store = typesetter.create_glyph_store(&font).unwrap(); + + let mut fps_chars: Vec = vec![]; + fps_chars.extend(" ./,:()".chars()); + fps_chars.extend(('A' as u32..('Z' as u32 + 1)).flat_map(char::from_u32)); + fps_chars.extend(('a' as u32..('z' as u32 + 1)).flat_map(char::from_u32)); + fps_chars.extend(('0' as u32..('9' as u32 + 1)).flat_map(char::from_u32)); + fps_chars.sort(); + let fps_codepoint_ranges = CodepointRanges::from_sorted_chars(&fps_chars); + let fps_glyph_store = GlyphStore::from_codepoints(&fps_codepoint_ranges, &font).unwrap(); + + GlyphStores { + main: main_glyph_store, + fps: fps_glyph_store, } } } @@ -277,7 +360,7 @@ impl Renderer { let mut rasterizer_options = RasterizerOptions::from_env().unwrap(); if env::var("PATHFINDER_SHADER_PATH").is_err() { - rasterizer_options.shader_path = PathBuf::from(SHADER_PATH) + rasterizer_options.shader_path = PathBuf::from(PATHFINDER_SHADER_PATH) } let rasterizer = Rasterizer::new(&instance, device, queue, rasterizer_options).unwrap(); @@ -291,7 +374,7 @@ impl Renderer { let (mut solid_color_vertex_buffer, mut solid_color_index_buffer) = (0, 0); let mut solid_color_vertex_array = 0; unsafe { - composite_program = create_program(COMPOSITE_VERTEX_SHADER, COMPOSITE_FRAGMENT_SHADER); + composite_program = create_program("composite"); composite_position_attribute = gl::GetAttribLocation(composite_program, "aPosition\0".as_ptr() as *const GLchar); composite_tex_coord_attribute = @@ -311,8 +394,7 @@ impl Renderer { gl::GetUniformLocation(composite_program, "uBackgroundColor\0".as_ptr() as *const GLchar); - solid_color_program = create_program(SOLID_COLOR_VERTEX_SHADER, - SOLID_COLOR_FRAGMENT_SHADER); + solid_color_program = create_program("solid_color"); solid_color_position_attribute = gl::GetAttribLocation(solid_color_program, "aPosition\0".as_ptr() as *const GLchar); @@ -370,7 +452,7 @@ impl Renderer { gl::STATIC_DRAW); } - // FIXME(pcwalton) + // FIXME(pcwalton): Dynamically resizing atlas. let atlas_size = Size2D::new(ATLAS_SIZE, ATLAS_SIZE); let coverage_buffer_options = CoverageBufferOptions { size: atlas_size, @@ -870,8 +952,21 @@ impl CompositeVertexArray { } } -fn create_program(vertex_shader_source: &str, fragment_shader_source: &str) -> GLuint { +struct RedrawResult { + events: Option, + glyphs_drawn: u32, +} + +fn create_program(name: &str) -> GLuint { unsafe { + let (mut vertex_shader_source, mut fragment_shader_source) = (vec![], vec![]); + File::open(&format!("{}/{}.vs.glsl", + EXAMPLE_SHADER_PATH, + name)).unwrap().read_to_end(&mut vertex_shader_source).unwrap(); + File::open(&format!("{}/{}.fs.glsl", + EXAMPLE_SHADER_PATH, + name)).unwrap().read_to_end(&mut fragment_shader_source).unwrap(); + let vertex_shader = gl::CreateShader(gl::VERTEX_SHADER); let fragment_shader = gl::CreateShader(gl::FRAGMENT_SHADER); gl::ShaderSource(vertex_shader, @@ -915,102 +1010,3 @@ fn create_image(rasterizer: &Rasterizer, atlas_size: &Size2D) -> (Image, GL (compute_image, gl_texture) } -struct RedrawResult { - events: Option, - glyphs_drawn: u32, -} - -static COMPOSITE_VERTEX_SHADER: &'static str = "\ -#version 330 - -uniform mat2 uTransform; -uniform vec2 uTranslation; - -in vec2 aPosition; -in vec2 aTexCoord; - -out vec2 vTexCoord; - -void main() { - vTexCoord = aTexCoord; - gl_Position = vec4(uTransform * aPosition + uTranslation, 0.0f, 1.0f); -} -"; - -static COMPOSITE_FRAGMENT_SHADER: &'static str = "\ -#version 330 - -uniform sampler2DRect uAtlas; -uniform vec3 uForegroundColor; -uniform vec3 uBackgroundColor; - -in vec2 vTexCoord; - -out vec4 oFragColor; - -void main() { - vec3 value = texture(uAtlas, vTexCoord).rgb; - vec3 color = mix(uBackgroundColor, uForegroundColor, value); - oFragColor = vec4(color, 1.0f); -} -"; - -static SOLID_COLOR_VERTEX_SHADER: &'static str = "\ -#version 330 - -in vec2 aPosition; - -void main() { - gl_Position = vec4(aPosition, 0.0f, 1.0f); -} -"; - -static SOLID_COLOR_FRAGMENT_SHADER: &'static str = "\ -#version 330 - -uniform vec3 uColor; - -out vec4 oFragColor; - -void main() { - oFragColor = vec4(uColor, 1.0f); -} -"; - -static RECT_INDICES: [u16; 6] = [0, 1, 3, 1, 2, 3]; - -static TEXT: &'static str = "\ -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur scelerisque pellentesque risus \ -quis vehicula. Ut sollicitudin aliquet diam, vel lobortis orci porta in. Sed eu nisi egestas odio \ -tincidunt cursus eget ut lorem. Fusce lacinia ex nec lectus rutrum mollis. Donec in ultrices \ -purus. Integer id suscipit magna. Suspendisse congue pulvinar neque id ultrices. Curabitur nec \ -tellus et est pellentesque posuere. Duis ut metus euismod, feugiat arcu vitae, posuere libero. \ -Curabitur nunc urna, rhoncus vitae scelerisque quis, viverra et odio. Suspendisse accumsan \ -pretium mi, nec fringilla metus condimentum id. Duis dignissim quam eu felis lobortis, eget \ -dignissim lectus fermentum. Nunc et massa id orci pellentesque rutrum. Nam imperdiet quam vel \ -ligula efficitur ultricies vel eu tellus. Maecenas luctus risus a erat euismod ultricies. \ -Pellentesque neque mauris, laoreet vitae finibus quis, molestie ut velit. Donec laoreet justo \ -risus. In id mi sed odio placerat interdum ut vitae erat. Fusce quis mollis mauris, sit amet \ -efficitur libero. In efficitur tortor nulla, sollicitudin sodales mi tempor in. In egestas \ -ultrices fermentum. Quisque mattis egestas nulla. Interdum et malesuada fames ac ante ipsum \ -primis in faucibus. Etiam in tempus sapien, in dignissim arcu. Quisque diam nulla, rhoncus et \ -tempor nec, facilisis porta purus. Nulla ut eros laoreet, placerat dolor ut, interdum orci. Sed \ -posuere eleifend mollis. Integer at nunc ex. Vestibulum aliquet risus quis lacinia convallis. \ -Fusce et metus viverra, varius nulla in, rutrum justo. Interdum et malesuada fames ac ante ipsum \ -primis in faucibus. Praesent non est vel lectus suscipit malesuada id ut nisl. Aenean sem ipsum, \ -tincidunt non orci non, varius consectetur purus. Aenean sed mollis turpis, sit amet vestibulum \ -risus. Nunc ut hendrerit urna, sit amet lacinia arcu. Curabitur laoreet a enim et eleifend. Etiam \ -consectetur pharetra massa, sed elementum quam molestie nec. Integer eu justo lectus. Vestibulum \ -sed vulputate sapien. Curabitur pretium luctus orci et interdum. Quisque ligula nisi, varius id \ -sodales id, volutpat et lorem. Pellentesque ex urna, malesuada at ex non, elementum ultricies \ -nulla. Nunc sodales, turpis at maximus bibendum, neque lorem laoreet felis, eget convallis sem \ -mauris ac quam. Mauris non pretium nulla. Nam semper pulvinar convallis. Suspendisse ultricies \ -odio vitae tortor congue, rutrum finibus nisl malesuada. Interdum et malesuada fames ac ante \ -ipsum primis in faucibus. Vestibulum aliquam et lacus sit amet lobortis. In sed ligula quis urna \ -accumsan vehicula sit amet id magna. Cras mollis orci vitae turpis porta, sed gravida nunc \ -aliquam. Phasellus nec facilisis nunc. Suspendisse volutpat leo felis, in iaculis nisi dignissim \ -et. Phasellus at urna purus. Nullam vitae metus ante. Praesent porttitor libero quis velit \ -fermentum rhoncus. Cras vitae rhoncus nulla. In efficitur risus sapien, sed viverra neque \ -scelerisque at. Morbi fringilla odio massa. Donec tincidunt magna diam, eget congue leo tristique \ -eget. Cras et sapien nulla."; - diff --git a/resources/examples/lorem-ipsum/composite.fs.glsl b/resources/examples/lorem-ipsum/composite.fs.glsl new file mode 100644 index 00000000..73017889 --- /dev/null +++ b/resources/examples/lorem-ipsum/composite.fs.glsl @@ -0,0 +1,16 @@ +#version 330 + +uniform sampler2DRect uAtlas; +uniform vec3 uForegroundColor; +uniform vec3 uBackgroundColor; + +in vec2 vTexCoord; + +out vec4 oFragColor; + +void main() { + vec3 value = texture(uAtlas, vTexCoord).rgb; + vec3 color = mix(uBackgroundColor, uForegroundColor, value); + oFragColor = vec4(color, 1.0f); +} + diff --git a/resources/examples/lorem-ipsum/composite.vs.glsl b/resources/examples/lorem-ipsum/composite.vs.glsl new file mode 100644 index 00000000..6d53749b --- /dev/null +++ b/resources/examples/lorem-ipsum/composite.vs.glsl @@ -0,0 +1,15 @@ +#version 330 + +uniform mat2 uTransform; +uniform vec2 uTranslation; + +in vec2 aPosition; +in vec2 aTexCoord; + +out vec2 vTexCoord; + +void main() { + vTexCoord = aTexCoord; + gl_Position = vec4(uTransform * aPosition + uTranslation, 0.0f, 1.0f); +} + diff --git a/resources/examples/lorem-ipsum/default.txt b/resources/examples/lorem-ipsum/default.txt new file mode 100644 index 00000000..92dc8fde --- /dev/null +++ b/resources/examples/lorem-ipsum/default.txt @@ -0,0 +1,34 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur scelerisque pellentesque risus +quis vehicula. Ut sollicitudin aliquet diam, vel lobortis orci porta in. Sed eu nisi egestas odio +tincidunt cursus eget ut lorem. Fusce lacinia ex nec lectus rutrum mollis. Donec in ultrices +purus. Integer id suscipit magna. Suspendisse congue pulvinar neque id ultrices. Curabitur nec +tellus et est pellentesque posuere. Duis ut metus euismod, feugiat arcu vitae, posuere libero. +Curabitur nunc urna, rhoncus vitae scelerisque quis, viverra et odio. Suspendisse accumsan +pretium mi, nec fringilla metus condimentum id. Duis dignissim quam eu felis lobortis, eget +dignissim lectus fermentum. Nunc et massa id orci pellentesque rutrum. Nam imperdiet quam vel +ligula efficitur ultricies vel eu tellus. Maecenas luctus risus a erat euismod ultricies. +Pellentesque neque mauris, laoreet vitae finibus quis, molestie ut velit. Donec laoreet justo +risus. In id mi sed odio placerat interdum ut vitae erat. Fusce quis mollis mauris, sit amet +efficitur libero. In efficitur tortor nulla, sollicitudin sodales mi tempor in. In egestas +ultrices fermentum. Quisque mattis egestas nulla. Interdum et malesuada fames ac ante ipsum +primis in faucibus. Etiam in tempus sapien, in dignissim arcu. Quisque diam nulla, rhoncus et +tempor nec, facilisis porta purus. Nulla ut eros laoreet, placerat dolor ut, interdum orci. Sed +posuere eleifend mollis. Integer at nunc ex. Vestibulum aliquet risus quis lacinia convallis. +Fusce et metus viverra, varius nulla in, rutrum justo. Interdum et malesuada fames ac ante ipsum +primis in faucibus. Praesent non est vel lectus suscipit malesuada id ut nisl. Aenean sem ipsum, +tincidunt non orci non, varius consectetur purus. Aenean sed mollis turpis, sit amet vestibulum +risus. Nunc ut hendrerit urna, sit amet lacinia arcu. Curabitur laoreet a enim et eleifend. Etiam +consectetur pharetra massa, sed elementum quam molestie nec. Integer eu justo lectus. Vestibulum +sed vulputate sapien. Curabitur pretium luctus orci et interdum. Quisque ligula nisi, varius id +sodales id, volutpat et lorem. Pellentesque ex urna, malesuada at ex non, elementum ultricies +nulla. Nunc sodales, turpis at maximus bibendum, neque lorem laoreet felis, eget convallis sem +mauris ac quam. Mauris non pretium nulla. Nam semper pulvinar convallis. Suspendisse ultricies +odio vitae tortor congue, rutrum finibus nisl malesuada. Interdum et malesuada fames ac ante +ipsum primis in faucibus. Vestibulum aliquam et lacus sit amet lobortis. In sed ligula quis urna +accumsan vehicula sit amet id magna. Cras mollis orci vitae turpis porta, sed gravida nunc +aliquam. Phasellus nec facilisis nunc. Suspendisse volutpat leo felis, in iaculis nisi dignissim +et. Phasellus at urna purus. Nullam vitae metus ante. Praesent porttitor libero quis velit +fermentum rhoncus. Cras vitae rhoncus nulla. In efficitur risus sapien, sed viverra neque +scelerisque at. Morbi fringilla odio massa. Donec tincidunt magna diam, eget congue leo tristique +eget. Cras et sapien nulla. + diff --git a/resources/examples/lorem-ipsum/solid_color.fs.glsl b/resources/examples/lorem-ipsum/solid_color.fs.glsl new file mode 100644 index 00000000..7c1742b2 --- /dev/null +++ b/resources/examples/lorem-ipsum/solid_color.fs.glsl @@ -0,0 +1,10 @@ +#version 330 + +uniform vec3 uColor; + +out vec4 oFragColor; + +void main() { + oFragColor = vec4(uColor, 1.0f); +} + diff --git a/resources/examples/lorem-ipsum/solid_color.vs.glsl b/resources/examples/lorem-ipsum/solid_color.vs.glsl new file mode 100644 index 00000000..35067e51 --- /dev/null +++ b/resources/examples/lorem-ipsum/solid_color.vs.glsl @@ -0,0 +1,8 @@ +#version 330 + +in vec2 aPosition; + +void main() { + gl_Position = vec4(aPosition, 0.0f, 1.0f); +} +