Skip to content

Commit ee41e16

Browse files
committed
Implement new overloads for RenderTexture + remove useless overloads with textureRect for sf::Texture
* sf::RenderTexture is stored flipped upside down. To draw it properly it's necessary to change uv's and add a new overload * Also removed Image/ImageButton overloads for sf::Texture which had textureRect as param - use sf::Sprite for that functionality, they're cheap to construct.
1 parent 757a4c6 commit ee41e16

File tree

3 files changed

+124
-64
lines changed

3 files changed

+124
-64
lines changed

README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,43 @@ The first loaded font is treated as the default one and doesn't need to be pushe
165165
SFML related ImGui overloads / new widgets
166166
---
167167

168-
There are some useful overloads implemented for SFML objects (see header for overloads):
168+
There are some useful overloads implemented for SFML objects (see `imgui-SFML.h` for other overloads):
169+
169170
```cpp
170171
ImGui::Image(const sf::Sprite& sprite);
171172
ImGui::Image(const sf::Texture& texture);
173+
ImGui::Image(const sf::RenderTexture& texture);
174+
172175
ImGui::ImageButton(const sf::Sprite& sprite);
173176
ImGui::ImageButton(const sf::Texture& texture);
177+
ImGui::ImageButton(const sf::RenderTexture& texture);
178+
```
179+
180+
A note about sf::RenderTexture
181+
---
182+
183+
`sf::RenderTexture`'s texture is stored with pixels flipped upside down. To display it properly when drawing `ImGui::Image` or `ImGui::ImageButton`, use overloads for `sf::RenderTexture`:
184+
185+
```cpp
186+
sf::RenderTexture texture;
187+
sf::Sprite sprite(texture.getTexture());
188+
ImGui::Image(texture); // OK
189+
ImGui::Image(sprite); // NOT OK
190+
ImGui::Image(texture.getTexture()); // NOT OK
174191
```
175192

