diff --git a/data/images/objects/candle/candle-light-1.sprite b/data/images/objects/candle/candle-light-1.sprite index f8559847a49..01533e1c4a7 100644 --- a/data/images/objects/candle/candle-light-1.sprite +++ b/data/images/objects/candle/candle-light-1.sprite @@ -1,12 +1,31 @@ (supertux-sprite (action (name "default") - (images "candle-light-1.png") + (surfaces + (surface + (diffuse-texture + (file "candle-light-1.png") + ) + (circle + (radius 140) + ) + ) + ) + (images ) (hitbox 260 280 256 256) ) (action (name "white") - (images "candle-light-white-1.png") + (surfaces + (surface + (diffuse-texture + (file "candle-light-white-1.png") + ) + (circle + (radius 140) + ) + ) + ) (hitbox 260 280 256 256) ) ) diff --git a/data/images/objects/candle/candle-light-2.sprite b/data/images/objects/candle/candle-light-2.sprite index 6ba59fb1b70..73a9262fdb0 100644 --- a/data/images/objects/candle/candle-light-2.sprite +++ b/data/images/objects/candle/candle-light-2.sprite @@ -1,12 +1,30 @@ (supertux-sprite (action (name "default") - (images "candle-light-2.png") + (surfaces + (surface + (diffuse-texture + (file "candle-light-2.png") + ) + (circle + (radius 140) + ) + ) + ) (hitbox 260 280 256 256) ) (action (name "white") - (images "candle-light-white-2.png") + (surfaces + (surface + (diffuse-texture + (file "candle-light-white-2.png") + ) + (circle + (radius 140) + ) + ) + ) (hitbox 260 280 256 256) ) ) diff --git a/data/images/objects/lightmap_light/lightmap_light-large.sprite b/data/images/objects/lightmap_light/lightmap_light-large.sprite index 94ee84c2204..c24af194f99 100644 --- a/data/images/objects/lightmap_light/lightmap_light-large.sprite +++ b/data/images/objects/lightmap_light/lightmap_light-large.sprite @@ -1,7 +1,16 @@ (supertux-sprite (action (name "default") - (images "lightmap_light-large.png") + (surfaces + (surface + (diffuse-texture + (file "lightmap_light-large.png") + ) + (circle + (radius 360) + ) + ) + ) (hitbox 512 512 0 0) ) ) diff --git a/data/images/objects/lightmap_light/lightmap_light-medium.sprite b/data/images/objects/lightmap_light/lightmap_light-medium.sprite index 670a152792e..c223dcaf8db 100644 --- a/data/images/objects/lightmap_light/lightmap_light-medium.sprite +++ b/data/images/objects/lightmap_light/lightmap_light-medium.sprite @@ -1,7 +1,16 @@ (supertux-sprite (action (name "default") - (images "lightmap_light-medium.png") + (surfaces + (surface + (diffuse-texture + (file "lightmap_light-medium.png") + ) + (circle + (radius 160) + ) + ) + ) (hitbox 192 192 0 0) ) ) diff --git a/data/images/objects/lightmap_light/lightmap_light-small.sprite b/data/images/objects/lightmap_light/lightmap_light-small.sprite index 350efca9f70..d1f96c8a8d0 100644 --- a/data/images/objects/lightmap_light/lightmap_light-small.sprite +++ b/data/images/objects/lightmap_light/lightmap_light-small.sprite @@ -1,7 +1,16 @@ (supertux-sprite (action (name "default") - (images "lightmap_light-small.png") + (surfaces + (surface + (diffuse-texture + (file "lightmap_light-small.png") + ) + (circle + (radius 50) + ) + ) + ) (hitbox 64 64 0 0) ) ) diff --git a/data/images/objects/lightmap_light/lightmap_light-tiny.sprite b/data/images/objects/lightmap_light/lightmap_light-tiny.sprite index 841be38c5e2..c5fe9823cca 100644 --- a/data/images/objects/lightmap_light/lightmap_light-tiny.sprite +++ b/data/images/objects/lightmap_light/lightmap_light-tiny.sprite @@ -1,7 +1,16 @@ (supertux-sprite (action (name "default") - (images "lightmap_light-tiny.png") + (surfaces + (surface + (diffuse-texture + (file "lightmap_light-tiny.png") + ) + (circle + (radius 30) + ) + ) + ) (hitbox 32 32 0 0) ) ) diff --git a/data/images/objects/lightmap_light/lightmap_light.sprite b/data/images/objects/lightmap_light/lightmap_light.sprite index 862c0df5fe2..c5af9ad3060 100644 --- a/data/images/objects/lightmap_light/lightmap_light.sprite +++ b/data/images/objects/lightmap_light/lightmap_light.sprite @@ -1,7 +1,16 @@ (supertux-sprite (action (name "default") - (images "lightmap_light.png") + (surfaces + (surface + (diffuse-texture + (file "lightmap_light.png") + ) + (circle + (radius 200) + ) + ) + ) (hitbox 256 256 0 0) ) ) diff --git a/data/images/objects/torch/flame_light.sprite b/data/images/objects/torch/flame_light.sprite index f0299cf4adb..08ebdce6933 100644 --- a/data/images/objects/torch/flame_light.sprite +++ b/data/images/objects/torch/flame_light.sprite @@ -2,11 +2,29 @@ (action (name "default") (hitbox 357 384 384 384) - (images "flame_light.png") + (surfaces + (surface + (diffuse-texture + (file "flame_light.png") + ) + (circle + (radius 220) + ) + ) + ) ) (action (name "greyscale") (hitbox 357 384 384 384) - (images "greyscale/flame_light.png") + (surfaces + (surface + (diffuse-texture + (file "greyscale/flame_light.png") + ) + (circle + (radius 220) + ) + ) + ) ) ) diff --git a/src/badguy/badguy.cpp b/src/badguy/badguy.cpp index 01ab9387301..f928a505789 100644 --- a/src/badguy/badguy.cpp +++ b/src/badguy/badguy.cpp @@ -170,7 +170,7 @@ BadGuy::draw(DrawingContext& context) if (m_glowing) { - m_lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0); + m_lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } } } diff --git a/src/badguy/bomb.cpp b/src/badguy/bomb.cpp index 41eaf53bd10..51eb42451ed 100644 --- a/src/badguy/bomb.cpp +++ b/src/badguy/bomb.cpp @@ -92,7 +92,7 @@ Bomb::draw(DrawingContext& context) m_exploding_sprite->set_action("exploding"); m_exploding_sprite->set_blend(Blend::ADD); m_exploding_sprite->draw(context.light(), - get_pos() + Vector(get_bbox().get_width() / 2, get_bbox().get_height() / 2), m_layer, m_flip); + get_pos() + Vector(get_bbox().get_width() / 2, get_bbox().get_height() / 2), m_layer, m_flip, ColorSpace::LIGHTSPRITES); BadGuy::draw(context); } diff --git a/src/badguy/dive_mine.cpp b/src/badguy/dive_mine.cpp index 2b63adeb87f..2ee1e0e1ac5 100644 --- a/src/badguy/dive_mine.cpp +++ b/src/badguy/dive_mine.cpp @@ -123,7 +123,7 @@ DiveMine::draw(DrawingContext& context) m_ticking_glow->draw(context.light(), Vector(m_col.m_bbox.get_left() + m_col.m_bbox.get_width() / 2, m_col.m_bbox.get_top() - 8.f), - m_layer, m_flip); + m_layer, m_flip, ColorSpace::LIGHTSPRITES); } void diff --git a/src/badguy/ghosttree.cpp b/src/badguy/ghosttree.cpp index b74b3b60725..03a00fad5f4 100644 --- a/src/badguy/ghosttree.cpp +++ b/src/badguy/ghosttree.cpp @@ -223,7 +223,7 @@ GhostTree::draw(DrawingContext& context) } else { context.set_alpha(0.5f); } - glow_sprite->draw(context.light(), get_pos(), m_layer); + glow_sprite->draw(context.light(), get_pos(), m_layer, NO_FLIP, ColorSpace::LIGHTSPRITES); context.pop_transform(); } diff --git a/src/badguy/goldbomb.cpp b/src/badguy/goldbomb.cpp index ad413647e39..b570dd52ae1 100644 --- a/src/badguy/goldbomb.cpp +++ b/src/badguy/goldbomb.cpp @@ -287,7 +287,7 @@ GoldBomb::draw(DrawingContext& context) { m_exploding_sprite->set_blend(Blend::ADD); m_exploding_sprite->draw(context.light(), - get_pos() + Vector(get_bbox().get_width() / 2, get_bbox().get_height() / 2), m_layer, m_flip); + get_pos() + Vector(get_bbox().get_width() / 2, get_bbox().get_height() / 2), m_layer, m_flip, ColorSpace::LIGHTSPRITES); } WalkingBadguy::draw(context); } diff --git a/src/badguy/haywire.cpp b/src/badguy/haywire.cpp index 3a86f2f1bf1..65c79321fdb 100644 --- a/src/badguy/haywire.cpp +++ b/src/badguy/haywire.cpp @@ -233,7 +233,7 @@ Haywire::draw(DrawingContext& context) { m_exploding_sprite->set_blend(Blend::ADD); m_exploding_sprite->draw(context.light(), - get_pos()+Vector(get_bbox().get_width()/2, get_bbox().get_height()/2), m_layer, m_flip); + get_pos()+Vector(get_bbox().get_width()/2, get_bbox().get_height()/2), m_layer, m_flip, ColorSpace::LIGHTSPRITES); } WalkingBadguy::draw(context); } diff --git a/src/badguy/kugelblitz.cpp b/src/badguy/kugelblitz.cpp index 78d99d9ea9d..a5a74a8004b 100644 --- a/src/badguy/kugelblitz.cpp +++ b/src/badguy/kugelblitz.cpp @@ -152,7 +152,7 @@ void Kugelblitz::draw(DrawingContext& context) { m_sprite->draw(context.color(), get_pos(), m_layer); - lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0); + lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } void diff --git a/src/badguy/treewillowisp.cpp b/src/badguy/treewillowisp.cpp index b147d881f2c..dcb7de3a6f6 100644 --- a/src/badguy/treewillowisp.cpp +++ b/src/badguy/treewillowisp.cpp @@ -106,7 +106,7 @@ void TreeWillOWisp::draw(DrawingContext& context) { m_sprite->draw(context.color(), get_pos(), m_layer); - m_sprite->draw(context.light(), get_pos(), m_layer); + m_sprite->draw(context.light(), get_pos(), m_layer, NO_FLIP, ColorSpace::LIGHTSPRITES); } void diff --git a/src/math/circle.cpp b/src/math/circle.cpp new file mode 100644 index 00000000000..cc6c142155e --- /dev/null +++ b/src/math/circle.cpp @@ -0,0 +1,46 @@ +// SuperTux +// Copyright (C) 2024 Vankata453 +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "math/circle.hpp" + +#include "math/rectf.hpp" +#include "util/reader_mapping.hpp" + +Circle +Circle::from_reader(const ReaderMapping& mapping) +{ + Circle circle; + + mapping.get("radius", circle.m_radius); + + return circle; +} + + +Circle::Circle(const Vector& center, float radius) : + m_center(center), + m_radius(radius) +{ +} + +bool +Circle::contains(const Vector& point) const +{ + const float distance = powf(point.x - m_center.x, 2) + powf(point.y - m_center.y, 2); + return distance <= powf(m_radius, 2); +} + +/* EOF */ diff --git a/src/math/circle.hpp b/src/math/circle.hpp new file mode 100644 index 00000000000..6189214fb62 --- /dev/null +++ b/src/math/circle.hpp @@ -0,0 +1,45 @@ +// SuperTux +// Copyright (C) 2024 Vankata453 +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef HEADER_SUPERTUX_MATH_CIRCLE_HPP +#define HEADER_SUPERTUX_MATH_CIRCLE_HPP + +#include "math/vector.hpp" + +class ReaderMapping; +class Rectf; + +class Circle final +{ +public: + static Circle from_reader(const ReaderMapping& mapping); + +public: + Circle(const Vector& center = Vector(0.f, 0.f), float radius = 0.f); + + bool contains(const Vector& point) const; + + const Vector& get_center() const { return m_center; } + void set_center(const Vector& center) { m_center = center; } + +private: + Vector m_center; + float m_radius; +}; + +#endif + +/* EOF */ diff --git a/src/object/bonus_block.cpp b/src/object/bonus_block.cpp index 1a9dcf48fb1..c5c9923c306 100644 --- a/src/object/bonus_block.cpp +++ b/src/object/bonus_block.cpp @@ -688,7 +688,7 @@ BonusBlock::draw(DrawingContext& context) { Vector pos = get_pos() + (m_col.m_bbox.get_size().as_vector() - Vector(static_cast(m_lightsprite->get_width()), static_cast(m_lightsprite->get_height()))) / 2.0f; - context.light().draw_surface(m_lightsprite, pos, 10); + context.light().draw_surface(m_lightsprite, pos, 10, ColorSpace::LIGHTSPRITES); } } diff --git a/src/object/bullet.cpp b/src/object/bullet.cpp index c9af24a1c99..c14550a8440 100644 --- a/src/object/bullet.cpp +++ b/src/object/bullet.cpp @@ -93,7 +93,7 @@ Bullet::draw(DrawingContext& context) { sprite->draw(context.color(), get_pos(), LAYER_OBJECTS); if (type == FIRE_BONUS){ - lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0); + lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } } diff --git a/src/object/candle.cpp b/src/object/candle.cpp index bb049413318..11e8735f298 100644 --- a/src/object/candle.cpp +++ b/src/object/candle.cpp @@ -92,10 +92,10 @@ Candle::draw(DrawingContext& context) // draw approx. 1 in 10 frames darker. Makes the candle flicker. if (graphicsRandom.rand(10) != 0 || !flicker) { // context.color().draw_surface(candle_light_1, pos, layer); - candle_light_1->draw(context.light(), m_col.m_bbox.get_middle(), m_layer); + candle_light_1->draw(context.light(), m_col.m_bbox.get_middle(), m_layer, NO_FLIP, ColorSpace::LIGHTSPRITES); } else { // context.color().draw_surface(candle_light_2, pos, layer); - candle_light_2->draw(context.light(), m_col.m_bbox.get_middle(), m_layer); + candle_light_2->draw(context.light(), m_col.m_bbox.get_middle(), m_layer, NO_FLIP, ColorSpace::LIGHTSPRITES); } } } diff --git a/src/object/explosion.cpp b/src/object/explosion.cpp index e576fd01e30..baaabbefd92 100644 --- a/src/object/explosion.cpp +++ b/src/object/explosion.cpp @@ -167,7 +167,7 @@ void Explosion::draw(DrawingContext& context) { m_sprite->draw(context.color(), get_pos(), LAYER_OBJECTS+40); - lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0); + lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } HitResponse diff --git a/src/object/firefly.cpp b/src/object/firefly.cpp index 37b473d7a66..0bc594cfbda 100644 --- a/src/object/firefly.cpp +++ b/src/object/firefly.cpp @@ -66,7 +66,7 @@ Firefly::draw(DrawingContext& context) if (m_sprite_name.find("torch", 0) != std::string::npos && (activated || m_sprite->get_action() == "ringing")) { - m_sprite_light->draw(context.light(), m_col.m_bbox.get_middle() + (m_flip == NO_FLIP ? -TORCH_LIGHT_OFFSET : TORCH_LIGHT_OFFSET), 0); + m_sprite_light->draw(context.light(), m_col.m_bbox.get_middle() + (m_flip == NO_FLIP ? -TORCH_LIGHT_OFFSET : TORCH_LIGHT_OFFSET), 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } } diff --git a/src/object/flower.cpp b/src/object/flower.cpp index a3f35c4fc0f..2c49906c899 100644 --- a/src/object/flower.cpp +++ b/src/object/flower.cpp @@ -66,7 +66,7 @@ void Flower::draw(DrawingContext& context) { sprite->draw(context.color(), get_pos(), LAYER_OBJECTS, flip); - lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0); + lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } HitResponse diff --git a/src/object/growup.cpp b/src/object/growup.cpp index 64333ff3dc4..073e1eb2775 100644 --- a/src/object/growup.cpp +++ b/src/object/growup.cpp @@ -59,7 +59,7 @@ GrowUp::draw(DrawingContext& context) return; shadesprite->draw(context.color(), get_pos(), m_layer); - lightsprite->draw(context.light(), get_bbox().get_middle(), 0); + lightsprite->draw(context.light(), get_bbox().get_middle(), 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } void diff --git a/src/object/key.cpp b/src/object/key.cpp index 2e8f2e47035..4a85d2721f0 100644 --- a/src/object/key.cpp +++ b/src/object/key.cpp @@ -181,7 +181,7 @@ void Key::draw(DrawingContext& context) { m_sprite->draw(context.color(), get_pos(), m_layer, m_flip); - m_lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), m_layer+1); + m_lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), m_layer+1, NO_FLIP, ColorSpace::LIGHTSPRITES); } ObjectSettings diff --git a/src/object/lantern.cpp b/src/object/lantern.cpp index 9b979d0602e..35a40ef147b 100644 --- a/src/object/lantern.cpp +++ b/src/object/lantern.cpp @@ -92,7 +92,7 @@ Lantern::draw(DrawingContext& context){ //Draw the Sprite. MovingSprite::draw(context); //Let there be light. - lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0); + lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } HitResponse Lantern::collision(GameObject& other, const CollisionHit& hit) { diff --git a/src/object/light.cpp b/src/object/light.cpp index 13cf1654e7e..ad8707d292e 100644 --- a/src/object/light.cpp +++ b/src/object/light.cpp @@ -40,7 +40,7 @@ Light::draw(DrawingContext& context) { sprite->set_color(color); sprite->set_blend(Blend::ADD); - sprite->draw(context.light(), position, 0); + sprite->draw(context.light(), position, 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } /* EOF */ diff --git a/src/object/lit_object.cpp b/src/object/lit_object.cpp index 03390a03fec..27a60e630bf 100644 --- a/src/object/lit_object.cpp +++ b/src/object/lit_object.cpp @@ -52,7 +52,7 @@ void LitObject::draw(DrawingContext& context) { m_sprite->draw(context.color(), get_pos(), m_layer - 1, m_flip); - m_light_sprite->draw(context.light(), get_pos() - m_light_offset, m_layer - 1, m_flip); + m_light_sprite->draw(context.light(), get_pos() - m_light_offset, m_layer - 1, m_flip, ColorSpace::LIGHTSPRITES); } void diff --git a/src/object/magicblock.cpp b/src/object/magicblock.cpp index 66b92910051..1429cc1c3ca 100644 --- a/src/object/magicblock.cpp +++ b/src/object/magicblock.cpp @@ -189,7 +189,7 @@ void MagicBlock::draw(DrawingContext& context) { // Ask for update about lightmap at center of this block - context.light().get_pixel(m_center, m_light); + context.light().get_pixel(ColorSpace::LIGHTSPRITES, m_center, m_light); MovingSprite::draw(context); context.color().draw_filled_rect(m_col.m_bbox, m_color, m_layer); diff --git a/src/object/powerup.cpp b/src/object/powerup.cpp index 0211972bdf6..bd3d305c6f2 100644 --- a/src/object/powerup.cpp +++ b/src/object/powerup.cpp @@ -290,7 +290,7 @@ PowerUp::draw(DrawingContext& context) if (m_type == STAR || m_type == HERRING) m_sprite->draw(context.color(), get_pos(), m_layer, m_flip); - lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0); + lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } ObjectSettings diff --git a/src/object/rublight.cpp b/src/object/rublight.cpp index afe021e8326..d32be35c3c8 100644 --- a/src/object/rublight.cpp +++ b/src/object/rublight.cpp @@ -140,7 +140,7 @@ RubLight::draw(DrawingContext& context) Color col = color.multiply_linearly(brightness); light->set_color(col); light->set_blend(Blend::ADD); - light->draw(context.light(), get_pos(), m_layer); + light->draw(context.light(), get_pos(), m_layer, NO_FLIP, ColorSpace::LIGHTSPRITES); } m_sprite->draw(context.color(), get_pos(), m_layer, m_flip); diff --git a/src/object/spotlight.cpp b/src/object/spotlight.cpp index 4a446eb570b..4b1ccadf696 100644 --- a/src/object/spotlight.cpp +++ b/src/object/spotlight.cpp @@ -145,7 +145,7 @@ Spotlight::draw(DrawingContext& context) light->set_color(color); light->set_blend(Blend::ADD); light->set_angle(angle); - light->draw(context.light(), m_col.m_bbox.p1(), m_layer); + light->draw(context.light(), m_col.m_bbox.p1(), m_layer, NO_FLIP, ColorSpace::LIGHTSPRITES); //lightcone->set_angle(angle); //lightcone->draw(context.color(), position, m_layer); diff --git a/src/object/sprite_particle.cpp b/src/object/sprite_particle.cpp index 634dc0e3845..a68c5901190 100644 --- a/src/object/sprite_particle.cpp +++ b/src/object/sprite_particle.cpp @@ -104,8 +104,8 @@ SpriteParticle::draw(DrawingContext& context) //Sparkles glow in the dark if (glow) { - sprite->draw(context.light(), position, drawing_layer); - lightsprite->draw(context.light(), position + Vector(12, 12), 0); + sprite->draw(context.light(), position, drawing_layer, NO_FLIP, ColorSpace::LIGHTSPRITES); + lightsprite->draw(context.light(), position + Vector(12, 12), 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } } diff --git a/src/object/star.cpp b/src/object/star.cpp index ca5be430bae..d905f3b4280 100644 --- a/src/object/star.cpp +++ b/src/object/star.cpp @@ -71,7 +71,7 @@ void Star::draw(DrawingContext& context) { MovingSprite::draw(context); - lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0); + lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } void diff --git a/src/object/torch.cpp b/src/object/torch.cpp index 07acd062aca..15f55dc5b62 100644 --- a/src/object/torch.cpp +++ b/src/object/torch.cpp @@ -60,7 +60,7 @@ Torch::draw(DrawingContext& context) m_flame->draw(context.color(), pos, m_layer - 1, m_flip); m_flame->set_action(m_light_color.greyscale() >= 1.f ? "default" : "greyscale"); - m_flame_light->draw(context.light(), pos, m_layer); + m_flame_light->draw(context.light(), pos, m_layer, NO_FLIP, ColorSpace::LIGHTSPRITES); m_flame_light->set_action(m_light_color.greyscale() >= 1.f ? "default" : "greyscale"); m_flame_glow->draw(context.color(), pos, m_layer - 1, m_flip); diff --git a/src/object/weak_block.cpp b/src/object/weak_block.cpp index 6c5b32fc5f6..d8b48087448 100644 --- a/src/object/weak_block.cpp +++ b/src/object/weak_block.cpp @@ -218,7 +218,7 @@ WeakBlock::draw(DrawingContext& context) if (m_type == HAY && (state != STATE_NORMAL)) { - lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0); + lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0, NO_FLIP, ColorSpace::LIGHTSPRITES); } } diff --git a/src/sprite/sprite.cpp b/src/sprite/sprite.cpp index de3098359be..9ef64e8e876 100644 --- a/src/sprite/sprite.cpp +++ b/src/sprite/sprite.cpp @@ -166,7 +166,7 @@ Sprite::update() void Sprite::draw(Canvas& canvas, const Vector& pos, int layer, - Flip flip) + Flip flip, ColorSpace::Type colorspace) { assert(m_action != nullptr); update(); @@ -183,7 +183,8 @@ Sprite::draw(Canvas& canvas, const Vector& pos, int layer, m_angle, m_color, m_blend, - layer); + layer, + colorspace); context.pop_transform(); } diff --git a/src/sprite/sprite.hpp b/src/sprite/sprite.hpp index 1e6eb95965c..4b34561ee33 100644 --- a/src/sprite/sprite.hpp +++ b/src/sprite/sprite.hpp @@ -38,7 +38,7 @@ class Sprite final /** Draw sprite, automatically calculates next frame */ void draw(Canvas& canvas, const Vector& pos, int layer, - Flip flip = NO_FLIP); + Flip flip = NO_FLIP, ColorSpace::Type colorspace = ColorSpace::NONE); /** Set action (or state) */ void set_action(const std::string& name, int loops = -1); diff --git a/src/video/canvas.cpp b/src/video/canvas.cpp index 2ba978a3993..5834e0cc5cc 100644 --- a/src/video/canvas.cpp +++ b/src/video/canvas.cpp @@ -31,7 +31,8 @@ Canvas::Canvas(DrawingContext& context, obstack& obst) : m_context(context), m_obst(obst), - m_requests() + m_requests(), + m_colorspaces() { m_requests.reserve(500); } @@ -102,8 +103,14 @@ Canvas::render(Renderer& renderer, Filter filter) break; case RequestType::GETPIXEL: - painter.get_pixel(static_cast(request)); + { + const GetPixelRequest& pixel_request = static_cast(request); + if (m_colorspaces.find(pixel_request.colorspace) == m_colorspaces.end()) + continue; + + *pixel_request.color_ptr = m_colorspaces[pixel_request.colorspace].get_pixel(pixel_request.pos); break; + } } } @@ -113,7 +120,7 @@ Canvas::render(Renderer& renderer, Filter filter) void Canvas::draw_surface(const SurfacePtr& surface, const Vector& position, float angle, const Color& color, const Blend& blend, - int layer) + int layer, ColorSpace::Type colorspace) { if (!surface) return; @@ -141,26 +148,46 @@ Canvas::draw_surface(const SurfacePtr& surface, request->displacement_texture = surface->get_displacement_texture().get(); request->color = color; + if (colorspace != ColorSpace::NONE) + { + if (m_colorspaces.find(colorspace) == m_colorspaces.end()) + m_colorspaces[colorspace] = ColorSpace(); + + if (surface->get_circle_data()) + { + Circle circle = *surface->get_circle_data(); + circle.set_center(position + Vector(static_cast(surface->get_width()) / 2, + static_cast(surface->get_height()) / 2)); + m_colorspaces[colorspace].add(circle, color); + } + else + { + m_colorspaces[colorspace].add(Rectf(position, + Sizef(static_cast(surface->get_width()), + static_cast(surface->get_height()))), color); + } + } + m_requests.push_back(request); } void -Canvas::draw_surface(const SurfacePtr& surface, const Vector& position, int layer) +Canvas::draw_surface(const SurfacePtr& surface, const Vector& position, int layer, ColorSpace::Type colorspace) { - draw_surface(surface, position, 0.0f, Color(1.0f, 1.0f, 1.0f), Blend(), layer); + draw_surface(surface, position, 0.0f, Color(1.0f, 1.0f, 1.0f), Blend(), layer, colorspace); } void Canvas::draw_surface_scaled(const SurfacePtr& surface, const Rectf& dstrect, - int layer, const PaintStyle& style) + int layer, const PaintStyle& style, ColorSpace::Type colorspace) { draw_surface_part(surface, Rectf(0.0f, 0.0f, static_cast(surface->get_width()), static_cast(surface->get_height())), - dstrect, layer, style); + dstrect, layer, style, colorspace); } void Canvas::draw_surface_part(const SurfacePtr& surface, const Rectf& srcrect, const Rectf& dstrect, - int layer, const PaintStyle& style) + int layer, const PaintStyle& style, ColorSpace::Type colorspace) { if (!surface) return; @@ -178,6 +205,14 @@ Canvas::draw_surface_part(const SurfacePtr& surface, const Rectf& srcrect, const request->displacement_texture = surface->get_displacement_texture().get(); request->color = style.get_color(); + if (colorspace != ColorSpace::NONE) + { + if (m_colorspaces.find(colorspace) == m_colorspaces.end()) + m_colorspaces[colorspace] = ColorSpace(); + + m_colorspaces[colorspace].add(dstrect, style.get_color()); + } + m_requests.push_back(request); } @@ -264,13 +299,13 @@ Canvas::draw_gradient(const Color& top, const Color& bottom, int layer, void Canvas::draw_filled_rect(const Rectf& rect, const Color& color, - int layer) + int layer, ColorSpace::Type colorspace) { - draw_filled_rect(rect, color, 0.0f, layer); + draw_filled_rect(rect, color, 0.0f, layer, colorspace); } void -Canvas::draw_filled_rect(const Rectf& rect, const Color& color, float radius, int layer) +Canvas::draw_filled_rect(const Rectf& rect, const Color& color, float radius, int layer, ColorSpace::Type colorspace) { auto request = new(m_obst) FillRectRequest(m_context.transform()); @@ -282,6 +317,14 @@ Canvas::draw_filled_rect(const Rectf& rect, const Color& color, float radius, in request->color.alpha = color.alpha * m_context.transform().alpha; request->radius = radius; + if (colorspace != ColorSpace::NONE) + { + if (m_colorspaces.find(colorspace) == m_colorspaces.end()) + m_colorspaces[colorspace] = ColorSpace(); + + m_colorspaces[colorspace].add(rect, color); + } + m_requests.push_back(request); } @@ -332,26 +375,16 @@ Canvas::draw_triangle(const Vector& pos1, const Vector& pos2, const Vector& pos3 } void -Canvas::get_pixel(const Vector& position, const std::shared_ptr& color_out) +Canvas::get_pixel(ColorSpace::Type colorspace, const Vector& position, const std::shared_ptr& color_out) { + assert(colorspace != ColorSpace::NONE); assert(color_out); - Vector pos = apply_translate(position)*scale(); - - // There is no light offscreen. - if (pos.x >= static_cast(m_context.get_viewport().get_width()) || - pos.y >= static_cast(m_context.get_viewport().get_height()) || - pos.x < 0.0f || - pos.y < 0.0f) - { - *color_out = Color(0, 0, 0); - return; - } - auto request = new(m_obst) GetPixelRequest(m_context.transform()); request->layer = LAYER_GETPIXEL; - request->pos = pos; + request->colorspace = colorspace; + request->pos = position; request->color_ptr = color_out; m_requests.push_back(request); diff --git a/src/video/canvas.hpp b/src/video/canvas.hpp index 91223211b2b..729404d0553 100644 --- a/src/video/canvas.hpp +++ b/src/video/canvas.hpp @@ -19,6 +19,7 @@ #define HEADER_SUPERTUX_VIDEO_CANVAS_HPP #include +#include #include #include #include @@ -27,6 +28,7 @@ #include "math/vector.hpp" #include "video/blend.hpp" #include "video/color.hpp" +#include "video/colorspace.hpp" #include "video/drawing_target.hpp" #include "video/font.hpp" #include "video/font_ptr.hpp" @@ -49,13 +51,13 @@ class Canvas final Canvas(DrawingContext& context, obstack& obst); ~Canvas(); - void draw_surface(const SurfacePtr& surface, const Vector& position, int layer); + void draw_surface(const SurfacePtr& surface, const Vector& position, int layer, ColorSpace::Type colorspace = ColorSpace::NONE); void draw_surface(const SurfacePtr& surface, const Vector& position, float angle, const Color& color, const Blend& blend, - int layer); + int layer, ColorSpace::Type colorspace = ColorSpace::NONE); void draw_surface_part(const SurfacePtr& surface, const Rectf& srcrect, const Rectf& dstrect, - int layer, const PaintStyle& style = PaintStyle()); + int layer, const PaintStyle& style = PaintStyle(), ColorSpace::Type colorspace = ColorSpace::NONE); void draw_surface_scaled(const SurfacePtr& surface, const Rectf& dstrect, - int layer, const PaintStyle& style = PaintStyle()); + int layer, const PaintStyle& style = PaintStyle(), ColorSpace::Type colorspace = ColorSpace::NONE); void draw_surface_batch(const SurfacePtr& surface, std::vector srcrects, std::vector dstrects, @@ -74,16 +76,16 @@ class Canvas final const Vector& position, int layer, const Color& color = Color(1.0,1.0,1.0)); void draw_gradient(const Color& from, const Color& to, int layer, const GradientDirection& direction, const Rectf& region, const Blend& blend = Blend()); - void draw_filled_rect(const Rectf& rect, const Color& color, int layer); - void draw_filled_rect(const Rectf& rect, const Color& color, float radius, int layer); + void draw_filled_rect(const Rectf& rect, const Color& color, int layer, ColorSpace::Type colorspace = ColorSpace::NONE); + void draw_filled_rect(const Rectf& rect, const Color& color, float radius, int layer, ColorSpace::Type colorspace = ColorSpace::NONE); void draw_inverse_ellipse(const Vector& pos, const Vector& size, const Color& color, int layer); void draw_line(const Vector& pos1, const Vector& pos2, const Color& color, int layer); void draw_triangle(const Vector& pos1, const Vector& pos2, const Vector& pos3, const Color& color, int layer); - /** on next update, set color to lightmap's color at position */ - void get_pixel(const Vector& position, const std::shared_ptr& color_out); + /** on next update, set color to the color at the provided position in the colorspace */ + void get_pixel(ColorSpace::Type colorspace, const Vector& position, const std::shared_ptr& color_out); void clear(); void render(Renderer& renderer, Filter filter); @@ -98,6 +100,7 @@ class Canvas final DrawingContext& m_context; obstack& m_obst; std::vector m_requests; + std::unordered_map m_colorspaces; private: Canvas(const Canvas&) = delete; diff --git a/src/video/color.cpp b/src/video/color.cpp index 868e7c59d8f..a7191659eb3 100644 --- a/src/video/color.cpp +++ b/src/video/color.cpp @@ -16,7 +16,7 @@ #include "video/color.hpp" -#include +#include "math/util.hpp" const Color Color::BLACK(0.0, 0.0, 0.0); const Color Color::RED(1.0, 0.0, 0.0); @@ -40,9 +40,9 @@ Color::Color(float red_, float green_, float blue_, float alpha_) : blue(blue_), alpha(alpha_) { - assert(0 <= red && red <= 1.0f); - assert(0 <= green && green <= 1.0f); - assert(0 <= blue && blue <= 1.0f); + red = math::clamp(red, 0.f, 1.f); + green = math::clamp(green, 0.f, 1.f); + blue = math::clamp(blue, 0.f, 1.f); } Color::Color(const std::vector& vals) : @@ -65,9 +65,10 @@ Color::Color(const std::vector& vals) : alpha = vals[3]; else alpha = 1.0; - assert(0 <= red && red <= 1.0f); - assert(0 <= green && green <= 1.0f); - assert(0 <= blue && blue <= 1.0f); + + red = math::clamp(red, 0.f, 1.f); + green = math::clamp(green, 0.f, 1.f); + blue = math::clamp(blue, 0.f, 1.f); } bool diff --git a/src/video/colorspace.cpp b/src/video/colorspace.cpp new file mode 100644 index 00000000000..ddbbb40b882 --- /dev/null +++ b/src/video/colorspace.cpp @@ -0,0 +1,56 @@ +// SuperTux +// Copyright (C) 2024 Vankata453 +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "video/colorspace.hpp" + +ColorSpace::ColorSpace() : + m_rects(), + m_circles() +{ +} + +void +ColorSpace::add(const Rectf& rect, const Color& color) +{ + m_rects.emplace_back(rect, color); +} + +void +ColorSpace::add(const Circle& circle, const Color& color) +{ + m_circles.emplace_back(circle, color); +} + +Color +ColorSpace::get_pixel(const Vector& point) const +{ + Color result(0.f, 0.f, 0.f); + + for (const auto& rect : m_rects) + { + if (rect.shape.contains(point)) + result = (result + rect.color).validate(); // Additive blending + } + for (const auto& circle : m_circles) + { + if (circle.shape.contains(point)) + result = (result + circle.color).validate(); // Additive blending + } + + return result; +} + +/* EOF */ diff --git a/src/video/colorspace.hpp b/src/video/colorspace.hpp new file mode 100644 index 00000000000..e479bf86283 --- /dev/null +++ b/src/video/colorspace.hpp @@ -0,0 +1,65 @@ +// SuperTux +// Copyright (C) 2024 Vankata453 +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef HEADER_SUPERTUX_VIDEO_COLORSPACE_HPP +#define HEADER_SUPERTUX_VIDEO_COLORSPACE_HPP + +#include + +#include "math/circle.hpp" +#include "math/rectf.hpp" +#include "video/color.hpp" + +/** A virtual colorspace, consisting of colored shapes, + where the color at a provided point can be gathered deterministically. */ +class ColorSpace final +{ +public: + enum Type + { + NONE, + LIGHTSPRITES /* Colorspace of object light sprites */ + }; + +public: + ColorSpace(); + + void add(const Rectf& rect, const Color& color); + void add(const Circle& circle, const Color& color); + + Color get_pixel(const Vector& point) const; + +private: + template + struct ColoredShape final + { + ColoredShape(const T& shape_, const Color& color_) : + shape(shape_), + color(color_) + {} + + T shape; + Color color; + }; + +private: + std::vector> m_rects; + std::vector> m_circles; +}; + +#endif + +/* EOF */ diff --git a/src/video/drawing_request.hpp b/src/video/drawing_request.hpp index b0227d2571d..60f7f8ee294 100644 --- a/src/video/drawing_request.hpp +++ b/src/video/drawing_request.hpp @@ -25,6 +25,7 @@ #include "math/vector.hpp" #include "video/blend.hpp" #include "video/color.hpp" +#include "video/colorspace.hpp" #include "video/drawing_transform.hpp" #include "video/font.hpp" #include "video/gradient.hpp" @@ -173,12 +174,14 @@ struct GetPixelRequest : public DrawingRequest { GetPixelRequest(const DrawingTransform& transform) : DrawingRequest(transform), + colorspace(ColorSpace::NONE), pos(0.0f, 0.0f), color_ptr() {} RequestType get_type() const override { return RequestType::GETPIXEL; } + ColorSpace::Type colorspace; Vector pos; std::shared_ptr color_ptr; diff --git a/src/video/gl/gl_painter.cpp b/src/video/gl/gl_painter.cpp index 38508b74af7..9f732745a50 100644 --- a/src/video/gl/gl_painter.cpp +++ b/src/video/gl/gl_painter.cpp @@ -471,43 +471,6 @@ GLPainter::clear(const Color& color) assert_gl(); } -void -GLPainter::get_pixel(const GetPixelRequest& request) const -{ - assert_gl(); - - const Rect& rect = m_renderer.get_rect(); - const Size& logical_size = m_renderer.get_logical_size(); - - float x = request.pos.x * static_cast(rect.get_width()) / static_cast(logical_size.width); - float y = request.pos.y * static_cast(rect.get_height()) / static_cast(logical_size.height); - - x += static_cast(rect.left); - y += static_cast(rect.top); - -#if 0 - // #ifndef USE_OPENGLES2 - // - // FIXME: glFenceSync() causes crashes on Intel I965, so disable - // GLPixelRequest for now, it's not yet properly used anyway. - GLPixelRequest pixel_request(1, 1); - pixel_request.request(static_cast(x), static_cast(y)); - - *(request.color_ptr) = pixel_request.get_color(); - -#else - float pixels[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - - // OpenGLES2 does not have PBOs, only GLES3 has. - glReadPixels(static_cast(x), static_cast(y), - 1, 1, GL_RGB, GL_FLOAT, pixels); - - *(request.color_ptr) = Color(pixels[0], pixels[1], pixels[2]); -#endif - - assert_gl(); -} - void GLPainter::set_clip_rect(const Rect& clip_rect) { diff --git a/src/video/gl/gl_painter.hpp b/src/video/gl/gl_painter.hpp index b7f09d2f019..4c0769a4882 100644 --- a/src/video/gl/gl_painter.hpp +++ b/src/video/gl/gl_painter.hpp @@ -38,7 +38,6 @@ class GLPainter final : public Painter virtual void draw_triangle(const TriangleRequest& request) override; virtual void clear(const Color& color) override; - virtual void get_pixel(const GetPixelRequest& request) const override; virtual void set_clip_rect(const Rect& rect) override; virtual void clear_clip_rect() override; diff --git a/src/video/null/null_painter.cpp b/src/video/null/null_painter.cpp index 608405925ef..80b5e0d2be1 100644 --- a/src/video/null/null_painter.cpp +++ b/src/video/null/null_painter.cpp @@ -70,12 +70,6 @@ NullPainter::clear(const Color& color) log_info << "NullPainter::clear()" << std::endl; } -void -NullPainter::get_pixel(const GetPixelRequest& request) const -{ - log_info << "NullPainter::get_pixel()" << std::endl; -} - void NullPainter::set_clip_rect(const Rect& rect) { diff --git a/src/video/null/null_painter.hpp b/src/video/null/null_painter.hpp index 27ce274e7ab..4e3303d52e2 100644 --- a/src/video/null/null_painter.hpp +++ b/src/video/null/null_painter.hpp @@ -35,7 +35,6 @@ class NullPainter : public Painter virtual void draw_triangle(const TriangleRequest& request) override; virtual void clear(const Color& color) override; - virtual void get_pixel(const GetPixelRequest& request) const override; virtual void set_clip_rect(const Rect& rect) override; virtual void clear_clip_rect() override; diff --git a/src/video/painter.hpp b/src/video/painter.hpp index 244c4b53597..c7bc2eea783 100644 --- a/src/video/painter.hpp +++ b/src/video/painter.hpp @@ -47,7 +47,6 @@ class Painter virtual void draw_triangle(const TriangleRequest& request) = 0; virtual void clear(const Color& color) = 0; - virtual void get_pixel(const GetPixelRequest& request) const = 0; virtual void set_clip_rect(const Rect& rect) = 0; virtual void clear_clip_rect() = 0; diff --git a/src/video/sdl/sdl_painter.cpp b/src/video/sdl/sdl_painter.cpp index 3797f3137af..2c7ccdcfd21 100644 --- a/src/video/sdl/sdl_painter.cpp +++ b/src/video/sdl/sdl_painter.cpp @@ -613,29 +613,4 @@ SDLPainter::clear_clip_rect() } } -void -SDLPainter::get_pixel(const GetPixelRequest& request) const -{ - const Rect& rect = m_renderer.get_rect(); - const Size& logical_size = m_renderer.get_logical_size(); - - SDL_Rect srcrect; - srcrect.x = rect.left + static_cast(request.pos.x * static_cast(rect.get_width()) / static_cast(logical_size.width)); - srcrect.y = rect.top + static_cast(request.pos.y * static_cast(rect.get_height()) / static_cast(logical_size.height)); - srcrect.w = 1; - srcrect.h = 1; - - Uint8 pixel[4]; - int ret = SDL_RenderReadPixels(m_sdl_renderer, &srcrect, - SDL_PIXELFORMAT_RGB888, - pixel, - 1); - if (ret != 0) - { - log_warning << "failed to read pixels: " << SDL_GetError() << std::endl; - } - - *(request.color_ptr) = Color::from_rgb888(pixel[2], pixel[1], pixel[0]); -} - /* EOF */ diff --git a/src/video/sdl/sdl_painter.hpp b/src/video/sdl/sdl_painter.hpp index 4aae452fa07..b0407d9b5aa 100644 --- a/src/video/sdl/sdl_painter.hpp +++ b/src/video/sdl/sdl_painter.hpp @@ -40,7 +40,6 @@ class SDLPainter final : public Painter virtual void draw_triangle(const TriangleRequest& request) override; virtual void clear(const Color& color) override; - virtual void get_pixel(const GetPixelRequest& request) const override; virtual void set_clip_rect(const Rect& rect) override; virtual void clear_clip_rect() override; diff --git a/src/video/surface.cpp b/src/video/surface.cpp index 2bdb520e835..5f18d84e95d 100644 --- a/src/video/surface.cpp +++ b/src/video/surface.cpp @@ -50,7 +50,14 @@ Surface::from_reader(const ReaderMapping& mapping, const std::optional& re flip ^= flip_v[1] ? VERTICAL_FLIP : NO_FLIP; } - auto surface = new Surface(diffuse_texture, displacement_texture, flip, filename); + std::optional circle_data; + std::optional circle_mapping; + if (mapping.get("circle", circle_mapping)) + { + circle_data = Circle::from_reader(*circle_mapping); + } + + auto surface = new Surface(diffuse_texture, displacement_texture, flip, filename, circle_data); return SurfacePtr(surface); } @@ -89,24 +96,28 @@ Surface::from_file(const std::string& filename, const std::optional& rect) Surface::Surface(const TexturePtr& diffuse_texture, const TexturePtr& displacement_texture, - Flip flip, const std::string& filename) : + Flip flip, const std::string& filename, + const std::optional& circle_data) : m_diffuse_texture(diffuse_texture), m_displacement_texture(displacement_texture), m_region(0, 0, m_diffuse_texture->get_image_width(), m_diffuse_texture->get_image_height()), m_flip(flip), - m_source_filename(filename) + m_source_filename(filename), + m_circle_data(circle_data) { } Surface::Surface(const TexturePtr& diffuse_texture, const TexturePtr& displacement_texture, const Rect& region, - Flip flip, const std::string& filename) : + Flip flip, const std::string& filename, + const std::optional& circle_data) : m_diffuse_texture(diffuse_texture), m_displacement_texture(displacement_texture), m_region(region), m_flip(flip), - m_source_filename(filename) + m_source_filename(filename), + m_circle_data(circle_data) { } diff --git a/src/video/surface.hpp b/src/video/surface.hpp index 0a584fef929..b398edd1672 100644 --- a/src/video/surface.hpp +++ b/src/video/surface.hpp @@ -20,6 +20,7 @@ #include #include +#include "math/circle.hpp" #include "math/rect.hpp" #include "math/vector.hpp" #include "video/flip.hpp" @@ -29,9 +30,13 @@ class ReaderMapping; class SurfaceData; -/** A rectangular image. The class basically holds a reference to a - texture with additional UV coordinates that specify a rectangular - area on this texture */ +/** + A rectangular image. + + This class basically holds a reference to a + texture with additional UV coordinates that specify a rectangular + area on the texture, as well as other additional data. +*/ class Surface final { public: @@ -40,8 +45,10 @@ class Surface final static SurfacePtr from_reader(const ReaderMapping& mapping, const std::optional& rect = std::nullopt, const std::string& filename = ""); private: - Surface(const TexturePtr& diffuse_texture, const TexturePtr& displacement_texture, Flip flip, const std::string& filename = ""); - Surface(const TexturePtr& diffuse_texture, const TexturePtr& displacement_texture, const Rect& region, Flip flip, const std::string& filename = ""); + Surface(const TexturePtr& diffuse_texture, const TexturePtr& displacement_texture, Flip flip, const std::string& filename = "", + const std::optional& circle_data = std::nullopt); + Surface(const TexturePtr& diffuse_texture, const TexturePtr& displacement_texture, const Rect& region, Flip flip, const std::string& filename = "", + const std::optional& circle_data = std::nullopt); public: ~Surface(); @@ -57,6 +64,8 @@ class Surface final Flip get_flip() const { return m_flip; } std::string get_filename() const { return m_source_filename; } + const std::optional& get_circle_data() const { return m_circle_data; } + private: const TexturePtr m_diffuse_texture; const TexturePtr m_displacement_texture; @@ -64,6 +73,8 @@ class Surface final const Flip m_flip; const std::string m_source_filename; + const std::optional m_circle_data; + private: Surface& operator=(const Surface&) = delete; };