Merge branch 'master' of https://github.com/servo/pathfinder into swf_renderer
This commit is contained in:
commit
ba1ff45cb2
|
@ -6,6 +6,7 @@ target
|
|||
/site/dist
|
||||
node_modules
|
||||
/examples/c_canvas_minimal/build
|
||||
/shaders/build
|
||||
|
||||
# Editors
|
||||
*.swp
|
||||
|
|
|
@ -161,6 +161,24 @@ dependencies = [
|
|||
"pathfinder_renderer 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "canvas_metal_minimal"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pathfinder_canvas 0.1.0",
|
||||
"pathfinder_geometry 0.3.0",
|
||||
"pathfinder_gl 0.1.0",
|
||||
"pathfinder_gpu 0.1.0",
|
||||
"pathfinder_metal 0.1.0",
|
||||
"pathfinder_renderer 0.1.0",
|
||||
"sdl2 0.32.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sdl2-sys 0.32.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "canvas_minimal"
|
||||
version = "0.1.0"
|
||||
|
@ -419,13 +437,16 @@ name = "demo"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"color-backtrace 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pathfinder_demo 0.1.0",
|
||||
"pathfinder_geometry 0.3.0",
|
||||
"pathfinder_gl 0.1.0",
|
||||
"pathfinder_gpu 0.1.0",
|
||||
"pathfinder_metal 0.1.0",
|
||||
"pathfinder_simd 0.3.0",
|
||||
"pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sdl2 0.32.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1083,6 +1104,23 @@ name = "memoffset"
|
|||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "metal"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nfd"
|
||||
version = "0.0.4"
|
||||
|
@ -1187,6 +1225,33 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc_exception 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc-foundation"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc_exception"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc_id"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1280,9 +1345,11 @@ dependencies = [
|
|||
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.21.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pathfinder_geometry 0.3.0",
|
||||
"pathfinder_gl 0.1.0",
|
||||
"pathfinder_gpu 0.1.0",
|
||||
"pathfinder_metal 0.1.0",
|
||||
"pathfinder_renderer 0.1.0",
|
||||
"pathfinder_simd 0.3.0",
|
||||
"pathfinder_svg 0.1.0",
|
||||
|
@ -1356,10 +1423,28 @@ dependencies = [
|
|||
"usvg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathfinder_metal"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pathfinder_geometry 0.3.0",
|
||||
"pathfinder_gpu 0.1.0",
|
||||
"pathfinder_simd 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathfinder_renderer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2374,6 +2459,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
|
||||
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
|
||||
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
|
||||
"checksum metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd3f21d259068945192293b7a98b1c6844af9eb7602e393c405198b229efc157"
|
||||
"checksum nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98"
|
||||
"checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b"
|
||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||
|
@ -2387,6 +2473,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
|
||||
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
|
||||
"checksum objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "31d20fd2b37e07cf5125be68357b588672e8cefe9a96f8c17a9d46053b3e590d"
|
||||
"checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
|
||||
"checksum objc_exception 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "098cd29a2fa3c230d3463ae069cecccc3fdfd64c0d2496ab5b96f82dab6a00dc"
|
||||
"checksum objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
|
||||
"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
|
||||
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
|
||||
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
|
||||
|
|
|
@ -7,6 +7,7 @@ members = [
|
|||
"demo/magicleap",
|
||||
"demo/native",
|
||||
"examples/canvas_glutin_minimal",
|
||||
"examples/canvas_metal_minimal",
|
||||
"examples/canvas_minimal",
|
||||
"examples/canvas_moire",
|
||||
"examples/canvas_text",
|
||||
|
@ -17,6 +18,7 @@ members = [
|
|||
"gpu",
|
||||
"flash",
|
||||
"lottie",
|
||||
"metal",
|
||||
"renderer",
|
||||
"simd",
|
||||
"svg",
|
||||
|
|
|
@ -25,17 +25,23 @@ extern "C" {
|
|||
#define PF_LINE_CAP_SQUARE 1
|
||||
#define PF_LINE_CAP_ROUND 2
|
||||
|
||||
#define PF_LINE_JOIN_MITER 0
|
||||
#define PF_LINE_JOIN_BEVEL 1
|
||||
#define PF_LINE_JOIN_ROUND 2
|
||||
|
||||
// `geometry`
|
||||
|
||||
#define PF_ARC_DIRECTION_CW 0
|
||||
#define PF_ARC_DIRECTION_CCW 1
|
||||
|
||||
// `gl`
|
||||
|
||||
#define PF_GL_VERSION_GL3 0
|
||||
#define PF_GL_VERSION_GLES3 1
|
||||
|
||||
// `gpu`
|
||||
// `renderer`
|
||||
|
||||
#define PF_CLEAR_FLAGS_HAS_COLOR 0x1
|
||||
#define PF_CLEAR_FLAGS_HAS_DEPTH 0x2
|
||||
#define PF_CLEAR_FLAGS_HAS_STENCIL 0x4
|
||||
#define PF_CLEAR_FLAGS_HAS_RECT 0x8
|
||||
#define PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR 0x1
|
||||
|
||||
// Types
|
||||
|
||||
|
@ -48,6 +54,8 @@ typedef struct PFPath *PFPathRef;
|
|||
struct PFCanvasFontContext;
|
||||
typedef struct PFCanvasFontContext *PFCanvasFontContextRef;
|
||||
typedef uint8_t PFLineCap;
|
||||
typedef uint8_t PFLineJoin;
|
||||
typedef uint8_t PFArcDirection;
|
||||
|
||||
// `geometry`
|
||||
|
||||
|
@ -85,24 +93,21 @@ typedef uint32_t PFGLVersion;
|
|||
|
||||
// `gpu`
|
||||
|
||||
typedef uint8_t PFClearFlags;
|
||||
struct PFClearParams {
|
||||
PFColorF color;
|
||||
float depth;
|
||||
uint8_t stencil;
|
||||
PFRectI rect;
|
||||
PFClearFlags flags;
|
||||
};
|
||||
typedef struct PFClearParams PFClearParams;
|
||||
struct PFResourceLoader;
|
||||
typedef struct PFResourceLoader *PFResourceLoaderRef;
|
||||
|
||||
// `renderer`
|
||||
|
||||
struct PFRenderOptions {
|
||||
typedef uint8_t PFRendererOptionsFlags;
|
||||
struct PFRendererOptions {
|
||||
PFColorF background_color;
|
||||
PFRendererOptionsFlags flags;
|
||||
};
|
||||
struct PFBuildOptions {
|
||||
uint32_t placeholder;
|
||||
};
|
||||
typedef struct PFRenderOptions PFRenderOptions;
|
||||
typedef struct PFRendererOptions PFRendererOptions;
|
||||
typedef struct PFBuildOptions PFBuildOptions;
|
||||
struct PFScene;
|
||||
typedef struct PFScene *PFSceneRef;
|
||||
struct PFSceneProxy;
|
||||
|
@ -122,6 +127,12 @@ void PFCanvasFillRect(PFCanvasRef canvas, const PFRectF *rect);
|
|||
void PFCanvasStrokeRect(PFCanvasRef canvas, const PFRectF *rect);
|
||||
void PFCanvasSetLineWidth(PFCanvasRef canvas, float new_line_width);
|
||||
void PFCanvasSetLineCap(PFCanvasRef canvas, PFLineCap new_line_cap);
|
||||
void PFCanvasSetLineJoin(PFCanvasRef canvas, PFLineJoin new_line_join);
|
||||
void PFCanvasSetMiterLimit(PFCanvasRef canvas, float new_miter_limit);
|
||||
void PFCanvasSetLineDash(PFCanvasRef canvas,
|
||||
const float *new_line_dashes,
|
||||
size_t new_line_dash_count);
|
||||
void PFCanvasSetLineDashOffset(PFCanvasRef canvas, float offset);
|
||||
void PFCanvasFillPath(PFCanvasRef canvas, PFPathRef path);
|
||||
void PFCanvasStrokePath(PFCanvasRef canvas, PFPathRef path);
|
||||
PFPathRef PFPathCreate();
|
||||
|
@ -134,6 +145,20 @@ void PFPathBezierCurveTo(PFPathRef path,
|
|||
const PFVector2F *ctrl0,
|
||||
const PFVector2F *ctrl1,
|
||||
const PFVector2F *to);
|
||||
void PFPathArc(PFPathRef path,
|
||||
const PFVector2F *center,
|
||||
float radius,
|
||||
float start_angle,
|
||||
float end_angle,
|
||||
PFArcDirection direction);
|
||||
void PFPathArcTo(PFPathRef path, const PFVector2F *ctrl, const PFVector2F *to, float radius);
|
||||
void PFPathRect(PFPathRef path, const PFRectF *rect);
|
||||
void PFPathEllipse(PFPathRef path,
|
||||
const PFVector2F *center,
|
||||
const PFVector2F *axes,
|
||||
float rotation,
|
||||
float start_angle,
|
||||
float end_angle);
|
||||
void PFPathClosePath(PFPathRef path);
|
||||
|
||||
// `gl`
|
||||
|
@ -142,17 +167,17 @@ PFGLDestFramebufferRef PFGLDestFramebufferCreateFullWindow(const PFVector2I *win
|
|||
void PFGLDestFramebufferDestroy(PFGLDestFramebufferRef dest_framebuffer);
|
||||
PFGLDeviceRef PFGLDeviceCreate(PFGLVersion version, uint32_t default_framebuffer);
|
||||
void PFGLDeviceDestroy(PFGLDeviceRef device);
|
||||
void PFGLDeviceClear(PFGLDeviceRef device, const PFClearParams *params);
|
||||
void PFGLLoadWith(PFGLFunctionLoader loader, void *userdata);
|
||||
PFGLRendererRef PFGLRendererCreate(PFGLDeviceRef device,
|
||||
PFResourceLoaderRef resources,
|
||||
PFGLDestFramebufferRef dest_framebuffer);
|
||||
PFGLDestFramebufferRef dest_framebuffer,
|
||||
const PFRendererOptions *options);
|
||||
void PFGLRendererDestroy(PFGLRendererRef renderer);
|
||||
/// Returns a borrowed reference to the device.
|
||||
PFGLDeviceRef PFGLRendererGetDevice(PFGLRendererRef renderer);
|
||||
void PFSceneProxyBuildAndRenderGL(PFSceneProxyRef scene_proxy,
|
||||
PFGLRendererRef renderer,
|
||||
const PFRenderOptions *options);
|
||||
const PFBuildOptions *build_options);
|
||||
|
||||
// `gpu`
|
||||
|
||||
|
|
172
c/src/lib.rs
172
c/src/lib.rs
|
@ -11,33 +11,45 @@
|
|||
//! C bindings to Pathfinder.
|
||||
|
||||
use gl;
|
||||
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, Path2D};
|
||||
use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
|
||||
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, LineJoin, Path2D};
|
||||
use pathfinder_geometry::basic::rect::{RectF, RectI};
|
||||
use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
|
||||
use pathfinder_geometry::color::ColorF;
|
||||
use pathfinder_geometry::outline::ArcDirection;
|
||||
use pathfinder_geometry::stroke::LineCap;
|
||||
use pathfinder_gl::{GLDevice, GLVersion};
|
||||
use pathfinder_gpu::resources::{FilesystemResourceLoader, ResourceLoader};
|
||||
use pathfinder_gpu::{ClearParams, Device};
|
||||
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
|
||||
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
|
||||
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, Renderer};
|
||||
use pathfinder_renderer::options::RenderOptions;
|
||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
||||
use pathfinder_renderer::gpu::renderer::Renderer;
|
||||
use pathfinder_renderer::options::BuildOptions;
|
||||
use pathfinder_renderer::scene::Scene;
|
||||
use pathfinder_simd::default::F32x4;
|
||||
use std::ffi::CString;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
use std::slice;
|
||||
|
||||
// Constants
|
||||
|
||||
// `canvas`
|
||||
|
||||
pub const PF_LINE_CAP_BUTT: u8 = 0;
|
||||
pub const PF_LINE_CAP_SQUARE: u8 = 1;
|
||||
pub const PF_LINE_CAP_ROUND: u8 = 2;
|
||||
|
||||
pub const PF_CLEAR_FLAGS_HAS_COLOR: u8 = 0x1;
|
||||
pub const PF_CLEAR_FLAGS_HAS_DEPTH: u8 = 0x2;
|
||||
pub const PF_CLEAR_FLAGS_HAS_STENCIL: u8 = 0x4;
|
||||
pub const PF_CLEAR_FLAGS_HAS_RECT: u8 = 0x8;
|
||||
pub const PF_LINE_JOIN_MITER: u8 = 0;
|
||||
pub const PF_LINE_JOIN_BEVEL: u8 = 1;
|
||||
pub const PF_LINE_JOIN_ROUND: u8 = 2;
|
||||
|
||||
// `geometry`
|
||||
|
||||
pub const PF_ARC_DIRECTION_CW: u8 = 0;
|
||||
pub const PF_ARC_DIRECTION_CCW: u8 = 1;
|
||||
|
||||
// `renderer`
|
||||
|
||||
pub const PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR: u8 = 0x1;
|
||||
|
||||
// Types
|
||||
|
||||
|
@ -46,6 +58,8 @@ pub type PFCanvasRef = *mut CanvasRenderingContext2D;
|
|||
pub type PFPathRef = *mut Path2D;
|
||||
pub type PFCanvasFontContextRef = *mut CanvasFontContext;
|
||||
pub type PFLineCap = u8;
|
||||
pub type PFLineJoin = u8;
|
||||
pub type PFArcDirection = u8;
|
||||
|
||||
// `geometry`
|
||||
#[repr(C)]
|
||||
|
@ -87,22 +101,19 @@ pub type PFGLRendererRef = *mut Renderer<GLDevice>;
|
|||
// FIXME(pcwalton): Double-boxing is unfortunate. Remove this when `std::raw::TraitObject` is
|
||||
// stable?
|
||||
pub type PFResourceLoaderRef = *mut Box<dyn ResourceLoader>;
|
||||
#[repr(C)]
|
||||
pub struct PFClearParams {
|
||||
pub color: PFColorF,
|
||||
pub depth: f32,
|
||||
pub stencil: u8,
|
||||
pub rect: PFRectI,
|
||||
pub flags: PFClearFlags,
|
||||
}
|
||||
pub type PFClearFlags = u8;
|
||||
|
||||
// `renderer`
|
||||
pub type PFSceneRef = *mut Scene;
|
||||
pub type PFSceneProxyRef = *mut SceneProxy;
|
||||
#[repr(C)]
|
||||
pub struct PFRendererOptions {
|
||||
pub background_color: PFColorF,
|
||||
pub flags: PFRendererOptionsFlags,
|
||||
}
|
||||
pub type PFRendererOptionsFlags = u8;
|
||||
// TODO(pcwalton)
|
||||
#[repr(C)]
|
||||
pub struct PFRenderOptions {
|
||||
pub struct PFBuildOptions {
|
||||
pub placeholder: u32,
|
||||
}
|
||||
|
||||
|
@ -168,6 +179,32 @@ pub unsafe extern "C" fn PFCanvasSetLineCap(canvas: PFCanvasRef, new_line_cap: P
|
|||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFCanvasSetLineJoin(canvas: PFCanvasRef, new_line_join: PFLineJoin) {
|
||||
(*canvas).set_line_join(match new_line_join {
|
||||
PF_LINE_JOIN_BEVEL => LineJoin::Bevel,
|
||||
PF_LINE_JOIN_ROUND => LineJoin::Round,
|
||||
_ => LineJoin::Miter,
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFCanvasSetMiterLimit(canvas: PFCanvasRef, new_miter_limit: f32) {
|
||||
(*canvas).set_miter_limit(new_miter_limit);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFCanvasSetLineDash(canvas: PFCanvasRef,
|
||||
new_line_dashes: *const f32,
|
||||
new_line_dash_count: usize) {
|
||||
(*canvas).set_line_dash(slice::from_raw_parts(new_line_dashes, new_line_dash_count).to_vec())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFCanvasSetLineDashOffset(canvas: PFCanvasRef, new_offset: f32) {
|
||||
(*canvas).set_line_dash_offset(new_offset)
|
||||
}
|
||||
|
||||
/// Consumes the path.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFCanvasFillPath(canvas: PFCanvasRef, path: PFPathRef) {
|
||||
|
@ -220,6 +257,40 @@ pub unsafe extern "C" fn PFPathBezierCurveTo(path: PFPathRef,
|
|||
(*path).bezier_curve_to((*ctrl0).to_rust(), (*ctrl1).to_rust(), (*to).to_rust())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFPathArc(path: PFPathRef,
|
||||
center: *const PFVector2F,
|
||||
radius: f32,
|
||||
start_angle: f32,
|
||||
end_angle: f32,
|
||||
direction: PFArcDirection) {
|
||||
let direction = if direction == 0 { ArcDirection::CW } else { ArcDirection::CCW };
|
||||
(*path).arc((*center).to_rust(), radius, start_angle, end_angle, direction)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFPathArcTo(path: PFPathRef,
|
||||
ctrl: *const PFVector2F,
|
||||
to: *const PFVector2F,
|
||||
radius: f32) {
|
||||
(*path).arc_to((*ctrl).to_rust(), (*to).to_rust(), radius)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFPathRect(path: PFPathRef, rect: *const PFRectF) {
|
||||
(*path).rect((*rect).to_rust())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFPathEllipse(path: PFPathRef,
|
||||
center: *const PFVector2F,
|
||||
axes: *const PFVector2F,
|
||||
rotation: f32,
|
||||
start_angle: f32,
|
||||
end_angle: f32) {
|
||||
(*path).ellipse((*center).to_rust(), (*axes).to_rust(), rotation, start_angle, end_angle)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFPathClosePath(path: PFPathRef) {
|
||||
(*path).close_path()
|
||||
|
@ -252,11 +323,6 @@ pub unsafe extern "C" fn PFGLDeviceDestroy(device: PFGLDeviceRef) {
|
|||
drop(Box::from_raw(device))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFGLDeviceClear(device: PFGLDeviceRef, params: *const PFClearParams) {
|
||||
(*device).clear(&(*params).to_rust())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFResourceLoaderDestroy(loader: PFResourceLoaderRef) {
|
||||
drop(Box::from_raw(loader))
|
||||
|
@ -279,11 +345,13 @@ pub unsafe extern "C" fn PFGLDestFramebufferDestroy(dest_framebuffer: PFGLDestFr
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFGLRendererCreate(device: PFGLDeviceRef,
|
||||
resources: PFResourceLoaderRef,
|
||||
dest_framebuffer: PFGLDestFramebufferRef)
|
||||
dest_framebuffer: PFGLDestFramebufferRef,
|
||||
options: *const PFRendererOptions)
|
||||
-> PFGLRendererRef {
|
||||
Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device),
|
||||
&**resources,
|
||||
*Box::from_raw(dest_framebuffer))))
|
||||
*Box::from_raw(dest_framebuffer),
|
||||
(*options).to_rust())))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -299,8 +367,8 @@ pub unsafe extern "C" fn PFGLRendererGetDevice(renderer: PFGLRendererRef) -> PFG
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFSceneProxyBuildAndRenderGL(scene_proxy: PFSceneProxyRef,
|
||||
renderer: PFGLRendererRef,
|
||||
options: *const PFRenderOptions) {
|
||||
(*scene_proxy).build_and_render(&mut *renderer, (*options).to_rust())
|
||||
build_options: *const PFBuildOptions) {
|
||||
(*scene_proxy).build_and_render(&mut *renderer, (*build_options).to_rust())
|
||||
}
|
||||
|
||||
// `renderer`
|
||||
|
@ -358,39 +426,23 @@ impl PFVector2I {
|
|||
}
|
||||
}
|
||||
|
||||
// Helpers for `gpu`
|
||||
|
||||
impl PFClearParams {
|
||||
pub fn to_rust(&self) -> ClearParams {
|
||||
ClearParams {
|
||||
color: if (self.flags & PF_CLEAR_FLAGS_HAS_COLOR) != 0 {
|
||||
Some(self.color.to_rust())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
rect: if (self.flags & PF_CLEAR_FLAGS_HAS_RECT) != 0 {
|
||||
Some(self.rect.to_rust())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
depth: if (self.flags & PF_CLEAR_FLAGS_HAS_DEPTH) != 0 {
|
||||
Some(self.depth)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
stencil: if (self.flags & PF_CLEAR_FLAGS_HAS_STENCIL) != 0 {
|
||||
Some(self.stencil)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers for `renderer`
|
||||
|
||||
impl PFRenderOptions {
|
||||
pub fn to_rust(&self) -> RenderOptions {
|
||||
RenderOptions::default()
|
||||
impl PFRendererOptions {
|
||||
pub fn to_rust(&self) -> RendererOptions {
|
||||
let has_background_color = self.flags & PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR;
|
||||
RendererOptions {
|
||||
background_color: if has_background_color != 0 {
|
||||
Some(self.background_color.to_rust())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PFBuildOptions {
|
||||
pub fn to_rust(&self) -> BuildOptions {
|
||||
BuildOptions::default()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ version = "0.1.0"
|
|||
edition = "2018"
|
||||
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
|
||||
|
||||
[features]
|
||||
pf-gl = []
|
||||
|
||||
[dependencies]
|
||||
clap = "2.32"
|
||||
gl = "0.6"
|
||||
|
@ -39,3 +42,9 @@ path = "../../svg"
|
|||
|
||||
[dependencies.pathfinder_ui]
|
||||
path = "../../ui"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
metal = "0.14"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
|
||||
path = "../../metal"
|
||||
|
|
|
@ -63,20 +63,19 @@ where
|
|||
) -> GroundVertexArray<D> {
|
||||
let vertex_array = device.create_vertex_array();
|
||||
|
||||
let position_attr = device.get_vertex_attr(&ground_program.program, "Position");
|
||||
let position_attr = device.get_vertex_attr(&ground_program.program, "Position").unwrap();
|
||||
|
||||
device.bind_vertex_array(&vertex_array);
|
||||
device.use_program(&ground_program.program);
|
||||
device.bind_buffer(quad_vertex_positions_buffer, BufferTarget::Vertex);
|
||||
device.configure_vertex_attr(&position_attr, &VertexAttrDescriptor {
|
||||
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
|
||||
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
|
||||
size: 2,
|
||||
class: VertexAttrClass::Float,
|
||||
attr_type: VertexAttrType::U8,
|
||||
stride: 0,
|
||||
class: VertexAttrClass::Int,
|
||||
attr_type: VertexAttrType::I16,
|
||||
stride: 4,
|
||||
offset: 0,
|
||||
divisor: 0,
|
||||
buffer_index: 0,
|
||||
});
|
||||
device.bind_buffer(quad_vertex_indices_buffer, BufferTarget::Index);
|
||||
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
|
||||
|
||||
GroundVertexArray { vertex_array }
|
||||
}
|
||||
|
|
|
@ -27,12 +27,12 @@ use pathfinder_geometry::basic::rect::RectF;
|
|||
use pathfinder_geometry::basic::transform2d::Transform2DF;
|
||||
use pathfinder_geometry::basic::transform3d::Transform3DF;
|
||||
use pathfinder_geometry::color::ColorU;
|
||||
use pathfinder_gl::GLDevice;
|
||||
use pathfinder_gpu::Device;
|
||||
use pathfinder_gpu::resources::ResourceLoader;
|
||||
use pathfinder_gpu::Device;
|
||||
use pathfinder_renderer::concurrent::scene_proxy::{RenderCommandStream, SceneProxy};
|
||||
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, RenderStats, RenderTime, Renderer};
|
||||
use pathfinder_renderer::options::{RenderOptions, RenderTransform};
|
||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
||||
use pathfinder_renderer::gpu::renderer::{RenderStats, RenderTime, Renderer};
|
||||
use pathfinder_renderer::options::{BuildOptions, RenderTransform};
|
||||
use pathfinder_renderer::post::STEM_DARKENING_FACTORS;
|
||||
use pathfinder_renderer::scene::Scene;
|
||||
use pathfinder_svg::BuiltSVG;
|
||||
|
@ -44,6 +44,11 @@ use std::thread;
|
|||
use std::time::Duration;
|
||||
use usvg::{Options as UsvgOptions, Tree};
|
||||
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
use pathfinder_gl::GLDevice as DeviceImpl;
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
use pathfinder_metal::MetalDevice as DeviceImpl;
|
||||
|
||||
static DEFAULT_SVG_VIRTUAL_PATH: &'static str = "svg/Ghostscript_Tiger.svg";
|
||||
|
||||
const MOUSELOOK_ROTATION_SPEED: f32 = 0.007;
|
||||
|
@ -112,22 +117,31 @@ pub struct DemoApp<W> where W: Window {
|
|||
build_time: Option<Duration>,
|
||||
|
||||
ui_model: DemoUIModel,
|
||||
ui_presenter: DemoUIPresenter<GLDevice>,
|
||||
ui_presenter: DemoUIPresenter<DeviceImpl>,
|
||||
|
||||
scene_proxy: SceneProxy,
|
||||
renderer: Renderer<GLDevice>,
|
||||
renderer: Renderer<DeviceImpl>,
|
||||
|
||||
scene_framebuffer: Option<<GLDevice as Device>::Framebuffer>,
|
||||
scene_framebuffer: Option<<DeviceImpl as Device>::Framebuffer>,
|
||||
|
||||
ground_program: GroundProgram<GLDevice>,
|
||||
ground_vertex_array: GroundVertexArray<GLDevice>,
|
||||
ground_program: GroundProgram<DeviceImpl>,
|
||||
ground_vertex_array: GroundVertexArray<DeviceImpl>,
|
||||
}
|
||||
|
||||
impl<W> DemoApp<W> where W: Window {
|
||||
pub fn new(window: W, window_size: WindowSize, mut options: Options) -> DemoApp<W> {
|
||||
let expire_message_event_id = window.create_user_event_id();
|
||||
|
||||
let device = GLDevice::new(window.gl_version(), window.gl_default_framebuffer());
|
||||
let device;
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
{
|
||||
device = DeviceImpl::new(window.metal_layer());
|
||||
}
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
{
|
||||
device = DeviceImpl::new(window.gl_version(), window.gl_default_framebuffer());
|
||||
}
|
||||
|
||||
let resources = window.resource_loader();
|
||||
|
||||
// Read command line options.
|
||||
|
@ -144,8 +158,12 @@ impl<W> DemoApp<W> where W: Window {
|
|||
viewport,
|
||||
window_size: window_size.device_size(),
|
||||
};
|
||||
// FIXME(pcwalton)
|
||||
let render_options = RendererOptions {
|
||||
background_color: None,
|
||||
};
|
||||
|
||||
let renderer = Renderer::new(device, resources, dest_framebuffer);
|
||||
let renderer = Renderer::new(device, resources, dest_framebuffer, render_options);
|
||||
let scene_metadata = SceneMetadata::new_clipping_view_box(&mut built_svg.scene,
|
||||
viewport.size());
|
||||
let camera = Camera::new(options.mode, scene_metadata.view_box, viewport.size());
|
||||
|
@ -246,7 +264,7 @@ impl<W> DemoApp<W> where W: Window {
|
|||
Camera::TwoD(transform) => Some(RenderTransform::Transform2D(transform)),
|
||||
};
|
||||
|
||||
let render_options = RenderOptions {
|
||||
let build_options = BuildOptions {
|
||||
transform: self.render_transform.clone().unwrap(),
|
||||
dilation: if self.ui_model.stem_darkening_effect_enabled {
|
||||
let font_size = APPROX_FONT_SIZE * self.window_size.backing_scale_factor;
|
||||
|
@ -258,7 +276,7 @@ impl<W> DemoApp<W> where W: Window {
|
|||
subpixel_aa_enabled: self.ui_model.subpixel_aa_effect_enabled,
|
||||
};
|
||||
|
||||
self.render_command_stream = Some(self.scene_proxy.build_with_stream(render_options));
|
||||
self.render_command_stream = Some(self.scene_proxy.build_with_stream(build_options));
|
||||
}
|
||||
|
||||
fn handle_events(&mut self, events: Vec<Event>) -> Vec<UIEvent> {
|
||||
|
@ -488,7 +506,9 @@ impl<W> DemoApp<W> where W: Window {
|
|||
|
||||
self.handle_ui_events(frame, &mut ui_action);
|
||||
|
||||
self.window.present();
|
||||
self.renderer.device.end_commands();
|
||||
|
||||
self.window.present(&mut self.renderer.device);
|
||||
self.frame_counter += 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,13 @@ use crate::window::{View, Window};
|
|||
use crate::{BackgroundColor, DemoApp, UIVisibility};
|
||||
use image::ColorType;
|
||||
use pathfinder_geometry::color::{ColorF, ColorU};
|
||||
use pathfinder_gpu::{ClearParams, DepthFunc, DepthState, Device, Primitive, RenderState};
|
||||
use pathfinder_gpu::{TextureFormat, UniformData};
|
||||
use pathfinder_gpu::{ClearOps, DepthFunc, DepthState, Device, Primitive, RenderOptions};
|
||||
use pathfinder_gpu::{RenderState, RenderTarget, TextureData, TextureFormat, UniformData};
|
||||
use pathfinder_geometry::basic::rect::RectI;
|
||||
use pathfinder_geometry::basic::transform3d::Transform3DF;
|
||||
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, RenderMode};
|
||||
use pathfinder_geometry::basic::vector::Vector2I;
|
||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
||||
use pathfinder_renderer::gpu::renderer::RenderMode;
|
||||
use pathfinder_renderer::gpu_data::RenderCommand;
|
||||
use pathfinder_renderer::options::RenderTransform;
|
||||
use pathfinder_renderer::post::DEFRINGING_KERNEL_CORE_GRAPHICS;
|
||||
|
@ -42,13 +45,14 @@ const GRIDLINE_COUNT: i32 = 10;
|
|||
|
||||
impl<W> DemoApp<W> where W: Window {
|
||||
pub fn prepare_frame_rendering(&mut self) -> u32 {
|
||||
// Make the GL context current.
|
||||
// Make the context current.
|
||||
let view = self.ui_model.mode.view(0);
|
||||
self.window.make_current(view);
|
||||
|
||||
// Set up framebuffers.
|
||||
let window_size = self.window_size.device_size();
|
||||
let scene_count = match self.camera.mode() {
|
||||
let mode = self.camera.mode();
|
||||
let scene_count = match mode {
|
||||
Mode::VR => {
|
||||
let viewport = self.window.viewport(View::Stereo(0));
|
||||
if self.scene_framebuffer.is_none()
|
||||
|
@ -82,40 +86,33 @@ impl<W> DemoApp<W> where W: Window {
|
|||
}
|
||||
};
|
||||
|
||||
// Begin drawing the scene.
|
||||
self.renderer.bind_dest_framebuffer();
|
||||
|
||||
// Clear to the appropriate color.
|
||||
let clear_color = if scene_count == 2 {
|
||||
ColorF::transparent_black()
|
||||
} else {
|
||||
self.background_color().to_f32()
|
||||
let clear_color = match mode {
|
||||
Mode::TwoD => Some(self.background_color().to_f32()),
|
||||
Mode::ThreeD => None,
|
||||
Mode::VR => Some(ColorF::transparent_black()),
|
||||
};
|
||||
self.renderer.device.clear(&ClearParams {
|
||||
color: Some(clear_color),
|
||||
depth: Some(1.0),
|
||||
stencil: Some(0),
|
||||
..ClearParams::default()
|
||||
});
|
||||
self.renderer.set_options(RendererOptions { background_color: clear_color });
|
||||
|
||||
scene_count
|
||||
}
|
||||
|
||||
pub fn draw_scene(&mut self) {
|
||||
self.renderer.device.begin_commands();
|
||||
|
||||
let view = self.ui_model.mode.view(0);
|
||||
self.window.make_current(view);
|
||||
|
||||
if self.camera.mode() != Mode::VR {
|
||||
self.draw_environment();
|
||||
self.draw_environment(0);
|
||||
}
|
||||
|
||||
self.renderer.device.end_commands();
|
||||
|
||||
self.render_vector_scene();
|
||||
|
||||
// Reattach default framebuffer.
|
||||
if self.camera.mode() != Mode::VR {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.camera.mode() == Mode::VR {
|
||||
if let DestFramebuffer::Other(scene_framebuffer) =
|
||||
self.renderer
|
||||
.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||
|
@ -126,6 +123,11 @@ impl<W> DemoApp<W> where W: Window {
|
|||
self.scene_framebuffer = Some(scene_framebuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn begin_compositing(&mut self) {
|
||||
self.renderer.device.begin_commands();
|
||||
}
|
||||
|
||||
pub fn composite_scene(&mut self, render_scene_index: u32) {
|
||||
let (eye_transforms, scene_transform, modelview_transform) = match self.camera {
|
||||
|
@ -151,21 +153,12 @@ impl<W> DemoApp<W> where W: Window {
|
|||
let viewport = self.window.viewport(View::Stereo(render_scene_index));
|
||||
self.window.make_current(View::Stereo(render_scene_index));
|
||||
|
||||
self.renderer
|
||||
.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||
self.renderer.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||
viewport,
|
||||
window_size: self.window_size.device_size(),
|
||||
});
|
||||
|
||||
self.renderer.bind_draw_framebuffer();
|
||||
self.renderer.device.clear(&ClearParams {
|
||||
color: Some(self.background_color().to_f32()),
|
||||
depth: Some(1.0),
|
||||
stencil: Some(0),
|
||||
rect: Some(viewport),
|
||||
});
|
||||
|
||||
self.draw_environment();
|
||||
self.draw_environment(render_scene_index);
|
||||
|
||||
let scene_framebuffer = self.scene_framebuffer.as_ref().unwrap();
|
||||
let scene_texture = self.renderer.device.framebuffer_texture(scene_framebuffer);
|
||||
|
@ -207,7 +200,7 @@ impl<W> DemoApp<W> where W: Window {
|
|||
}
|
||||
|
||||
// Draws the ground, if applicable.
|
||||
fn draw_environment(&self) {
|
||||
fn draw_environment(&self, render_scene_index: u32) {
|
||||
let frame = &self.current_frame.as_ref().unwrap();
|
||||
|
||||
let perspective = match frame.transform {
|
||||
|
@ -233,31 +226,35 @@ impl<W> DemoApp<W> where W: Window {
|
|||
transform =
|
||||
transform.post_mul(&Transform3DF::from_scale(ground_scale, 1.0, ground_scale));
|
||||
|
||||
let device = &self.renderer.device;
|
||||
device.bind_vertex_array(&self.ground_vertex_array.vertex_array);
|
||||
device.use_program(&self.ground_program.program);
|
||||
device.set_uniform(
|
||||
&self.ground_program.transform_uniform,
|
||||
UniformData::from_transform_3d(&transform),
|
||||
);
|
||||
device.set_uniform(
|
||||
&self.ground_program.ground_color_uniform,
|
||||
UniformData::Vec4(GROUND_SOLID_COLOR.to_f32().0),
|
||||
);
|
||||
device.set_uniform(
|
||||
&self.ground_program.gridline_color_uniform,
|
||||
UniformData::Vec4(GROUND_LINE_COLOR.to_f32().0),
|
||||
);
|
||||
device.set_uniform(&self.ground_program.gridline_count_uniform,
|
||||
UniformData::Int(GRIDLINE_COUNT));
|
||||
device.draw_elements(
|
||||
Primitive::Triangles,
|
||||
6,
|
||||
&RenderState {
|
||||
// Don't clear the first scene after drawing it.
|
||||
let clear_color = if render_scene_index == 0 {
|
||||
Some(self.background_color().to_f32())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
self.renderer.device.draw_elements(6, &RenderState {
|
||||
target: &self.renderer.draw_render_target(),
|
||||
program: &self.ground_program.program,
|
||||
vertex_array: &self.ground_vertex_array.vertex_array,
|
||||
primitive: Primitive::Triangles,
|
||||
textures: &[],
|
||||
uniforms: &[
|
||||
(&self.ground_program.transform_uniform,
|
||||
UniformData::from_transform_3d(&transform)),
|
||||
(&self.ground_program.ground_color_uniform,
|
||||
UniformData::Vec4(GROUND_SOLID_COLOR.to_f32().0)),
|
||||
(&self.ground_program.gridline_color_uniform,
|
||||
UniformData::Vec4(GROUND_LINE_COLOR.to_f32().0)),
|
||||
(&self.ground_program.gridline_count_uniform, UniformData::Int(GRIDLINE_COUNT)),
|
||||
],
|
||||
viewport: self.renderer.draw_viewport(),
|
||||
options: RenderOptions {
|
||||
depth: Some(DepthState { func: DepthFunc::Less, write: true }),
|
||||
..RenderState::default()
|
||||
clear_ops: ClearOps { color: clear_color, depth: Some(1.0), stencil: Some(0) },
|
||||
..RenderOptions::default()
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn render_vector_scene(&mut self) {
|
||||
|
@ -305,10 +302,11 @@ impl<W> DemoApp<W> where W: Window {
|
|||
|
||||
pub fn take_raster_screenshot(&mut self, path: PathBuf) {
|
||||
let drawable_size = self.window_size.device_size();
|
||||
let pixels = self
|
||||
.renderer
|
||||
.device
|
||||
.read_pixels_from_default_framebuffer(drawable_size);
|
||||
let viewport = RectI::new(Vector2I::default(), drawable_size);
|
||||
let pixels = match self.renderer.device.read_pixels(&RenderTarget::Default, viewport) {
|
||||
TextureData::U8(pixels) => pixels,
|
||||
TextureData::U16(_) => panic!("Unexpected pixel format for default framebuffer!"),
|
||||
};
|
||||
image::save_buffer(
|
||||
path,
|
||||
&pixels,
|
||||
|
|
|
@ -500,9 +500,7 @@ where
|
|||
Vector2I::new(widget_x, slider_track_y),
|
||||
Vector2I::new(SLIDER_WIDTH, SLIDER_TRACK_HEIGHT),
|
||||
);
|
||||
debug_ui_presenter
|
||||
.ui_presenter
|
||||
.draw_rect_outline(device, slider_track_rect, TEXT_COLOR);
|
||||
debug_ui_presenter.ui_presenter.draw_rect_outline(device, slider_track_rect, TEXT_COLOR);
|
||||
|
||||
let slider_knob_x = widget_x + model.rotation - SLIDER_KNOB_WIDTH / 2;
|
||||
let slider_knob_rect = RectI::new(
|
||||
|
@ -528,7 +526,11 @@ where
|
|||
let widget_origin = panel_position + Vector2I::new(0, widget_size.y() * index);
|
||||
let widget_rect = RectI::new(widget_origin, widget_size);
|
||||
|
||||
if self.draw_menu_item(device, debug_ui_presenter, &text, widget_rect, false) {
|
||||
if self.draw_menu_item(device,
|
||||
debug_ui_presenter,
|
||||
&text,
|
||||
widget_rect,
|
||||
false) {
|
||||
// FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
|
||||
// the contents of the file.
|
||||
if let Ok(path) = window.run_save_dialog(screenshot_type.extension()) {
|
||||
|
@ -554,7 +556,11 @@ where
|
|||
let widget_rect = RectI::new(widget_origin, widget_size);
|
||||
|
||||
let selected = color == model.background_color;
|
||||
if self.draw_menu_item(device, debug_ui_presenter, text, widget_rect, selected) {
|
||||
if self.draw_menu_item(device,
|
||||
debug_ui_presenter,
|
||||
text,
|
||||
widget_rect,
|
||||
selected) {
|
||||
model.background_color = color;
|
||||
*action = UIAction::ModelChanged;
|
||||
}
|
||||
|
|
|
@ -10,24 +10,38 @@
|
|||
|
||||
//! A minimal cross-platform windowing layer.
|
||||
|
||||
use gl::types::GLuint;
|
||||
use pathfinder_geometry::basic::vector::Vector2I;
|
||||
use pathfinder_geometry::basic::rect::RectI;
|
||||
use pathfinder_geometry::basic::transform3d::{Perspective, Transform3DF};
|
||||
use pathfinder_gl::GLVersion;
|
||||
use pathfinder_gpu::resources::ResourceLoader;
|
||||
use rayon::ThreadPoolBuilder;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub trait Window {
|
||||
fn gl_version(&self) -> GLVersion;
|
||||
fn gl_default_framebuffer(&self) -> GLuint {
|
||||
0
|
||||
}
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
use metal::CoreAnimationLayerRef;
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
use pathfinder_metal::MetalDevice;
|
||||
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
use gl::types::GLuint;
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
use pathfinder_gl::{GLDevice, GLVersion};
|
||||
|
||||
pub trait Window {
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
fn gl_version(&self) -> GLVersion;
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
fn gl_default_framebuffer(&self) -> GLuint { 0 }
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
fn present(&mut self, device: &mut GLDevice);
|
||||
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
fn metal_layer(&self) -> &CoreAnimationLayerRef;
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
fn present(&mut self, device: &mut MetalDevice);
|
||||
|
||||
fn viewport(&self, view: View) -> RectI;
|
||||
fn make_current(&mut self, view: View);
|
||||
fn present(&mut self);
|
||||
fn viewport(&self, view: View) -> RectI;
|
||||
fn resource_loader(&self) -> &dyn ResourceLoader;
|
||||
fn create_user_event_id(&self) -> u32;
|
||||
fn push_user_event(message_type: u32, message_data: u32);
|
||||
|
|
|
@ -113,6 +113,7 @@ pub unsafe extern "C" fn magicleap_pathfinder_demo_run(app: *mut c_void) {
|
|||
}
|
||||
let scene_count = app.demo.prepare_frame(events);
|
||||
app.demo.draw_scene();
|
||||
app.demo.begin_compositing();
|
||||
for scene_index in 0..scene_count {
|
||||
app.demo.composite_scene(scene_index);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ edition = "2018"
|
|||
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
|
||||
|
||||
[features]
|
||||
pf-gl = ["pathfinder_demo/pf-gl"]
|
||||
pf-no-simd = ["pathfinder_simd/pf-no-simd"]
|
||||
|
||||
[dependencies]
|
||||
|
@ -30,5 +31,12 @@ path = "../../gpu"
|
|||
[dependencies.pathfinder_simd]
|
||||
path = "../../simd"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
foreign-types = "0.3"
|
||||
metal = "0.14"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
|
||||
path = "../../metal"
|
||||
|
||||
[target.'cfg(not(windows))'.dependencies]
|
||||
jemallocator = "0.1"
|
||||
|
|
|
@ -15,16 +15,33 @@ use pathfinder_demo::window::{Event, Keycode, SVGPath, View, Window, WindowSize}
|
|||
use pathfinder_demo::{DemoApp, Options};
|
||||
use pathfinder_geometry::basic::vector::Vector2I;
|
||||
use pathfinder_geometry::basic::rect::RectI;
|
||||
use pathfinder_gl::GLVersion;
|
||||
use pathfinder_gpu::resources::{FilesystemResourceLoader, ResourceLoader};
|
||||
use sdl2::event::{Event as SDLEvent, WindowEvent};
|
||||
use sdl2::keyboard::Keycode as SDLKeycode;
|
||||
use sdl2::video::{GLContext, GLProfile, Window as SDLWindow};
|
||||
use sdl2::video::Window as SDLWindow;
|
||||
use sdl2::{EventPump, EventSubsystem, Sdl, VideoSubsystem};
|
||||
use sdl2_sys::{SDL_Event, SDL_UserEvent};
|
||||
use std::path::PathBuf;
|
||||
use std::ptr;
|
||||
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
use foreign_types::ForeignTypeRef;
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
use metal::{CAMetalLayer, CoreAnimationLayerRef};
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
use pathfinder_metal::MetalDevice;
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
use sdl2::hint;
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
use sdl2::render::Canvas;
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
use sdl2_sys::SDL_RenderGetMetalLayer;
|
||||
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
use pathfinder_gl::{GLDevice, GLVersion};
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
use sdl2::video::{GLContext, GLProfile};
|
||||
|
||||
#[cfg(not(windows))]
|
||||
use jemallocator;
|
||||
|
||||
|
@ -55,6 +72,7 @@ fn main() {
|
|||
|
||||
let scene_count = app.prepare_frame(events);
|
||||
app.draw_scene();
|
||||
app.begin_compositing();
|
||||
for scene_index in 0..scene_count {
|
||||
app.composite_scene(scene_index);
|
||||
}
|
||||
|
@ -69,22 +87,36 @@ thread_local! {
|
|||
}
|
||||
|
||||
struct WindowImpl {
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
window: SDLWindow,
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
gl_context: GLContext,
|
||||
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
canvas: Canvas<SDLWindow>,
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
metal_layer: *mut CAMetalLayer,
|
||||
|
||||
event_pump: EventPump,
|
||||
#[allow(dead_code)]
|
||||
gl_context: GLContext,
|
||||
resource_loader: FilesystemResourceLoader,
|
||||
selected_file: Option<PathBuf>,
|
||||
open_svg_message_type: u32,
|
||||
}
|
||||
|
||||
impl Window for WindowImpl {
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
fn gl_version(&self) -> GLVersion {
|
||||
GLVersion::GL3
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
fn metal_layer(&self) -> &CoreAnimationLayerRef {
|
||||
unsafe { CoreAnimationLayerRef::from_ptr(self.metal_layer) }
|
||||
}
|
||||
|
||||
fn viewport(&self, view: View) -> RectI {
|
||||
let (width, height) = self.window.drawable_size();
|
||||
let (width, height) = self.window().drawable_size();
|
||||
let mut width = width as i32;
|
||||
let height = height as i32;
|
||||
let mut x_offset = 0;
|
||||
|
@ -95,12 +127,22 @@ impl Window for WindowImpl {
|
|||
RectI::new(Vector2I::new(x_offset, 0), Vector2I::new(width, height))
|
||||
}
|
||||
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
fn make_current(&mut self, _view: View) {
|
||||
self.window.gl_make_current(&self.gl_context).unwrap();
|
||||
self.window().gl_make_current(&self.gl_context).unwrap();
|
||||
}
|
||||
|
||||
fn present(&mut self) {
|
||||
self.window.gl_swap_window();
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
fn make_current(&mut self, _: View) {}
|
||||
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
fn present(&mut self, _: &mut GLDevice) {
|
||||
self.window().gl_swap_window();
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
fn present(&mut self, device: &mut MetalDevice) {
|
||||
device.present_drawable();
|
||||
}
|
||||
|
||||
fn resource_loader(&self) -> &dyn ResourceLoader {
|
||||
|
@ -141,6 +183,7 @@ impl Window for WindowImpl {
|
|||
}
|
||||
|
||||
impl WindowImpl {
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
fn new() -> WindowImpl {
|
||||
SDL_VIDEO.with(|sdl_video| {
|
||||
SDL_EVENT.with(|sdl_event| {
|
||||
|
@ -185,9 +228,55 @@ impl WindowImpl {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
fn new() -> WindowImpl {
|
||||
assert!(hint::set("SDL_RENDER_DRIVER", "metal"));
|
||||
|
||||
SDL_VIDEO.with(|sdl_video| {
|
||||
SDL_EVENT.with(|sdl_event| {
|
||||
let window = sdl_video
|
||||
.window(
|
||||
"Pathfinder Demo",
|
||||
DEFAULT_WINDOW_WIDTH,
|
||||
DEFAULT_WINDOW_HEIGHT,
|
||||
)
|
||||
.opengl()
|
||||
.resizable()
|
||||
.allow_highdpi()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let canvas = window.into_canvas().present_vsync().build().unwrap();
|
||||
let metal_layer = unsafe {
|
||||
SDL_RenderGetMetalLayer(canvas.raw()) as *mut CAMetalLayer
|
||||
};
|
||||
|
||||
let event_pump = SDL_CONTEXT.with(|sdl_context| sdl_context.event_pump().unwrap());
|
||||
|
||||
let resource_loader = FilesystemResourceLoader::locate();
|
||||
|
||||
let open_svg_message_type = unsafe { sdl_event.register_event().unwrap() };
|
||||
|
||||
WindowImpl {
|
||||
event_pump,
|
||||
canvas,
|
||||
metal_layer,
|
||||
resource_loader,
|
||||
open_svg_message_type,
|
||||
selected_file: None,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
|
||||
fn window(&self) -> &SDLWindow { &self.window }
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
fn window(&self) -> &SDLWindow { self.canvas.window() }
|
||||
|
||||
fn size(&self) -> WindowSize {
|
||||
let (logical_width, logical_height) = self.window.size();
|
||||
let (drawable_width, _) = self.window.drawable_size();
|
||||
let (logical_width, logical_height) = self.window().size();
|
||||
let (drawable_width, _) = self.window().drawable_size();
|
||||
WindowSize {
|
||||
logical_size: Vector2I::new(logical_width as i32, logical_height as i32),
|
||||
backing_scale_factor: drawable_width as f32 / logical_width as f32,
|
||||
|
|
|
@ -58,11 +58,9 @@ int main(int argc, const char **argv) {
|
|||
PFGLDestFramebufferCreateFullWindow(&(PFVector2I){640, 480});
|
||||
PFGLRendererRef renderer = PFGLRendererCreate(PFGLDeviceCreate(PF_GL_VERSION_GL3, 0),
|
||||
PFFilesystemResourceLoaderLocate(),
|
||||
dest_framebuffer);
|
||||
|
||||
// Clear to white.
|
||||
PFGLDeviceClear(PFGLRendererGetDevice(renderer), &(PFClearParams){
|
||||
(PFColorF){1.0, 1.0, 1.0, 1.0}, 0.0, 0, {0}, PF_CLEAR_FLAGS_HAS_COLOR
|
||||
dest_framebuffer,
|
||||
&(PFRendererOptions){
|
||||
(PFColorF){1.0, 1.0, 1.0, 1.0}, PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR
|
||||
});
|
||||
|
||||
// Make a canvas. We're going to draw a house.
|
||||
|
@ -89,7 +87,7 @@ int main(int argc, const char **argv) {
|
|||
// Render the canvas to screen.
|
||||
PFSceneRef scene = PFCanvasCreateScene(canvas);
|
||||
PFSceneProxyRef scene_proxy = PFSceneProxyCreateFromSceneAndRayonExecutor(scene);
|
||||
PFSceneProxyBuildAndRenderGL(scene_proxy, renderer, &(PFRenderOptions){0});
|
||||
PFSceneProxyBuildAndRenderGL(scene_proxy, renderer, &(PFBuildOptions){0});
|
||||
SDL_GL_SwapWindow(window);
|
||||
|
||||
// Wait for a keypress.
|
||||
|
|
|
@ -19,11 +19,11 @@ use pathfinder_geometry::basic::rect::RectF;
|
|||
use pathfinder_geometry::color::ColorF;
|
||||
use pathfinder_gl::{GLDevice, GLVersion};
|
||||
use pathfinder_gpu::resources::FilesystemResourceLoader;
|
||||
use pathfinder_gpu::{ClearParams, Device};
|
||||
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
|
||||
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
|
||||
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, Renderer};
|
||||
use pathfinder_renderer::options::RenderOptions;
|
||||
use pathfinder_renderer::gpu::renderer::Renderer;
|
||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
||||
use pathfinder_renderer::options::BuildOptions;
|
||||
|
||||
fn main() {
|
||||
// Calculate the right logical size of the window.
|
||||
|
@ -50,10 +50,8 @@ fn main() {
|
|||
// Create a Pathfinder renderer.
|
||||
let mut renderer = Renderer::new(GLDevice::new(GLVersion::GL3, 0),
|
||||
&FilesystemResourceLoader::locate(),
|
||||
DestFramebuffer::full_window(window_size));
|
||||
|
||||
// Clear to white.
|
||||
renderer.device.clear(&ClearParams { color: Some(ColorF::white()), ..ClearParams::default() });
|
||||
DestFramebuffer::full_window(window_size),
|
||||
RendererOptions { background_color: Some(ColorF::white()) });
|
||||
|
||||
// Make a canvas. We're going to draw a house.
|
||||
let mut canvas = CanvasRenderingContext2D::new(CanvasFontContext::new(), window_size.to_f32());
|
||||
|
@ -77,7 +75,7 @@ fn main() {
|
|||
|
||||
// Render the canvas to screen.
|
||||
let scene = SceneProxy::from_scene(canvas.into_scene(), RayonExecutor);
|
||||
scene.build_and_render(&mut renderer, RenderOptions::default());
|
||||
scene.build_and_render(&mut renderer, BuildOptions::default());
|
||||
gl_context.swap_buffers().unwrap();
|
||||
|
||||
// Wait for a keypress.
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
[package]
|
||||
name = "canvas_metal_minimal"
|
||||
version = "0.1.0"
|
||||
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
foreign-types = "0.3"
|
||||
gl = "0.6"
|
||||
metal = "0.14"
|
||||
objc = "0.2"
|
||||
sdl2 = "0.32"
|
||||
sdl2-sys = "0.32"
|
||||
|
||||
[dependencies.pathfinder_canvas]
|
||||
path = "../../canvas"
|
||||
|
||||
[dependencies.pathfinder_geometry]
|
||||
path = "../../geometry"
|
||||
|
||||
[dependencies.pathfinder_gl]
|
||||
path = "../../gl"
|
||||
|
||||
[dependencies.pathfinder_gpu]
|
||||
path = "../../gpu"
|
||||
|
||||
[dependencies.pathfinder_metal]
|
||||
path = "../../metal"
|
||||
|
||||
[dependencies.pathfinder_renderer]
|
||||
path = "../../renderer"
|
|
@ -0,0 +1,87 @@
|
|||
// pathfinder/examples/canvas_metal_minimal/src/main.rs
|
||||
//
|
||||
// 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.
|
||||
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use metal::{CAMetalLayer, CoreAnimationLayerRef};
|
||||
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, Path2D};
|
||||
use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
|
||||
use pathfinder_geometry::basic::rect::RectF;
|
||||
use pathfinder_geometry::color::ColorF;
|
||||
use pathfinder_gpu::resources::FilesystemResourceLoader;
|
||||
use pathfinder_metal::MetalDevice;
|
||||
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
|
||||
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
|
||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
||||
use pathfinder_renderer::gpu::renderer::Renderer;
|
||||
use pathfinder_renderer::options::BuildOptions;
|
||||
use sdl2::event::Event;
|
||||
use sdl2::hint;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use sdl2_sys::SDL_RenderGetMetalLayer;
|
||||
|
||||
fn main() {
|
||||
// Set up SDL2.
|
||||
assert!(hint::set("SDL_RENDER_DRIVER", "metal"));
|
||||
let sdl_context = sdl2::init().unwrap();
|
||||
let video = sdl_context.video().unwrap();
|
||||
|
||||
// Open a window.
|
||||
let window_size = Vector2I::new(640, 480);
|
||||
let window = video.window("Minimal example", window_size.x() as u32, window_size.y() as u32)
|
||||
.opengl()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Create a Metal context.
|
||||
let canvas = window.into_canvas().present_vsync().build().unwrap();
|
||||
let metal_layer = unsafe {
|
||||
CoreAnimationLayerRef::from_ptr(SDL_RenderGetMetalLayer(canvas.raw()) as *mut CAMetalLayer)
|
||||
};
|
||||
|
||||
// Create a Pathfinder renderer.
|
||||
let mut renderer = Renderer::new(MetalDevice::new(metal_layer),
|
||||
&FilesystemResourceLoader::locate(),
|
||||
DestFramebuffer::full_window(window_size),
|
||||
RendererOptions { background_color: Some(ColorF::white()) });
|
||||
|
||||
// Make a canvas. We're going to draw a house.
|
||||
let mut canvas = CanvasRenderingContext2D::new(CanvasFontContext::new(), window_size.to_f32());
|
||||
|
||||
// Set line width.
|
||||
canvas.set_line_width(10.0);
|
||||
|
||||
// Draw walls.
|
||||
canvas.stroke_rect(RectF::new(Vector2F::new(75.0, 140.0), Vector2F::new(150.0, 110.0)));
|
||||
|
||||
// Draw door.
|
||||
canvas.fill_rect(RectF::new(Vector2F::new(130.0, 190.0), Vector2F::new(40.0, 60.0)));
|
||||
|
||||
// Draw roof.
|
||||
let mut path = Path2D::new();
|
||||
path.move_to(Vector2F::new(50.0, 140.0));
|
||||
path.line_to(Vector2F::new(150.0, 60.0));
|
||||
path.line_to(Vector2F::new(250.0, 140.0));
|
||||
path.close_path();
|
||||
canvas.stroke_path(path);
|
||||
|
||||
// Render the canvas to screen.
|
||||
let scene = SceneProxy::from_scene(canvas.into_scene(), RayonExecutor);
|
||||
scene.build_and_render(&mut renderer, BuildOptions::default());
|
||||
renderer.device.present_drawable();
|
||||
|
||||
// Wait for a keypress.
|
||||
let mut event_pump = sdl_context.event_pump().unwrap();
|
||||
loop {
|
||||
match event_pump.wait_event() {
|
||||
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => return,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,11 +14,11 @@ use pathfinder_geometry::basic::rect::RectF;
|
|||
use pathfinder_geometry::color::ColorF;
|
||||
use pathfinder_gl::{GLDevice, GLVersion};
|
||||
use pathfinder_gpu::resources::FilesystemResourceLoader;
|
||||
use pathfinder_gpu::{ClearParams, Device};
|
||||
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
|
||||
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
|
||||
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, Renderer};
|
||||
use pathfinder_renderer::options::RenderOptions;
|
||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
||||
use pathfinder_renderer::gpu::renderer::Renderer;
|
||||
use pathfinder_renderer::options::BuildOptions;
|
||||
use sdl2::event::Event;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use sdl2::video::GLProfile;
|
||||
|
@ -48,10 +48,8 @@ fn main() {
|
|||
// Create a Pathfinder renderer.
|
||||
let mut renderer = Renderer::new(GLDevice::new(GLVersion::GL3, 0),
|
||||
&FilesystemResourceLoader::locate(),
|
||||
DestFramebuffer::full_window(window_size));
|
||||
|
||||
// Clear to white.
|
||||
renderer.device.clear(&ClearParams { color: Some(ColorF::white()), ..ClearParams::default() });
|
||||
DestFramebuffer::full_window(window_size),
|
||||
RendererOptions { background_color: Some(ColorF::white()) });
|
||||
|
||||
// Make a canvas. We're going to draw a house.
|
||||
let mut canvas = CanvasRenderingContext2D::new(CanvasFontContext::new(), window_size.to_f32());
|
||||
|
@ -75,7 +73,7 @@ fn main() {
|
|||
|
||||
// Render the canvas to screen.
|
||||
let scene = SceneProxy::from_scene(canvas.into_scene(), RayonExecutor);
|
||||
scene.build_and_render(&mut renderer, RenderOptions::default());
|
||||
scene.build_and_render(&mut renderer, BuildOptions::default());
|
||||
window.gl_swap_window();
|
||||
|
||||
// Wait for a keypress.
|
||||
|
|
|
@ -13,11 +13,11 @@ use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
|
|||
use pathfinder_geometry::color::{ColorF, ColorU};
|
||||
use pathfinder_gl::{GLDevice, GLVersion};
|
||||
use pathfinder_gpu::resources::FilesystemResourceLoader;
|
||||
use pathfinder_gpu::{ClearParams, Device};
|
||||
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
|
||||
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
|
||||
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, Renderer};
|
||||
use pathfinder_renderer::options::RenderOptions;
|
||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
||||
use pathfinder_renderer::gpu::renderer::Renderer;
|
||||
use pathfinder_renderer::options::BuildOptions;
|
||||
use sdl2::event::Event;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use sdl2::video::GLProfile;
|
||||
|
@ -67,7 +67,8 @@ fn main() {
|
|||
// Create our renderers.
|
||||
let renderer = Renderer::new(GLDevice::new(GLVersion::GL3, 0),
|
||||
&FilesystemResourceLoader::locate(),
|
||||
DestFramebuffer::full_window(drawable_size));
|
||||
DestFramebuffer::full_window(drawable_size),
|
||||
RendererOptions { background_color: Some(ColorF::white()) });
|
||||
let mut moire_renderer = MoireRenderer::new(renderer, window_size, drawable_size);
|
||||
|
||||
// Enter main render loop.
|
||||
|
@ -124,10 +125,7 @@ impl MoireRenderer {
|
|||
Vector2F::new(1.0, sin_time).scale(cos_time * INNER_RADIUS);
|
||||
|
||||
// Clear to background color.
|
||||
self.renderer.device.clear(&ClearParams {
|
||||
color: Some(background_color),
|
||||
..ClearParams::default()
|
||||
});
|
||||
self.renderer.set_options(RendererOptions { background_color: Some(background_color) });
|
||||
|
||||
// Make a canvas.
|
||||
let mut canvas = CanvasRenderingContext2D::new(self.font_context.clone(),
|
||||
|
@ -142,7 +140,7 @@ impl MoireRenderer {
|
|||
|
||||
// Build and render scene.
|
||||
self.scene.replace_scene(canvas.into_scene());
|
||||
self.scene.build_and_render(&mut self.renderer, RenderOptions::default());
|
||||
self.scene.build_and_render(&mut self.renderer, BuildOptions::default());
|
||||
|
||||
self.frame += 1;
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
|
|||
use pathfinder_geometry::color::ColorF;
|
||||
use pathfinder_gl::{GLDevice, GLVersion};
|
||||
use pathfinder_gpu::resources::FilesystemResourceLoader;
|
||||
use pathfinder_gpu::{ClearParams, Device};
|
||||
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
|
||||
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
|
||||
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, Renderer};
|
||||
use pathfinder_renderer::options::RenderOptions;
|
||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
||||
use pathfinder_renderer::gpu::renderer::Renderer;
|
||||
use pathfinder_renderer::options::BuildOptions;
|
||||
use sdl2::event::Event;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use sdl2::video::GLProfile;
|
||||
|
@ -47,10 +47,8 @@ fn main() {
|
|||
// Create a Pathfinder renderer.
|
||||
let mut renderer = Renderer::new(GLDevice::new(GLVersion::GL3, 0),
|
||||
&FilesystemResourceLoader::locate(),
|
||||
DestFramebuffer::full_window(window_size));
|
||||
|
||||
// Clear to white.
|
||||
renderer.device.clear(&ClearParams { color: Some(ColorF::white()), ..ClearParams::default() });
|
||||
DestFramebuffer::full_window(window_size),
|
||||
RendererOptions { background_color: Some(ColorF::white()) });
|
||||
|
||||
// Make a canvas. We're going to draw some text.
|
||||
let mut canvas = CanvasRenderingContext2D::new(CanvasFontContext::new(), window_size.to_f32());
|
||||
|
@ -63,7 +61,7 @@ fn main() {
|
|||
|
||||
// Render the canvas to screen.
|
||||
let scene = SceneProxy::from_scene(canvas.into_scene(), RayonExecutor);
|
||||
scene.build_and_render(&mut renderer, RenderOptions::default());
|
||||
scene.build_and_render(&mut renderer, BuildOptions::default());
|
||||
window.gl_swap_window();
|
||||
|
||||
// Wait for a keypress.
|
||||
|
|
|
@ -75,13 +75,18 @@ impl Debug for ColorU {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct ColorF(pub F32x4);
|
||||
|
||||
impl ColorF {
|
||||
#[inline]
|
||||
pub fn new(r: f32, g: f32, b: f32, a: f32) -> ColorF {
|
||||
ColorF(F32x4::new(r, g, b, a))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn transparent_black() -> ColorF {
|
||||
ColorF(F32x4::default())
|
||||
ColorF::default()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -120,3 +125,16 @@ impl ColorF {
|
|||
self.0[3]
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for ColorF {
|
||||
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
|
||||
write!(
|
||||
formatter,
|
||||
"rgba({}, {}, {}, {})",
|
||||
self.r() * 255.0,
|
||||
self.g() * 255.0,
|
||||
self.b() * 255.0,
|
||||
self.a()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
440
gl/src/lib.rs
440
gl/src/lib.rs
|
@ -14,13 +14,13 @@
|
|||
extern crate log;
|
||||
|
||||
use gl::types::{GLboolean, GLchar, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid};
|
||||
use pathfinder_geometry::basic::vector::Vector2I;
|
||||
use pathfinder_geometry::basic::rect::RectI;
|
||||
use pathfinder_geometry::basic::vector::Vector2I;
|
||||
use pathfinder_gpu::resources::ResourceLoader;
|
||||
use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, ClearParams};
|
||||
use pathfinder_gpu::{DepthFunc, Device, Primitive, RenderState, ShaderKind, StencilFunc};
|
||||
use pathfinder_gpu::{TextureFormat, UniformData, VertexAttrClass};
|
||||
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
|
||||
use pathfinder_gpu::{RenderTarget, BlendState, BufferData, BufferTarget, BufferUploadMode};
|
||||
use pathfinder_gpu::{ClearOps, DepthFunc, Device, Primitive, RenderOptions, RenderState};
|
||||
use pathfinder_gpu::{ShaderKind, StencilFunc, TextureData, TextureFormat, UniformData};
|
||||
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
|
||||
use pathfinder_simd::default::F32x4;
|
||||
use std::ffi::CString;
|
||||
use std::mem;
|
||||
|
@ -60,10 +60,32 @@ impl GLDevice {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_render_state(&self, render_state: &RenderState) {
|
||||
fn set_render_state(&self, render_state: &RenderState<GLDevice>) {
|
||||
self.bind_render_target(render_state.target);
|
||||
|
||||
unsafe {
|
||||
let (origin, size) = (render_state.viewport.origin(), render_state.viewport.size());
|
||||
gl::Viewport(origin.x(), origin.y(), size.x(), size.y());
|
||||
}
|
||||
|
||||
if render_state.options.clear_ops.has_ops() {
|
||||
self.clear(&render_state.options.clear_ops);
|
||||
}
|
||||
|
||||
self.use_program(render_state.program);
|
||||
self.bind_vertex_array(render_state.vertex_array);
|
||||
for (texture_unit, texture) in render_state.textures.iter().enumerate() {
|
||||
self.bind_texture(texture, texture_unit as u32);
|
||||
}
|
||||
|
||||
render_state.uniforms.iter().for_each(|(uniform, data)| self.set_uniform(uniform, data));
|
||||
self.set_render_options(&render_state.options);
|
||||
}
|
||||
|
||||
fn set_render_options(&self, render_options: &RenderOptions) {
|
||||
unsafe {
|
||||
// Set blend.
|
||||
match render_state.blend {
|
||||
match render_options.blend {
|
||||
BlendState::Off => {
|
||||
gl::Disable(gl::BLEND); ck();
|
||||
}
|
||||
|
@ -91,7 +113,7 @@ impl GLDevice {
|
|||
}
|
||||
|
||||
// Set depth.
|
||||
match render_state.depth {
|
||||
match render_options.depth {
|
||||
None => {
|
||||
gl::Disable(gl::DEPTH_TEST); ck();
|
||||
}
|
||||
|
@ -103,7 +125,7 @@ impl GLDevice {
|
|||
}
|
||||
|
||||
// Set stencil.
|
||||
match render_state.stencil {
|
||||
match render_options.stencil {
|
||||
None => {
|
||||
gl::Disable(gl::STENCIL_TEST); ck();
|
||||
}
|
||||
|
@ -123,14 +145,50 @@ impl GLDevice {
|
|||
}
|
||||
|
||||
// Set color mask.
|
||||
let color_mask = render_state.color_mask as GLboolean;
|
||||
let color_mask = render_options.color_mask as GLboolean;
|
||||
gl::ColorMask(color_mask, color_mask, color_mask, color_mask); ck();
|
||||
}
|
||||
}
|
||||
|
||||
fn reset_render_state(&self, render_state: &RenderState) {
|
||||
fn set_uniform(&self, uniform: &GLUniform, data: &UniformData) {
|
||||
unsafe {
|
||||
match render_state.blend {
|
||||
match *data {
|
||||
UniformData::Int(value) => {
|
||||
gl::Uniform1i(uniform.location, value); ck();
|
||||
}
|
||||
UniformData::Mat4(data) => {
|
||||
assert_eq!(mem::size_of::<[F32x4; 4]>(), 4 * 4 * 4);
|
||||
let data_ptr: *const F32x4 = data.as_ptr();
|
||||
gl::UniformMatrix4fv(uniform.location,
|
||||
1,
|
||||
gl::FALSE,
|
||||
data_ptr as *const GLfloat);
|
||||
}
|
||||
UniformData::Vec2(data) => {
|
||||
gl::Uniform2f(uniform.location, data.x(), data.y()); ck();
|
||||
}
|
||||
UniformData::Vec4(data) => {
|
||||
gl::Uniform4f(uniform.location, data.x(), data.y(), data.z(), data.w()); ck();
|
||||
}
|
||||
UniformData::TextureUnit(unit) => {
|
||||
gl::Uniform1i(uniform.location, unit as GLint); ck();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reset_render_state(&self, render_state: &RenderState<GLDevice>) {
|
||||
self.reset_render_options(&render_state.options);
|
||||
for texture_unit in 0..(render_state.textures.len() as u32) {
|
||||
self.unbind_texture(texture_unit);
|
||||
}
|
||||
self.unuse_program();
|
||||
self.unbind_vertex_array();
|
||||
}
|
||||
|
||||
fn reset_render_options(&self, render_options: &RenderOptions) {
|
||||
unsafe {
|
||||
match render_options.blend {
|
||||
BlendState::Off => {}
|
||||
BlendState::RGBOneAlphaOneMinusSrcAlpha |
|
||||
BlendState::RGBOneAlphaOne |
|
||||
|
@ -139,11 +197,11 @@ impl GLDevice {
|
|||
}
|
||||
}
|
||||
|
||||
if render_state.depth.is_some() {
|
||||
if render_options.depth.is_some() {
|
||||
gl::Disable(gl::DEPTH_TEST); ck();
|
||||
}
|
||||
|
||||
if render_state.stencil.is_some() {
|
||||
if render_options.stencil.is_some() {
|
||||
gl::StencilMask(!0); ck();
|
||||
gl::Disable(gl::STENCIL_TEST); ck();
|
||||
}
|
||||
|
@ -165,37 +223,18 @@ impl Device for GLDevice {
|
|||
type VertexAttr = GLVertexAttr;
|
||||
|
||||
fn create_texture(&self, format: TextureFormat, size: Vector2I) -> GLTexture {
|
||||
let (gl_internal_format, gl_format, gl_type);
|
||||
match format {
|
||||
TextureFormat::R8 => {
|
||||
gl_internal_format = gl::R8 as GLint;
|
||||
gl_format = gl::RED;
|
||||
gl_type = gl::UNSIGNED_BYTE;
|
||||
}
|
||||
TextureFormat::R16F => {
|
||||
gl_internal_format = gl::R16F as GLint;
|
||||
gl_format = gl::RED;
|
||||
gl_type = gl::HALF_FLOAT;
|
||||
}
|
||||
TextureFormat::RGBA8 => {
|
||||
gl_internal_format = gl::RGBA as GLint;
|
||||
gl_format = gl::RGBA;
|
||||
gl_type = gl::UNSIGNED_BYTE;
|
||||
}
|
||||
}
|
||||
|
||||
let mut texture = GLTexture { gl_texture: 0, size };
|
||||
let mut texture = GLTexture { gl_texture: 0, size, format };
|
||||
unsafe {
|
||||
gl::GenTextures(1, &mut texture.gl_texture); ck();
|
||||
self.bind_texture(&texture, 0);
|
||||
gl::TexImage2D(gl::TEXTURE_2D,
|
||||
0,
|
||||
gl_internal_format,
|
||||
format.gl_internal_format(),
|
||||
size.x() as GLsizei,
|
||||
size.y() as GLsizei,
|
||||
0,
|
||||
gl_format,
|
||||
gl_type,
|
||||
format.gl_format(),
|
||||
format.gl_type(),
|
||||
ptr::null()); ck();
|
||||
}
|
||||
|
||||
|
@ -206,7 +245,7 @@ impl Device for GLDevice {
|
|||
fn create_texture_from_data(&self, size: Vector2I, data: &[u8]) -> GLTexture {
|
||||
assert!(data.len() >= size.x() as usize * size.y() as usize);
|
||||
|
||||
let mut texture = GLTexture { gl_texture: 0, size };
|
||||
let mut texture = GLTexture { gl_texture: 0, size, format: TextureFormat::R8 };
|
||||
unsafe {
|
||||
gl::GenTextures(1, &mut texture.gl_texture); ck();
|
||||
self.bind_texture(&texture, 0);
|
||||
|
@ -324,13 +363,14 @@ impl Device for GLDevice {
|
|||
GLUniform { location }
|
||||
}
|
||||
|
||||
fn use_program(&self, program: &Self::Program) {
|
||||
unsafe {
|
||||
gl::UseProgram(program.gl_program); ck();
|
||||
}
|
||||
}
|
||||
fn configure_vertex_attr(&self,
|
||||
vertex_array: &GLVertexArray,
|
||||
attr: &GLVertexAttr,
|
||||
descriptor: &VertexAttrDescriptor) {
|
||||
debug_assert_ne!(descriptor.stride, 0);
|
||||
|
||||
self.bind_vertex_array(vertex_array);
|
||||
|
||||
fn configure_vertex_attr(&self, attr: &GLVertexAttr, descriptor: &VertexAttrDescriptor) {
|
||||
unsafe {
|
||||
let attr_type = descriptor.attr_type.to_gl_type();
|
||||
match descriptor.class {
|
||||
|
@ -359,41 +399,8 @@ impl Device for GLDevice {
|
|||
gl::VertexAttribDivisor(attr.attr, descriptor.divisor); ck();
|
||||
gl::EnableVertexAttribArray(attr.attr); ck();
|
||||
}
|
||||
}
|
||||
|
||||
fn set_uniform(&self, uniform: &Self::Uniform, data: UniformData) {
|
||||
unsafe {
|
||||
match data {
|
||||
UniformData::Int(value) => {
|
||||
gl::Uniform1i(uniform.location, value); ck();
|
||||
}
|
||||
UniformData::Mat2(data) => {
|
||||
assert_eq!(mem::size_of::<F32x4>(), 4 * 4);
|
||||
let data_ptr: *const F32x4 = &data;
|
||||
gl::UniformMatrix2fv(uniform.location,
|
||||
1,
|
||||
gl::FALSE,
|
||||
data_ptr as *const GLfloat);
|
||||
}
|
||||
UniformData::Mat4(data) => {
|
||||
assert_eq!(mem::size_of::<[F32x4; 4]>(), 4 * 4 * 4);
|
||||
let data_ptr: *const F32x4 = data.as_ptr();
|
||||
gl::UniformMatrix4fv(uniform.location,
|
||||
1,
|
||||
gl::FALSE,
|
||||
data_ptr as *const GLfloat);
|
||||
}
|
||||
UniformData::Vec2(data) => {
|
||||
gl::Uniform2f(uniform.location, data.x(), data.y()); ck();
|
||||
}
|
||||
UniformData::Vec4(data) => {
|
||||
gl::Uniform4f(uniform.location, data.x(), data.y(), data.z(), data.w()); ck();
|
||||
}
|
||||
UniformData::TextureUnit(unit) => {
|
||||
gl::Uniform1i(uniform.location, unit as GLint); ck();
|
||||
}
|
||||
}
|
||||
}
|
||||
self.unbind_vertex_array();
|
||||
}
|
||||
|
||||
fn create_framebuffer(&self, texture: GLTexture) -> GLFramebuffer {
|
||||
|
@ -470,77 +477,67 @@ impl Device for GLDevice {
|
|||
self.set_texture_parameters(texture);
|
||||
}
|
||||
|
||||
fn read_pixels_from_default_framebuffer(&self, size: Vector2I) -> Vec<u8> {
|
||||
let mut pixels = vec![0; size.x() as usize * size.y() as usize * 4];
|
||||
fn read_pixels(&self, render_target: &RenderTarget<GLDevice>, viewport: RectI) -> TextureData {
|
||||
let (origin, size) = (viewport.origin(), viewport.size());
|
||||
let format = self.render_target_format(render_target);
|
||||
self.bind_render_target(render_target);
|
||||
|
||||
match format {
|
||||
TextureFormat::R8 | TextureFormat::RGBA8 => {
|
||||
let channels = format.channels();
|
||||
let mut pixels = vec![0; size.x() as usize * size.y() as usize * channels];
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.default_framebuffer); ck();
|
||||
gl::ReadPixels(0,
|
||||
0,
|
||||
gl::ReadPixels(origin.x(),
|
||||
origin.y(),
|
||||
size.x() as GLsizei,
|
||||
size.y() as GLsizei,
|
||||
gl::RGBA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
format.gl_format(),
|
||||
format.gl_type(),
|
||||
pixels.as_mut_ptr() as *mut GLvoid); ck();
|
||||
}
|
||||
|
||||
// Flip right-side-up.
|
||||
let stride = size.x() as usize * 4;
|
||||
for y in 0..(size.y() as usize / 2) {
|
||||
let (index_a, index_b) = (y * stride, (size.y() as usize - y - 1) * stride);
|
||||
for offset in 0..stride {
|
||||
pixels.swap(index_a + offset, index_b + offset);
|
||||
flip_y(&mut pixels, size, channels);
|
||||
TextureData::U8(pixels)
|
||||
}
|
||||
}
|
||||
|
||||
pixels
|
||||
}
|
||||
|
||||
fn clear(&self, params: &ClearParams) {
|
||||
TextureFormat::R16F => {
|
||||
let mut pixels = vec![0; size.x() as usize * size.y() as usize];
|
||||
unsafe {
|
||||
if let Some(rect) = params.rect {
|
||||
let (origin, size) = (rect.origin(), rect.size());
|
||||
gl::Scissor(origin.x(), origin.y(), size.x(), size.y()); ck();
|
||||
gl::Enable(gl::SCISSOR_TEST); ck();
|
||||
gl::ReadPixels(origin.x(),
|
||||
origin.y(),
|
||||
size.x() as GLsizei,
|
||||
size.y() as GLsizei,
|
||||
format.gl_format(),
|
||||
format.gl_type(),
|
||||
pixels.as_mut_ptr() as *mut GLvoid); ck();
|
||||
}
|
||||
|
||||
let mut flags = 0;
|
||||
if let Some(color) = params.color {
|
||||
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE); ck();
|
||||
gl::ClearColor(color.r(), color.g(), color.b(), color.a()); ck();
|
||||
flags |= gl::COLOR_BUFFER_BIT;
|
||||
}
|
||||
if let Some(depth) = params.depth {
|
||||
gl::DepthMask(gl::TRUE); ck();
|
||||
gl::ClearDepthf(depth as _); ck(); // FIXME(pcwalton): GLES
|
||||
flags |= gl::DEPTH_BUFFER_BIT;
|
||||
}
|
||||
if let Some(stencil) = params.stencil {
|
||||
gl::StencilMask(!0); ck();
|
||||
gl::ClearStencil(stencil as GLint); ck();
|
||||
flags |= gl::STENCIL_BUFFER_BIT;
|
||||
}
|
||||
if flags != 0 {
|
||||
gl::Clear(flags); ck();
|
||||
}
|
||||
|
||||
if params.rect.is_some() {
|
||||
gl::Disable(gl::SCISSOR_TEST); ck();
|
||||
flip_y(&mut pixels, size, 1);
|
||||
TextureData::U16(pixels)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_arrays(&self, primitive: Primitive, index_count: u32, render_state: &RenderState) {
|
||||
fn begin_commands(&self) {
|
||||
// TODO(pcwalton): Add some checks in debug mode to make sure render commands are bracketed
|
||||
// by these?
|
||||
}
|
||||
|
||||
fn end_commands(&self) {
|
||||
unsafe { gl::Flush(); }
|
||||
}
|
||||
|
||||
fn draw_arrays(&self, index_count: u32, render_state: &RenderState<Self>) {
|
||||
self.set_render_state(render_state);
|
||||
unsafe {
|
||||
gl::DrawArrays(primitive.to_gl_primitive(), 0, index_count as GLsizei); ck();
|
||||
gl::DrawArrays(render_state.primitive.to_gl_primitive(),
|
||||
0,
|
||||
index_count as GLsizei); ck();
|
||||
}
|
||||
self.reset_render_state(render_state);
|
||||
}
|
||||
|
||||
fn draw_elements(&self, primitive: Primitive, index_count: u32, render_state: &RenderState) {
|
||||
fn draw_elements(&self, index_count: u32, render_state: &RenderState<Self>) {
|
||||
self.set_render_state(render_state);
|
||||
unsafe {
|
||||
gl::DrawElements(primitive.to_gl_primitive(),
|
||||
gl::DrawElements(render_state.primitive.to_gl_primitive(),
|
||||
index_count as GLsizei,
|
||||
gl::UNSIGNED_INT,
|
||||
ptr::null()); ck();
|
||||
|
@ -549,13 +546,12 @@ impl Device for GLDevice {
|
|||
}
|
||||
|
||||
fn draw_elements_instanced(&self,
|
||||
primitive: Primitive,
|
||||
index_count: u32,
|
||||
instance_count: u32,
|
||||
render_state: &RenderState) {
|
||||
render_state: &RenderState<Self>) {
|
||||
self.set_render_state(render_state);
|
||||
unsafe {
|
||||
gl::DrawElementsInstanced(primitive.to_gl_primitive(),
|
||||
gl::DrawElementsInstanced(render_state.primitive.to_gl_primitive(),
|
||||
index_count as GLsizei,
|
||||
gl::UNSIGNED_INT,
|
||||
ptr::null(),
|
||||
|
@ -588,66 +584,102 @@ impl Device for GLDevice {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn timer_query_is_available(&self, query: &Self::TimerQuery) -> bool {
|
||||
fn get_timer_query(&self, query: &Self::TimerQuery) -> Option<Duration> {
|
||||
unsafe {
|
||||
let mut result = 0;
|
||||
gl::GetQueryObjectiv(query.gl_query, gl::QUERY_RESULT_AVAILABLE, &mut result); ck();
|
||||
result != gl::FALSE as GLint
|
||||
if result == gl::FALSE as GLint {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_timer_query(&self, query: &Self::TimerQuery) -> Duration {
|
||||
unsafe {
|
||||
let mut result = 0;
|
||||
gl::GetQueryObjectui64v(query.gl_query, gl::QUERY_RESULT, &mut result); ck();
|
||||
Duration::from_nanos(result)
|
||||
Some(Duration::from_nanos(result))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn bind_buffer(&self, vertex_array: &GLVertexArray, buffer: &GLBuffer, target: BufferTarget) {
|
||||
self.bind_vertex_array(vertex_array);
|
||||
unsafe {
|
||||
gl::BindBuffer(target.to_gl_target(), buffer.gl_buffer); ck();
|
||||
}
|
||||
self.unbind_vertex_array();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn create_shader(
|
||||
&self,
|
||||
resources: &dyn ResourceLoader,
|
||||
name: &str,
|
||||
kind: ShaderKind,
|
||||
) -> Self::Shader {
|
||||
let suffix = match kind {
|
||||
ShaderKind::Vertex => 'v',
|
||||
ShaderKind::Fragment => 'f',
|
||||
};
|
||||
let path = format!("shaders/gl3/{}.{}s.glsl", name, suffix);
|
||||
self.create_shader_from_source(name, &resources.slurp(&path).unwrap(), kind)
|
||||
}
|
||||
}
|
||||
|
||||
impl GLDevice {
|
||||
fn bind_render_target(&self, attachment: &RenderTarget<GLDevice>) {
|
||||
match *attachment {
|
||||
RenderTarget::Default => self.bind_default_framebuffer(),
|
||||
RenderTarget::Framebuffer(framebuffer) => self.bind_framebuffer(framebuffer),
|
||||
}
|
||||
}
|
||||
|
||||
fn bind_vertex_array(&self, vertex_array: &GLVertexArray) {
|
||||
unsafe {
|
||||
gl::BindVertexArray(vertex_array.gl_vertex_array); ck();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn bind_buffer(&self, buffer: &GLBuffer, target: BufferTarget) {
|
||||
fn unbind_vertex_array(&self) {
|
||||
unsafe {
|
||||
gl::BindBuffer(target.to_gl_target(), buffer.gl_buffer); ck();
|
||||
gl::BindVertexArray(0); ck();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn bind_default_framebuffer(&self, viewport: RectI) {
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.default_framebuffer); ck();
|
||||
gl::Viewport(viewport.origin().x(),
|
||||
viewport.origin().y(),
|
||||
viewport.size().x(),
|
||||
viewport.size().y()); ck();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn bind_framebuffer(&self, framebuffer: &GLFramebuffer) {
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer.gl_framebuffer); ck();
|
||||
gl::Viewport(0, 0, framebuffer.texture.size.x(), framebuffer.texture.size.y()); ck();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn bind_texture(&self, texture: &GLTexture, unit: u32) {
|
||||
unsafe {
|
||||
gl::ActiveTexture(gl::TEXTURE0 + unit); ck();
|
||||
gl::BindTexture(gl::TEXTURE_2D, texture.gl_texture); ck();
|
||||
}
|
||||
}
|
||||
|
||||
fn unbind_texture(&self, unit: u32) {
|
||||
unsafe {
|
||||
gl::ActiveTexture(gl::TEXTURE0 + unit); ck();
|
||||
gl::BindTexture(gl::TEXTURE_2D, 0); ck();
|
||||
}
|
||||
}
|
||||
|
||||
fn use_program(&self, program: &GLProgram) {
|
||||
unsafe {
|
||||
gl::UseProgram(program.gl_program); ck();
|
||||
}
|
||||
}
|
||||
|
||||
fn unuse_program(&self) {
|
||||
unsafe {
|
||||
gl::UseProgram(0); ck();
|
||||
}
|
||||
}
|
||||
|
||||
fn bind_default_framebuffer(&self) {
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.default_framebuffer); ck();
|
||||
}
|
||||
}
|
||||
|
||||
fn bind_framebuffer(&self, framebuffer: &GLFramebuffer) {
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer.gl_framebuffer); ck();
|
||||
}
|
||||
}
|
||||
|
||||
impl GLDevice {
|
||||
fn preprocess(&self, output: &mut Vec<u8>, source: &[u8], version: &str) {
|
||||
let mut index = 0;
|
||||
while index < source.len() {
|
||||
|
@ -669,6 +701,39 @@ impl GLDevice {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn clear(&self, ops: &ClearOps) {
|
||||
unsafe {
|
||||
let mut flags = 0;
|
||||
if let Some(color) = ops.color {
|
||||
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE); ck();
|
||||
gl::ClearColor(color.r(), color.g(), color.b(), color.a()); ck();
|
||||
flags |= gl::COLOR_BUFFER_BIT;
|
||||
}
|
||||
if let Some(depth) = ops.depth {
|
||||
gl::DepthMask(gl::TRUE); ck();
|
||||
gl::ClearDepthf(depth as _); ck(); // FIXME(pcwalton): GLES
|
||||
flags |= gl::DEPTH_BUFFER_BIT;
|
||||
}
|
||||
if let Some(stencil) = ops.stencil {
|
||||
gl::StencilMask(!0); ck();
|
||||
gl::ClearStencil(stencil as GLint); ck();
|
||||
flags |= gl::STENCIL_BUFFER_BIT;
|
||||
}
|
||||
if flags != 0 {
|
||||
gl::Clear(flags); ck();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render_target_format(&self, render_target: &RenderTarget<GLDevice>) -> TextureFormat {
|
||||
match *render_target {
|
||||
RenderTarget::Default => TextureFormat::RGBA8,
|
||||
RenderTarget::Framebuffer(ref framebuffer) => {
|
||||
self.framebuffer_texture(framebuffer).format
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GLVertexArray {
|
||||
|
@ -753,7 +818,7 @@ impl Drop for GLBuffer {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct GLUniform {
|
||||
pub location: GLint,
|
||||
location: GLint,
|
||||
}
|
||||
|
||||
pub struct GLProgram {
|
||||
|
@ -787,6 +852,7 @@ impl Drop for GLShader {
|
|||
pub struct GLTexture {
|
||||
gl_texture: GLuint,
|
||||
pub size: Vector2I,
|
||||
pub format: TextureFormat,
|
||||
}
|
||||
|
||||
pub struct GLTimerQuery {
|
||||
|
@ -863,7 +929,36 @@ impl StencilFuncExt for StencilFunc {
|
|||
match self {
|
||||
StencilFunc::Always => gl::ALWAYS,
|
||||
StencilFunc::Equal => gl::EQUAL,
|
||||
StencilFunc::NotEqual => gl::NOTEQUAL,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait TextureFormatExt {
|
||||
fn gl_internal_format(self) -> GLint;
|
||||
fn gl_format(self) -> GLuint;
|
||||
fn gl_type(self) -> GLuint;
|
||||
}
|
||||
|
||||
impl TextureFormatExt for TextureFormat {
|
||||
fn gl_internal_format(self) -> GLint {
|
||||
match self {
|
||||
TextureFormat::R8 => gl::R8 as GLint,
|
||||
TextureFormat::R16F => gl::R16F as GLint,
|
||||
TextureFormat::RGBA8 => gl::RGBA as GLint,
|
||||
}
|
||||
}
|
||||
|
||||
fn gl_format(self) -> GLuint {
|
||||
match self {
|
||||
TextureFormat::R8 | TextureFormat::R16F => gl::RED,
|
||||
TextureFormat::RGBA8 => gl::RGBA,
|
||||
}
|
||||
}
|
||||
|
||||
fn gl_type(self) -> GLuint {
|
||||
match self {
|
||||
TextureFormat::R8 | TextureFormat::RGBA8 => gl::UNSIGNED_BYTE,
|
||||
TextureFormat::R16F => gl::HALF_FLOAT,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -929,4 +1024,15 @@ fn ck() {
|
|||
#[cfg(not(debug_assertions))]
|
||||
fn ck() {}
|
||||
|
||||
// Shader preprocessing
|
||||
// Utilities
|
||||
|
||||
// Flips a buffer of image data upside-down.
|
||||
fn flip_y<T>(pixels: &mut [T], size: Vector2I, channels: usize) {
|
||||
let stride = size.x() as usize * channels;
|
||||
for y in 0..(size.y() as usize / 2) {
|
||||
let (index_a, index_b) = (y * stride, (size.y() as usize - y - 1) * stride);
|
||||
for offset in 0..stride {
|
||||
pixels.swap(index_a + offset, index_b + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
124
gpu/src/lib.rs
124
gpu/src/lib.rs
|
@ -21,7 +21,7 @@ use std::time::Duration;
|
|||
|
||||
pub mod resources;
|
||||
|
||||
pub trait Device {
|
||||
pub trait Device: Sized {
|
||||
type Buffer;
|
||||
type Framebuffer;
|
||||
type Program;
|
||||
|
@ -34,6 +34,8 @@ pub trait Device {
|
|||
|
||||
fn create_texture(&self, format: TextureFormat, size: Vector2I) -> Self::Texture;
|
||||
fn create_texture_from_data(&self, size: Vector2I, data: &[u8]) -> Self::Texture;
|
||||
fn create_shader(&self, resources: &dyn ResourceLoader, name: &str, kind: ShaderKind)
|
||||
-> Self::Shader;
|
||||
fn create_shader_from_source(&self, name: &str, source: &[u8], kind: ShaderKind)
|
||||
-> Self::Shader;
|
||||
fn create_vertex_array(&self) -> Self::VertexArray;
|
||||
|
@ -46,9 +48,14 @@ pub trait Device {
|
|||
) -> Self::Program;
|
||||
fn get_vertex_attr(&self, program: &Self::Program, name: &str) -> Option<Self::VertexAttr>;
|
||||
fn get_uniform(&self, program: &Self::Program, name: &str) -> Self::Uniform;
|
||||
fn use_program(&self, program: &Self::Program);
|
||||
fn configure_vertex_attr(&self, attr: &Self::VertexAttr, descriptor: &VertexAttrDescriptor);
|
||||
fn set_uniform(&self, uniform: &Self::Uniform, data: UniformData);
|
||||
fn bind_buffer(&self,
|
||||
vertex_array: &Self::VertexArray,
|
||||
buffer: &Self::Buffer,
|
||||
target: BufferTarget);
|
||||
fn configure_vertex_attr(&self,
|
||||
vertex_array: &Self::VertexArray,
|
||||
attr: &Self::VertexAttr,
|
||||
descriptor: &VertexAttrDescriptor);
|
||||
fn create_framebuffer(&self, texture: Self::Texture) -> Self::Framebuffer;
|
||||
fn create_buffer(&self) -> Self::Buffer;
|
||||
fn allocate_buffer<T>(
|
||||
|
@ -61,27 +68,19 @@ pub trait Device {
|
|||
fn framebuffer_texture<'f>(&self, framebuffer: &'f Self::Framebuffer) -> &'f Self::Texture;
|
||||
fn texture_size(&self, texture: &Self::Texture) -> Vector2I;
|
||||
fn upload_to_texture(&self, texture: &Self::Texture, size: Vector2I, data: &[u8]);
|
||||
fn read_pixels_from_default_framebuffer(&self, size: Vector2I) -> Vec<u8>;
|
||||
fn clear(&self, params: &ClearParams);
|
||||
fn draw_arrays(&self, primitive: Primitive, index_count: u32, render_state: &RenderState);
|
||||
fn draw_elements(&self, primitive: Primitive, index_count: u32, render_state: &RenderState);
|
||||
fn read_pixels(&self, target: &RenderTarget<Self>, viewport: RectI) -> TextureData;
|
||||
fn begin_commands(&self);
|
||||
fn end_commands(&self);
|
||||
fn draw_arrays(&self, index_count: u32, render_state: &RenderState<Self>);
|
||||
fn draw_elements(&self, index_count: u32, render_state: &RenderState<Self>);
|
||||
fn draw_elements_instanced(&self,
|
||||
primitive: Primitive,
|
||||
index_count: u32,
|
||||
instance_count: u32,
|
||||
render_state: &RenderState);
|
||||
render_state: &RenderState<Self>);
|
||||
fn create_timer_query(&self) -> Self::TimerQuery;
|
||||
fn begin_timer_query(&self, query: &Self::TimerQuery);
|
||||
fn end_timer_query(&self, query: &Self::TimerQuery);
|
||||
fn timer_query_is_available(&self, query: &Self::TimerQuery) -> bool;
|
||||
fn get_timer_query(&self, query: &Self::TimerQuery) -> Duration;
|
||||
|
||||
// TODO(pcwalton): Go bindless...
|
||||
fn bind_vertex_array(&self, vertex_array: &Self::VertexArray);
|
||||
fn bind_buffer(&self, buffer: &Self::Buffer, target: BufferTarget);
|
||||
fn bind_default_framebuffer(&self, viewport: RectI);
|
||||
fn bind_framebuffer(&self, framebuffer: &Self::Framebuffer);
|
||||
fn bind_texture(&self, texture: &Self::Texture, unit: u32);
|
||||
fn get_timer_query(&self, query: &Self::TimerQuery) -> Option<Duration>;
|
||||
|
||||
fn create_texture_from_png(&self, resources: &dyn ResourceLoader, name: &str) -> Self::Texture {
|
||||
let data = resources.slurp(&format!("textures/{}.png", name)).unwrap();
|
||||
|
@ -92,20 +91,6 @@ pub trait Device {
|
|||
self.create_texture_from_data(size, &image)
|
||||
}
|
||||
|
||||
fn create_shader(
|
||||
&self,
|
||||
resources: &dyn ResourceLoader,
|
||||
name: &str,
|
||||
kind: ShaderKind,
|
||||
) -> Self::Shader {
|
||||
let suffix = match kind {
|
||||
ShaderKind::Vertex => 'v',
|
||||
ShaderKind::Fragment => 'f',
|
||||
};
|
||||
let source = resources.slurp(&format!("shaders/gl3/{}.{}s.glsl", name, suffix)).unwrap();
|
||||
self.create_shader_from_source(name, &source, kind)
|
||||
}
|
||||
|
||||
fn create_program_from_shader_names(
|
||||
&self,
|
||||
resources: &dyn ResourceLoader,
|
||||
|
@ -124,7 +109,7 @@ pub trait Device {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum TextureFormat {
|
||||
R8,
|
||||
R16F,
|
||||
|
@ -167,7 +152,6 @@ pub enum ShaderKind {
|
|||
#[derive(Clone, Copy)]
|
||||
pub enum UniformData {
|
||||
Int(i32),
|
||||
Mat2(F32x4),
|
||||
Mat4([F32x4; 4]),
|
||||
Vec2(F32x4),
|
||||
Vec4(F32x4),
|
||||
|
@ -180,23 +164,41 @@ pub enum Primitive {
|
|||
Lines,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct ClearParams {
|
||||
#[derive(Clone)]
|
||||
pub struct RenderState<'a, D> where D: Device {
|
||||
pub target: &'a RenderTarget<'a, D>,
|
||||
pub program: &'a D::Program,
|
||||
pub vertex_array: &'a D::VertexArray,
|
||||
pub primitive: Primitive,
|
||||
pub uniforms: &'a [(&'a D::Uniform, UniformData)],
|
||||
pub textures: &'a [&'a D::Texture],
|
||||
pub viewport: RectI,
|
||||
pub options: RenderOptions,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RenderOptions {
|
||||
pub blend: BlendState,
|
||||
pub depth: Option<DepthState>,
|
||||
pub stencil: Option<StencilState>,
|
||||
pub clear_ops: ClearOps,
|
||||
pub color_mask: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct ClearOps {
|
||||
pub color: Option<ColorF>,
|
||||
pub rect: Option<RectI>,
|
||||
pub depth: Option<f32>,
|
||||
pub stencil: Option<u8>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RenderState {
|
||||
pub blend: BlendState,
|
||||
pub depth: Option<DepthState>,
|
||||
pub stencil: Option<StencilState>,
|
||||
pub color_mask: bool,
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum RenderTarget<'a, D> where D: Device {
|
||||
Default,
|
||||
Framebuffer(&'a D::Framebuffer),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum BlendState {
|
||||
Off,
|
||||
RGBOneAlphaOne,
|
||||
|
@ -228,16 +230,16 @@ pub struct StencilState {
|
|||
pub enum StencilFunc {
|
||||
Always,
|
||||
Equal,
|
||||
NotEqual,
|
||||
}
|
||||
|
||||
impl Default for RenderState {
|
||||
impl Default for RenderOptions {
|
||||
#[inline]
|
||||
fn default() -> RenderState {
|
||||
RenderState {
|
||||
fn default() -> RenderOptions {
|
||||
RenderOptions {
|
||||
blend: BlendState::default(),
|
||||
depth: None,
|
||||
stencil: None,
|
||||
clear_ops: ClearOps::default(),
|
||||
color_mask: true,
|
||||
}
|
||||
}
|
||||
|
@ -276,6 +278,12 @@ impl Default for StencilFunc {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum TextureData {
|
||||
U8(Vec<u8>),
|
||||
U16(Vec<u16>),
|
||||
}
|
||||
|
||||
impl UniformData {
|
||||
#[inline]
|
||||
pub fn from_transform_3d(transform: &Transform3DF) -> UniformData {
|
||||
|
@ -291,6 +299,7 @@ pub struct VertexAttrDescriptor {
|
|||
pub stride: usize,
|
||||
pub offset: usize,
|
||||
pub divisor: u32,
|
||||
pub buffer_index: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
|
@ -299,3 +308,20 @@ pub enum VertexAttrClass {
|
|||
FloatNorm,
|
||||
Int,
|
||||
}
|
||||
|
||||
impl TextureFormat {
|
||||
#[inline]
|
||||
pub fn channels(self) -> usize {
|
||||
match self {
|
||||
TextureFormat::R8 | TextureFormat::R16F => 1,
|
||||
TextureFormat::RGBA8 => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ClearOps {
|
||||
#[inline]
|
||||
pub fn has_ops(&self) -> bool {
|
||||
self.color.is_some() || self.depth.is_some() || self.stencil.is_some()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
[package]
|
||||
name = "pathfinder_metal"
|
||||
version = "0.1.0"
|
||||
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
byteorder = "1.3"
|
||||
block = "0.1"
|
||||
cocoa = "0.18"
|
||||
core-foundation = "0.6"
|
||||
foreign-types = "0.3"
|
||||
metal = "0.14"
|
||||
objc = "0.2"
|
||||
|
||||
[dependencies.pathfinder_geometry]
|
||||
path = "../geometry"
|
||||
|
||||
[dependencies.pathfinder_gpu]
|
||||
path = "../gpu"
|
||||
|
||||
[dependencies.pathfinder_simd]
|
||||
path = "../simd"
|
File diff suppressed because it is too large
Load Diff
|
@ -5,6 +5,7 @@ edition = "2018"
|
|||
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
byteorder = "1.2"
|
||||
fixedbitset = "0.1"
|
||||
hashbrown = "0.1"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
use crate::concurrent::executor::Executor;
|
||||
use crate::gpu_data::{AlphaTileBatchPrimitive, BuiltObject, FillBatchPrimitive, RenderCommand};
|
||||
use crate::options::{PreparedRenderOptions, RenderCommandListener};
|
||||
use crate::options::{PreparedBuildOptions, RenderCommandListener};
|
||||
use crate::scene::Scene;
|
||||
use crate::tile_map::DenseTileMap;
|
||||
use crate::tiles::{self, TILE_HEIGHT, TILE_WIDTH, Tiler};
|
||||
|
@ -28,7 +28,7 @@ use std::u16;
|
|||
|
||||
pub(crate) struct SceneBuilder<'a> {
|
||||
scene: &'a Scene,
|
||||
built_options: &'a PreparedRenderOptions,
|
||||
built_options: &'a PreparedBuildOptions,
|
||||
|
||||
pub(crate) next_alpha_tile_index: AtomicUsize,
|
||||
pub(crate) z_buffer: ZBuffer,
|
||||
|
@ -38,7 +38,7 @@ pub(crate) struct SceneBuilder<'a> {
|
|||
impl<'a> SceneBuilder<'a> {
|
||||
pub(crate) fn new(
|
||||
scene: &'a Scene,
|
||||
built_options: &'a PreparedRenderOptions,
|
||||
built_options: &'a PreparedBuildOptions,
|
||||
listener: Box<dyn RenderCommandListener>,
|
||||
) -> SceneBuilder<'a> {
|
||||
let effective_view_box = scene.effective_view_box(built_options);
|
||||
|
@ -76,7 +76,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
&self,
|
||||
path_index: usize,
|
||||
view_box: RectF,
|
||||
built_options: &PreparedRenderOptions,
|
||||
built_options: &PreparedBuildOptions,
|
||||
scene: &Scene,
|
||||
) -> Vec<AlphaTileBatchPrimitive> {
|
||||
let path_object = &scene.paths[path_index];
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
use crate::concurrent::executor::Executor;
|
||||
use crate::gpu::renderer::Renderer;
|
||||
use crate::gpu_data::RenderCommand;
|
||||
use crate::options::{RenderCommandListener, RenderOptions};
|
||||
use crate::options::{BuildOptions, RenderCommandListener};
|
||||
use crate::scene::Scene;
|
||||
use pathfinder_geometry::basic::rect::RectF;
|
||||
use pathfinder_gpu::Device;
|
||||
|
@ -59,15 +59,15 @@ impl SceneProxy {
|
|||
|
||||
#[inline]
|
||||
pub fn build_with_listener(&self,
|
||||
options: RenderOptions,
|
||||
options: BuildOptions,
|
||||
listener: Box<dyn RenderCommandListener>) {
|
||||
self.sender.send(MainToWorkerMsg::Build(options, listener)).unwrap();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn build_with_stream(&self, options: RenderOptions) -> RenderCommandStream {
|
||||
pub fn build_with_stream(&self, options: BuildOptions) -> RenderCommandStream {
|
||||
let (sender, receiver) = mpsc::sync_channel(MAX_MESSAGES_IN_FLIGHT);
|
||||
let listener = Box::new(move |command| sender.send(command).unwrap());
|
||||
let listener = Box::new(move |command| drop(sender.send(command)));
|
||||
self.build_with_listener(options, listener);
|
||||
RenderCommandStream::new(receiver)
|
||||
}
|
||||
|
@ -81,11 +81,11 @@ impl SceneProxy {
|
|||
/// renderer.render_command(&command)
|
||||
/// }
|
||||
#[inline]
|
||||
pub fn build_and_render<D>(&self, renderer: &mut Renderer<D>, options: RenderOptions)
|
||||
pub fn build_and_render<D>(&self, renderer: &mut Renderer<D>, build_options: BuildOptions)
|
||||
where D: Device {
|
||||
renderer.begin_scene();
|
||||
for command in self.build_with_stream(options) {
|
||||
renderer.render_command(&command)
|
||||
for command in self.build_with_stream(build_options) {
|
||||
renderer.render_command(&command);
|
||||
}
|
||||
renderer.end_scene();
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ fn scene_thread<E>(mut scene: Scene,
|
|||
enum MainToWorkerMsg {
|
||||
ReplaceScene(Scene),
|
||||
SetViewBox(RectF),
|
||||
Build(RenderOptions, Box<dyn RenderCommandListener>),
|
||||
Build(BuildOptions, Box<dyn RenderCommandListener>),
|
||||
GetSVG(Sender<Vec<u8>>),
|
||||
}
|
||||
|
||||
|
|
|
@ -11,4 +11,5 @@
|
|||
//! The GPU renderer for Pathfinder 3.
|
||||
|
||||
pub mod debug;
|
||||
pub mod options;
|
||||
pub mod renderer;
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
// pathfinder/renderer/src/gpu/options.rs
|
||||
//
|
||||
// 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.
|
||||
|
||||
use pathfinder_geometry::basic::rect::RectI;
|
||||
use pathfinder_geometry::basic::vector::Vector2I;
|
||||
use pathfinder_geometry::color::ColorF;
|
||||
use pathfinder_gpu::Device;
|
||||
|
||||
/// Options that influence rendering.
|
||||
#[derive(Default)]
|
||||
pub struct RendererOptions {
|
||||
pub background_color: Option<ColorF>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum DestFramebuffer<D>
|
||||
where
|
||||
D: Device,
|
||||
{
|
||||
Default {
|
||||
viewport: RectI,
|
||||
window_size: Vector2I,
|
||||
},
|
||||
Other(D::Framebuffer),
|
||||
}
|
||||
|
||||
impl<D> Default for DestFramebuffer<D> where D: Device {
|
||||
#[inline]
|
||||
fn default() -> DestFramebuffer<D> {
|
||||
DestFramebuffer::Default { viewport: RectI::default(), window_size: Vector2I::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<D> DestFramebuffer<D>
|
||||
where
|
||||
D: Device,
|
||||
{
|
||||
#[inline]
|
||||
pub fn full_window(window_size: Vector2I) -> DestFramebuffer<D> {
|
||||
let viewport = RectI::new(Vector2I::default(), window_size);
|
||||
DestFramebuffer::Default { viewport, window_size }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn window_size(&self, device: &D) -> Vector2I {
|
||||
match *self {
|
||||
DestFramebuffer::Default { window_size, .. } => window_size,
|
||||
DestFramebuffer::Other(ref framebuffer) => {
|
||||
device.texture_size(device.framebuffer_texture(framebuffer))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -75,6 +75,7 @@ pub struct SolidTileBatchPrimitive {
|
|||
pub origin_u: u16,
|
||||
pub origin_v: u16,
|
||||
pub object_index: u16,
|
||||
pub pad: u16,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
//! The CPU portion of Pathfinder's renderer.
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
//! Options that control how rendering is to be performed.
|
||||
|
||||
use crate::gpu_data::RenderCommand;
|
||||
use pathfinder_geometry::basic::vector::{Vector2F, Vector4F};
|
||||
use pathfinder_geometry::basic::rect::RectF;
|
||||
use pathfinder_geometry::basic::transform2d::Transform2DF;
|
||||
use pathfinder_geometry::basic::transform3d::Perspective;
|
||||
use pathfinder_geometry::basic::vector::{Vector2F, Vector4F};
|
||||
use pathfinder_geometry::clip::PolygonClipper3D;
|
||||
|
||||
pub trait RenderCommandListener: Send + Sync {
|
||||
|
@ -31,16 +31,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Options that influence scene building.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct RenderOptions {
|
||||
pub struct BuildOptions {
|
||||
pub transform: RenderTransform,
|
||||
pub dilation: Vector2F,
|
||||
pub subpixel_aa_enabled: bool,
|
||||
}
|
||||
|
||||
impl RenderOptions {
|
||||
pub(crate) fn prepare(self, bounds: RectF) -> PreparedRenderOptions {
|
||||
PreparedRenderOptions {
|
||||
impl BuildOptions {
|
||||
pub(crate) fn prepare(self, bounds: RectF) -> PreparedBuildOptions {
|
||||
PreparedBuildOptions {
|
||||
transform: self.transform.prepare(bounds),
|
||||
dilation: self.dilation,
|
||||
subpixel_aa_enabled: self.subpixel_aa_enabled,
|
||||
|
@ -119,13 +120,13 @@ impl RenderTransform {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct PreparedRenderOptions {
|
||||
pub(crate) struct PreparedBuildOptions {
|
||||
pub(crate) transform: PreparedRenderTransform,
|
||||
pub(crate) dilation: Vector2F,
|
||||
pub(crate) subpixel_aa_enabled: bool,
|
||||
}
|
||||
|
||||
impl PreparedRenderOptions {
|
||||
impl PreparedBuildOptions {
|
||||
#[inline]
|
||||
pub(crate) fn bounding_quad(&self) -> BoundingQuad {
|
||||
match self.transform {
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
|
||||
use crate::builder::SceneBuilder;
|
||||
use crate::concurrent::executor::Executor;
|
||||
use crate::options::{PreparedRenderOptions, PreparedRenderTransform};
|
||||
use crate::options::{RenderCommandListener, RenderOptions};
|
||||
use crate::options::{BuildOptions, PreparedBuildOptions};
|
||||
use crate::options::{PreparedRenderTransform, RenderCommandListener};
|
||||
use crate::paint::{Paint, PaintId};
|
||||
use hashbrown::HashMap;
|
||||
use pathfinder_geometry::basic::vector::Vector2F;
|
||||
|
@ -89,7 +89,7 @@ impl Scene {
|
|||
pub(crate) fn apply_render_options(
|
||||
&self,
|
||||
original_outline: &Outline,
|
||||
options: &PreparedRenderOptions,
|
||||
options: &PreparedBuildOptions,
|
||||
) -> Outline {
|
||||
let effective_view_box = self.effective_view_box(options);
|
||||
|
||||
|
@ -156,7 +156,7 @@ impl Scene {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn effective_view_box(&self, render_options: &PreparedRenderOptions) -> RectF {
|
||||
pub(crate) fn effective_view_box(&self, render_options: &PreparedBuildOptions) -> RectF {
|
||||
if render_options.subpixel_aa_enabled {
|
||||
self.view_box.scale_xy(Vector2F::new(3.0, 1.0))
|
||||
} else {
|
||||
|
@ -166,7 +166,7 @@ impl Scene {
|
|||
|
||||
#[inline]
|
||||
pub fn build<E>(&self,
|
||||
options: RenderOptions,
|
||||
options: BuildOptions,
|
||||
listener: Box<dyn RenderCommandListener>,
|
||||
executor: &E)
|
||||
where E: Executor {
|
||||
|
|
|
@ -91,6 +91,7 @@ impl SolidTileBatchPrimitive {
|
|||
object_index: object_index,
|
||||
origin_u: origin_uv.x() as u16,
|
||||
origin_v: origin_uv.y() as u16,
|
||||
pad: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -14,10 +16,10 @@ precision highp float;
|
|||
|
||||
uniform vec2 uFramebufferSize;
|
||||
|
||||
in vec2 aPosition;
|
||||
in ivec2 aPosition;
|
||||
|
||||
void main(){
|
||||
vec2 position = aPosition / uFramebufferSize * 2.0 - 1.0;
|
||||
vec2 position = vec2(aPosition)/ uFramebufferSize * 2.0 - 1.0;
|
||||
gl_Position = vec4(position . x, - position . y, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -15,14 +17,14 @@ precision highp float;
|
|||
uniform vec2 uFramebufferSize;
|
||||
uniform vec2 uTextureSize;
|
||||
|
||||
in vec2 aPosition;
|
||||
in vec2 aTexCoord;
|
||||
in ivec2 aPosition;
|
||||
in ivec2 aTexCoord;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main(){
|
||||
vTexCoord = aTexCoord / uTextureSize;
|
||||
vec2 position = aPosition / uFramebufferSize * 2.0 - 1.0;
|
||||
vTexCoord = vec2(aTexCoord)/ uTextureSize;
|
||||
vec2 position = vec2(aPosition)/ uFramebufferSize * 2.0 - 1.0;
|
||||
gl_Position = vec4(position . x, - position . y, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -15,12 +17,12 @@ precision highp float;
|
|||
uniform mat4 uTransform;
|
||||
uniform int uGridlineCount;
|
||||
|
||||
in vec2 aPosition;
|
||||
in ivec2 aPosition;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main(){
|
||||
vTexCoord = aPosition * float(uGridlineCount);
|
||||
gl_Position = uTransform * vec4(aPosition . x, 0.0, aPosition . y, 1.0);
|
||||
vTexCoord = vec2(aPosition * uGridlineCount);
|
||||
gl_Position = uTransform * vec4(ivec4(aPosition . x, 0, aPosition . y, 1));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -15,7 +17,7 @@ precision highp float;
|
|||
uniform vec2 uFramebufferSize;
|
||||
uniform vec2 uTileSize;
|
||||
|
||||
in vec2 aTessCoord;
|
||||
in uvec2 aTessCoord;
|
||||
in uint aFromPx;
|
||||
in uint aToPx;
|
||||
in vec2 aFromSubpx;
|
||||
|
@ -27,7 +29,7 @@ out vec2 vTo;
|
|||
|
||||
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){
|
||||
uint tilesPerRow = uint(stencilTextureWidth / uTileSize . x);
|
||||
uvec2 tileOffset = uvec2(aTileIndex % tilesPerRow, aTileIndex / tilesPerRow);
|
||||
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
|
||||
return vec2(tileOffset)* uTileSize;
|
||||
}
|
||||
|
||||
|
@ -38,11 +40,11 @@ void main(){
|
|||
vec2 to = vec2(aToPx & 15u, aToPx >> 4u)+ aToSubpx;
|
||||
|
||||
vec2 position;
|
||||
if(aTessCoord . x < 0.5)
|
||||
if(aTessCoord . x == 0u)
|
||||
position . x = floor(min(from . x, to . x));
|
||||
else
|
||||
position . x = ceil(max(from . x, to . x));
|
||||
if(aTessCoord . y < 0.5)
|
||||
if(aTessCoord . y == 0u)
|
||||
position . y = floor(min(from . y, to . y));
|
||||
else
|
||||
position . y = uTileSize . y;
|
||||
|
@ -50,6 +52,10 @@ void main(){
|
|||
vFrom = from - position;
|
||||
vTo = to - position;
|
||||
|
||||
gl_Position = vec4((tileOrigin + position)/ uFramebufferSize * 2.0 - 1.0, 0.0, 1.0);
|
||||
vec2 globalPosition =(tileOrigin + position)/ uFramebufferSize * 2.0 - 1.0;
|
||||
|
||||
|
||||
|
||||
gl_Position = vec4(globalPosition, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -12,12 +14,12 @@
|
|||
|
||||
precision highp float;
|
||||
|
||||
in vec2 aPosition;
|
||||
in ivec2 aPosition;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main(){
|
||||
vTexCoord = aPosition;
|
||||
gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);
|
||||
vTexCoord = vec2(aPosition);
|
||||
gl_Position = vec4(vec2(aPosition)* 2.0 - 1.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -14,12 +16,17 @@ precision highp float;
|
|||
|
||||
uniform mat4 uNewTransform;
|
||||
|
||||
in vec2 aPosition;
|
||||
in ivec2 aPosition;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main(){
|
||||
vTexCoord = aPosition;
|
||||
gl_Position = uNewTransform * vec4(aPosition, 0.0, 1.0);
|
||||
vec2 position = vec2(aPosition);
|
||||
vTexCoord = position;
|
||||
|
||||
|
||||
|
||||
|
||||
gl_Position = uNewTransform * vec4(position, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -30,10 +32,10 @@ uniform vec2 uTileSize;
|
|||
uniform vec2 uStencilTextureSize;
|
||||
uniform vec2 uViewBoxOrigin;
|
||||
|
||||
in vec2 aTessCoord;
|
||||
in uvec2 aTessCoord;
|
||||
in uvec3 aTileOrigin;
|
||||
in int aBackdrop;
|
||||
in uint aTileIndex;
|
||||
in int aTileIndex;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
out float vBackdrop;
|
||||
|
@ -49,9 +51,9 @@ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){
|
|||
|
||||
void computeVaryings(){
|
||||
vec2 origin = vec2(aTileOrigin . xy)+ vec2(aTileOrigin . z & 15u, aTileOrigin . z >> 4u)* 256.0;
|
||||
vec2 pixelPosition =(origin + aTessCoord)* uTileSize + uViewBoxOrigin;
|
||||
vec2 pixelPosition =(origin + vec2(aTessCoord))* uTileSize + uViewBoxOrigin;
|
||||
vec2 position =(pixelPosition / uFramebufferSize * 2.0 - 1.0)* vec2(1.0, - 1.0);
|
||||
vec2 maskTexCoordOrigin = computeTileOffset(aTileIndex, uStencilTextureSize . x);
|
||||
vec2 maskTexCoordOrigin = computeTileOffset(uint(aTileIndex), uStencilTextureSize . x);
|
||||
vec2 maskTexCoord = maskTexCoordOrigin + aTessCoord * uTileSize;
|
||||
|
||||
vTexCoord = maskTexCoord / uStencilTextureSize;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -30,10 +32,10 @@ uniform vec2 uTileSize;
|
|||
uniform vec2 uStencilTextureSize;
|
||||
uniform vec2 uViewBoxOrigin;
|
||||
|
||||
in vec2 aTessCoord;
|
||||
in uvec2 aTessCoord;
|
||||
in uvec3 aTileOrigin;
|
||||
in int aBackdrop;
|
||||
in uint aTileIndex;
|
||||
in int aTileIndex;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
out float vBackdrop;
|
||||
|
@ -49,9 +51,9 @@ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){
|
|||
|
||||
void computeVaryings(){
|
||||
vec2 origin = vec2(aTileOrigin . xy)+ vec2(aTileOrigin . z & 15u, aTileOrigin . z >> 4u)* 256.0;
|
||||
vec2 pixelPosition =(origin + aTessCoord)* uTileSize + uViewBoxOrigin;
|
||||
vec2 pixelPosition =(origin + vec2(aTessCoord))* uTileSize + uViewBoxOrigin;
|
||||
vec2 position =(pixelPosition / uFramebufferSize * 2.0 - 1.0)* vec2(1.0, - 1.0);
|
||||
vec2 maskTexCoordOrigin = computeTileOffset(aTileIndex, uStencilTextureSize . x);
|
||||
vec2 maskTexCoordOrigin = computeTileOffset(uint(aTileIndex), uStencilTextureSize . x);
|
||||
vec2 maskTexCoord = maskTexCoordOrigin + aTessCoord * uTileSize;
|
||||
|
||||
vTexCoord = maskTexCoord / uStencilTextureSize;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -29,19 +31,18 @@ uniform vec2 uFramebufferSize;
|
|||
uniform vec2 uTileSize;
|
||||
uniform vec2 uViewBoxOrigin;
|
||||
|
||||
in vec2 aTessCoord;
|
||||
in vec2 aTileOrigin;
|
||||
in uvec2 aTessCoord;
|
||||
in ivec2 aTileOrigin;
|
||||
|
||||
out vec4 vColor;
|
||||
|
||||
vec4 getColor();
|
||||
|
||||
void computeVaryings(){
|
||||
vec2 pixelPosition =(aTileOrigin + aTessCoord)* uTileSize + uViewBoxOrigin;
|
||||
vec2 pixelPosition = vec2(aTileOrigin + ivec2(aTessCoord))* uTileSize + uViewBoxOrigin;
|
||||
vec2 position =(pixelPosition / uFramebufferSize * 2.0 - 1.0)* vec2(1.0, - 1.0);
|
||||
|
||||
vColor = getColor();
|
||||
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#version {{version}}
|
||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -29,19 +31,18 @@ uniform vec2 uFramebufferSize;
|
|||
uniform vec2 uTileSize;
|
||||
uniform vec2 uViewBoxOrigin;
|
||||
|
||||
in vec2 aTessCoord;
|
||||
in vec2 aTileOrigin;
|
||||
in uvec2 aTessCoord;
|
||||
in ivec2 aTileOrigin;
|
||||
|
||||
out vec4 vColor;
|
||||
|
||||
vec4 getColor();
|
||||
|
||||
void computeVaryings(){
|
||||
vec2 pixelPosition =(aTileOrigin + aTessCoord)* uTileSize + uViewBoxOrigin;
|
||||
vec2 pixelPosition = vec2(aTileOrigin + ivec2(aTessCoord))* uTileSize + uViewBoxOrigin;
|
||||
vec2 position =(pixelPosition / uFramebufferSize * 2.0 - 1.0)* vec2(1.0, - 1.0);
|
||||
|
||||
vColor = getColor();
|
||||
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float4* uColor [[id(0)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 oFragColor [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(float4 uColor [[buffer(0)]])
|
||||
fragment main0_out main0(constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.oFragColor = float4(uColor.xyz, 1.0) * uColor.w;
|
||||
out.oFragColor = float4((*spvDescriptorSet0.uColor).xyz, 1.0) * (*spvDescriptorSet0.uColor).w;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float2* uFramebufferSize [[id(0)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
|
@ -10,13 +16,13 @@ struct main0_out
|
|||
|
||||
struct main0_in
|
||||
{
|
||||
float2 aPosition [[attribute(0)]];
|
||||
int2 aPosition [[attribute(0)]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], float2 uFramebufferSize [[buffer(0)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float2 position = ((in.aPosition / uFramebufferSize) * 2.0) - float2(1.0);
|
||||
float2 position = ((float2(in.aPosition) / (*spvDescriptorSet0.uFramebufferSize)) * 2.0) - float2(1.0);
|
||||
out.gl_Position = float4(position.x, -position.y, 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float4* uColor [[id(0)]];
|
||||
texture2d<float> uTexture [[id(1)]];
|
||||
sampler uTextureSmplr [[id(2)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 oFragColor [[color(0)]];
|
||||
|
@ -13,11 +21,11 @@ struct main0_in
|
|||
float2 vTexCoord [[user(locn0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], float4 uColor [[buffer(0)]], texture2d<float> uTexture [[texture(0)]], sampler uTextureSmplr [[sampler(0)]])
|
||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float alpha = uTexture.sample(uTextureSmplr, in.vTexCoord).x * uColor.w;
|
||||
out.oFragColor = float4(uColor.xyz, 1.0) * alpha;
|
||||
float alpha = spvDescriptorSet0.uTexture.sample(spvDescriptorSet0.uTextureSmplr, in.vTexCoord).x * (*spvDescriptorSet0.uColor).w;
|
||||
out.oFragColor = float4((*spvDescriptorSet0.uColor).xyz, 1.0) * alpha;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float2* uTextureSize [[id(0)]];
|
||||
constant float2* uFramebufferSize [[id(1)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float2 vTexCoord [[user(locn0)]];
|
||||
|
@ -11,15 +18,15 @@ struct main0_out
|
|||
|
||||
struct main0_in
|
||||
{
|
||||
float2 aPosition [[attribute(0)]];
|
||||
float2 aTexCoord [[attribute(1)]];
|
||||
int2 aPosition [[attribute(0)]];
|
||||
int2 aTexCoord [[attribute(1)]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], float2 uTextureSize [[buffer(0)]], float2 uFramebufferSize [[buffer(1)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.vTexCoord = in.aTexCoord / uTextureSize;
|
||||
float2 position = ((in.aPosition / uFramebufferSize) * 2.0) - float2(1.0);
|
||||
out.vTexCoord = float2(in.aTexCoord) / (*spvDescriptorSet0.uTextureSize);
|
||||
float2 position = ((float2(in.aPosition) / (*spvDescriptorSet0.uFramebufferSize)) * 2.0) - float2(1.0);
|
||||
out.gl_Position = float4(position.x, -position.y, 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float4* uGridlineColor [[id(0)]];
|
||||
constant float4* uGroundColor [[id(1)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 oFragColor [[color(0)]];
|
||||
|
@ -13,12 +20,12 @@ struct main0_in
|
|||
float2 vTexCoord [[user(locn0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], float4 uGridlineColor [[buffer(0)]], float4 uGroundColor [[buffer(1)]])
|
||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float2 texCoordPx = fract(in.vTexCoord) / fwidth(in.vTexCoord);
|
||||
bool4 _33 = bool4(any(texCoordPx <= float2(1.0)));
|
||||
out.oFragColor = float4(_33.x ? uGridlineColor.x : uGroundColor.x, _33.y ? uGridlineColor.y : uGroundColor.y, _33.z ? uGridlineColor.z : uGroundColor.z, _33.w ? uGridlineColor.w : uGroundColor.w);
|
||||
out.oFragColor = float4(_33.x ? (*spvDescriptorSet0.uGridlineColor).x : (*spvDescriptorSet0.uGroundColor).x, _33.y ? (*spvDescriptorSet0.uGridlineColor).y : (*spvDescriptorSet0.uGroundColor).y, _33.z ? (*spvDescriptorSet0.uGridlineColor).z : (*spvDescriptorSet0.uGroundColor).z, _33.w ? (*spvDescriptorSet0.uGridlineColor).w : (*spvDescriptorSet0.uGroundColor).w);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant int* uGridlineCount [[id(0)]];
|
||||
constant float4x4* uTransform [[id(1)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float2 vTexCoord [[user(locn0)]];
|
||||
|
@ -11,14 +18,14 @@ struct main0_out
|
|||
|
||||
struct main0_in
|
||||
{
|
||||
float2 aPosition [[attribute(0)]];
|
||||
int2 aPosition [[attribute(0)]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], int uGridlineCount [[buffer(0)]], float4x4 uTransform [[buffer(1)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.vTexCoord = in.aPosition * float(uGridlineCount);
|
||||
out.gl_Position = uTransform * float4(in.aPosition.x, 0.0, in.aPosition.y, 1.0);
|
||||
out.vTexCoord = float2(in.aPosition * int2((*spvDescriptorSet0.uGridlineCount)));
|
||||
out.gl_Position = (*spvDescriptorSet0.uTransform) * float4(int4(in.aPosition.x, 0, in.aPosition.y, 1));
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
texture2d<float> uAreaLUT [[id(0)]];
|
||||
sampler uAreaLUTSmplr [[id(1)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 oFragColor [[color(0)]];
|
||||
|
@ -14,7 +21,7 @@ struct main0_in
|
|||
float2 vTo [[user(locn1)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uAreaLUT [[texture(0)]], sampler uAreaLUTSmplr [[sampler(0)]])
|
||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float2 from = in.vFrom;
|
||||
|
@ -29,7 +36,7 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uAreaLUT [[t
|
|||
float y = mix(left.y, right.y, t);
|
||||
float d = (right.y - left.y) / (right.x - left.x);
|
||||
float dX = window.x - window.y;
|
||||
out.oFragColor = float4(uAreaLUT.sample(uAreaLUTSmplr, (float2(y + 8.0, abs(d * dX)) / float2(16.0))).x * dX);
|
||||
out.oFragColor = float4(spvDescriptorSet0.uAreaLUT.sample(spvDescriptorSet0.uAreaLUTSmplr, (float2(y + 8.0, abs(d * dX)) / float2(16.0))).x * dX);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
|
@ -5,6 +6,12 @@
|
|||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float2* uTileSize [[id(0)]];
|
||||
constant float2* uFramebufferSize [[id(1)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float2 vFrom [[user(locn0)]];
|
||||
|
@ -14,7 +21,7 @@ struct main0_out
|
|||
|
||||
struct main0_in
|
||||
{
|
||||
float2 aTessCoord [[attribute(0)]];
|
||||
uint2 aTessCoord [[attribute(0)]];
|
||||
uint aFromPx [[attribute(1)]];
|
||||
uint aToPx [[attribute(2)]];
|
||||
float2 aFromSubpx [[attribute(3)]];
|
||||
|
@ -22,23 +29,23 @@ struct main0_in
|
|||
uint aTileIndex [[attribute(5)]];
|
||||
};
|
||||
|
||||
float2 computeTileOffset(thread const uint& tileIndex, thread const float& stencilTextureWidth, thread float2 uTileSize, thread uint& aTileIndex)
|
||||
float2 computeTileOffset(thread const uint& tileIndex, thread const float& stencilTextureWidth, thread float2 uTileSize)
|
||||
{
|
||||
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
|
||||
uint2 tileOffset = uint2(aTileIndex % tilesPerRow, aTileIndex / tilesPerRow);
|
||||
uint2 tileOffset = uint2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
|
||||
return float2(tileOffset) * uTileSize;
|
||||
}
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], float2 uTileSize [[buffer(0)]], float2 uFramebufferSize [[buffer(1)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
uint param = in.aTileIndex;
|
||||
float param_1 = uFramebufferSize.x;
|
||||
float2 tileOrigin = computeTileOffset(param, param_1, uTileSize, in.aTileIndex);
|
||||
float param_1 = (*spvDescriptorSet0.uFramebufferSize).x;
|
||||
float2 tileOrigin = computeTileOffset(param, param_1, (*spvDescriptorSet0.uTileSize));
|
||||
float2 from = float2(float(in.aFromPx & 15u), float(in.aFromPx >> 4u)) + in.aFromSubpx;
|
||||
float2 to = float2(float(in.aToPx & 15u), float(in.aToPx >> 4u)) + in.aToSubpx;
|
||||
float2 position;
|
||||
if (in.aTessCoord.x < 0.5)
|
||||
if (in.aTessCoord.x == 0u)
|
||||
{
|
||||
position.x = floor(fast::min(from.x, to.x));
|
||||
}
|
||||
|
@ -46,17 +53,19 @@ vertex main0_out main0(main0_in in [[stage_in]], float2 uTileSize [[buffer(0)]],
|
|||
{
|
||||
position.x = ceil(fast::max(from.x, to.x));
|
||||
}
|
||||
if (in.aTessCoord.y < 0.5)
|
||||
if (in.aTessCoord.y == 0u)
|
||||
{
|
||||
position.y = floor(fast::min(from.y, to.y));
|
||||
}
|
||||
else
|
||||
{
|
||||
position.y = uTileSize.y;
|
||||
position.y = (*spvDescriptorSet0.uTileSize).y;
|
||||
}
|
||||
out.vFrom = from - position;
|
||||
out.vTo = to - position;
|
||||
out.gl_Position = float4((((tileOrigin + position) / uFramebufferSize) * 2.0) - float2(1.0), 0.0, 1.0);
|
||||
float2 globalPosition = (((tileOrigin + position) / (*spvDescriptorSet0.uFramebufferSize)) * 2.0) - float2(1.0);
|
||||
globalPosition.y = -globalPosition.y;
|
||||
out.gl_Position = float4(globalPosition, 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
|
@ -5,6 +6,19 @@
|
|||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float4* uKernel [[id(0)]];
|
||||
texture2d<float> uGammaLUT [[id(1)]];
|
||||
texture2d<float> uSource [[id(2)]];
|
||||
constant float2* uSourceSize [[id(3)]];
|
||||
sampler uSourceSmplr [[id(4)]];
|
||||
sampler uGammaLUTSmplr [[id(5)]];
|
||||
constant int* uGammaCorrectionEnabled [[id(6)]];
|
||||
constant float4* uBGColor [[id(7)]];
|
||||
constant float4* uFGColor [[id(8)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 oFragColor [[color(0)]];
|
||||
|
@ -78,42 +92,42 @@ float3 gammaCorrect(thread const float3& bgColor, thread const float3& fgColor,
|
|||
return float3(gammaCorrectChannel(param, param_1, uGammaLUT, uGammaLUTSmplr), gammaCorrectChannel(param_2, param_3, uGammaLUT, uGammaLUTSmplr), gammaCorrectChannel(param_4, param_5, uGammaLUT, uGammaLUTSmplr));
|
||||
}
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], int uGammaCorrectionEnabled [[buffer(2)]], float4 uKernel [[buffer(0)]], float2 uSourceSize [[buffer(1)]], float4 uBGColor [[buffer(3)]], float4 uFGColor [[buffer(4)]], texture2d<float> uGammaLUT [[texture(0)]], texture2d<float> uSource [[texture(0)]], sampler uGammaLUTSmplr [[sampler(0)]], sampler uSourceSmplr [[sampler(0)]])
|
||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float3 alpha;
|
||||
if (uKernel.w == 0.0)
|
||||
if ((*spvDescriptorSet0.uKernel).w == 0.0)
|
||||
{
|
||||
alpha = uSource.sample(uSourceSmplr, in.vTexCoord).xxx;
|
||||
alpha = spvDescriptorSet0.uSource.sample(spvDescriptorSet0.uSourceSmplr, in.vTexCoord).xxx;
|
||||
}
|
||||
else
|
||||
{
|
||||
float param_3 = 1.0 / uSourceSize.x;
|
||||
float param_3 = 1.0 / (*spvDescriptorSet0.uSourceSize).x;
|
||||
float4 param;
|
||||
float param_1;
|
||||
float4 param_2;
|
||||
sample9Tap(param, param_1, param_2, param_3, uKernel, uSource, uSourceSmplr, in.vTexCoord);
|
||||
sample9Tap(param, param_1, param_2, param_3, (*spvDescriptorSet0.uKernel), spvDescriptorSet0.uSource, spvDescriptorSet0.uSourceSmplr, in.vTexCoord);
|
||||
float4 alphaLeft = param;
|
||||
float alphaCenter = param_1;
|
||||
float4 alphaRight = param_2;
|
||||
float4 param_4 = alphaLeft;
|
||||
float3 param_5 = float3(alphaCenter, alphaRight.xy);
|
||||
float r = convolve7Tap(param_4, param_5, uKernel);
|
||||
float r = convolve7Tap(param_4, param_5, (*spvDescriptorSet0.uKernel));
|
||||
float4 param_6 = float4(alphaLeft.yzw, alphaCenter);
|
||||
float3 param_7 = alphaRight.xyz;
|
||||
float g = convolve7Tap(param_6, param_7, uKernel);
|
||||
float g = convolve7Tap(param_6, param_7, (*spvDescriptorSet0.uKernel));
|
||||
float4 param_8 = float4(alphaLeft.zw, alphaCenter, alphaRight.x);
|
||||
float3 param_9 = alphaRight.yzw;
|
||||
float b = convolve7Tap(param_8, param_9, uKernel);
|
||||
float b = convolve7Tap(param_8, param_9, (*spvDescriptorSet0.uKernel));
|
||||
alpha = float3(r, g, b);
|
||||
}
|
||||
if (uGammaCorrectionEnabled != 0)
|
||||
if ((*spvDescriptorSet0.uGammaCorrectionEnabled) != 0)
|
||||
{
|
||||
float3 param_10 = uBGColor.xyz;
|
||||
float3 param_10 = (*spvDescriptorSet0.uBGColor).xyz;
|
||||
float3 param_11 = alpha;
|
||||
alpha = gammaCorrect(param_10, param_11, uGammaLUT, uGammaLUTSmplr);
|
||||
alpha = gammaCorrect(param_10, param_11, spvDescriptorSet0.uGammaLUT, spvDescriptorSet0.uGammaLUTSmplr);
|
||||
}
|
||||
out.oFragColor = float4(mix(uBGColor.xyz, uFGColor.xyz, alpha), 1.0);
|
||||
out.oFragColor = float4(mix((*spvDescriptorSet0.uBGColor).xyz, (*spvDescriptorSet0.uFGColor).xyz, alpha), 1.0);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
|
@ -11,14 +12,14 @@ struct main0_out
|
|||
|
||||
struct main0_in
|
||||
{
|
||||
float2 aPosition [[attribute(0)]];
|
||||
int2 aPosition [[attribute(0)]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.vTexCoord = in.aPosition;
|
||||
out.gl_Position = float4((in.aPosition * 2.0) - float2(1.0), 0.0, 1.0);
|
||||
out.vTexCoord = float2(in.aPosition);
|
||||
out.gl_Position = float4((float2(in.aPosition) * 2.0) - float2(1.0), 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float4x4* uOldTransform [[id(0)]];
|
||||
texture2d<float> uTexture [[id(1)]];
|
||||
sampler uTextureSmplr [[id(2)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 oFragColor [[color(0)]];
|
||||
|
@ -13,12 +21,12 @@ struct main0_in
|
|||
float2 vTexCoord [[user(locn0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], float4x4 uOldTransform [[buffer(0)]], texture2d<float> uTexture [[texture(0)]], sampler uTextureSmplr [[sampler(0)]])
|
||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float4 normTexCoord = uOldTransform * float4(in.vTexCoord, 0.0, 1.0);
|
||||
float4 normTexCoord = (*spvDescriptorSet0.uOldTransform) * float4(in.vTexCoord, 0.0, 1.0);
|
||||
float2 texCoord = ((normTexCoord.xy / float2(normTexCoord.w)) + float2(1.0)) * 0.5;
|
||||
out.oFragColor = uTexture.sample(uTextureSmplr, texCoord);
|
||||
out.oFragColor = spvDescriptorSet0.uTexture.sample(spvDescriptorSet0.uTextureSmplr, texCoord);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float4x4* uNewTransform [[id(0)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float2 vTexCoord [[user(locn0)]];
|
||||
|
@ -11,14 +17,16 @@ struct main0_out
|
|||
|
||||
struct main0_in
|
||||
{
|
||||
float2 aPosition [[attribute(0)]];
|
||||
int2 aPosition [[attribute(0)]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], float4x4 uNewTransform [[buffer(0)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.vTexCoord = in.aPosition;
|
||||
out.gl_Position = uNewTransform * float4(in.aPosition, 0.0, 1.0);
|
||||
float2 position = float2(in.aPosition);
|
||||
out.vTexCoord = position;
|
||||
position.y = 1.0 - position.y;
|
||||
out.gl_Position = (*spvDescriptorSet0.uNewTransform) * float4(position, 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
|
@ -13,7 +14,7 @@ struct main0_in
|
|||
float3 aPosition [[attribute(0)]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_Position = float4(in.aPosition, 1.0);
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
texture2d<float> uStencilTexture [[id(0)]];
|
||||
sampler uStencilTextureSmplr [[id(1)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 oFragColor [[color(0)]];
|
||||
|
@ -15,10 +22,10 @@ struct main0_in
|
|||
float4 vColor [[user(locn2)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uStencilTexture [[texture(0)]], sampler uStencilTextureSmplr [[sampler(0)]])
|
||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float coverage = abs(uStencilTexture.sample(uStencilTextureSmplr, in.vTexCoord).x + in.vBackdrop);
|
||||
float coverage = abs(spvDescriptorSet0.uStencilTexture.sample(spvDescriptorSet0.uStencilTextureSmplr, in.vTexCoord).x + in.vBackdrop);
|
||||
out.oFragColor = float4(in.vColor.xyz, in.vColor.w * coverage);
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
|
@ -5,6 +6,15 @@
|
|||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float2* uTileSize [[id(0)]];
|
||||
constant float2* uViewBoxOrigin [[id(1)]];
|
||||
constant float2* uFramebufferSize [[id(2)]];
|
||||
constant float2* uStencilTextureSize [[id(3)]];
|
||||
constant float4* uColor [[id(4)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float2 vTexCoord [[user(locn0)]];
|
||||
|
@ -15,10 +25,10 @@ struct main0_out
|
|||
|
||||
struct main0_in
|
||||
{
|
||||
float2 aTessCoord [[attribute(0)]];
|
||||
uint2 aTessCoord [[attribute(0)]];
|
||||
uint3 aTileOrigin [[attribute(1)]];
|
||||
int aBackdrop [[attribute(2)]];
|
||||
uint aTileIndex [[attribute(3)]];
|
||||
int aTileIndex [[attribute(3)]];
|
||||
};
|
||||
|
||||
float2 computeTileOffset(thread const uint& tileIndex, thread const float& stencilTextureWidth, thread float2 uTileSize)
|
||||
|
@ -33,25 +43,25 @@ float4 getColor(thread float4 uColor)
|
|||
return uColor;
|
||||
}
|
||||
|
||||
void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread float2& aTessCoord, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread uint& aTileIndex, thread float2 uStencilTextureSize, thread float2& vTexCoord, thread float& vBackdrop, thread int& aBackdrop, thread float4& vColor, thread float4& gl_Position, thread float4 uColor)
|
||||
void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread uint2& aTessCoord, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread int& aTileIndex, thread float2 uStencilTextureSize, thread float2& vTexCoord, thread float& vBackdrop, thread int& aBackdrop, thread float4& vColor, thread float4& gl_Position, thread float4 uColor)
|
||||
{
|
||||
float2 origin = float2(aTileOrigin.xy) + (float2(float(aTileOrigin.z & 15u), float(aTileOrigin.z >> 4u)) * 256.0);
|
||||
float2 pixelPosition = ((origin + aTessCoord) * uTileSize) + uViewBoxOrigin;
|
||||
float2 pixelPosition = ((origin + float2(aTessCoord)) * uTileSize) + uViewBoxOrigin;
|
||||
float2 position = (((pixelPosition / uFramebufferSize) * 2.0) - float2(1.0)) * float2(1.0, -1.0);
|
||||
uint param = aTileIndex;
|
||||
uint param = uint(aTileIndex);
|
||||
float param_1 = uStencilTextureSize.x;
|
||||
float2 maskTexCoordOrigin = computeTileOffset(param, param_1, uTileSize);
|
||||
float2 maskTexCoord = maskTexCoordOrigin + (aTessCoord * uTileSize);
|
||||
float2 maskTexCoord = maskTexCoordOrigin + (float2(aTessCoord) * uTileSize);
|
||||
vTexCoord = maskTexCoord / uStencilTextureSize;
|
||||
vBackdrop = float(aBackdrop);
|
||||
vColor = getColor(uColor);
|
||||
gl_Position = float4(position, 0.0, 1.0);
|
||||
}
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], float2 uTileSize [[buffer(0)]], float2 uViewBoxOrigin [[buffer(1)]], float2 uFramebufferSize [[buffer(2)]], float2 uStencilTextureSize [[buffer(3)]], float4 uColor [[buffer(4)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
computeVaryings(uTileSize, in.aTileOrigin, in.aTessCoord, uViewBoxOrigin, uFramebufferSize, in.aTileIndex, uStencilTextureSize, out.vTexCoord, out.vBackdrop, in.aBackdrop, out.vColor, out.gl_Position, uColor);
|
||||
computeVaryings((*spvDescriptorSet0.uTileSize), in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uViewBoxOrigin), (*spvDescriptorSet0.uFramebufferSize), in.aTileIndex, (*spvDescriptorSet0.uStencilTextureSize), out.vTexCoord, out.vBackdrop, in.aBackdrop, out.vColor, out.gl_Position, (*spvDescriptorSet0.uColor));
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
|
@ -5,6 +6,16 @@
|
|||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float2* uTileSize [[id(0)]];
|
||||
texture2d<float> uPaintTexture [[id(1)]];
|
||||
constant float2* uViewBoxOrigin [[id(2)]];
|
||||
sampler uPaintTextureSmplr [[id(3)]];
|
||||
constant float2* uFramebufferSize [[id(4)]];
|
||||
constant float2* uStencilTextureSize [[id(5)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float2 vTexCoord [[user(locn0)]];
|
||||
|
@ -15,10 +26,10 @@ struct main0_out
|
|||
|
||||
struct main0_in
|
||||
{
|
||||
float2 aTessCoord [[attribute(0)]];
|
||||
uint2 aTessCoord [[attribute(0)]];
|
||||
uint3 aTileOrigin [[attribute(1)]];
|
||||
int aBackdrop [[attribute(2)]];
|
||||
uint aTileIndex [[attribute(3)]];
|
||||
int aTileIndex [[attribute(3)]];
|
||||
float2 aColorTexCoord [[attribute(4)]];
|
||||
};
|
||||
|
||||
|
@ -34,25 +45,25 @@ float4 getColor(thread texture2d<float> uPaintTexture, thread const sampler uPai
|
|||
return uPaintTexture.sample(uPaintTextureSmplr, aColorTexCoord, level(0.0));
|
||||
}
|
||||
|
||||
void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread float2& aTessCoord, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread uint& aTileIndex, thread float2 uStencilTextureSize, thread float2& vTexCoord, thread float& vBackdrop, thread int& aBackdrop, thread float4& vColor, thread float4& gl_Position, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& aColorTexCoord)
|
||||
void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread uint2& aTessCoord, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread int& aTileIndex, thread float2 uStencilTextureSize, thread float2& vTexCoord, thread float& vBackdrop, thread int& aBackdrop, thread float4& vColor, thread float4& gl_Position, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& aColorTexCoord)
|
||||
{
|
||||
float2 origin = float2(aTileOrigin.xy) + (float2(float(aTileOrigin.z & 15u), float(aTileOrigin.z >> 4u)) * 256.0);
|
||||
float2 pixelPosition = ((origin + aTessCoord) * uTileSize) + uViewBoxOrigin;
|
||||
float2 pixelPosition = ((origin + float2(aTessCoord)) * uTileSize) + uViewBoxOrigin;
|
||||
float2 position = (((pixelPosition / uFramebufferSize) * 2.0) - float2(1.0)) * float2(1.0, -1.0);
|
||||
uint param = aTileIndex;
|
||||
uint param = uint(aTileIndex);
|
||||
float param_1 = uStencilTextureSize.x;
|
||||
float2 maskTexCoordOrigin = computeTileOffset(param, param_1, uTileSize);
|
||||
float2 maskTexCoord = maskTexCoordOrigin + (aTessCoord * uTileSize);
|
||||
float2 maskTexCoord = maskTexCoordOrigin + (float2(aTessCoord) * uTileSize);
|
||||
vTexCoord = maskTexCoord / uStencilTextureSize;
|
||||
vBackdrop = float(aBackdrop);
|
||||
vColor = getColor(uPaintTexture, uPaintTextureSmplr, aColorTexCoord);
|
||||
gl_Position = float4(position, 0.0, 1.0);
|
||||
}
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], float2 uTileSize [[buffer(0)]], float2 uViewBoxOrigin [[buffer(1)]], float2 uFramebufferSize [[buffer(2)]], float2 uStencilTextureSize [[buffer(3)]], texture2d<float> uPaintTexture [[texture(0)]], sampler uPaintTextureSmplr [[sampler(0)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
computeVaryings(uTileSize, in.aTileOrigin, in.aTessCoord, uViewBoxOrigin, uFramebufferSize, in.aTileIndex, uStencilTextureSize, out.vTexCoord, out.vBackdrop, in.aBackdrop, out.vColor, out.gl_Position, uPaintTexture, uPaintTextureSmplr, in.aColorTexCoord);
|
||||
computeVaryings((*spvDescriptorSet0.uTileSize), in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uViewBoxOrigin), (*spvDescriptorSet0.uFramebufferSize), in.aTileIndex, (*spvDescriptorSet0.uStencilTextureSize), out.vTexCoord, out.vBackdrop, in.aBackdrop, out.vColor, out.gl_Position, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.aColorTexCoord);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
|
@ -5,6 +6,14 @@
|
|||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float2* uTileSize [[id(0)]];
|
||||
constant float2* uViewBoxOrigin [[id(1)]];
|
||||
constant float2* uFramebufferSize [[id(2)]];
|
||||
constant float4* uColor [[id(3)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 vColor [[user(locn0)]];
|
||||
|
@ -13,8 +22,8 @@ struct main0_out
|
|||
|
||||
struct main0_in
|
||||
{
|
||||
float2 aTessCoord [[attribute(0)]];
|
||||
float2 aTileOrigin [[attribute(1)]];
|
||||
uint2 aTessCoord [[attribute(0)]];
|
||||
int2 aTileOrigin [[attribute(1)]];
|
||||
};
|
||||
|
||||
float4 getColor(thread float4 uColor)
|
||||
|
@ -22,18 +31,18 @@ float4 getColor(thread float4 uColor)
|
|||
return uColor;
|
||||
}
|
||||
|
||||
void computeVaryings(thread float2& aTileOrigin, thread float2& aTessCoord, thread float2 uTileSize, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread float4& vColor, thread float4& gl_Position, thread float4 uColor)
|
||||
void computeVaryings(thread int2& aTileOrigin, thread uint2& aTessCoord, thread float2 uTileSize, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread float4& vColor, thread float4& gl_Position, thread float4 uColor)
|
||||
{
|
||||
float2 pixelPosition = ((aTileOrigin + aTessCoord) * uTileSize) + uViewBoxOrigin;
|
||||
float2 pixelPosition = (float2(aTileOrigin + int2(aTessCoord)) * uTileSize) + uViewBoxOrigin;
|
||||
float2 position = (((pixelPosition / uFramebufferSize) * 2.0) - float2(1.0)) * float2(1.0, -1.0);
|
||||
vColor = getColor(uColor);
|
||||
gl_Position = float4(position, 0.0, 1.0);
|
||||
}
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], float2 uTileSize [[buffer(0)]], float2 uViewBoxOrigin [[buffer(1)]], float2 uFramebufferSize [[buffer(2)]], float4 uColor [[buffer(3)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
computeVaryings(in.aTileOrigin, in.aTessCoord, uTileSize, uViewBoxOrigin, uFramebufferSize, out.vColor, out.gl_Position, uColor);
|
||||
computeVaryings(in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uTileSize), (*spvDescriptorSet0.uViewBoxOrigin), (*spvDescriptorSet0.uFramebufferSize), out.vColor, out.gl_Position, (*spvDescriptorSet0.uColor));
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
|
@ -5,6 +6,15 @@
|
|||
|
||||
using namespace metal;
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
constant float2* uTileSize [[id(0)]];
|
||||
texture2d<float> uPaintTexture [[id(1)]];
|
||||
constant float2* uViewBoxOrigin [[id(2)]];
|
||||
sampler uPaintTextureSmplr [[id(3)]];
|
||||
constant float2* uFramebufferSize [[id(4)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 vColor [[user(locn0)]];
|
||||
|
@ -13,8 +23,8 @@ struct main0_out
|
|||
|
||||
struct main0_in
|
||||
{
|
||||
float2 aTessCoord [[attribute(0)]];
|
||||
float2 aTileOrigin [[attribute(1)]];
|
||||
uint2 aTessCoord [[attribute(0)]];
|
||||
int2 aTileOrigin [[attribute(1)]];
|
||||
float2 aColorTexCoord [[attribute(2)]];
|
||||
};
|
||||
|
||||
|
@ -23,18 +33,18 @@ float4 getColor(thread texture2d<float> uPaintTexture, thread const sampler uPai
|
|||
return uPaintTexture.sample(uPaintTextureSmplr, aColorTexCoord, level(0.0));
|
||||
}
|
||||
|
||||
void computeVaryings(thread float2& aTileOrigin, thread float2& aTessCoord, thread float2 uTileSize, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread float4& vColor, thread float4& gl_Position, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& aColorTexCoord)
|
||||
void computeVaryings(thread int2& aTileOrigin, thread uint2& aTessCoord, thread float2 uTileSize, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread float4& vColor, thread float4& gl_Position, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& aColorTexCoord)
|
||||
{
|
||||
float2 pixelPosition = ((aTileOrigin + aTessCoord) * uTileSize) + uViewBoxOrigin;
|
||||
float2 pixelPosition = (float2(aTileOrigin + int2(aTessCoord)) * uTileSize) + uViewBoxOrigin;
|
||||
float2 position = (((pixelPosition / uFramebufferSize) * 2.0) - float2(1.0)) * float2(1.0, -1.0);
|
||||
vColor = getColor(uPaintTexture, uPaintTextureSmplr, aColorTexCoord);
|
||||
gl_Position = float4(position, 0.0, 1.0);
|
||||
}
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], float2 uTileSize [[buffer(0)]], float2 uViewBoxOrigin [[buffer(1)]], float2 uFramebufferSize [[buffer(2)]], texture2d<float> uPaintTexture [[texture(0)]], sampler uPaintTextureSmplr [[sampler(0)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
computeVaryings(in.aTileOrigin, in.aTessCoord, uTileSize, uViewBoxOrigin, uFramebufferSize, out.vColor, out.gl_Position, uPaintTexture, uPaintTextureSmplr, in.aColorTexCoord);
|
||||
computeVaryings(in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uTileSize), (*spvDescriptorSet0.uViewBoxOrigin), (*spvDescriptorSet0.uFramebufferSize), out.vColor, out.gl_Position, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.aColorTexCoord);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -37,14 +37,20 @@ INCLUDES=\
|
|||
OUT=\
|
||||
$(SHADERS:%=$(TARGET_DIR)/gl3/%) \
|
||||
$(SHADERS:%.glsl=$(TARGET_DIR)/metal/%.metal) \
|
||||
$(SHADERS:%.glsl=build/metal/%.spv) \
|
||||
$(EMPTY)
|
||||
|
||||
GLSL_VERSION=330
|
||||
GLSLANGFLAGS=--auto-map-locations -I.
|
||||
GLSLANGFLAGS_METAL=$(GLSLANGFLAGS) -DPF_ORIGIN_UPPER_LEFT=1
|
||||
|
||||
SPIRVCROSSFLAGS=--msl
|
||||
SPIRVCROSS?=spirv-cross
|
||||
SPIRVCROSSFLAGS=--msl --msl-version 020100 --msl-argument-buffers
|
||||
|
||||
SED_ARGS=-e "s/\#version 330/\#version \{\{version\}\}/" -e "s/\#line.*$$//"
|
||||
GLSL_VERSION_HEADER="\#version {{version}}"
|
||||
HEADER="// Automatically generated from files in pathfinder/shaders/. Do not edit!"
|
||||
|
||||
GLSL_SED_ARGS=-e "s/\#version 330//" -e "s/\#line.*$$//"
|
||||
|
||||
all: $(OUT)
|
||||
|
||||
|
@ -53,17 +59,17 @@ all: $(OUT)
|
|||
clean:
|
||||
rm -f $(OUT)
|
||||
|
||||
$(TARGET_DIR)/spirv/%.fs.spv: %.fs.glsl $(INCLUDES)
|
||||
mkdir -p $(TARGET_DIR)/spirv && glslangValidator $(GLSLANGFLAGS) -G$(GLSL_VERSION) -S frag -o $@ $<
|
||||
build/metal/%.fs.spv: %.fs.glsl $(INCLUDES)
|
||||
mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -G$(GLSL_VERSION) -S frag -o $@ $<
|
||||
|
||||
$(TARGET_DIR)/gl3/%.fs.glsl: %.fs.glsl $(INCLUDES)
|
||||
mkdir -p $(TARGET_DIR)/gl3 && glslangValidator $(GLSLANGFLAGS) -S frag -E $< | sed $(SED_ARGS) > $@
|
||||
mkdir -p $(TARGET_DIR)/gl3 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S frag -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )
|
||||
|
||||
$(TARGET_DIR)/spirv/%.vs.spv: %.vs.glsl $(INCLUDES)
|
||||
mkdir -p $(TARGET_DIR)/spirv && glslangValidator $(GLSLANGFLAGS) -G$(GLSL_VERSION) -S vert -o $@ $<
|
||||
build/metal/%.vs.spv: %.vs.glsl $(INCLUDES)
|
||||
mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -G$(GLSL_VERSION) -S vert -o $@ $<
|
||||
|
||||
$(TARGET_DIR)/gl3/%.vs.glsl: %.vs.glsl $(INCLUDES)
|
||||
mkdir -p $(TARGET_DIR)/gl3 && glslangValidator $(GLSLANGFLAGS) -S vert -E $< | sed $(SED_ARGS) > $@
|
||||
mkdir -p $(TARGET_DIR)/gl3 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S vert -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )
|
||||
|
||||
$(TARGET_DIR)/metal/%.metal: $(TARGET_DIR)/spirv/%.spv
|
||||
mkdir -p $(TARGET_DIR)/metal && spirv-cross $(SPIRVCROSSFLAGS) --output $@ $<
|
||||
$(TARGET_DIR)/metal/%.metal: build/metal/%.spv
|
||||
mkdir -p $(TARGET_DIR)/metal && echo $(HEADER) > $@ && ( $(SPIRVCROSS) $(SPIRVCROSSFLAGS) $< | sed $(METAL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )
|
||||
|
|
|
@ -14,9 +14,9 @@ precision highp float;
|
|||
|
||||
uniform vec2 uFramebufferSize;
|
||||
|
||||
in vec2 aPosition;
|
||||
in ivec2 aPosition;
|
||||
|
||||
void main() {
|
||||
vec2 position = aPosition / uFramebufferSize * 2.0 - 1.0;
|
||||
vec2 position = vec2(aPosition) / uFramebufferSize * 2.0 - 1.0;
|
||||
gl_Position = vec4(position.x, -position.y, 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@ precision highp float;
|
|||
uniform vec2 uFramebufferSize;
|
||||
uniform vec2 uTextureSize;
|
||||
|
||||
in vec2 aPosition;
|
||||
in vec2 aTexCoord;
|
||||
in ivec2 aPosition;
|
||||
in ivec2 aTexCoord;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
vTexCoord = aTexCoord / uTextureSize;
|
||||
vec2 position = aPosition / uFramebufferSize * 2.0 - 1.0;
|
||||
vTexCoord = vec2(aTexCoord) / uTextureSize;
|
||||
vec2 position = vec2(aPosition) / uFramebufferSize * 2.0 - 1.0;
|
||||
gl_Position = vec4(position.x, -position.y, 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -15,11 +15,11 @@ precision highp float;
|
|||
uniform mat4 uTransform;
|
||||
uniform int uGridlineCount;
|
||||
|
||||
in vec2 aPosition;
|
||||
in ivec2 aPosition;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
vTexCoord = aPosition * float(uGridlineCount);
|
||||
gl_Position = uTransform * vec4(aPosition.x, 0.0, aPosition.y, 1.0);
|
||||
vTexCoord = vec2(aPosition * uGridlineCount);
|
||||
gl_Position = uTransform * vec4(ivec4(aPosition.x, 0, aPosition.y, 1));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#version 330
|
||||
|
||||
// pathfinder/resources/fill.vs.glsl
|
||||
// pathfinder/shaders/fill.vs.glsl
|
||||
//
|
||||
// Copyright © 2019 The Pathfinder Project Developers.
|
||||
//
|
||||
|
@ -15,7 +15,7 @@ precision highp float;
|
|||
uniform vec2 uFramebufferSize;
|
||||
uniform vec2 uTileSize;
|
||||
|
||||
in vec2 aTessCoord;
|
||||
in uvec2 aTessCoord;
|
||||
in uint aFromPx;
|
||||
in uint aToPx;
|
||||
in vec2 aFromSubpx;
|
||||
|
@ -27,7 +27,7 @@ out vec2 vTo;
|
|||
|
||||
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
|
||||
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
|
||||
uvec2 tileOffset = uvec2(aTileIndex % tilesPerRow, aTileIndex / tilesPerRow);
|
||||
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
|
||||
return vec2(tileOffset) * uTileSize;
|
||||
}
|
||||
|
||||
|
@ -38,11 +38,11 @@ void main() {
|
|||
vec2 to = vec2(aToPx & 15u, aToPx >> 4u) + aToSubpx;
|
||||
|
||||
vec2 position;
|
||||
if (aTessCoord.x < 0.5)
|
||||
if (aTessCoord.x == 0u)
|
||||
position.x = floor(min(from.x, to.x));
|
||||
else
|
||||
position.x = ceil(max(from.x, to.x));
|
||||
if (aTessCoord.y < 0.5)
|
||||
if (aTessCoord.y == 0u)
|
||||
position.y = floor(min(from.y, to.y));
|
||||
else
|
||||
position.y = uTileSize.y;
|
||||
|
@ -50,5 +50,9 @@ void main() {
|
|||
vFrom = from - position;
|
||||
vTo = to - position;
|
||||
|
||||
gl_Position = vec4((tileOrigin + position) / uFramebufferSize * 2.0 - 1.0, 0.0, 1.0);
|
||||
vec2 globalPosition = (tileOrigin + position) / uFramebufferSize * 2.0 - 1.0;
|
||||
#ifdef PF_ORIGIN_UPPER_LEFT
|
||||
globalPosition.y = -globalPosition.y;
|
||||
#endif
|
||||
gl_Position = vec4(globalPosition, 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
|
||||
precision highp float;
|
||||
|
||||
in vec2 aPosition;
|
||||
in ivec2 aPosition;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
vTexCoord = aPosition;
|
||||
gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);
|
||||
vTexCoord = vec2(aPosition);
|
||||
gl_Position = vec4(vec2(aPosition) * 2.0 - 1.0, 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -14,11 +14,17 @@ precision highp float;
|
|||
|
||||
uniform mat4 uNewTransform;
|
||||
|
||||
in vec2 aPosition;
|
||||
in ivec2 aPosition;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
vTexCoord = aPosition;
|
||||
gl_Position = uNewTransform * vec4(aPosition, 0.0, 1.0);
|
||||
vec2 position = vec2(aPosition);
|
||||
vTexCoord = position;
|
||||
|
||||
#ifdef PF_ORIGIN_UPPER_LEFT
|
||||
// FIXME(pcwalton): This is wrong.
|
||||
position.y = 1.0 - position.y;
|
||||
#endif
|
||||
gl_Position = uNewTransform * vec4(position, 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -13,10 +13,10 @@ uniform vec2 uTileSize;
|
|||
uniform vec2 uStencilTextureSize;
|
||||
uniform vec2 uViewBoxOrigin;
|
||||
|
||||
in vec2 aTessCoord;
|
||||
in uvec2 aTessCoord;
|
||||
in uvec3 aTileOrigin;
|
||||
in int aBackdrop;
|
||||
in uint aTileIndex;
|
||||
in int aTileIndex;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
out float vBackdrop;
|
||||
|
@ -32,9 +32,9 @@ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
|
|||
|
||||
void computeVaryings() {
|
||||
vec2 origin = vec2(aTileOrigin.xy) + vec2(aTileOrigin.z & 15u, aTileOrigin.z >> 4u) * 256.0;
|
||||
vec2 pixelPosition = (origin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
||||
vec2 pixelPosition = (origin + vec2(aTessCoord)) * uTileSize + uViewBoxOrigin;
|
||||
vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0);
|
||||
vec2 maskTexCoordOrigin = computeTileOffset(aTileIndex, uStencilTextureSize.x);
|
||||
vec2 maskTexCoordOrigin = computeTileOffset(uint(aTileIndex), uStencilTextureSize.x);
|
||||
vec2 maskTexCoord = maskTexCoordOrigin + aTessCoord * uTileSize;
|
||||
|
||||
vTexCoord = maskTexCoord / uStencilTextureSize;
|
||||
|
|
|
@ -12,18 +12,17 @@ uniform vec2 uFramebufferSize;
|
|||
uniform vec2 uTileSize;
|
||||
uniform vec2 uViewBoxOrigin;
|
||||
|
||||
in vec2 aTessCoord;
|
||||
in vec2 aTileOrigin;
|
||||
in uvec2 aTessCoord;
|
||||
in ivec2 aTileOrigin;
|
||||
|
||||
out vec4 vColor;
|
||||
|
||||
vec4 getColor();
|
||||
|
||||
void computeVaryings() {
|
||||
vec2 pixelPosition = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
||||
vec2 pixelPosition = vec2(aTileOrigin + ivec2(aTessCoord)) * uTileSize + uViewBoxOrigin;
|
||||
vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0);
|
||||
|
||||
vColor = getColor();
|
||||
//vColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
}
|
||||
|
|
103
ui/src/lib.rs
103
ui/src/lib.rs
|
@ -22,7 +22,7 @@ use pathfinder_geometry::basic::rect::RectI;
|
|||
use pathfinder_geometry::color::ColorU;
|
||||
use pathfinder_gpu::resources::ResourceLoader;
|
||||
use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, Device, Primitive};
|
||||
use pathfinder_gpu::{RenderState, UniformData, VertexAttrClass};
|
||||
use pathfinder_gpu::{RenderOptions, RenderState, RenderTarget, UniformData, VertexAttrClass};
|
||||
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
|
||||
use pathfinder_simd::default::F32x4;
|
||||
use serde_json;
|
||||
|
@ -131,7 +131,11 @@ impl<D> UIPresenter<D> where D: Device {
|
|||
self.draw_rect(device, rect, color, false);
|
||||
}
|
||||
|
||||
fn draw_rect(&self, device: &D, rect: RectI, color: ColorU, filled: bool) {
|
||||
fn draw_rect(&self,
|
||||
device: &D,
|
||||
rect: RectI,
|
||||
color: ColorU,
|
||||
filled: bool) {
|
||||
let vertex_data = [
|
||||
DebugSolidVertex::new(rect.origin()),
|
||||
DebugSolidVertex::new(rect.upper_right()),
|
||||
|
@ -160,8 +164,6 @@ impl<D> UIPresenter<D> where D: Device {
|
|||
index_data: &[u32],
|
||||
color: ColorU,
|
||||
filled: bool) {
|
||||
device.bind_vertex_array(&self.solid_vertex_array.vertex_array);
|
||||
|
||||
device.allocate_buffer(&self.solid_vertex_array.vertex_buffer,
|
||||
BufferData::Memory(vertex_data),
|
||||
BufferTarget::Vertex,
|
||||
|
@ -171,15 +173,23 @@ impl<D> UIPresenter<D> where D: Device {
|
|||
BufferTarget::Index,
|
||||
BufferUploadMode::Dynamic);
|
||||
|
||||
device.use_program(&self.solid_program.program);
|
||||
device.set_uniform(&self.solid_program.framebuffer_size_uniform,
|
||||
UniformData::Vec2(self.framebuffer_size.0.to_f32x4()));
|
||||
set_color_uniform(device, &self.solid_program.color_uniform, color);
|
||||
|
||||
let primitive = if filled { Primitive::Triangles } else { Primitive::Lines };
|
||||
device.draw_elements(primitive, index_data.len() as u32, &RenderState {
|
||||
device.draw_elements(index_data.len() as u32, &RenderState {
|
||||
target: &RenderTarget::Default,
|
||||
program: &self.solid_program.program,
|
||||
vertex_array: &self.solid_vertex_array.vertex_array,
|
||||
primitive,
|
||||
uniforms: &[
|
||||
(&self.solid_program.framebuffer_size_uniform,
|
||||
UniformData::Vec2(self.framebuffer_size.0.to_f32x4())),
|
||||
(&self.solid_program.color_uniform, get_color_uniform(color)),
|
||||
],
|
||||
textures: &[],
|
||||
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
|
||||
options: RenderOptions {
|
||||
blend: BlendState::RGBOneAlphaOneMinusSrcAlpha,
|
||||
..RenderState::default()
|
||||
..RenderOptions::default()
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -396,19 +406,25 @@ impl<D> UIPresenter<D> where D: Device {
|
|||
BufferTarget::Index,
|
||||
BufferUploadMode::Dynamic);
|
||||
|
||||
device.bind_vertex_array(&self.texture_vertex_array.vertex_array);
|
||||
device.use_program(&self.texture_program.program);
|
||||
device.set_uniform(&self.texture_program.framebuffer_size_uniform,
|
||||
UniformData::Vec2(self.framebuffer_size.0.to_f32x4()));
|
||||
device.set_uniform(&self.texture_program.texture_size_uniform,
|
||||
UniformData::Vec2(device.texture_size(&texture).0.to_f32x4()));
|
||||
set_color_uniform(device, &self.texture_program.color_uniform, color);
|
||||
device.bind_texture(texture, 0);
|
||||
device.set_uniform(&self.texture_program.texture_uniform, UniformData::TextureUnit(0));
|
||||
|
||||
device.draw_elements(Primitive::Triangles, index_data.len() as u32, &RenderState {
|
||||
device.draw_elements(index_data.len() as u32, &RenderState {
|
||||
target: &RenderTarget::Default,
|
||||
program: &self.texture_program.program,
|
||||
vertex_array: &self.texture_vertex_array.vertex_array,
|
||||
primitive: Primitive::Triangles,
|
||||
textures: &[&texture],
|
||||
uniforms: &[
|
||||
(&self.texture_program.framebuffer_size_uniform,
|
||||
UniformData::Vec2(self.framebuffer_size.0.to_f32x4())),
|
||||
(&self.texture_program.color_uniform, get_color_uniform(color)),
|
||||
(&self.texture_program.texture_uniform, UniformData::TextureUnit(0)),
|
||||
(&self.texture_program.texture_size_uniform,
|
||||
UniformData::Vec2(device.texture_size(&texture).0.to_f32x4()))
|
||||
],
|
||||
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
|
||||
options: RenderOptions {
|
||||
blend: BlendState::RGBOneAlphaOneMinusSrcAlpha,
|
||||
..RenderState::default()
|
||||
..RenderOptions::default()
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -590,25 +606,25 @@ impl<D> DebugTextureVertexArray<D> where D: Device {
|
|||
let tex_coord_attr = device.get_vertex_attr(&debug_texture_program.program, "TexCoord")
|
||||
.unwrap();
|
||||
|
||||
device.bind_vertex_array(&vertex_array);
|
||||
device.use_program(&debug_texture_program.program);
|
||||
device.bind_buffer(&vertex_buffer, BufferTarget::Vertex);
|
||||
device.bind_buffer(&index_buffer, BufferTarget::Index);
|
||||
device.configure_vertex_attr(&position_attr, &VertexAttrDescriptor {
|
||||
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
|
||||
device.bind_buffer(&vertex_array, &index_buffer, BufferTarget::Index);
|
||||
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
|
||||
size: 2,
|
||||
class: VertexAttrClass::Float,
|
||||
attr_type: VertexAttrType::U16,
|
||||
class: VertexAttrClass::Int,
|
||||
attr_type: VertexAttrType::I16,
|
||||
stride: DEBUG_TEXTURE_VERTEX_SIZE,
|
||||
offset: 0,
|
||||
divisor: 0,
|
||||
buffer_index: 0,
|
||||
});
|
||||
device.configure_vertex_attr(&tex_coord_attr, &VertexAttrDescriptor {
|
||||
device.configure_vertex_attr(&vertex_array, &tex_coord_attr, &VertexAttrDescriptor {
|
||||
size: 2,
|
||||
class: VertexAttrClass::Float,
|
||||
attr_type: VertexAttrType::U16,
|
||||
class: VertexAttrClass::Int,
|
||||
attr_type: VertexAttrType::I16,
|
||||
stride: DEBUG_TEXTURE_VERTEX_SIZE,
|
||||
offset: 4,
|
||||
divisor: 0,
|
||||
buffer_index: 0,
|
||||
});
|
||||
|
||||
DebugTextureVertexArray { vertex_array, vertex_buffer, index_buffer }
|
||||
|
@ -626,19 +642,18 @@ impl<D> DebugSolidVertexArray<D> where D: Device {
|
|||
let (vertex_buffer, index_buffer) = (device.create_buffer(), device.create_buffer());
|
||||
let vertex_array = device.create_vertex_array();
|
||||
|
||||
let position_attr = device.get_vertex_attr(&debug_solid_program.program, "Position")
|
||||
.unwrap();
|
||||
device.bind_vertex_array(&vertex_array);
|
||||
device.use_program(&debug_solid_program.program);
|
||||
device.bind_buffer(&vertex_buffer, BufferTarget::Vertex);
|
||||
device.bind_buffer(&index_buffer, BufferTarget::Index);
|
||||
device.configure_vertex_attr(&position_attr, &VertexAttrDescriptor {
|
||||
let position_attr =
|
||||
device.get_vertex_attr(&debug_solid_program.program, "Position").unwrap();
|
||||
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
|
||||
device.bind_buffer(&vertex_array, &index_buffer, BufferTarget::Index);
|
||||
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
|
||||
size: 2,
|
||||
class: VertexAttrClass::Float,
|
||||
attr_type: VertexAttrType::U16,
|
||||
class: VertexAttrClass::Int,
|
||||
attr_type: VertexAttrType::I16,
|
||||
stride: DEBUG_SOLID_VERTEX_SIZE,
|
||||
offset: 0,
|
||||
divisor: 0,
|
||||
buffer_index: 0,
|
||||
});
|
||||
|
||||
DebugSolidVertexArray { vertex_array, vertex_buffer, index_buffer }
|
||||
|
@ -714,9 +729,9 @@ impl CornerRects {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_color_uniform<D>(device: &D, uniform: &D::Uniform, color: ColorU) where D: Device {
|
||||
fn get_color_uniform(color: ColorU) -> UniformData {
|
||||
let color = F32x4::new(color.r as f32, color.g as f32, color.b as f32, color.a as f32);
|
||||
device.set_uniform(uniform, UniformData::Vec4(color * F32x4::splat(1.0 / 255.0)));
|
||||
UniformData::Vec4(color * F32x4::splat(1.0 / 255.0))
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
|
Loading…
Reference in New Issue