193+
If you want to draw only a part of `sf::RenderTexture` and you're trying to use `sf::Sprite` the texture will be displayed upside-down. To prevent this, you can do this:
194+
195+
```cpp
196+
// make a normal sf::Texture from sf::RenderTexture's flipped texture
197+
sf::Texture texture(renderTexture.getTexture());
198+
199+
sf::Sprite sprite(texture);
200+
ImGui::Image(sprite); // the texture is displayed properly
201+
```
202+
203+
For more notes see [this issue](https://github.com/eliasdaler/imgui-sfml/issues/35).
204+
176205
Mouse cursors
177206
---
178207
You can change your cursors in ImGui like this:

imgui-SFML.cpp

Lines changed: 78 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <SFML/Config.hpp>
55
#include <SFML/Graphics/Color.hpp>
66
#include <SFML/Graphics/RenderTarget.hpp>
7+
#include <SFML/Graphics/RenderTexture.hpp>
78
#include <SFML/Graphics/RenderWindow.hpp>
89
#include <SFML/Graphics/Sprite.hpp>
910
#include <SFML/Graphics/Texture.hpp>
@@ -155,12 +156,6 @@ GLuint convertImTextureIDToGLTextureHandle(ImTextureID textureID);
155156
void RenderDrawLists(
156157
ImDrawData* draw_data); // rendering callback function prototype
157158

158-
// Implementation of ImageButton overload
159-
bool imageButtonImpl(const sf::Texture& texture,
160-
const sf::FloatRect& textureRect, const sf::Vector2f& size,
161-
const int framePadding, const sf::Color& bgColor,
162-
const sf::Color& tintColor);
163-
164159
// Default mapping is XInput gamepad mapping
165160
void initDefaultJoystickMapping();
166161

@@ -549,51 +544,48 @@ void SetLStickYAxis(sf::Joystick::Axis lStickYAxis, bool inverted) {
549544

550545
} // end of namespace SFML
551546

552-
/////////////// Image Overloads
547+
/////////////// Image Overloads for sf::Texture
553548

554549
void Image(const sf::Texture& texture, const sf::Color& tintColor,
555550
const sf::Color& borderColor) {
556-
Image(texture, static_cast<sf::Vector2f>(texture.getSize()), tintColor,
557-
borderColor);
551+
Image(texture, static_cast<sf::Vector2f>(texture.getSize()),
552+
tintColor, borderColor);
558553
}
559554

560555
void Image(const sf::Texture& texture, const sf::Vector2f& size,
561556
const sf::Color& tintColor, const sf::Color& borderColor) {
562557
ImTextureID textureID =
563558
convertGLTextureHandleToImTextureID(texture.getNativeHandle());
564559

565-
ImGui::Image(textureID, ImVec2(size.x,size.y), ImVec2(0, 0), ImVec2(1, 1), toImColor(tintColor),
566-
toImColor(borderColor));
567-
}
568-
569-
void Image(const sf::Texture& texture, const sf::FloatRect& textureRect,
570-
const sf::Color& tintColor, const sf::Color& borderColor) {
571-
Image(
572-
texture,
573-
sf::Vector2f(std::abs(textureRect.width), std::abs(textureRect.height)),
574-
textureRect, tintColor, borderColor);
560+
ImGui::Image(textureID, ImVec2(size.x,size.y),
561+
ImVec2(0, 0), ImVec2(1, 1),
562+
toImColor(tintColor), toImColor(borderColor));
575563
}
576564

577-
void Image(const sf::Texture& texture, const sf::Vector2f& size,
578-
const sf::FloatRect& textureRect, const sf::Color& tintColor,
565+
/////////////// Image Overloads for sf::RenderTexture
566+
void Image(const sf::RenderTexture& texture, const sf::Color& tintColor,
579567
const sf::Color& borderColor) {
580-
sf::Vector2f textureSize = static_cast<sf::Vector2f>(texture.getSize());
581-
ImVec2 uv0(textureRect.left / textureSize.x,
582-
textureRect.top / textureSize.y);
583-
ImVec2 uv1((textureRect.left + textureRect.width) / textureSize.x,
584-
(textureRect.top + textureRect.height) / textureSize.y);
568+
Image(texture, static_cast<sf::Vector2f>(texture.getSize()),
569+
tintColor, borderColor);
570+
}
585571

572+
void Image(const sf::RenderTexture& texture, const sf::Vector2f& size,
573+
const sf::Color& tintColor, const sf::Color& borderColor) {
586574
ImTextureID textureID =
587-
convertGLTextureHandleToImTextureID(texture.getNativeHandle());
588-
ImGui::Image(textureID, ImVec2(size.x, size.y), uv0, uv1, toImColor(tintColor),
589-
toImColor(borderColor));
575+
convertGLTextureHandleToImTextureID(texture.getTexture().getNativeHandle());
576+
577+
ImGui::Image(textureID, ImVec2(size.x,size.y),
578+
ImVec2(0, 1), ImVec2(1, 0), // flipped vertically, because textures in sf::RenderTexture are stored this way
579+
toImColor(tintColor), toImColor(borderColor));
590580
}
591581

582+
/////////////// Image Overloads for sf::Sprite
583+
592584
void Image(const sf::Sprite& sprite, const sf::Color& tintColor,
593585
const sf::Color& borderColor) {
594586
sf::FloatRect bounds = sprite.getGlobalBounds();
595-
Image(sprite, sf::Vector2f(bounds.width, bounds.height), tintColor,
596-
borderColor);
587+
Image(sprite, sf::Vector2f(bounds.width, bounds.height),
588+
tintColor, borderColor);
597589
}
598590

599591
void Image(const sf::Sprite& sprite, const sf::Vector2f& size,
@@ -604,12 +596,22 @@ void Image(const sf::Sprite& sprite, const sf::Vector2f& size,
604596
return;
605597
}
606598

607-
Image(*texturePtr, size,
608-
static_cast<sf::FloatRect>(sprite.getTextureRect()), tintColor,
609-
borderColor);
599+
const sf::Texture& texture = *texturePtr;
600+
sf::Vector2f textureSize = static_cast<sf::Vector2f>(texture.getSize());
601+
const sf::IntRect& textureRect = sprite.getTextureRect();
602+
ImVec2 uv0(textureRect.left / textureSize.x,
603+
textureRect.top / textureSize.y);
604+
ImVec2 uv1((textureRect.left + textureRect.width) / textureSize.x,
605+
(textureRect.top + textureRect.height) / textureSize.y);
606+
607+
ImTextureID textureID =
608+
convertGLTextureHandleToImTextureID(texture.getNativeHandle());
609+
610+
ImGui::Image(textureID, ImVec2(size.x, size.y), uv0, uv1,
611+
toImColor(tintColor), toImColor(borderColor));
610612
}
611613

612-
/////////////// Image Button Overloads
614+
/////////////// Image Button Overloads for sf::Texture
613615

614616
bool ImageButton(const sf::Texture& texture, const int framePadding,
615617
const sf::Color& bgColor, const sf::Color& tintColor) {
@@ -620,12 +622,35 @@ bool ImageButton(const sf::Texture& texture, const int framePadding,
620622
bool ImageButton(const sf::Texture& texture, const sf::Vector2f& size,
621623
const int framePadding, const sf::Color& bgColor,
622624
const sf::Color& tintColor) {
623-
sf::Vector2f textureSize = static_cast<sf::Vector2f>(texture.getSize());
624-
return ::imageButtonImpl(
625-
texture, sf::FloatRect(0.f, 0.f, textureSize.x, textureSize.y), size,
626-
framePadding, bgColor, tintColor);
625+
ImTextureID textureID =
626+
convertGLTextureHandleToImTextureID(texture.getNativeHandle());
627+
628+
return ImGui::ImageButton(textureID, ImVec2(size.x,size.y),
629+
ImVec2(0, 0), ImVec2(1, 1), framePadding,
630+
toImColor(tintColor), toImColor(tintColor));
631+
}
632+
633+
/////////////// Image Button Overloads for sf::RenderTexture
634+
635+
bool ImageButton(const sf::RenderTexture& texture, const int framePadding,
636+
const sf::Color& bgColor, const sf::Color& tintColor) {
637+
return ImageButton(texture, static_cast<sf::Vector2f>(texture.getSize()),
638+
framePadding, bgColor, tintColor);
639+
}
640+
641+
bool ImageButton(const sf::RenderTexture& texture, const sf::Vector2f& size,
642+
const int framePadding, const sf::Color& bgColor,
643+
const sf::Color& tintColor) {
644+
ImTextureID textureID =
645+
convertGLTextureHandleToImTextureID(texture.getTexture().getNativeHandle());
646+
647+
return ImGui::ImageButton(textureID, ImVec2(size.x,size.y),
648+
ImVec2(0, 1), ImVec2(1, 0), // flipped vertically, because textures in sf::RenderTexture are stored this way
649+
framePadding, toImColor(tintColor), toImColor(tintColor));
627650
}
628651

652+
/////////////// Image Button Overloads for sf::Sprite
653+
629654
bool ImageButton(const sf::Sprite& sprite, const int framePadding,
630655
const sf::Color& bgColor, const sf::Color& tintColor) {
631656
sf::FloatRect spriteSize = sprite.getGlobalBounds();
@@ -638,12 +663,23 @@ bool ImageButton(const sf::Sprite& sprite, const sf::Vector2f& size,
638663
const int framePadding, const sf::Color& bgColor,
639664
const sf::Color& tintColor) {
640665
const sf::Texture* texturePtr = sprite.getTexture();
666+
// sprite without texture cannot be drawn
641667
if (!texturePtr) {
642668
return false;
643669
}
644-
return ::imageButtonImpl(
645-
*texturePtr, static_cast<sf::FloatRect>(sprite.getTextureRect()), size,
646-
framePadding, bgColor, tintColor);
670+
671+
const sf::Texture& texture = *texturePtr;
672+
sf::Vector2f textureSize = static_cast<sf::Vector2f>(texture.getSize());
673+
const sf::IntRect& textureRect = sprite.getTextureRect();
674+
ImVec2 uv0(textureRect.left / textureSize.x,
675+
textureRect.top / textureSize.y);
676+
ImVec2 uv1((textureRect.left + textureRect.width) / textureSize.x,
677+
(textureRect.top + textureRect.height) / textureSize.y);
678+
679+
ImTextureID textureID =
680+
convertGLTextureHandleToImTextureID(texture.getNativeHandle());
681+
return ImGui::ImageButton(textureID, ImVec2(size.x,size.y), uv0, uv1, framePadding,
682+
toImColor(bgColor), toImColor(tintColor));
647683
}
648684

649685
/////////////// Draw_list Overloads
@@ -799,23 +835,6 @@ void RenderDrawLists(ImDrawData* draw_data) {
799835
#endif
800836
}
801837

802-
bool imageButtonImpl(const sf::Texture& texture,
803-
const sf::FloatRect& textureRect, const sf::Vector2f& size,
804-
const int framePadding, const sf::Color& bgColor,
805-
const sf::Color& tintColor) {
806-
sf::Vector2f textureSize = static_cast<sf::Vector2f>(texture.getSize());
807-
808-
ImVec2 uv0(textureRect.left / textureSize.x,
809-
textureRect.top / textureSize.y);
810-
ImVec2 uv1((textureRect.left + textureRect.width) / textureSize.x,
811-
(textureRect.top + textureRect.height) / textureSize.y);
812-
813-
ImTextureID textureID =
814-
convertGLTextureHandleToImTextureID(texture.getNativeHandle());
815-
return ImGui::ImageButton(textureID, ImVec2(size.x,size.y), uv0, uv1, framePadding, toImColor(bgColor),
816-
toImColor(tintColor));
817-
}
818-
819838
unsigned int getConnectedJoystickId() {
820839
for (unsigned int i = 0; i < (unsigned int)sf::Joystick::Count; ++i) {
821840
if (sf::Joystick::isConnected(i)) return i;

imgui-SFML.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace sf
1313
{
1414
class Event;
1515
class RenderTarget;
16+
class RenderTexture;
1617
class RenderWindow;
1718
class Sprite;
1819
class Texture;
@@ -55,34 +56,45 @@ namespace ImGui
5556

5657
// custom ImGui widgets for SFML stuff
5758

58-
// Image overloads
59+
// Image overloads for sf::Texture
5960
IMGUI_SFML_API void Image(const sf::Texture& texture,
6061
const sf::Color& tintColor = sf::Color::White,
6162
const sf::Color& borderColor = sf::Color::Transparent);
6263
IMGUI_SFML_API void Image(const sf::Texture& texture, const sf::Vector2f& size,
6364
const sf::Color& tintColor = sf::Color::White,
6465
const sf::Color& borderColor = sf::Color::Transparent);
65-
IMGUI_SFML_API void Image(const sf::Texture& texture, const sf::FloatRect& textureRect,
66+
67+
// Image overloads for sf::RenderTexture
68+
IMGUI_SFML_API void Image(const sf::RenderTexture& texture,
6669
const sf::Color& tintColor = sf::Color::White,
6770
const sf::Color& borderColor = sf::Color::Transparent);
68-
IMGUI_SFML_API void Image(const sf::Texture& texture, const sf::Vector2f& size, const sf::FloatRect& textureRect,
71+
IMGUI_SFML_API void Image(const sf::RenderTexture& texture, const sf::Vector2f& size,
6972
const sf::Color& tintColor = sf::Color::White,
7073
const sf::Color& borderColor = sf::Color::Transparent);
7174

75+
// Image overloads for sf::Sprite
7276
IMGUI_SFML_API void Image(const sf::Sprite& sprite,
7377
const sf::Color& tintColor = sf::Color::White,
7478
const sf::Color& borderColor = sf::Color::Transparent);
7579
IMGUI_SFML_API void Image(const sf::Sprite& sprite, const sf::Vector2f& size,
7680
const sf::Color& tintColor = sf::Color::White,
7781
const sf::Color& borderColor = sf::Color::Transparent);
7882

79-
// ImageButton overloads
83+
// ImageButton overloads for sf::Texture
8084
IMGUI_SFML_API bool ImageButton(const sf::Texture& texture, const int framePadding = -1,
8185
const sf::Color& bgColor = sf::Color::Transparent,
8286
const sf::Color& tintColor = sf::Color::White);
8387
IMGUI_SFML_API bool ImageButton(const sf::Texture& texture, const sf::Vector2f& size, const int framePadding = -1,
8488
const sf::Color& bgColor = sf::Color::Transparent, const sf::Color& tintColor = sf::Color::White);
8589

90+
// ImageButton overloads for sf::RenderTexture
91+
IMGUI_SFML_API bool ImageButton(const sf::RenderTexture& texture, const int framePadding = -1,
92+
const sf::Color& bgColor = sf::Color::Transparent,
93+
const sf::Color& tintColor = sf::Color::White);
94+
IMGUI_SFML_API bool ImageButton(const sf::RenderTexture& texture, const sf::Vector2f& size, const int framePadding = -1,
95+
const sf::Color& bgColor = sf::Color::Transparent, const sf::Color& tintColor = sf::Color::White);
96+
97+
// ImageButton overloads for sf::Sprite
8698
IMGUI_SFML_API bool ImageButton(const sf::Sprite& sprite, const int framePadding = -1,
8799
const sf::Color& bgColor = sf::Color::Transparent,
88100
const sf::Color& tintColor = sf::Color::White);

0 commit comments

Comments
 (0)