Add some ground to the 3D scene, no depth buffer yet
This commit is contained in:
parent
0983812b90
commit
e4803cfddf
Binary file not shown.
After Width: | Height: | Size: 973 B |
Binary file not shown.
After Width: | Height: | Size: 879 B |
Binary file not shown.
After Width: | Height: | Size: 868 B |
|
@ -0,0 +1,21 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
// pathfinder/demo/resources/shaders/demo_ground.fs.glsl
|
||||||
|
//
|
||||||
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform vec4 uColor;
|
||||||
|
|
||||||
|
out vec4 oFragColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
oFragColor = uColor;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
// pathfinder/demo/resources/shaders/demo_ground.vs.glsl
|
||||||
|
//
|
||||||
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform mat4 uTransform;
|
||||||
|
|
||||||
|
in vec2 aPosition;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = uTransform * vec4(aPosition.x * 800.0, -30.0, aPosition.y * 800.0, 1.0);
|
||||||
|
}
|
344
demo/src/main.rs
344
demo/src/main.rs
|
@ -13,11 +13,14 @@
|
||||||
use crate::ui::{DemoUI, UIAction, UIEvent};
|
use crate::ui::{DemoUI, UIAction, UIEvent};
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
|
use gl::types::GLsizei;
|
||||||
use jemallocator;
|
use jemallocator;
|
||||||
use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32, Point3DF32};
|
use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32, Point3DF32};
|
||||||
use pathfinder_geometry::basic::rect::RectF32;
|
use pathfinder_geometry::basic::rect::RectF32;
|
||||||
use pathfinder_geometry::basic::transform2d::Transform2DF32;
|
use pathfinder_geometry::basic::transform2d::Transform2DF32;
|
||||||
use pathfinder_geometry::basic::transform3d::{Perspective, Transform3DF32};
|
use pathfinder_geometry::basic::transform3d::{Perspective, Transform3DF32};
|
||||||
|
use pathfinder_gl::device::{Buffer, BufferTarget, BufferUploadMode, Program, Uniform};
|
||||||
|
use pathfinder_gl::device::{VertexArray, VertexAttr};
|
||||||
use pathfinder_gl::renderer::Renderer;
|
use pathfinder_gl::renderer::Renderer;
|
||||||
use pathfinder_renderer::builder::{RenderOptions, RenderTransform, SceneBuilder};
|
use pathfinder_renderer::builder::{RenderOptions, RenderTransform, SceneBuilder};
|
||||||
use pathfinder_renderer::gpu_data::BuiltScene;
|
use pathfinder_renderer::gpu_data::BuiltScene;
|
||||||
|
@ -57,10 +60,14 @@ const CAMERA_SCALE_SPEED_2D: f32 = 2.0;
|
||||||
const CAMERA_ZOOM_AMOUNT_2D: f32 = 0.1;
|
const CAMERA_ZOOM_AMOUNT_2D: f32 = 0.1;
|
||||||
|
|
||||||
const BACKGROUND_COLOR: ColorU = ColorU { r: 32, g: 32, b: 32, a: 255 };
|
const BACKGROUND_COLOR: ColorU = ColorU { r: 32, g: 32, b: 32, a: 255 };
|
||||||
|
const GROUND_SOLID_COLOR: ColorU = ColorU { r: 80, g: 80, b: 80, a: 255 };
|
||||||
|
const GROUND_LINE_COLOR: ColorU = ColorU { r: 127, g: 127, b: 127, a: 255 };
|
||||||
|
|
||||||
const APPROX_FONT_SIZE: f32 = 16.0;
|
const APPROX_FONT_SIZE: f32 = 16.0;
|
||||||
|
|
||||||
const WORLD_SCALE: f32 = 1.0 / 800.0;
|
const WORLD_SCALE: f32 = 800.0;
|
||||||
|
const GROUND_SCALE: f32 = 2.0;
|
||||||
|
const GRIDLINE_COUNT: u8 = 10;
|
||||||
|
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|
||||||
|
@ -90,6 +97,11 @@ struct DemoApp {
|
||||||
ui: DemoUI,
|
ui: DemoUI,
|
||||||
scene_thread_proxy: SceneThreadProxy,
|
scene_thread_proxy: SceneThreadProxy,
|
||||||
renderer: Renderer,
|
renderer: Renderer,
|
||||||
|
|
||||||
|
device: DemoDevice,
|
||||||
|
ground_program: GroundProgram,
|
||||||
|
ground_solid_vertex_array: GroundSolidVertexArray,
|
||||||
|
ground_line_vertex_array: GroundLineVertexArray,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DemoApp {
|
impl DemoApp {
|
||||||
|
@ -121,11 +133,18 @@ impl DemoApp {
|
||||||
let drawable_size = Size2D::new(drawable_width, drawable_height);
|
let drawable_size = Size2D::new(drawable_width, drawable_height);
|
||||||
|
|
||||||
let base_scene = load_scene(&options.input_path);
|
let base_scene = load_scene(&options.input_path);
|
||||||
|
let renderer = Renderer::new(&drawable_size);
|
||||||
let scene_thread_proxy = SceneThreadProxy::new(base_scene, options.clone());
|
let scene_thread_proxy = SceneThreadProxy::new(base_scene, options.clone());
|
||||||
update_drawable_size(&window, &scene_thread_proxy);
|
update_drawable_size(&window, &scene_thread_proxy);
|
||||||
|
|
||||||
let camera = if options.threed { Camera::three_d() } else { Camera::two_d() };
|
let camera = if options.threed { Camera::three_d() } else { Camera::two_d() };
|
||||||
|
|
||||||
|
let grid_vertex_positions = create_grid_vertex_positions();
|
||||||
|
let ground_program = GroundProgram::new();
|
||||||
|
let ground_solid_vertex_array =
|
||||||
|
GroundSolidVertexArray::new(&ground_program, &renderer.quad_vertex_positions_buffer());
|
||||||
|
let ground_line_vertex_array = GroundLineVertexArray::new(&ground_program);
|
||||||
|
|
||||||
DemoApp {
|
DemoApp {
|
||||||
window,
|
window,
|
||||||
sdl_context,
|
sdl_context,
|
||||||
|
@ -144,7 +163,12 @@ impl DemoApp {
|
||||||
|
|
||||||
ui: DemoUI::new(options),
|
ui: DemoUI::new(options),
|
||||||
scene_thread_proxy,
|
scene_thread_proxy,
|
||||||
renderer: Renderer::new(&drawable_size),
|
renderer,
|
||||||
|
|
||||||
|
device: DemoDevice,
|
||||||
|
ground_program,
|
||||||
|
ground_solid_vertex_array,
|
||||||
|
ground_line_vertex_array,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,31 +189,14 @@ impl DemoApp {
|
||||||
|
|
||||||
fn build_scene(&mut self) {
|
fn build_scene(&mut self) {
|
||||||
let (drawable_width, drawable_height) = self.window.drawable_size();
|
let (drawable_width, drawable_height) = self.window.drawable_size();
|
||||||
let drawable_size = Size2D::new(drawable_width, drawable_height);
|
let drawable_size = Point2DI32::new(drawable_width as i32, drawable_height as i32);
|
||||||
|
|
||||||
let render_transform = match self.camera {
|
let render_transform = match self.camera {
|
||||||
Camera::ThreeD { ref mut position, velocity, yaw, pitch } => {
|
Camera::ThreeD { ref mut transform, ref mut velocity } => {
|
||||||
let rotation = Transform3DF32::from_rotation(-yaw, -pitch, 0.0);
|
if transform.offset(*velocity) {
|
||||||
|
|
||||||
if !velocity.is_zero() {
|
|
||||||
*position = *position + rotation.transform_point(velocity);
|
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
|
RenderTransform::Perspective(transform.to_perspective(drawable_size, true))
|
||||||
let aspect = drawable_size.width as f32 / drawable_size.height as f32;
|
|
||||||
let mut transform =
|
|
||||||
Transform3DF32::from_perspective(FRAC_PI_4, aspect, 0.025, 100.0);
|
|
||||||
|
|
||||||
transform = transform.post_mul(&Transform3DF32::from_scale(WORLD_SCALE,
|
|
||||||
WORLD_SCALE,
|
|
||||||
WORLD_SCALE));
|
|
||||||
transform = transform.post_mul(&Transform3DF32::from_rotation(yaw, pitch, 0.0));
|
|
||||||
let translation = position.scale(-1.0);
|
|
||||||
transform = transform.post_mul(&Transform3DF32::from_translation(translation.x(),
|
|
||||||
translation.y(),
|
|
||||||
translation.z()));
|
|
||||||
|
|
||||||
RenderTransform::Perspective(Perspective::new(&transform, &drawable_size))
|
|
||||||
}
|
}
|
||||||
Camera::TwoD(transform) => RenderTransform::Transform2D(transform),
|
Camera::TwoD(transform) => RenderTransform::Transform2D(transform),
|
||||||
};
|
};
|
||||||
|
@ -242,10 +249,9 @@ impl DemoApp {
|
||||||
ui_event = UIEvent::MouseDown(point);
|
ui_event = UIEvent::MouseDown(point);
|
||||||
}
|
}
|
||||||
Event::MouseMotion { xrel, yrel, .. } if self.mouselook_enabled => {
|
Event::MouseMotion { xrel, yrel, .. } if self.mouselook_enabled => {
|
||||||
if let Camera::ThreeD { ref mut yaw, ref mut pitch, .. } =
|
if let Camera::ThreeD { ref mut transform, .. } = self.camera {
|
||||||
self.camera {
|
transform.yaw += xrel as f32 * MOUSELOOK_ROTATION_SPEED;
|
||||||
*yaw += xrel as f32 * MOUSELOOK_ROTATION_SPEED;
|
transform.pitch += yrel as f32 * MOUSELOOK_ROTATION_SPEED;
|
||||||
*pitch -= yrel as f32 * MOUSELOOK_ROTATION_SPEED;
|
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,14 +321,100 @@ impl DemoApp {
|
||||||
fn draw_scene(&mut self, render_msg: SceneToMainMsg, mut ui_event: UIEvent) {
|
fn draw_scene(&mut self, render_msg: SceneToMainMsg, mut ui_event: UIEvent) {
|
||||||
let SceneToMainMsg::Render { built_scene, tile_time } = render_msg;
|
let SceneToMainMsg::Render { built_scene, tile_time } = render_msg;
|
||||||
|
|
||||||
unsafe {
|
self.device.clear();
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
self.draw_environment();
|
||||||
gl::ClearColor(BACKGROUND_COLOR.r as f32 / 255.0,
|
self.render_vector_scene(&built_scene);
|
||||||
BACKGROUND_COLOR.g as f32 / 255.0,
|
|
||||||
BACKGROUND_COLOR.b as f32 / 255.0,
|
|
||||||
BACKGROUND_COLOR.a as f32 / 255.0);
|
|
||||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
|
let rendering_time = self.renderer.shift_timer_query();
|
||||||
|
self.renderer.debug_ui.add_sample(tile_time, rendering_time);
|
||||||
|
self.renderer.debug_ui.draw();
|
||||||
|
|
||||||
|
if !ui_event.is_none() {
|
||||||
|
self.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ui_action = UIAction::None;
|
||||||
|
self.ui.update(&mut self.renderer.debug_ui, &mut ui_event, &mut ui_action);
|
||||||
|
self.handle_ui_action(&mut ui_action);
|
||||||
|
|
||||||
|
// Switch camera mode (2D/3D) if requested.
|
||||||
|
//
|
||||||
|
// FIXME(pcwalton): This mess should really be an MVC setup.
|
||||||
|
match (&self.camera, self.ui.threed_enabled) {
|
||||||
|
(&Camera::TwoD { .. }, true) => self.camera = Camera::three_d(),
|
||||||
|
(&Camera::ThreeD { .. }, false) => self.camera = Camera::two_d(),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
match ui_event {
|
||||||
|
UIEvent::MouseDown(_) if self.camera.is_3d() => {
|
||||||
|
// If nothing handled the mouse-down event, toggle mouselook.
|
||||||
|
self.mouselook_enabled = !self.mouselook_enabled;
|
||||||
|
}
|
||||||
|
UIEvent::MouseDragged { relative_position, .. } => {
|
||||||
|
if let Camera::TwoD(ref mut transform) = self.camera {
|
||||||
|
*transform = transform.post_translate(relative_position.to_f32());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.window.gl_swap_window();
|
||||||
|
self.frame_counter += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_environment(&self) {
|
||||||
|
let transform = match self.camera {
|
||||||
|
Camera::TwoD(..) => return,
|
||||||
|
Camera::ThreeD { ref transform, .. } => *transform,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (drawable_width, drawable_height) = self.window.drawable_size();
|
||||||
|
let drawable_size = Point2DI32::new(drawable_width as i32, drawable_height as i32);
|
||||||
|
let perspective = transform.to_perspective(drawable_size, false);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut transform = perspective.transform;
|
||||||
|
transform =
|
||||||
|
transform.post_mul(&Transform3DF32::from_scale(GROUND_SCALE, 1.0, GROUND_SCALE));
|
||||||
|
gl::BindVertexArray(self.ground_solid_vertex_array.vertex_array.gl_vertex_array);
|
||||||
|
gl::UseProgram(self.ground_program.program.gl_program);
|
||||||
|
gl::UniformMatrix4fv(self.ground_program.transform_uniform.location,
|
||||||
|
1,
|
||||||
|
gl::FALSE,
|
||||||
|
transform.as_ptr());
|
||||||
|
let color = GROUND_SOLID_COLOR.to_f32();
|
||||||
|
gl::Uniform4f(self.ground_program.color_uniform.location,
|
||||||
|
color.r(),
|
||||||
|
color.g(),
|
||||||
|
color.b(),
|
||||||
|
color.a());
|
||||||
|
gl::Disable(gl::BLEND);
|
||||||
|
gl::DrawArrays(gl::TRIANGLE_FAN, 0, 4);
|
||||||
|
|
||||||
|
let mut transform = perspective.transform;
|
||||||
|
let gridline_scale = GROUND_SCALE / GRIDLINE_COUNT as f32;
|
||||||
|
transform = transform.post_mul(&Transform3DF32::from_scale(gridline_scale,
|
||||||
|
1.0,
|
||||||
|
gridline_scale));
|
||||||
|
gl::BindVertexArray(self.ground_line_vertex_array.vertex_array.gl_vertex_array);
|
||||||
|
gl::UseProgram(self.ground_program.program.gl_program);
|
||||||
|
gl::UniformMatrix4fv(self.ground_program.transform_uniform.location,
|
||||||
|
1,
|
||||||
|
gl::FALSE,
|
||||||
|
transform.as_ptr());
|
||||||
|
let color = GROUND_LINE_COLOR.to_f32();
|
||||||
|
gl::Uniform4f(self.ground_program.color_uniform.location,
|
||||||
|
color.r(),
|
||||||
|
color.g(),
|
||||||
|
color.b(),
|
||||||
|
color.a());
|
||||||
|
gl::Disable(gl::BLEND);
|
||||||
|
gl::DrawArrays(gl::LINES, 0, (GRIDLINE_COUNT as GLsizei + 1) * 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_vector_scene(&mut self, built_scene: &BuiltScene) {
|
||||||
if self.ui.gamma_correction_effect_enabled {
|
if self.ui.gamma_correction_effect_enabled {
|
||||||
self.renderer.enable_gamma_correction(BACKGROUND_COLOR);
|
self.renderer.enable_gamma_correction(BACKGROUND_COLOR);
|
||||||
} else {
|
} else {
|
||||||
|
@ -336,22 +428,12 @@ impl DemoApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.renderer.render_scene(&built_scene);
|
self.renderer.render_scene(&built_scene);
|
||||||
|
|
||||||
let rendering_time = self.renderer.shift_timer_query();
|
|
||||||
self.renderer.debug_ui.add_sample(tile_time, rendering_time);
|
|
||||||
self.renderer.debug_ui.draw();
|
|
||||||
|
|
||||||
if !ui_event.is_none() {
|
|
||||||
self.dirty = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ui_action = UIAction::None;
|
fn handle_ui_action(&mut self, ui_action: &mut UIAction) {
|
||||||
self.ui.update(&mut self.renderer.debug_ui, &mut ui_event, &mut ui_action);
|
|
||||||
|
|
||||||
// Handle UI actions.
|
|
||||||
match ui_action {
|
match ui_action {
|
||||||
UIAction::None => {}
|
UIAction::None => {}
|
||||||
UIAction::OpenFile(path) => {
|
UIAction::OpenFile(ref path) => {
|
||||||
let scene = load_scene(&path);
|
let scene = load_scene(&path);
|
||||||
self.scene_thread_proxy.load_scene(scene);
|
self.scene_thread_proxy.load_scene(scene);
|
||||||
update_drawable_size(&self.window, &self.scene_thread_proxy);
|
update_drawable_size(&self.window, &self.scene_thread_proxy);
|
||||||
|
@ -382,37 +464,11 @@ impl DemoApp {
|
||||||
let old_rotation = transform.rotation();
|
let old_rotation = transform.rotation();
|
||||||
let center = center_of_window(&self.window);
|
let center = center_of_window(&self.window);
|
||||||
*transform = transform.post_translate(-center)
|
*transform = transform.post_translate(-center)
|
||||||
.post_rotate(theta - old_rotation)
|
.post_rotate(*theta - old_rotation)
|
||||||
.post_translate(center);
|
.post_translate(center);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch camera mode (2D/3D) if requested.
|
|
||||||
//
|
|
||||||
// FIXME(pcwalton): This mess should really be an MVC setup.
|
|
||||||
match (&self.camera, self.ui.threed_enabled) {
|
|
||||||
(&Camera::TwoD { .. }, true) => self.camera = Camera::three_d(),
|
|
||||||
(&Camera::ThreeD { .. }, false) => self.camera = Camera::two_d(),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
match ui_event {
|
|
||||||
UIEvent::MouseDown(_) if self.camera.is_3d() => {
|
|
||||||
// If nothing handled the mouse-down event, toggle mouselook.
|
|
||||||
self.mouselook_enabled = !self.mouselook_enabled;
|
|
||||||
}
|
|
||||||
UIEvent::MouseDragged { relative_position, .. } => {
|
|
||||||
if let Camera::TwoD(ref mut transform) = self.camera {
|
|
||||||
*transform = transform.post_translate(relative_position.to_f32());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.window.gl_swap_window();
|
|
||||||
self.frame_counter += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,7 +654,7 @@ fn center_of_window(window: &Window) -> Point2DF32 {
|
||||||
|
|
||||||
enum Camera {
|
enum Camera {
|
||||||
TwoD(Transform2DF32),
|
TwoD(Transform2DF32),
|
||||||
ThreeD { position: Point3DF32, velocity: Point3DF32, yaw: f32, pitch: f32 },
|
ThreeD { transform: CameraTransform3D, velocity: Point3DF32 },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Camera {
|
impl Camera {
|
||||||
|
@ -607,15 +663,143 @@ impl Camera {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn three_d() -> Camera {
|
fn three_d() -> Camera {
|
||||||
Camera::ThreeD {
|
Camera::ThreeD { transform: CameraTransform3D::new(), velocity: Point3DF32::default() }
|
||||||
position: Point3DF32::new(500.0, 500.0, 3000.0, 1.0),
|
|
||||||
velocity: Point3DF32::new(0.0, 0.0, 0.0, 1.0),
|
|
||||||
yaw: 0.0,
|
|
||||||
pitch: 0.0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_3d(&self) -> bool {
|
fn is_3d(&self) -> bool {
|
||||||
match *self { Camera::ThreeD { .. } => true, Camera::TwoD { .. } => false }
|
match *self { Camera::ThreeD { .. } => true, Camera::TwoD { .. } => false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
struct CameraTransform3D {
|
||||||
|
position: Point3DF32,
|
||||||
|
yaw: f32,
|
||||||
|
pitch: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CameraTransform3D {
|
||||||
|
fn new() -> CameraTransform3D {
|
||||||
|
CameraTransform3D {
|
||||||
|
position: Point3DF32::new(500.0, 500.0, 3000.0, 1.0),
|
||||||
|
yaw: 0.0,
|
||||||
|
pitch: 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn offset(&mut self, vector: Point3DF32) -> bool {
|
||||||
|
let update = !vector.is_zero();
|
||||||
|
if update {
|
||||||
|
let rotation = Transform3DF32::from_rotation(-self.yaw, -self.pitch, 0.0);
|
||||||
|
self.position = self.position + rotation.transform_point(vector);
|
||||||
|
}
|
||||||
|
update
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_perspective(&self, drawable_size: Point2DI32, flip_y: bool) -> Perspective {
|
||||||
|
let aspect = drawable_size.x() as f32 / drawable_size.y() as f32;
|
||||||
|
let mut transform = Transform3DF32::from_perspective(FRAC_PI_4, aspect, 0.025, 100.0);
|
||||||
|
|
||||||
|
let scale_inv = 1.0 / WORLD_SCALE;
|
||||||
|
transform = transform.post_mul(&Transform3DF32::from_rotation(self.yaw, self.pitch, 0.0));
|
||||||
|
transform = transform.post_mul(&Transform3DF32::from_uniform_scale(scale_inv));
|
||||||
|
transform = transform.post_mul(&Transform3DF32::from_translation(-self.position.x(),
|
||||||
|
-self.position.y(),
|
||||||
|
-self.position.z()));
|
||||||
|
|
||||||
|
if flip_y {
|
||||||
|
transform = transform.post_mul(&Transform3DF32::from_scale(1.0, -1.0, 1.0));
|
||||||
|
transform =
|
||||||
|
transform.post_mul(&Transform3DF32::from_translation(0.0, -WORLD_SCALE, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
let drawable_size = Size2D::new(drawable_size.x() as u32, drawable_size.y() as u32);
|
||||||
|
Perspective::new(&transform, &drawable_size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DemoDevice;
|
||||||
|
|
||||||
|
impl DemoDevice {
|
||||||
|
fn clear(&self) {
|
||||||
|
let color = BACKGROUND_COLOR.to_f32();
|
||||||
|
unsafe {
|
||||||
|
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||||
|
gl::ClearColor(color.r(), color.g(), color.b(), color.a());
|
||||||
|
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GroundProgram {
|
||||||
|
program: Program,
|
||||||
|
transform_uniform: Uniform,
|
||||||
|
color_uniform: Uniform,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GroundProgram {
|
||||||
|
fn new() -> GroundProgram {
|
||||||
|
let program = Program::new("demo_ground");
|
||||||
|
let transform_uniform = Uniform::new(&program, "Transform");
|
||||||
|
let color_uniform = Uniform::new(&program, "Color");
|
||||||
|
GroundProgram { program, transform_uniform, color_uniform }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GroundSolidVertexArray {
|
||||||
|
vertex_array: VertexArray,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GroundSolidVertexArray {
|
||||||
|
fn new(ground_program: &GroundProgram, quad_vertex_positions_buffer: &Buffer)
|
||||||
|
-> GroundSolidVertexArray {
|
||||||
|
let vertex_array = VertexArray::new();
|
||||||
|
unsafe {
|
||||||
|
let position_attr = VertexAttr::new(&ground_program.program, "Position");
|
||||||
|
|
||||||
|
gl::BindVertexArray(vertex_array.gl_vertex_array);
|
||||||
|
gl::UseProgram(ground_program.program.gl_program);
|
||||||
|
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vertex_positions_buffer.gl_buffer);
|
||||||
|
position_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
GroundSolidVertexArray { vertex_array }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GroundLineVertexArray {
|
||||||
|
vertex_array: VertexArray,
|
||||||
|
grid_vertex_positions_buffer: Buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GroundLineVertexArray {
|
||||||
|
fn new(ground_program: &GroundProgram) -> GroundLineVertexArray {
|
||||||
|
let grid_vertex_positions_buffer = Buffer::new();
|
||||||
|
grid_vertex_positions_buffer.upload(&create_grid_vertex_positions(),
|
||||||
|
BufferTarget::Vertex,
|
||||||
|
BufferUploadMode::Static);
|
||||||
|
|
||||||
|
let vertex_array = VertexArray::new();
|
||||||
|
unsafe {
|
||||||
|
let position_attr = VertexAttr::new(&ground_program.program, "Position");
|
||||||
|
|
||||||
|
gl::BindVertexArray(vertex_array.gl_vertex_array);
|
||||||
|
gl::UseProgram(ground_program.program.gl_program);
|
||||||
|
gl::BindBuffer(gl::ARRAY_BUFFER, grid_vertex_positions_buffer.gl_buffer);
|
||||||
|
position_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
GroundLineVertexArray { vertex_array, grid_vertex_positions_buffer }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_grid_vertex_positions() -> Vec<(u8, u8)> {
|
||||||
|
let mut positions = vec![];
|
||||||
|
for index in 0..(GRIDLINE_COUNT + 1) {
|
||||||
|
positions.extend_from_slice(&[
|
||||||
|
(0, index), (GRIDLINE_COUNT, index),
|
||||||
|
(index, 0), (index, GRIDLINE_COUNT),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
positions
|
||||||
|
}
|
||||||
|
|
|
@ -232,7 +232,7 @@ impl Sub<Point2DI32> for Point2DI32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 3D homogeneous points.
|
/// 3D homogeneous points.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub struct Point3DF32(pub F32x4);
|
pub struct Point3DF32(pub F32x4);
|
||||||
|
|
||||||
impl Point3DF32 {
|
impl Point3DF32 {
|
||||||
|
@ -350,3 +350,12 @@ impl Mul<Point3DF32> for Point3DF32 {
|
||||||
Point3DF32(self.0 * other.0)
|
Point3DF32(self.0 * other.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Point3DF32 {
|
||||||
|
#[inline]
|
||||||
|
fn default() -> Point3DF32 {
|
||||||
|
let mut point = F32x4::default();
|
||||||
|
point.set_w(1.0);
|
||||||
|
Point3DF32(point)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ use std::ops::{Add, Neg};
|
||||||
///
|
///
|
||||||
/// In column-major order.
|
/// In column-major order.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct Transform3DF32 {
|
pub struct Transform3DF32 {
|
||||||
c0: F32x4,
|
c0: F32x4,
|
||||||
c1: F32x4,
|
c1: F32x4,
|
||||||
|
@ -64,6 +65,11 @@ impl Transform3DF32 {
|
||||||
0.0, 0.0, 0.0, 1.0)
|
0.0, 0.0, 0.0, 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn from_uniform_scale(factor: f32) -> Transform3DF32 {
|
||||||
|
Transform3DF32::from_scale(factor, factor, factor)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_translation(x: f32, y: f32, z: f32) -> Transform3DF32 {
|
pub fn from_translation(x: f32, y: f32, z: f32) -> Transform3DF32 {
|
||||||
Transform3DF32::row_major(1.0, 0.0, 0.0, x,
|
Transform3DF32::row_major(1.0, 0.0, 0.0, x,
|
||||||
|
@ -229,6 +235,11 @@ impl Transform3DF32 {
|
||||||
self.c2.approx_eq(other.c2, epsilon) &&
|
self.c2.approx_eq(other.c2, epsilon) &&
|
||||||
self.c3.approx_eq(other.c3, epsilon)
|
self.c3.approx_eq(other.c3, epsilon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn as_ptr(&self) -> *const f32 {
|
||||||
|
(&self.c0) as *const F32x4 as *const f32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add<Matrix2x2F32> for Matrix2x2F32 {
|
impl Add<Matrix2x2F32> for Matrix2x2F32 {
|
||||||
|
@ -261,7 +272,10 @@ impl Perspective {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn transform_point_2d(&self, point: &Point2DF32) -> Point2DF32 {
|
pub fn transform_point_2d(&self, point: &Point2DF32) -> Point2DF32 {
|
||||||
let point = self.transform.transform_point(point.to_3d()).perspective_divide().to_2d();
|
let point = self.transform
|
||||||
|
.transform_point(point.to_3d())
|
||||||
|
.perspective_divide()
|
||||||
|
.to_2d() * Point2DF32::new(1.0, -1.0);
|
||||||
let window_size = self.window_size.to_f32();
|
let window_size = self.window_size.to_f32();
|
||||||
let size_scale = Point2DF32::new(window_size.width * 0.5, window_size.height * 0.5);
|
let size_scale = Point2DF32::new(window_size.width * 0.5, window_size.height * 0.5);
|
||||||
(point + Point2DF32::splat(1.0)) * size_scale
|
(point + Point2DF32::splat(1.0)) * size_scale
|
||||||
|
|
|
@ -18,6 +18,30 @@ use std::io::Read;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
|
pub struct VertexArray {
|
||||||
|
pub gl_vertex_array: GLuint,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for VertexArray {
|
||||||
|
#[inline]
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
gl::DeleteVertexArrays(1, &mut self.gl_vertex_array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VertexArray {
|
||||||
|
#[inline]
|
||||||
|
pub fn new() -> VertexArray {
|
||||||
|
unsafe {
|
||||||
|
let mut array = VertexArray { gl_vertex_array: 0 };
|
||||||
|
gl::GenVertexArrays(1, &mut array.gl_vertex_array);
|
||||||
|
array
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct VertexAttr {
|
pub struct VertexAttr {
|
||||||
attr: GLuint,
|
attr: GLuint,
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
use crate::debug::DebugUI;
|
use crate::debug::DebugUI;
|
||||||
use crate::device::{Buffer, BufferTarget, BufferUploadMode, Framebuffer, Program, Texture};
|
use crate::device::{Buffer, BufferTarget, BufferUploadMode, Framebuffer, Program, Texture};
|
||||||
use crate::device::{TimerQuery, Uniform, VertexAttr};
|
use crate::device::{TimerQuery, Uniform, VertexArray, VertexAttr};
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use gl::types::{GLfloat, GLint, GLuint};
|
use gl::types::{GLfloat, GLint};
|
||||||
use pathfinder_renderer::gpu_data::{Batch, BuiltScene, SolidTileScenePrimitive};
|
use pathfinder_renderer::gpu_data::{Batch, BuiltScene, SolidTileScenePrimitive};
|
||||||
use pathfinder_renderer::paint::{ColorU, ObjectShader};
|
use pathfinder_renderer::paint::{ColorU, ObjectShader};
|
||||||
use pathfinder_renderer::post::DefringingKernel;
|
use pathfinder_renderer::post::DefringingKernel;
|
||||||
|
@ -39,7 +39,6 @@ pub struct Renderer {
|
||||||
solid_tile_program: SolidTileProgram,
|
solid_tile_program: SolidTileProgram,
|
||||||
mask_tile_program: MaskTileProgram,
|
mask_tile_program: MaskTileProgram,
|
||||||
area_lut_texture: Texture,
|
area_lut_texture: Texture,
|
||||||
#[allow(dead_code)]
|
|
||||||
quad_vertex_positions_buffer: Buffer,
|
quad_vertex_positions_buffer: Buffer,
|
||||||
fill_vertex_array: FillVertexArray,
|
fill_vertex_array: FillVertexArray,
|
||||||
mask_tile_vertex_array: MaskTileVertexArray,
|
mask_tile_vertex_array: MaskTileVertexArray,
|
||||||
|
@ -186,6 +185,11 @@ impl Renderer {
|
||||||
self.postprocess_options.gamma_correction_bg_color = Some(bg_color);
|
self.postprocess_options.gamma_correction_bg_color = Some(bg_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn quad_vertex_positions_buffer(&self) -> &Buffer {
|
||||||
|
&self.quad_vertex_positions_buffer
|
||||||
|
}
|
||||||
|
|
||||||
fn upload_shaders(&mut self, shaders: &[ObjectShader]) {
|
fn upload_shaders(&mut self, shaders: &[ObjectShader]) {
|
||||||
let size = Size2D::new(FILL_COLORS_TEXTURE_WIDTH, FILL_COLORS_TEXTURE_HEIGHT);
|
let size = Size2D::new(FILL_COLORS_TEXTURE_WIDTH, FILL_COLORS_TEXTURE_HEIGHT);
|
||||||
let mut fill_colors = vec![0; size.width as usize * size.height as usize * 4];
|
let mut fill_colors = vec![0; size.width as usize * size.height as usize * 4];
|
||||||
|
@ -221,7 +225,7 @@ impl Renderer {
|
||||||
gl::ClearColor(0.0, 0.0, 0.0, 0.0);
|
gl::ClearColor(0.0, 0.0, 0.0, 0.0);
|
||||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
gl::BindVertexArray(self.fill_vertex_array.gl_vertex_array);
|
gl::BindVertexArray(self.fill_vertex_array.vertex_array.gl_vertex_array);
|
||||||
gl::UseProgram(self.fill_program.program.gl_program);
|
gl::UseProgram(self.fill_program.program.gl_program);
|
||||||
gl::Uniform2f(self.fill_program.framebuffer_size_uniform.location,
|
gl::Uniform2f(self.fill_program.framebuffer_size_uniform.location,
|
||||||
MASK_FRAMEBUFFER_WIDTH as GLfloat,
|
MASK_FRAMEBUFFER_WIDTH as GLfloat,
|
||||||
|
@ -244,7 +248,7 @@ impl Renderer {
|
||||||
self.bind_draw_framebuffer();
|
self.bind_draw_framebuffer();
|
||||||
self.set_main_viewport();
|
self.set_main_viewport();
|
||||||
|
|
||||||
gl::BindVertexArray(self.mask_tile_vertex_array.gl_vertex_array);
|
gl::BindVertexArray(self.mask_tile_vertex_array.vertex_array.gl_vertex_array);
|
||||||
gl::UseProgram(self.mask_tile_program.program.gl_program);
|
gl::UseProgram(self.mask_tile_program.program.gl_program);
|
||||||
gl::Uniform2f(self.mask_tile_program.framebuffer_size_uniform.location,
|
gl::Uniform2f(self.mask_tile_program.framebuffer_size_uniform.location,
|
||||||
self.main_framebuffer_size.width as GLfloat,
|
self.main_framebuffer_size.width as GLfloat,
|
||||||
|
@ -275,7 +279,7 @@ impl Renderer {
|
||||||
self.bind_draw_framebuffer();
|
self.bind_draw_framebuffer();
|
||||||
self.set_main_viewport();
|
self.set_main_viewport();
|
||||||
|
|
||||||
gl::BindVertexArray(self.solid_tile_vertex_array.gl_vertex_array);
|
gl::BindVertexArray(self.solid_tile_vertex_array.vertex_array.gl_vertex_array);
|
||||||
gl::UseProgram(self.solid_tile_program.program.gl_program);
|
gl::UseProgram(self.solid_tile_program.program.gl_program);
|
||||||
gl::Uniform2f(self.solid_tile_program.framebuffer_size_uniform.location,
|
gl::Uniform2f(self.solid_tile_program.framebuffer_size_uniform.location,
|
||||||
self.main_framebuffer_size.width as GLfloat,
|
self.main_framebuffer_size.width as GLfloat,
|
||||||
|
@ -300,7 +304,7 @@ impl Renderer {
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||||
self.set_main_viewport();
|
self.set_main_viewport();
|
||||||
|
|
||||||
gl::BindVertexArray(self.postprocess_vertex_array.gl_vertex_array);
|
gl::BindVertexArray(self.postprocess_vertex_array.vertex_array.gl_vertex_array);
|
||||||
gl::UseProgram(self.postprocess_program.program.gl_program);
|
gl::UseProgram(self.postprocess_program.program.gl_program);
|
||||||
gl::Uniform2f(self.postprocess_program.framebuffer_size_uniform.location,
|
gl::Uniform2f(self.postprocess_program.framebuffer_size_uniform.location,
|
||||||
self.main_framebuffer_size.width as GLfloat,
|
self.main_framebuffer_size.width as GLfloat,
|
||||||
|
@ -406,14 +410,13 @@ struct PostprocessOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FillVertexArray {
|
struct FillVertexArray {
|
||||||
gl_vertex_array: GLuint,
|
vertex_array: VertexArray,
|
||||||
vertex_buffer: Buffer,
|
vertex_buffer: Buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FillVertexArray {
|
impl FillVertexArray {
|
||||||
fn new(fill_program: &FillProgram, quad_vertex_positions_buffer: &Buffer) -> FillVertexArray {
|
fn new(fill_program: &FillProgram, quad_vertex_positions_buffer: &Buffer) -> FillVertexArray {
|
||||||
let vertex_buffer = Buffer::new();
|
let (vertex_array, vertex_buffer) = (VertexArray::new(), Buffer::new());
|
||||||
let mut gl_vertex_array = 0;
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let tess_coord_attr = VertexAttr::new(&fill_program.program, "TessCoord");
|
let tess_coord_attr = VertexAttr::new(&fill_program.program, "TessCoord");
|
||||||
let from_px_attr = VertexAttr::new(&fill_program.program, "FromPx");
|
let from_px_attr = VertexAttr::new(&fill_program.program, "FromPx");
|
||||||
|
@ -422,8 +425,7 @@ impl FillVertexArray {
|
||||||
let to_subpx_attr = VertexAttr::new(&fill_program.program, "ToSubpx");
|
let to_subpx_attr = VertexAttr::new(&fill_program.program, "ToSubpx");
|
||||||
let tile_index_attr = VertexAttr::new(&fill_program.program, "TileIndex");
|
let tile_index_attr = VertexAttr::new(&fill_program.program, "TileIndex");
|
||||||
|
|
||||||
gl::GenVertexArrays(1, &mut gl_vertex_array);
|
gl::BindVertexArray(vertex_array.gl_vertex_array);
|
||||||
gl::BindVertexArray(gl_vertex_array);
|
|
||||||
gl::UseProgram(fill_program.program.gl_program);
|
gl::UseProgram(fill_program.program.gl_program);
|
||||||
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vertex_positions_buffer.gl_buffer);
|
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vertex_positions_buffer.gl_buffer);
|
||||||
tess_coord_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
tess_coord_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
||||||
|
@ -435,29 +437,19 @@ impl FillVertexArray {
|
||||||
tile_index_attr.configure_int(1, gl::UNSIGNED_SHORT, FILL_INSTANCE_SIZE, 6, 1);
|
tile_index_attr.configure_int(1, gl::UNSIGNED_SHORT, FILL_INSTANCE_SIZE, 6, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
FillVertexArray { gl_vertex_array, vertex_buffer }
|
FillVertexArray { vertex_array, vertex_buffer }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for FillVertexArray {
|
|
||||||
#[inline]
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
gl::DeleteVertexArrays(1, &mut self.gl_vertex_array);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MaskTileVertexArray {
|
struct MaskTileVertexArray {
|
||||||
gl_vertex_array: GLuint,
|
vertex_array: VertexArray,
|
||||||
vertex_buffer: Buffer,
|
vertex_buffer: Buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MaskTileVertexArray {
|
impl MaskTileVertexArray {
|
||||||
fn new(mask_tile_program: &MaskTileProgram, quad_vertex_positions_buffer: &Buffer)
|
fn new(mask_tile_program: &MaskTileProgram, quad_vertex_positions_buffer: &Buffer)
|
||||||
-> MaskTileVertexArray {
|
-> MaskTileVertexArray {
|
||||||
let vertex_buffer = Buffer::new();
|
let (vertex_array, vertex_buffer) = (VertexArray::new(), Buffer::new());
|
||||||
let mut gl_vertex_array = 0;
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let tess_coord_attr = VertexAttr::new(&mask_tile_program.program, "TessCoord");
|
let tess_coord_attr = VertexAttr::new(&mask_tile_program.program, "TessCoord");
|
||||||
let tile_origin_attr = VertexAttr::new(&mask_tile_program.program, "TileOrigin");
|
let tile_origin_attr = VertexAttr::new(&mask_tile_program.program, "TileOrigin");
|
||||||
|
@ -466,8 +458,7 @@ impl MaskTileVertexArray {
|
||||||
|
|
||||||
// NB: The object must be of type short, not unsigned short, to work around a macOS
|
// NB: The object must be of type short, not unsigned short, to work around a macOS
|
||||||
// Radeon driver bug.
|
// Radeon driver bug.
|
||||||
gl::GenVertexArrays(1, &mut gl_vertex_array);
|
gl::BindVertexArray(vertex_array.gl_vertex_array);
|
||||||
gl::BindVertexArray(gl_vertex_array);
|
|
||||||
gl::UseProgram(mask_tile_program.program.gl_program);
|
gl::UseProgram(mask_tile_program.program.gl_program);
|
||||||
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vertex_positions_buffer.gl_buffer);
|
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vertex_positions_buffer.gl_buffer);
|
||||||
tess_coord_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
tess_coord_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
||||||
|
@ -477,29 +468,19 @@ impl MaskTileVertexArray {
|
||||||
object_attr.configure_int(2, gl::SHORT, MASK_TILE_INSTANCE_SIZE, 6, 1);
|
object_attr.configure_int(2, gl::SHORT, MASK_TILE_INSTANCE_SIZE, 6, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
MaskTileVertexArray { gl_vertex_array, vertex_buffer }
|
MaskTileVertexArray { vertex_array, vertex_buffer }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for MaskTileVertexArray {
|
|
||||||
#[inline]
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
gl::DeleteVertexArrays(1, &mut self.gl_vertex_array);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SolidTileVertexArray {
|
struct SolidTileVertexArray {
|
||||||
gl_vertex_array: GLuint,
|
vertex_array: VertexArray,
|
||||||
vertex_buffer: Buffer,
|
vertex_buffer: Buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SolidTileVertexArray {
|
impl SolidTileVertexArray {
|
||||||
fn new(solid_tile_program: &SolidTileProgram, quad_vertex_positions_buffer: &Buffer)
|
fn new(solid_tile_program: &SolidTileProgram, quad_vertex_positions_buffer: &Buffer)
|
||||||
-> SolidTileVertexArray {
|
-> SolidTileVertexArray {
|
||||||
let vertex_buffer = Buffer::new();
|
let (vertex_array, vertex_buffer) = (VertexArray::new(), Buffer::new());
|
||||||
let mut gl_vertex_array = 0;
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let tess_coord_attr = VertexAttr::new(&solid_tile_program.program, "TessCoord");
|
let tess_coord_attr = VertexAttr::new(&solid_tile_program.program, "TessCoord");
|
||||||
let tile_origin_attr = VertexAttr::new(&solid_tile_program.program, "TileOrigin");
|
let tile_origin_attr = VertexAttr::new(&solid_tile_program.program, "TileOrigin");
|
||||||
|
@ -507,8 +488,7 @@ impl SolidTileVertexArray {
|
||||||
|
|
||||||
// NB: The object must be of type short, not unsigned short, to work around a macOS
|
// NB: The object must be of type short, not unsigned short, to work around a macOS
|
||||||
// Radeon driver bug.
|
// Radeon driver bug.
|
||||||
gl::GenVertexArrays(1, &mut gl_vertex_array);
|
gl::BindVertexArray(vertex_array.gl_vertex_array);
|
||||||
gl::BindVertexArray(gl_vertex_array);
|
|
||||||
gl::UseProgram(solid_tile_program.program.gl_program);
|
gl::UseProgram(solid_tile_program.program.gl_program);
|
||||||
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vertex_positions_buffer.gl_buffer);
|
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vertex_positions_buffer.gl_buffer);
|
||||||
tess_coord_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
tess_coord_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
||||||
|
@ -517,16 +497,7 @@ impl SolidTileVertexArray {
|
||||||
object_attr.configure_int(1, gl::SHORT, SOLID_TILE_INSTANCE_SIZE, 4, 1);
|
object_attr.configure_int(1, gl::SHORT, SOLID_TILE_INSTANCE_SIZE, 4, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SolidTileVertexArray { gl_vertex_array, vertex_buffer }
|
SolidTileVertexArray { vertex_array, vertex_buffer }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for SolidTileVertexArray {
|
|
||||||
#[inline]
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
gl::DeleteVertexArrays(1, &mut self.gl_vertex_array);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,32 +609,22 @@ impl PostprocessProgram {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PostprocessVertexArray {
|
struct PostprocessVertexArray {
|
||||||
gl_vertex_array: GLuint,
|
vertex_array: VertexArray,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PostprocessVertexArray {
|
impl PostprocessVertexArray {
|
||||||
fn new(postprocess_program: &PostprocessProgram, quad_vertex_positions_buffer: &Buffer)
|
fn new(postprocess_program: &PostprocessProgram, quad_vertex_positions_buffer: &Buffer)
|
||||||
-> PostprocessVertexArray {
|
-> PostprocessVertexArray {
|
||||||
let mut gl_vertex_array = 0;
|
let vertex_array = VertexArray::new();
|
||||||
unsafe {
|
unsafe {
|
||||||
let position_attr = VertexAttr::new(&postprocess_program.program, "Position");
|
let position_attr = VertexAttr::new(&postprocess_program.program, "Position");
|
||||||
|
|
||||||
gl::GenVertexArrays(1, &mut gl_vertex_array);
|
gl::BindVertexArray(vertex_array.gl_vertex_array);
|
||||||
gl::BindVertexArray(gl_vertex_array);
|
|
||||||
gl::UseProgram(postprocess_program.program.gl_program);
|
gl::UseProgram(postprocess_program.program.gl_program);
|
||||||
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vertex_positions_buffer.gl_buffer);
|
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vertex_positions_buffer.gl_buffer);
|
||||||
position_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
position_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
PostprocessVertexArray { gl_vertex_array }
|
PostprocessVertexArray { vertex_array }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for PostprocessVertexArray {
|
|
||||||
#[inline]
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
gl::DeleteVertexArrays(1, &mut self.gl_vertex_array);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
//! How a path is to be filled.
|
//! How a path is to be filled.
|
||||||
|
|
||||||
|
use pathfinder_simd::default::F32x4;
|
||||||
use std::fmt::{self, Debug, Formatter};
|
use std::fmt::{self, Debug, Formatter};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
@ -38,6 +39,12 @@ impl ColorU {
|
||||||
a: 255,
|
a: 255,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn to_f32(&self) -> ColorF {
|
||||||
|
let color = F32x4::new(self.r as f32, self.g as f32, self.b as f32, self.a as f32);
|
||||||
|
ColorF(color * F32x4::splat(1.0 / 255.0))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for ColorU {
|
impl Debug for ColorU {
|
||||||
|
@ -55,6 +62,30 @@ impl Debug for ColorU {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct ColorF(pub F32x4);
|
||||||
|
|
||||||
|
impl ColorF {
|
||||||
|
#[inline]
|
||||||
|
pub fn r(&self) -> f32 {
|
||||||
|
self.0[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn g(&self) -> f32 {
|
||||||
|
self.0[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn b(&self) -> f32 {
|
||||||
|
self.0[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn a(&self) -> f32 {
|
||||||
|
self.0[3]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub struct ShaderId(pub u16);
|
pub struct ShaderId(pub u16);
|
||||||
|
|
Loading…
Reference in New Issue