@@ -82,97 +82,105 @@ const SamplerDescriptor& AtlasContents::GetSamplerDescriptor() const {
8282 return sampler_descriptor_;
8383}
8484
85+ const std::vector<Matrix>& AtlasContents::GetTransforms () const {
86+ return transforms_;
87+ }
88+
89+ const std::vector<Rect>& AtlasContents::GetTextureCoordinates () const {
90+ return texture_coords_;
91+ }
92+
93+ const std::vector<Color>& AtlasContents::GetColors () const {
94+ return colors_;
95+ }
96+
8597bool AtlasContents::Render (const ContentContext& renderer,
8698 const Entity& entity,
8799 RenderPass& pass) const {
88100 if (texture_ == nullptr || blend_mode_ == BlendMode::kClear ) {
89101 return true ;
90102 }
91103
104+ // Ensure that we use the actual computed bounds and not a cull-rect
105+ // approximation of them.
106+ auto coverage = ComputeBoundingBox ();
107+
92108 if (blend_mode_ == BlendMode::kSource || colors_.size () == 0 ) {
93- return RenderTexture (renderer, entity, pass, alpha_);
109+ auto child_contents = AtlasTextureContents (*this );
110+ child_contents.SetAlpha (alpha_);
111+ child_contents.SetCoverage (coverage);
112+ return child_contents.Render (renderer, entity, pass);
94113 }
95114 if (blend_mode_ == BlendMode::kDestination ) {
96- return RenderColors (renderer, entity, pass, alpha_);
115+ auto child_contents = AtlasColorContents (*this );
116+ child_contents.SetAlpha (alpha_);
117+ child_contents.SetCoverage (coverage);
118+ return child_contents.Render (renderer, entity, pass);
97119 }
98120
99- // Ensure that we use the actual computed bounds and not a cull-rect
100- // approximation of them.
101- auto coverage = ComputeBoundingBox ();
102- auto size = coverage.size ;
103-
104- // Simple blends.
105- if (blend_mode_ < BlendMode::kScreen ) {
106- auto subpass_texture = renderer.MakeSubpass (
107- ISize::Ceil (size),
108- [&contents = *this , &coverage](const ContentContext& renderer,
109- RenderPass& pass) -> bool {
110- Entity sub_entity;
111- sub_entity.SetBlendMode (BlendMode::kSourceOver );
112- sub_entity.SetTransformation (
113- Matrix::MakeTranslation (Vector3 (-coverage.origin )));
114- if (!contents.RenderColors (renderer, sub_entity, pass, 1.0 )) {
115- return false ;
116- }
117- return contents.RenderTexture (renderer, sub_entity, pass, 1.0 , true );
118- });
119- auto contents = ColorFilterContents::MakeBlend (
120- blend_mode_, {FilterInput::Make (subpass_texture)});
121- contents->SetAlpha (alpha_);
122- return contents->Render (renderer, entity, pass);
123- }
121+ auto src_contents = std::make_shared<AtlasTextureContents>(*this );
122+ src_contents->SetCoverage (coverage);
123+
124+ auto dst_contents = std::make_shared<AtlasColorContents>(*this );
125+ dst_contents->SetCoverage (coverage);
124126
125- auto dst_texture = renderer.MakeSubpass (
126- ISize::Ceil (size),
127- [&contents = *this , &coverage](const ContentContext& renderer,
128- RenderPass& pass) -> bool {
129- Entity sub_entity;
130- sub_entity.SetBlendMode (BlendMode::kSourceOver );
131- sub_entity.SetTransformation (
132- Matrix::MakeTranslation (Vector3 (-coverage.origin )));
133- return contents.RenderColors (renderer, sub_entity, pass, 1.0 );
134- });
135- auto src_texture = renderer.MakeSubpass (
136- ISize::Ceil (size),
137- [&contents = *this , &coverage](const ContentContext& renderer,
138- RenderPass& pass) -> bool {
139- Entity sub_entity;
140- sub_entity.SetBlendMode (BlendMode::kSourceOver );
141- sub_entity.SetTransformation (
142- Matrix::MakeTranslation (Vector3 (-coverage.origin )));
143- return contents.RenderTexture (renderer, sub_entity, pass, 1.0 );
144- });
145-
146- if (!src_texture || !dst_texture) {
147- return false ;
148- }
149127 auto contents = ColorFilterContents::MakeBlend (
150128 blend_mode_,
151- {FilterInput::Make (src_texture ), FilterInput::Make (dst_texture )});
129+ {FilterInput::Make (dst_contents ), FilterInput::Make (src_contents )});
152130 contents->SetAlpha (alpha_);
153131 return contents->Render (renderer, entity, pass);
154132}
155133
156- bool AtlasContents::RenderColors (const ContentContext& renderer,
157- const Entity& entity,
158- RenderPass& pass,
159- Scalar alpha) const {
160- using VS = GeometryColorPipeline::VertexShader;
161- using FS = GeometryColorPipeline::FragmentShader;
134+ // AtlasTextureContents
135+ // ---------------------------------------------------------
136+
137+ AtlasTextureContents::AtlasTextureContents (const AtlasContents& parent)
138+ : parent_(parent) {}
139+
140+ AtlasTextureContents::~AtlasTextureContents () {}
162141
142+ std::optional<Rect> AtlasTextureContents::GetCoverage (
143+ const Entity& entity) const {
144+ return coverage_.TransformBounds (entity.GetTransformation ());
145+ }
146+
147+ void AtlasTextureContents::SetAlpha (Scalar alpha) {
148+ alpha_ = alpha;
149+ }
150+
151+ void AtlasTextureContents::SetCoverage (Rect coverage) {
152+ coverage_ = coverage;
153+ }
154+
155+ bool AtlasTextureContents::Render (const ContentContext& renderer,
156+ const Entity& entity,
157+ RenderPass& pass) const {
158+ using VS = TextureFillVertexShader;
159+ using FS = TextureFillFragmentShader;
160+
161+ auto texture = parent_.GetTexture ();
162+ auto texture_coords = parent_.GetTextureCoordinates ();
163+ auto transforms = parent_.GetTransforms ();
164+
165+ const auto texture_size = texture->GetSize ();
163166 VertexBufferBuilder<VS::PerVertexData> vertex_builder;
164- vertex_builder.Reserve (texture_coords_ .size () * 6 );
167+ vertex_builder.Reserve (texture_coords .size () * 6 );
165168 constexpr size_t indices[6 ] = {0 , 1 , 2 , 1 , 2 , 3 };
166- for (size_t i = 0 ; i < texture_coords_.size (); i++) {
167- auto sample_rect = texture_coords_[i];
168- auto matrix = transforms_[i];
169+ constexpr Scalar width[6 ] = {0 , 1 , 0 , 1 , 0 , 1 };
170+ constexpr Scalar height[6 ] = {0 , 0 , 1 , 0 , 1 , 1 };
171+ for (size_t i = 0 ; i < texture_coords.size (); i++) {
172+ auto sample_rect = texture_coords[i];
173+ auto matrix = transforms[i];
169174 auto transformed_points =
170175 Rect::MakeSize (sample_rect.size ).GetTransformedPoints (matrix);
171176
172177 for (size_t j = 0 ; j < 6 ; j++) {
173178 VS::PerVertexData data;
174179 data.position = transformed_points[indices[j]];
175- data.color = colors_[i].Premultiply ();
180+ data.texture_coords =
181+ (sample_rect.origin + Point (sample_rect.size .width * width[j],
182+ sample_rect.size .height * height[j])) /
183+ texture_size;
176184 vertex_builder.AppendVertex (data);
177185 }
178186 }
@@ -182,7 +190,7 @@ bool AtlasContents::RenderColors(const ContentContext& renderer,
182190 }
183191
184192 Command cmd;
185- cmd.label = " DrawAtlas " ;
193+ cmd.label = " AtlasTexture " ;
186194
187195 auto & host_buffer = pass.GetTransientsBuffer ();
188196
@@ -191,45 +199,65 @@ bool AtlasContents::RenderColors(const ContentContext& renderer,
191199 entity.GetTransformation ();
192200
193201 FS::FragInfo frag_info;
194- frag_info.alpha = alpha;
202+ frag_info.texture_sampler_y_coord_scale = texture->GetYCoordScale ();
203+ frag_info.alpha = alpha_;
195204
196- auto opts = OptionsFromPassAndEntity (pass, entity);
197- opts.blend_mode = BlendMode::kSourceOver ;
198- cmd.pipeline = renderer.GetGeometryColorPipeline (opts);
205+ auto options = OptionsFromPassAndEntity (pass, entity);
206+ cmd.pipeline = renderer.GetTexturePipeline (options);
199207 cmd.stencil_reference = entity.GetStencilDepth ();
200208 cmd.BindVertices (vertex_builder.CreateVertexBuffer (host_buffer));
201209 VS::BindVertInfo (cmd, host_buffer.EmplaceUniform (vert_info));
202210 FS::BindFragInfo (cmd, host_buffer.EmplaceUniform (frag_info));
211+ FS::BindTextureSampler (cmd, texture,
212+ renderer.GetContext ()->GetSamplerLibrary ()->GetSampler (
213+ parent_.GetSamplerDescriptor ()));
203214 return pass.AddCommand (std::move (cmd));
204215}
205216
206- bool AtlasContents::RenderTexture (const ContentContext& renderer,
207- const Entity& entity,
208- RenderPass& pass,
209- Scalar alpha,
210- bool apply_blend) const {
211- using VS = TextureFillVertexShader;
212- using FS = TextureFillFragmentShader;
217+ // AtlasColorContents
218+ // ---------------------------------------------------------
219+
220+ AtlasColorContents::AtlasColorContents (const AtlasContents& parent)
221+ : parent_(parent) {}
222+
223+ AtlasColorContents::~AtlasColorContents () {}
224+
225+ std::optional<Rect> AtlasColorContents::GetCoverage (
226+ const Entity& entity) const {
227+ return coverage_.TransformBounds (entity.GetTransformation ());
228+ }
229+
230+ void AtlasColorContents::SetAlpha (Scalar alpha) {
231+ alpha_ = alpha;
232+ }
233+
234+ void AtlasColorContents::SetCoverage (Rect coverage) {
235+ coverage_ = coverage;
236+ }
237+
238+ bool AtlasColorContents::Render (const ContentContext& renderer,
239+ const Entity& entity,
240+ RenderPass& pass) const {
241+ using VS = GeometryColorPipeline::VertexShader;
242+ using FS = GeometryColorPipeline::FragmentShader;
243+
244+ auto texture_coords = parent_.GetTextureCoordinates ();
245+ auto transforms = parent_.GetTransforms ();
246+ auto colors = parent_.GetColors ();
213247
214- const auto texture_size = texture_->GetSize ();
215248 VertexBufferBuilder<VS::PerVertexData> vertex_builder;
216- vertex_builder.Reserve (texture_coords_ .size () * 6 );
249+ vertex_builder.Reserve (texture_coords .size () * 6 );
217250 constexpr size_t indices[6 ] = {0 , 1 , 2 , 1 , 2 , 3 };
218- constexpr Scalar width[6 ] = {0 , 1 , 0 , 1 , 0 , 1 };
219- constexpr Scalar height[6 ] = {0 , 0 , 1 , 0 , 1 , 1 };
220- for (size_t i = 0 ; i < texture_coords_.size (); i++) {
221- auto sample_rect = texture_coords_[i];
222- auto matrix = transforms_[i];
251+ for (size_t i = 0 ; i < texture_coords.size (); i++) {
252+ auto sample_rect = texture_coords[i];
253+ auto matrix = transforms[i];
223254 auto transformed_points =
224255 Rect::MakeSize (sample_rect.size ).GetTransformedPoints (matrix);
225256
226257 for (size_t j = 0 ; j < 6 ; j++) {
227258 VS::PerVertexData data;
228259 data.position = transformed_points[indices[j]];
229- data.texture_coords =
230- (sample_rect.origin + Point (sample_rect.size .width * width[j],
231- sample_rect.size .height * height[j])) /
232- texture_size;
260+ data.color = colors[i].Premultiply ();
233261 vertex_builder.AppendVertex (data);
234262 }
235263 }
@@ -239,7 +267,7 @@ bool AtlasContents::RenderTexture(const ContentContext& renderer,
239267 }
240268
241269 Command cmd;
242- cmd.label = " DrawAtlas " ;
270+ cmd.label = " AtlasColors " ;
243271
244272 auto & host_buffer = pass.GetTransientsBuffer ();
245273
@@ -248,21 +276,15 @@ bool AtlasContents::RenderTexture(const ContentContext& renderer,
248276 entity.GetTransformation ();
249277
250278 FS::FragInfo frag_info;
251- frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale ();
252- frag_info.alpha = alpha;
279+ frag_info.alpha = alpha_;
253280
254- auto options = OptionsFromPassAndEntity (pass, entity);
255- if (apply_blend) {
256- options.blend_mode = blend_mode_;
257- }
258- cmd.pipeline = renderer.GetTexturePipeline (options);
281+ auto opts = OptionsFromPassAndEntity (pass, entity);
282+ opts.blend_mode = BlendMode::kSourceOver ;
283+ cmd.pipeline = renderer.GetGeometryColorPipeline (opts);
259284 cmd.stencil_reference = entity.GetStencilDepth ();
260285 cmd.BindVertices (vertex_builder.CreateVertexBuffer (host_buffer));
261286 VS::BindVertInfo (cmd, host_buffer.EmplaceUniform (vert_info));
262287 FS::BindFragInfo (cmd, host_buffer.EmplaceUniform (frag_info));
263- FS::BindTextureSampler (cmd, texture_,
264- renderer.GetContext ()->GetSamplerLibrary ()->GetSampler (
265- sampler_descriptor_));
266288 return pass.AddCommand (std::move (cmd));
267289}
268290
0 commit comments