Rename "paint texture" to just "texture page"
This commit is contained in:
parent
d0f4579864
commit
a3736859ba
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
//! A simple quadtree-based texture allocator.
|
//! A simple quadtree-based texture allocator.
|
||||||
|
|
||||||
use crate::gpu_data::PaintPageId;
|
use crate::gpu_data::TexturePageId;
|
||||||
use pathfinder_content::render_target::RenderTargetId;
|
use pathfinder_content::render_target::RenderTargetId;
|
||||||
use pathfinder_geometry::rect::RectI;
|
use pathfinder_geometry::rect::RectI;
|
||||||
use pathfinder_geometry::vector::{Vector2F, Vector2I};
|
use pathfinder_geometry::vector::{Vector2F, Vector2I};
|
||||||
|
@ -40,7 +40,7 @@ pub struct TextureAtlasAllocator {
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
pub struct TextureLocation {
|
pub struct TextureLocation {
|
||||||
pub page: PaintPageId,
|
pub page: TexturePageId,
|
||||||
pub rect: RectI,
|
pub rect: RectI,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,14 +79,14 @@ impl TextureAllocator {
|
||||||
TexturePageAllocator::RenderTarget { .. } => {}
|
TexturePageAllocator::RenderTarget { .. } => {}
|
||||||
TexturePageAllocator::Atlas(ref mut allocator) => {
|
TexturePageAllocator::Atlas(ref mut allocator) => {
|
||||||
if let Some(rect) = allocator.allocate(requested_size) {
|
if let Some(rect) = allocator.allocate(requested_size) {
|
||||||
return TextureLocation { page: PaintPageId(page_index as u32), rect };
|
return TextureLocation { page: TexturePageId(page_index as u32), rect };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new atlas.
|
// Add a new atlas.
|
||||||
let page = PaintPageId(self.pages.len() as u32);
|
let page = TexturePageId(self.pages.len() as u32);
|
||||||
let mut allocator = TextureAtlasAllocator::new();
|
let mut allocator = TextureAtlasAllocator::new();
|
||||||
let rect = allocator.allocate(requested_size).expect("Allocation failed!");
|
let rect = allocator.allocate(requested_size).expect("Allocation failed!");
|
||||||
self.pages.push(TexturePageAllocator::Atlas(allocator));
|
self.pages.push(TexturePageAllocator::Atlas(allocator));
|
||||||
|
@ -94,7 +94,7 @@ impl TextureAllocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allocate_image(&mut self, requested_size: Vector2I) -> TextureLocation {
|
fn allocate_image(&mut self, requested_size: Vector2I) -> TextureLocation {
|
||||||
let page = PaintPageId(self.pages.len() as u32);
|
let page = TexturePageId(self.pages.len() as u32);
|
||||||
let rect = RectI::new(Vector2I::default(), requested_size);
|
let rect = RectI::new(Vector2I::default(), requested_size);
|
||||||
self.pages.push(TexturePageAllocator::Image { size: rect.size() });
|
self.pages.push(TexturePageAllocator::Image { size: rect.size() });
|
||||||
TextureLocation { page, rect }
|
TextureLocation { page, rect }
|
||||||
|
@ -102,13 +102,13 @@ impl TextureAllocator {
|
||||||
|
|
||||||
pub fn allocate_render_target(&mut self, requested_size: Vector2I, id: RenderTargetId)
|
pub fn allocate_render_target(&mut self, requested_size: Vector2I, id: RenderTargetId)
|
||||||
-> TextureLocation {
|
-> TextureLocation {
|
||||||
let page = PaintPageId(self.pages.len() as u32);
|
let page = TexturePageId(self.pages.len() as u32);
|
||||||
let rect = RectI::new(Vector2I::default(), requested_size);
|
let rect = RectI::new(Vector2I::default(), requested_size);
|
||||||
self.pages.push(TexturePageAllocator::RenderTarget { size: rect.size(), id });
|
self.pages.push(TexturePageAllocator::RenderTarget { size: rect.size(), id });
|
||||||
TextureLocation { page, rect }
|
TextureLocation { page, rect }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn page_size(&self, page_index: PaintPageId) -> Vector2I {
|
pub fn page_size(&self, page_index: TexturePageId) -> Vector2I {
|
||||||
match self.pages[page_index.0 as usize] {
|
match self.pages[page_index.0 as usize] {
|
||||||
TexturePageAllocator::Atlas(ref atlas) => Vector2I::splat(atlas.size as i32),
|
TexturePageAllocator::Atlas(ref atlas) => Vector2I::splat(atlas.size as i32),
|
||||||
TexturePageAllocator::Image { size, .. } |
|
TexturePageAllocator::Image { size, .. } |
|
||||||
|
@ -116,7 +116,7 @@ impl TextureAllocator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn page_scale(&self, page_index: PaintPageId) -> Vector2F {
|
pub fn page_scale(&self, page_index: TexturePageId) -> Vector2F {
|
||||||
Vector2F::splat(1.0) / self.page_size(page_index).to_f32()
|
Vector2F::splat(1.0) / self.page_size(page_index).to_f32()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ impl TextureAllocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn page_render_target_id(&self, page_index: PaintPageId) -> Option<RenderTargetId> {
|
pub fn page_render_target_id(&self, page_index: TexturePageId) -> Option<RenderTargetId> {
|
||||||
match self.pages[page_index.0 as usize] {
|
match self.pages[page_index.0 as usize] {
|
||||||
TexturePageAllocator::RenderTarget { id, .. } => Some(id),
|
TexturePageAllocator::RenderTarget { id, .. } => Some(id),
|
||||||
TexturePageAllocator::Atlas(_) | TexturePageAllocator::Image { .. } => None,
|
TexturePageAllocator::Atlas(_) | TexturePageAllocator::Image { .. } => None,
|
||||||
|
|
|
@ -13,9 +13,8 @@
|
||||||
use crate::concurrent::executor::Executor;
|
use crate::concurrent::executor::Executor;
|
||||||
use crate::gpu::renderer::{BlendModeProgram, MASK_TILES_ACROSS};
|
use crate::gpu::renderer::{BlendModeProgram, MASK_TILES_ACROSS};
|
||||||
use crate::gpu_data::{AlphaTile, AlphaTileBatch, AlphaTileVertex, FillBatchPrimitive, MaskTile};
|
use crate::gpu_data::{AlphaTile, AlphaTileBatch, AlphaTileVertex, FillBatchPrimitive, MaskTile};
|
||||||
use crate::gpu_data::{MaskTileVertex, PaintPageId, RenderCommand, RenderTargetTile};
|
use crate::gpu_data::{MaskTileVertex, RenderCommand, RenderTargetTile, RenderTargetTileBatch};
|
||||||
use crate::gpu_data::{RenderTargetTileBatch, RenderTargetTileVertex};
|
use crate::gpu_data::{RenderTargetTileVertex, SolidTileBatch, TexturePageId, TileObjectPrimitive};
|
||||||
use crate::gpu_data::{SolidTileBatch, TileObjectPrimitive};
|
|
||||||
use crate::options::{PreparedBuildOptions, RenderCommandListener};
|
use crate::options::{PreparedBuildOptions, RenderCommandListener};
|
||||||
use crate::paint::{PaintInfo, PaintMetadata};
|
use crate::paint::{PaintInfo, PaintMetadata};
|
||||||
use crate::scene::{DisplayItem, Scene};
|
use crate::scene::{DisplayItem, Scene};
|
||||||
|
@ -57,7 +56,7 @@ struct BuiltDrawPath {
|
||||||
path: BuiltPath,
|
path: BuiltPath,
|
||||||
blend_mode: BlendMode,
|
blend_mode: BlendMode,
|
||||||
sampling_flags: TextureSamplingFlags,
|
sampling_flags: TextureSamplingFlags,
|
||||||
paint_page: PaintPageId,
|
color_texture_page: TexturePageId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -111,10 +110,10 @@ impl<'a> SceneBuilder<'a> {
|
||||||
|
|
||||||
// Build paint data.
|
// Build paint data.
|
||||||
let PaintInfo {
|
let PaintInfo {
|
||||||
data: paint_data,
|
data: texture_data,
|
||||||
metadata: paint_metadata,
|
metadata: paint_metadata,
|
||||||
} = self.scene.build_paint_info();
|
} = self.scene.build_paint_info();
|
||||||
self.listener.send(RenderCommand::AddPaintData(paint_data));
|
self.listener.send(RenderCommand::AddTextureData(texture_data));
|
||||||
|
|
||||||
let effective_view_box = self.scene.effective_view_box(self.built_options);
|
let effective_view_box = self.scene.effective_view_box(self.built_options);
|
||||||
|
|
||||||
|
@ -197,7 +196,7 @@ impl<'a> SceneBuilder<'a> {
|
||||||
BuiltDrawPath {
|
BuiltDrawPath {
|
||||||
path: tiler.object_builder.built_path,
|
path: tiler.object_builder.built_path,
|
||||||
blend_mode: path_object.blend_mode(),
|
blend_mode: path_object.blend_mode(),
|
||||||
paint_page: paint_metadata.tex_page,
|
color_texture_page: paint_metadata.texture_page,
|
||||||
sampling_flags: paint_metadata.sampling_flags,
|
sampling_flags: paint_metadata.sampling_flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,10 +285,10 @@ impl<'a> SceneBuilder<'a> {
|
||||||
match culled_tiles.display_list.last() {
|
match culled_tiles.display_list.last() {
|
||||||
Some(&CulledDisplayItem::DrawAlphaTiles(AlphaTileBatch {
|
Some(&CulledDisplayItem::DrawAlphaTiles(AlphaTileBatch {
|
||||||
tiles: _,
|
tiles: _,
|
||||||
paint_page,
|
color_texture_page,
|
||||||
blend_mode,
|
blend_mode,
|
||||||
sampling_flags
|
sampling_flags
|
||||||
})) if paint_page == built_draw_path.paint_page &&
|
})) if color_texture_page == built_draw_path.color_texture_page &&
|
||||||
blend_mode == built_draw_path.blend_mode &&
|
blend_mode == built_draw_path.blend_mode &&
|
||||||
sampling_flags == built_draw_path.sampling_flags &&
|
sampling_flags == built_draw_path.sampling_flags &&
|
||||||
!BlendModeProgram::from_blend_mode(
|
!BlendModeProgram::from_blend_mode(
|
||||||
|
@ -297,7 +296,7 @@ impl<'a> SceneBuilder<'a> {
|
||||||
_ => {
|
_ => {
|
||||||
let batch = AlphaTileBatch {
|
let batch = AlphaTileBatch {
|
||||||
tiles: vec![],
|
tiles: vec![],
|
||||||
paint_page: built_draw_path.paint_page,
|
color_texture_page: built_draw_path.color_texture_page,
|
||||||
blend_mode: built_draw_path.blend_mode,
|
blend_mode: built_draw_path.blend_mode,
|
||||||
sampling_flags: built_draw_path.sampling_flags,
|
sampling_flags: built_draw_path.sampling_flags,
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,8 +19,8 @@ use crate::gpu::shaders::{ReprojectionProgram, ReprojectionVertexArray, SolidTil
|
||||||
use crate::gpu::shaders::{SolidTileVertexArray, StencilProgram, StencilVertexArray};
|
use crate::gpu::shaders::{SolidTileVertexArray, StencilProgram, StencilVertexArray};
|
||||||
use crate::gpu::shaders::{TileFilterBasicProgram, TileFilterBlurProgram, TileFilterProgram};
|
use crate::gpu::shaders::{TileFilterBasicProgram, TileFilterBlurProgram, TileFilterProgram};
|
||||||
use crate::gpu::shaders::{TileFilterTextProgram, TileFilterVertexArray};
|
use crate::gpu::shaders::{TileFilterTextProgram, TileFilterVertexArray};
|
||||||
use crate::gpu_data::{AlphaTile, FillBatchPrimitive, MaskTile, PaintData, PaintPageContents};
|
use crate::gpu_data::{AlphaTile, FillBatchPrimitive, MaskTile, RenderCommand, RenderTargetTile};
|
||||||
use crate::gpu_data::{PaintPageId, RenderCommand, RenderTargetTile, SolidTileVertex};
|
use crate::gpu_data::{SolidTileVertex, TextureData, TexturePageContents, TexturePageId};
|
||||||
use crate::options::BoundingQuad;
|
use crate::options::BoundingQuad;
|
||||||
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
||||||
use pathfinder_color::{self as color, ColorF};
|
use pathfinder_color::{self as color, ColorF};
|
||||||
|
@ -28,9 +28,9 @@ use pathfinder_content::effects::{BlendMode, BlurDirection, CompositeOp, Defring
|
||||||
use pathfinder_content::effects::{Effects, Filter};
|
use pathfinder_content::effects::{Effects, Filter};
|
||||||
use pathfinder_content::fill::FillRule;
|
use pathfinder_content::fill::FillRule;
|
||||||
use pathfinder_content::render_target::RenderTargetId;
|
use pathfinder_content::render_target::RenderTargetId;
|
||||||
use pathfinder_geometry::vector::{Vector2F, Vector2I, Vector4F};
|
|
||||||
use pathfinder_geometry::rect::RectI;
|
use pathfinder_geometry::rect::RectI;
|
||||||
use pathfinder_geometry::transform3d::Transform4F;
|
use pathfinder_geometry::transform3d::Transform4F;
|
||||||
|
use pathfinder_geometry::vector::{Vector2F, Vector2I, Vector4F};
|
||||||
use pathfinder_gpu::{BlendFactor, BlendOp, BlendState, BufferData, BufferTarget, BufferUploadMode};
|
use pathfinder_gpu::{BlendFactor, BlendOp, BlendState, BufferData, BufferTarget, BufferUploadMode};
|
||||||
use pathfinder_gpu::{ClearOps, DepthFunc, DepthState, Device, Primitive, RenderOptions};
|
use pathfinder_gpu::{ClearOps, DepthFunc, DepthState, Device, Primitive, RenderOptions};
|
||||||
use pathfinder_gpu::{RenderState, RenderTarget, StencilFunc, StencilState, TextureDataRef};
|
use pathfinder_gpu::{RenderState, RenderTarget, StencilFunc, StencilState, TextureDataRef};
|
||||||
|
@ -114,7 +114,7 @@ where
|
||||||
mask_framebuffer: D::Framebuffer,
|
mask_framebuffer: D::Framebuffer,
|
||||||
dest_blend_framebuffer: D::Framebuffer,
|
dest_blend_framebuffer: D::Framebuffer,
|
||||||
intermediate_dest_framebuffer: D::Framebuffer,
|
intermediate_dest_framebuffer: D::Framebuffer,
|
||||||
paint_textures: Vec<PaintTexture<D>>,
|
texture_pages: Vec<TexturePage<D>>,
|
||||||
render_targets: Vec<RenderTargetInfo<D>>,
|
render_targets: Vec<RenderTargetInfo<D>>,
|
||||||
render_target_stack: Vec<RenderTargetId>,
|
render_target_stack: Vec<RenderTargetId>,
|
||||||
|
|
||||||
|
@ -382,7 +382,7 @@ where
|
||||||
mask_framebuffer,
|
mask_framebuffer,
|
||||||
dest_blend_framebuffer,
|
dest_blend_framebuffer,
|
||||||
intermediate_dest_framebuffer,
|
intermediate_dest_framebuffer,
|
||||||
paint_textures: vec![],
|
texture_pages: vec![],
|
||||||
render_targets: vec![],
|
render_targets: vec![],
|
||||||
render_target_stack: vec![],
|
render_target_stack: vec![],
|
||||||
clear_paint_texture,
|
clear_paint_texture,
|
||||||
|
@ -427,7 +427,7 @@ where
|
||||||
RenderCommand::Start { bounding_quad, path_count, needs_readable_framebuffer } => {
|
RenderCommand::Start { bounding_quad, path_count, needs_readable_framebuffer } => {
|
||||||
self.start_rendering(bounding_quad, path_count, needs_readable_framebuffer);
|
self.start_rendering(bounding_quad, path_count, needs_readable_framebuffer);
|
||||||
}
|
}
|
||||||
RenderCommand::AddPaintData(ref paint_data) => self.upload_paint_data(paint_data),
|
RenderCommand::AddTextureData(ref paint_data) => self.add_texture_data(paint_data),
|
||||||
RenderCommand::AddFills(ref fills) => self.add_fills(fills),
|
RenderCommand::AddFills(ref fills) => self.add_fills(fills),
|
||||||
RenderCommand::FlushFills => {
|
RenderCommand::FlushFills => {
|
||||||
self.draw_buffered_fills();
|
self.draw_buffered_fills();
|
||||||
|
@ -451,14 +451,16 @@ where
|
||||||
let count = batch.vertices.len() / 4;
|
let count = batch.vertices.len() / 4;
|
||||||
self.stats.solid_tile_count += count;
|
self.stats.solid_tile_count += count;
|
||||||
self.upload_solid_tiles(&batch.vertices);
|
self.upload_solid_tiles(&batch.vertices);
|
||||||
self.draw_solid_tiles(count as u32, batch.paint_page, batch.sampling_flags);
|
self.draw_solid_tiles(count as u32,
|
||||||
|
batch.color_texture_page,
|
||||||
|
batch.sampling_flags);
|
||||||
}
|
}
|
||||||
RenderCommand::DrawAlphaTiles(ref batch) => {
|
RenderCommand::DrawAlphaTiles(ref batch) => {
|
||||||
let count = batch.tiles.len();
|
let count = batch.tiles.len();
|
||||||
self.stats.alpha_tile_count += count;
|
self.stats.alpha_tile_count += count;
|
||||||
self.upload_alpha_tiles(&batch.tiles);
|
self.upload_alpha_tiles(&batch.tiles);
|
||||||
self.draw_alpha_tiles(count as u32,
|
self.draw_alpha_tiles(count as u32,
|
||||||
batch.paint_page,
|
batch.color_texture_page,
|
||||||
batch.sampling_flags,
|
batch.sampling_flags,
|
||||||
batch.blend_mode)
|
batch.blend_mode)
|
||||||
}
|
}
|
||||||
|
@ -568,14 +570,12 @@ where
|
||||||
&self.quad_vertex_indices_buffer
|
&self.quad_vertex_indices_buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upload_paint_data(&mut self, paint_data: &PaintData) {
|
fn add_texture_data(&mut self, texture_data: &TextureData) {
|
||||||
// Clear out old paint textures.
|
// Clear out old paint textures.
|
||||||
for paint_texture in self.paint_textures.drain(..) {
|
for old_texture_page in self.texture_pages.drain(..) {
|
||||||
match paint_texture {
|
match old_texture_page {
|
||||||
PaintTexture::Texture(paint_texture) => {
|
TexturePage::Texture(texture) => self.texture_cache.release_texture(texture),
|
||||||
self.texture_cache.release_texture(paint_texture);
|
TexturePage::RenderTarget(_) => {}
|
||||||
}
|
|
||||||
PaintTexture::RenderTarget(_) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,28 +586,28 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build up new paint textures and render targets.
|
// Build up new paint textures and render targets.
|
||||||
for paint_page_data in &paint_data.pages {
|
for texture_page_data in &texture_data.pages {
|
||||||
let paint_size = paint_page_data.size;
|
let texture_size = texture_page_data.size;
|
||||||
let paint_texture = self.texture_cache.create_texture(&mut self.device,
|
let texture_page = self.texture_cache.create_texture(&mut self.device,
|
||||||
TextureFormat::RGBA8,
|
TextureFormat::RGBA8,
|
||||||
paint_size);
|
texture_size);
|
||||||
match paint_page_data.contents {
|
match texture_page_data.contents {
|
||||||
PaintPageContents::RenderTarget(render_target_id) => {
|
TexturePageContents::RenderTarget(render_target_id) => {
|
||||||
let framebuffer = self.device.create_framebuffer(paint_texture);
|
let framebuffer = self.device.create_framebuffer(texture_page);
|
||||||
self.render_targets.push(RenderTargetInfo {
|
self.render_targets.push(RenderTargetInfo {
|
||||||
framebuffer,
|
framebuffer,
|
||||||
must_preserve_contents: false
|
must_preserve_contents: false
|
||||||
});
|
});
|
||||||
|
|
||||||
self.paint_textures.push(PaintTexture::RenderTarget(render_target_id));
|
self.texture_pages.push(TexturePage::RenderTarget(render_target_id));
|
||||||
}
|
}
|
||||||
PaintPageContents::Texels(ref paint_texels) => {
|
TexturePageContents::Texels(ref texels) => {
|
||||||
let texels = color::color_slice_to_u8_slice(paint_texels);
|
let texels = color::color_slice_to_u8_slice(texels);
|
||||||
self.device.upload_to_texture(&paint_texture,
|
self.device.upload_to_texture(&texture_page,
|
||||||
RectI::new(Vector2I::default(), paint_size),
|
RectI::new(Vector2I::default(), texture_size),
|
||||||
TextureDataRef::U8(texels));
|
TextureDataRef::U8(texels));
|
||||||
|
|
||||||
self.paint_textures.push(PaintTexture::Texture(paint_texture));
|
self.texture_pages.push(TexturePage::Texture(texture_page));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -807,7 +807,7 @@ where
|
||||||
|
|
||||||
fn draw_alpha_tiles(&mut self,
|
fn draw_alpha_tiles(&mut self,
|
||||||
tile_count: u32,
|
tile_count: u32,
|
||||||
paint_page: PaintPageId,
|
color_texture_page: TexturePageId,
|
||||||
sampling_flags: TextureSamplingFlags,
|
sampling_flags: TextureSamplingFlags,
|
||||||
blend_mode: BlendMode) {
|
blend_mode: BlendMode) {
|
||||||
let blend_mode_program = BlendModeProgram::from_blend_mode(blend_mode);
|
let blend_mode_program = BlendModeProgram::from_blend_mode(blend_mode);
|
||||||
|
@ -866,7 +866,7 @@ where
|
||||||
// transparent black paint color doesn't zero out the mask.
|
// transparent black paint color doesn't zero out the mask.
|
||||||
&self.clear_paint_texture
|
&self.clear_paint_texture
|
||||||
}
|
}
|
||||||
_ => self.paint_texture(paint_page),
|
_ => self.texture_page(color_texture_page),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.device.set_texture_sampling_mode(paint_texture, sampling_flags);
|
self.device.set_texture_sampling_mode(paint_texture, sampling_flags);
|
||||||
|
@ -1031,7 +1031,7 @@ where
|
||||||
|
|
||||||
fn draw_solid_tiles(&mut self,
|
fn draw_solid_tiles(&mut self,
|
||||||
tile_count: u32,
|
tile_count: u32,
|
||||||
paint_page: PaintPageId,
|
color_texture_page: TexturePageId,
|
||||||
sampling_flags: TextureSamplingFlags) {
|
sampling_flags: TextureSamplingFlags) {
|
||||||
let clear_color = self.clear_color_for_draw_operation();
|
let clear_color = self.clear_color_for_draw_operation();
|
||||||
|
|
||||||
|
@ -1043,9 +1043,9 @@ where
|
||||||
UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32))),
|
UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32))),
|
||||||
];
|
];
|
||||||
|
|
||||||
let paint_texture = self.paint_texture(paint_page);
|
let texture_page = self.texture_page(color_texture_page);
|
||||||
self.device.set_texture_sampling_mode(paint_texture, sampling_flags);
|
self.device.set_texture_sampling_mode(texture_page, sampling_flags);
|
||||||
textures.push(paint_texture);
|
textures.push(texture_page);
|
||||||
uniforms.push((&self.solid_tile_program.paint_texture_uniform,
|
uniforms.push((&self.solid_tile_program.paint_texture_uniform,
|
||||||
UniformData::TextureUnit(0)));
|
UniformData::TextureUnit(0)));
|
||||||
|
|
||||||
|
@ -1430,10 +1430,10 @@ where
|
||||||
Vector2I::new(MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT))
|
Vector2I::new(MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_texture(&self, paint_page: PaintPageId) -> &D::Texture {
|
fn texture_page(&self, id: TexturePageId) -> &D::Texture {
|
||||||
match self.paint_textures[paint_page.0 as usize] {
|
match self.texture_pages[id.0 as usize] {
|
||||||
PaintTexture::Texture(ref texture) => texture,
|
TexturePage::Texture(ref texture) => texture,
|
||||||
PaintTexture::RenderTarget(render_target_id) => {
|
TexturePage::RenderTarget(render_target_id) => {
|
||||||
let framebuffer = &self.render_targets[render_target_id.0 as usize].framebuffer;
|
let framebuffer = &self.render_targets[render_target_id.0 as usize].framebuffer;
|
||||||
self.device.framebuffer_texture(framebuffer)
|
self.device.framebuffer_texture(framebuffer)
|
||||||
}
|
}
|
||||||
|
@ -1568,7 +1568,7 @@ impl<D> TextureCache<D> where D: Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PaintTexture<D> where D: Device {
|
enum TexturePage<D> where D: Device {
|
||||||
Texture(D::Texture),
|
Texture(D::Texture),
|
||||||
RenderTarget(RenderTargetId),
|
RenderTarget(RenderTargetId),
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,8 @@ pub enum RenderCommand {
|
||||||
needs_readable_framebuffer: bool,
|
needs_readable_framebuffer: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Uploads paint data for use with subsequent rendering commands to the GPU.
|
// Uploads texture data for use with subsequent rendering commands to the GPU.
|
||||||
AddPaintData(PaintData),
|
AddTextureData(TextureData),
|
||||||
|
|
||||||
// Adds fills to the queue.
|
// Adds fills to the queue.
|
||||||
AddFills(Vec<FillBatchPrimitive>),
|
AddFills(Vec<FillBatchPrimitive>),
|
||||||
|
@ -74,21 +74,21 @@ pub enum RenderCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PaintData {
|
pub struct TextureData {
|
||||||
pub pages: Vec<PaintPageData>,
|
pub pages: Vec<TexturePageData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
pub struct PaintPageId(pub u32);
|
pub struct TexturePageId(pub u32);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PaintPageData {
|
pub struct TexturePageData {
|
||||||
pub size: Vector2I,
|
pub size: Vector2I,
|
||||||
pub contents: PaintPageContents,
|
pub contents: TexturePageContents,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum PaintPageContents {
|
pub enum TexturePageContents {
|
||||||
Texels(Vec<ColorU>),
|
Texels(Vec<ColorU>),
|
||||||
RenderTarget(RenderTargetId),
|
RenderTarget(RenderTargetId),
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ pub enum PaintPageContents {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct AlphaTileBatch {
|
pub struct AlphaTileBatch {
|
||||||
pub tiles: Vec<AlphaTile>,
|
pub tiles: Vec<AlphaTile>,
|
||||||
pub paint_page: PaintPageId,
|
pub color_texture_page: TexturePageId,
|
||||||
pub blend_mode: BlendMode,
|
pub blend_mode: BlendMode,
|
||||||
pub sampling_flags: TextureSamplingFlags,
|
pub sampling_flags: TextureSamplingFlags,
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ pub struct AlphaTileBatch {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SolidTileBatch {
|
pub struct SolidTileBatch {
|
||||||
pub vertices: Vec<SolidTileVertex>,
|
pub vertices: Vec<SolidTileVertex>,
|
||||||
pub paint_page: PaintPageId,
|
pub color_texture_page: TexturePageId,
|
||||||
pub sampling_flags: TextureSamplingFlags,
|
pub sampling_flags: TextureSamplingFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,8 +214,8 @@ impl Debug for RenderCommand {
|
||||||
fn fmt(&self, formatter: &mut Formatter) -> DebugResult {
|
fn fmt(&self, formatter: &mut Formatter) -> DebugResult {
|
||||||
match *self {
|
match *self {
|
||||||
RenderCommand::Start { .. } => write!(formatter, "Start"),
|
RenderCommand::Start { .. } => write!(formatter, "Start"),
|
||||||
RenderCommand::AddPaintData(ref paint_data) => {
|
RenderCommand::AddTextureData(ref texture_data) => {
|
||||||
write!(formatter, "AddPaintData(x{})", paint_data.pages.len())
|
write!(formatter, "AddTextureData(x{})", texture_data.pages.len())
|
||||||
}
|
}
|
||||||
RenderCommand::AddFills(ref fills) => write!(formatter, "AddFills(x{})", fills.len()),
|
RenderCommand::AddFills(ref fills) => write!(formatter, "AddFills(x{})", fills.len()),
|
||||||
RenderCommand::FlushFills => write!(formatter, "FlushFills"),
|
RenderCommand::FlushFills => write!(formatter, "FlushFills"),
|
||||||
|
@ -230,7 +230,7 @@ impl Debug for RenderCommand {
|
||||||
write!(formatter,
|
write!(formatter,
|
||||||
"DrawAlphaTiles(x{}, {:?}, {:?}, {:?})",
|
"DrawAlphaTiles(x{}, {:?}, {:?}, {:?})",
|
||||||
batch.tiles.len(),
|
batch.tiles.len(),
|
||||||
batch.paint_page,
|
batch.color_texture_page,
|
||||||
batch.blend_mode,
|
batch.blend_mode,
|
||||||
batch.sampling_flags)
|
batch.sampling_flags)
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ impl Debug for RenderCommand {
|
||||||
write!(formatter,
|
write!(formatter,
|
||||||
"DrawSolidTiles(x{}, {:?}, {:?})",
|
"DrawSolidTiles(x{}, {:?}, {:?})",
|
||||||
batch.vertices.len(),
|
batch.vertices.len(),
|
||||||
batch.paint_page,
|
batch.color_texture_page,
|
||||||
batch.sampling_flags)
|
batch.sampling_flags)
|
||||||
}
|
}
|
||||||
RenderCommand::DrawRenderTargetTiles(ref batch) => {
|
RenderCommand::DrawRenderTargetTiles(ref batch) => {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use crate::allocator::{AllocationMode, TextureAllocator, TextureLocation};
|
use crate::allocator::{AllocationMode, TextureAllocator, TextureLocation};
|
||||||
use crate::gpu_data::{PaintData, PaintPageContents, PaintPageData, PaintPageId};
|
use crate::gpu_data::{TextureData, TexturePageContents, TexturePageData, TexturePageId};
|
||||||
use crate::scene::RenderTarget;
|
use crate::scene::RenderTarget;
|
||||||
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
@ -154,7 +154,7 @@ impl Paint {
|
||||||
|
|
||||||
pub struct PaintInfo {
|
pub struct PaintInfo {
|
||||||
/// The data that is sent to the renderer.
|
/// The data that is sent to the renderer.
|
||||||
pub data: PaintData,
|
pub data: TextureData,
|
||||||
/// The metadata for each paint.
|
/// The metadata for each paint.
|
||||||
///
|
///
|
||||||
/// The indices of this vector are paint IDs.
|
/// The indices of this vector are paint IDs.
|
||||||
|
@ -164,11 +164,11 @@ pub struct PaintInfo {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PaintMetadata {
|
pub struct PaintMetadata {
|
||||||
/// The location of the texture.
|
/// The location of the texture.
|
||||||
pub tex_page: PaintPageId,
|
pub texture_page: TexturePageId,
|
||||||
/// The rectangle within the texture atlas.
|
/// The rectangle within the texture atlas.
|
||||||
pub tex_rect: RectI,
|
pub texture_rect: RectI,
|
||||||
/// The transform to apply to screen coordinates to translate them into UVs.
|
/// The transform to apply to screen coordinates to translate them into UVs.
|
||||||
pub tex_transform: Transform2F,
|
pub texture_transform: Transform2F,
|
||||||
/// The sampling mode for the texture.
|
/// The sampling mode for the texture.
|
||||||
pub sampling_flags: TextureSamplingFlags,
|
pub sampling_flags: TextureSamplingFlags,
|
||||||
/// True if this paint is fully opaque.
|
/// True if this paint is fully opaque.
|
||||||
|
@ -209,10 +209,10 @@ impl Palette {
|
||||||
// Assign paint locations.
|
// Assign paint locations.
|
||||||
let mut solid_color_tile_builder = SolidColorTileBuilder::new();
|
let mut solid_color_tile_builder = SolidColorTileBuilder::new();
|
||||||
for paint in &self.paints {
|
for paint in &self.paints {
|
||||||
let (tex_location, mut sampling_flags);
|
let (texture_location, mut sampling_flags);
|
||||||
match paint {
|
match paint {
|
||||||
Paint::Color(_) => {
|
Paint::Color(_) => {
|
||||||
tex_location = solid_color_tile_builder.allocate(&mut allocator);
|
texture_location = solid_color_tile_builder.allocate(&mut allocator);
|
||||||
sampling_flags = TextureSamplingFlags::empty();
|
sampling_flags = TextureSamplingFlags::empty();
|
||||||
}
|
}
|
||||||
Paint::Gradient(_) => {
|
Paint::Gradient(_) => {
|
||||||
|
@ -220,14 +220,15 @@ impl Palette {
|
||||||
// 1. Use repeating/clamp on the sides.
|
// 1. Use repeating/clamp on the sides.
|
||||||
// 2. Choose an optimal size for the gradient that minimizes memory usage while
|
// 2. Choose an optimal size for the gradient that minimizes memory usage while
|
||||||
// retaining quality.
|
// retaining quality.
|
||||||
tex_location = allocator.allocate(Vector2I::splat(GRADIENT_TILE_LENGTH as i32),
|
texture_location = allocator.allocate(Vector2I::splat(GRADIENT_TILE_LENGTH as i32),
|
||||||
AllocationMode::Atlas);
|
AllocationMode::Atlas);
|
||||||
sampling_flags = TextureSamplingFlags::empty();
|
sampling_flags = TextureSamplingFlags::empty();
|
||||||
}
|
}
|
||||||
Paint::Pattern(ref pattern) => {
|
Paint::Pattern(ref pattern) => {
|
||||||
match pattern.source {
|
match pattern.source {
|
||||||
PatternSource::RenderTarget(render_target_id) => {
|
PatternSource::RenderTarget(render_target_id) => {
|
||||||
tex_location = render_target_locations[render_target_id.0 as usize];
|
texture_location =
|
||||||
|
render_target_locations[render_target_id.0 as usize];
|
||||||
}
|
}
|
||||||
PatternSource::Image(ref image) => {
|
PatternSource::Image(ref image) => {
|
||||||
// TODO(pcwalton): We should be able to use tile cleverness to repeat
|
// TODO(pcwalton): We should be able to use tile cleverness to repeat
|
||||||
|
@ -238,7 +239,7 @@ impl Palette {
|
||||||
AllocationMode::OwnPage
|
AllocationMode::OwnPage
|
||||||
};
|
};
|
||||||
|
|
||||||
tex_location = allocator.allocate(image.size(), allocation_mode);
|
texture_location = allocator.allocate(image.size(), allocation_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,9 +258,9 @@ impl Palette {
|
||||||
};
|
};
|
||||||
|
|
||||||
metadata.push(PaintMetadata {
|
metadata.push(PaintMetadata {
|
||||||
tex_page: tex_location.page,
|
texture_page: texture_location.page,
|
||||||
tex_rect: tex_location.rect,
|
texture_rect: texture_location.rect,
|
||||||
tex_transform: Transform2F::default(),
|
texture_transform: Transform2F::default(),
|
||||||
sampling_flags,
|
sampling_flags,
|
||||||
is_opaque: paint.is_opaque(),
|
is_opaque: paint.is_opaque(),
|
||||||
});
|
});
|
||||||
|
@ -267,26 +268,28 @@ impl Palette {
|
||||||
|
|
||||||
// Calculate texture transforms.
|
// Calculate texture transforms.
|
||||||
for (paint, metadata) in self.paints.iter().zip(metadata.iter_mut()) {
|
for (paint, metadata) in self.paints.iter().zip(metadata.iter_mut()) {
|
||||||
let texture_scale = allocator.page_scale(metadata.tex_page);
|
let texture_scale = allocator.page_scale(metadata.texture_page);
|
||||||
metadata.tex_transform = match paint {
|
metadata.texture_transform = match paint {
|
||||||
Paint::Color(_) => {
|
Paint::Color(_) => {
|
||||||
let vector = rect_to_inset_uv(metadata.tex_rect, texture_scale).origin();
|
let vector = rect_to_inset_uv(metadata.texture_rect, texture_scale).origin();
|
||||||
Transform2F { matrix: Matrix2x2F(F32x4::default()), vector }
|
Transform2F { matrix: Matrix2x2F(F32x4::default()), vector }
|
||||||
}
|
}
|
||||||
Paint::Gradient(_) => {
|
Paint::Gradient(_) => {
|
||||||
let texture_origin_uv = rect_to_uv(metadata.tex_rect, texture_scale).origin();
|
let texture_origin_uv =
|
||||||
|
rect_to_uv(metadata.texture_rect, texture_scale).origin();
|
||||||
let gradient_tile_scale = texture_scale.scale(GRADIENT_TILE_LENGTH as f32);
|
let gradient_tile_scale = texture_scale.scale(GRADIENT_TILE_LENGTH as f32);
|
||||||
Transform2F::from_translation(texture_origin_uv) *
|
Transform2F::from_translation(texture_origin_uv) *
|
||||||
Transform2F::from_scale(gradient_tile_scale / view_box_size.to_f32())
|
Transform2F::from_scale(gradient_tile_scale / view_box_size.to_f32())
|
||||||
}
|
}
|
||||||
Paint::Pattern(Pattern { source: PatternSource::Image(_), .. }) => {
|
Paint::Pattern(Pattern { source: PatternSource::Image(_), .. }) => {
|
||||||
let texture_origin_uv = rect_to_uv(metadata.tex_rect, texture_scale).origin();
|
let texture_origin_uv =
|
||||||
|
rect_to_uv(metadata.texture_rect, texture_scale).origin();
|
||||||
Transform2F::from_translation(texture_origin_uv) *
|
Transform2F::from_translation(texture_origin_uv) *
|
||||||
Transform2F::from_scale(texture_scale)
|
Transform2F::from_scale(texture_scale)
|
||||||
}
|
}
|
||||||
Paint::Pattern(Pattern { source: PatternSource::RenderTarget(_), .. }) => {
|
Paint::Pattern(Pattern { source: PatternSource::RenderTarget(_), .. }) => {
|
||||||
// FIXME(pcwalton): Only do this in GL, not Metal!
|
// FIXME(pcwalton): Only do this in GL, not Metal!
|
||||||
let texture_origin_uv = rect_to_uv(metadata.tex_rect,
|
let texture_origin_uv = rect_to_uv(metadata.texture_rect,
|
||||||
texture_scale).lower_left();
|
texture_scale).lower_left();
|
||||||
Transform2F::from_translation(texture_origin_uv) *
|
Transform2F::from_translation(texture_origin_uv) *
|
||||||
Transform2F::from_scale(texture_scale.scale_xy(Vector2F::new(1.0, -1.0)))
|
Transform2F::from_scale(texture_scale.scale_xy(Vector2F::new(1.0, -1.0)))
|
||||||
|
@ -297,42 +300,42 @@ impl Palette {
|
||||||
// Render the actual texels.
|
// Render the actual texels.
|
||||||
//
|
//
|
||||||
// TODO(pcwalton): This is slow. Do more on GPU.
|
// TODO(pcwalton): This is slow. Do more on GPU.
|
||||||
let mut paint_data = PaintData { pages: vec![] };
|
let mut texture_data = TextureData { pages: vec![] };
|
||||||
for page_index in 0..allocator.page_count() {
|
for page_index in 0..allocator.page_count() {
|
||||||
let page_index = PaintPageId(page_index);
|
let page_index = TexturePageId(page_index);
|
||||||
let page_size = allocator.page_size(page_index);
|
let page_size = allocator.page_size(page_index);
|
||||||
if let Some(render_target_id) = allocator.page_render_target_id(page_index) {
|
if let Some(render_target_id) = allocator.page_render_target_id(page_index) {
|
||||||
paint_data.pages.push(PaintPageData {
|
texture_data.pages.push(TexturePageData {
|
||||||
size: page_size,
|
size: page_size,
|
||||||
contents: PaintPageContents::RenderTarget(render_target_id),
|
contents: TexturePageContents::RenderTarget(render_target_id),
|
||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let page_area = page_size.x() as usize * page_size.y() as usize;
|
let page_area = page_size.x() as usize * page_size.y() as usize;
|
||||||
let texels = vec![ColorU::default(); page_area];
|
let texels = vec![ColorU::default(); page_area];
|
||||||
paint_data.pages.push(PaintPageData {
|
texture_data.pages.push(TexturePageData {
|
||||||
size: page_size,
|
size: page_size,
|
||||||
contents: PaintPageContents::Texels(texels),
|
contents: TexturePageContents::Texels(texels),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (paint, metadata) in self.paints.iter().zip(metadata.iter()) {
|
for (paint, metadata) in self.paints.iter().zip(metadata.iter()) {
|
||||||
let tex_page = metadata.tex_page;
|
let texture_page = metadata.texture_page;
|
||||||
let paint_page_data = &mut paint_data.pages[tex_page.0 as usize];
|
let paint_page_data = &mut texture_data.pages[texture_page.0 as usize];
|
||||||
let page_size = paint_page_data.size;
|
let page_size = paint_page_data.size;
|
||||||
let page_scale = allocator.page_scale(tex_page);
|
let page_scale = allocator.page_scale(texture_page);
|
||||||
|
|
||||||
match paint_page_data.contents {
|
match paint_page_data.contents {
|
||||||
PaintPageContents::Texels(ref mut texels) => {
|
TexturePageContents::Texels(ref mut texels) => {
|
||||||
match paint {
|
match paint {
|
||||||
Paint::Color(color) => {
|
Paint::Color(color) => {
|
||||||
put_pixel(metadata.tex_rect.origin(), *color, texels, page_size);
|
put_pixel(metadata.texture_rect.origin(), *color, texels, page_size);
|
||||||
}
|
}
|
||||||
Paint::Gradient(ref gradient) => {
|
Paint::Gradient(ref gradient) => {
|
||||||
self.render_gradient(gradient,
|
self.render_gradient(gradient,
|
||||||
metadata.tex_rect,
|
metadata.texture_rect,
|
||||||
&metadata.tex_transform,
|
&metadata.texture_transform,
|
||||||
texels,
|
texels,
|
||||||
page_size,
|
page_size,
|
||||||
page_scale);
|
page_scale);
|
||||||
|
@ -341,17 +344,20 @@ impl Palette {
|
||||||
match pattern.source {
|
match pattern.source {
|
||||||
PatternSource::RenderTarget(_) => {}
|
PatternSource::RenderTarget(_) => {}
|
||||||
PatternSource::Image(ref image) => {
|
PatternSource::Image(ref image) => {
|
||||||
self.render_image(image, metadata.tex_rect, texels, page_size);
|
self.render_image(image,
|
||||||
|
metadata.texture_rect,
|
||||||
|
texels,
|
||||||
|
page_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaintPageContents::RenderTarget(_) => {}
|
TexturePageContents::RenderTarget(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PaintInfo { data: paint_data, metadata };
|
return PaintInfo { data: texture_data, metadata };
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(pcwalton): This is slow. Do on GPU instead.
|
// TODO(pcwalton): This is slow. Do on GPU instead.
|
||||||
|
@ -532,7 +538,7 @@ impl PaintMetadata {
|
||||||
-> Vector2F {
|
-> Vector2F {
|
||||||
let tile_size = Vector2I::new(TILE_WIDTH as i32, TILE_HEIGHT as i32);
|
let tile_size = Vector2I::new(TILE_WIDTH as i32, TILE_HEIGHT as i32);
|
||||||
let position = tile_position.scale_xy(tile_size).to_f32();
|
let position = tile_position.scale_xy(tile_size).to_f32();
|
||||||
let tex_coords = self.tex_transform * path_transform_inv * position;
|
let tex_coords = self.texture_transform * path_transform_inv * position;
|
||||||
tex_coords
|
tex_coords
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,12 +79,12 @@ impl ZBuffer {
|
||||||
|
|
||||||
// Create a batch if necessary.
|
// Create a batch if necessary.
|
||||||
match solid_tiles.batches.last() {
|
match solid_tiles.batches.last() {
|
||||||
Some(ref batch) if batch.paint_page == paint_metadata.tex_page &&
|
Some(ref batch) if batch.color_texture_page == paint_metadata.texture_page &&
|
||||||
batch.sampling_flags == paint_metadata.sampling_flags => {}
|
batch.sampling_flags == paint_metadata.sampling_flags => {}
|
||||||
_ => {
|
_ => {
|
||||||
// Batch break.
|
// Batch break.
|
||||||
solid_tiles.batches.push(SolidTileBatch {
|
solid_tiles.batches.push(SolidTileBatch {
|
||||||
paint_page: paint_metadata.tex_page,
|
color_texture_page: paint_metadata.texture_page,
|
||||||
sampling_flags: paint_metadata.sampling_flags,
|
sampling_flags: paint_metadata.sampling_flags,
|
||||||
vertices: vec![],
|
vertices: vec![],
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue