[2.6.1] Drawing to RenderTexture "fails" after Texture copied from (Windows)
frayien opened this issue ยท 3 comments
Prerequisite Checklist
- I searched for existing issues to prevent duplicates
- I searched for existing discussions on the forum to prevent duplicates
- I am here to report an issue and not to just ask a question or look for help (use the forum or Discord instead)
Describe your issue here
When you take the Texture of a RenderTexture by copy, subsequent draw to the RenderTexture will result in no color (black).
basic example is Code (1),
notice the copy sf::Texture tex = rtex.getTexture();
It is worth noting that the first frame ever is rendered correctly.
(The same happen if you take the code example from sf::RenderTexture Class Reference and replace sf::Sprite sprite(texture.getTexture());
with sf::Texture tex = texture.getTexture(); sf::Sprite sprite(tex);
)
Due to how sf::RenderTexture Class Reference is ilustrated, Code (1) should be expected to work.
Observations :
- Works on Ubuntu 22.04 LTS
- Code (2) taking Texture by reference works.
- not calling
win.draw(sprite)
make it work (usingtex.copyToImage().saveToFile("tmp/fig" + std::to_string(i++) + ".png");
to see the texture content)
I messed around with setActive
to try some things, but honestly I dont really know how OpenGL contexts work, and to cite the doc "you shouldn't care about it if you're not doing direct OpenGL stuff" but hey, it also states "Only one context can be current in a thread".
- Code (3) calling setActive everywhere make it work.
- Code (4) not calling
window.setActive(false)
make it not work. (which is weird because "Activating a render target will automatically deactivate the previously active context (if any)")
Your Environment
- OS / distro / window manager: Windows 10 22H2
- GPU : AMD Radeon RX Vega 64; pilot version : 23.10.23.02-230720a-394441C-AMD-Software-Adrenalin-Edition; Windows AMD pilot version : 31.0.21023.2012; OpenGL API Version 4.6; OpenGL Driver Version 23.07.230531_53c0013
- SFML version: 2.6.1
- Compiler / toolchain: cmake 3.27.6 gcc 13.0.1 x86_64-w64-mingw32 (mingw 64) / MSVC 19.29.30145.0
- Special compiler / CMake flags: (SFML built with FetchContent)
- set(CMAKE_CXX_STANDARD 23)
- set(CMAKE_CXX_EXTENSIONS OFF)
- set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
- set(CMAKE_CXX_FLAGS "-Wall -Wextra")
- set(CMAKE_CXX_FLAGS_DEBUG "-Og -g")
- set(CMAKE_CXX_FLAGS_RELEASE "-O3 -g1")
- set(BUILD_SHARED_LIBS OFF)
- set(SFML_BUILD_EXAMPLES OFF)
- set(SFML_BUILD_DOC OFF)
- set(SFML_BUILD_NETWORK OFF)
- set(SFML_BUILD_AUDIO ON)
- set(SFML_BUILD_GRAPHICS ON)
- set(SFML_BUILD_WINDOW ON)
- target_link_libraries(${PROJECT_NAME} sfml-graphics sfml-window sfml-system sfml-audio)
Steps to reproduce
- Draw to the RenderTexture
- Take the result Texture by copy
- Assign it to a Sprite
- Draw it to the RenderWindow
- Problem does not happen if Texture is taken by reference !
- Problem does not happen if Sprite is not drawn to the RenderWindow ! (Texture content seen with
tex.copyToImage().saveToFile("tmp/fig" + std::to_string(i++) + ".png");
)
cmake_minimum_required(VERSION 3.21.0)
include(FetchContent)
project(Demo)
### CMake config ###
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
message(STATUS "GCC detected, adding compile flags")
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -g1")
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
### Dependency declaration ###
FetchContent_Declare(
sfml
GIT_REPOSITORY "https://github.com/SFML/SFML.git"
GIT_TAG 2.6.1
)
### Dependency population ###
set(BUILD_SHARED_LIBS OFF)
# sfml
set(SFML_BUILD_EXAMPLES OFF)
set(SFML_BUILD_DOC OFF)
set(SFML_BUILD_NETWORK OFF)
set(SFML_BUILD_AUDIO ON)
set(SFML_BUILD_GRAPHICS ON)
set(SFML_BUILD_WINDOW ON)
# !sfml
FetchContent_MakeAvailable(sfml)
set(SRCS ${CMAKE_CURRENT_LIST_DIR}/test.cpp)
add_executable(${PROJECT_NAME} ${SRCS})
target_link_libraries(
${PROJECT_NAME}
sfml-graphics
sfml-window
sfml-system
sfml-audio
)
Code (1)
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow win(sf::VideoMode(640, 480), "Title");
sf::RenderTexture rtex;
rtex.create(50,50);
sf::CircleShape shape(25);
shape.setFillColor(sf::Color::Red);
while(win.isOpen())
{
// render texture
rtex.clear(sf::Color(0x00000000));
rtex.draw(shape);
rtex.display();
// render window
win.clear(sf::Color(0x1a5e21FF));
sf::Texture tex = rtex.getTexture();
sf::Sprite sprite(tex);
win.draw(sprite);
win.display();
sf::Event event;
while(win.pollEvent(event))
{
if(event.type == sf::Event::Closed)
{
win.close();
}
}
}
}
Code (2)
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow win(sf::VideoMode(640, 480), "Title");
sf::RenderTexture rtex;
rtex.create(50,50);
sf::CircleShape shape(25);
shape.setFillColor(sf::Color::Red);
while(win.isOpen())
{
// render texture
rtex.clear(sf::Color(0x00000000));
rtex.draw(shape);
rtex.display();
// render window
win.clear(sf::Color(0x1a5e21FF));
const sf::Texture & tex = rtex.getTexture(); // <-- here
sf::Sprite sprite(tex);
win.draw(sprite);
win.display();
sf::Event event;
while(win.pollEvent(event))
{
if(event.type == sf::Event::Closed)
{
win.close();
}
}
}
}
Code (3)
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow win(sf::VideoMode(640, 480), "Title");
sf::RenderTexture rtex;
rtex.create(50,50);
sf::CircleShape shape(25);
shape.setFillColor(sf::Color::Red);
while(win.isOpen())
{
rtex.setActive(true); // <-- here
// render texture
rtex.clear(sf::Color(0x00000000));
rtex.draw(shape);
rtex.display();
rtex.setActive(false); // <-- here
win.setActive(true); // <-- here
// render window
win.clear(sf::Color(0x1a5e21FF));
sf::Texture tex = rtex.getTexture();
sf::Sprite sprite(tex);
win.draw(sprite);
win.display();
win.setActive(false); // <-- here
sf::Event event;
while(win.pollEvent(event))
{
if(event.type == sf::Event::Closed)
{
win.close();
}
}
}
}
Code (4)
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow win(sf::VideoMode(640, 480), "Title");
sf::RenderTexture rtex;
rtex.create(50,50);
sf::CircleShape shape(25);
shape.setFillColor(sf::Color::Red);
while(win.isOpen())
{
rtex.setActive(true); // <-- here
// render texture
rtex.clear(sf::Color(0x00000000));
rtex.draw(shape);
rtex.display();
//rtex.setActive(false); // <-- here
win.setActive(true); // <-- here
// render window
win.clear(sf::Color(0x1a5e21FF));
sf::Texture tex = rtex.getTexture();
sf::Sprite sprite(tex);
win.draw(sprite);
win.display();
//win.setActive(false); // <-- "not" here
sf::Event event;
while(win.pollEvent(event))
{
if(event.type == sf::Event::Closed)
{
win.close();
}
}
}
}
Expected behavior
The shape is drawn on the RenderTexture and the RenderTexture is drawn on the RenderWindow
Actual behavior
Code (1) and (4) : the shaped is drawn without color
Code (2) and (3) : expected behavior
Sooo, writing this whole thing made me realize I did not upgrade by graphic drivers since 6 months ago, so I upgraded them to latest and now I cant reproduce...
Did I just spend my weekend tracking down a hardware specific issue I could have solved by upgrading my drivers from the start ?
Software development is unforgiving ...
Closing this as driver bug ๐