How does a change in memory relate to the rendering of something on a window?
The window you see is just the representation of some memory in the GPU. A render texture is basically nothing else than a window that doesn't get draw to the screen, but is only kept in memory.
So when you look at the chain RenderTexture -> Texture -> Window you see the connection between. But it seems like on your GPU textures are handeled oddly and when you actually copy from the render texture into a normal texture, it somehow still links to the render texture. Now when you delete the render texture before drawing it to the screen, the copied texture seems to be also affected by the deletion and thus shows nothing.
What causes what? Is it direct?
Hard to say... It works for FRex on an Intel GPU and for me on an AMD GPU, so it really seems to be a problem with your PC or at least with the graphics card or its driver. (Is the driver up-to-date?)
What happens if you delete the render texture after the application execution? E.g.
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
int main(){
sf::RenderWindow window(sf::VideoMode(400,300), "Placeholder", 7);
sf::Vertex * sh = new sf::Vertex[3];
sh[0] = sf::Vertex(sf::Vector2f(0,64), sf::Color(255,127,64,255));
sh[1] = sf::Vertex(sf::Vector2f(32,0), sf::Color(255,191,127,255));
sh[2] = sf::Vertex(sf::Vector2f(64,64), sf::Color(255,127,64,255));
sf::RenderTexture * shipRTex = new sf::RenderTexture;
if(!shipRTex->create(64,64)){
return -1;
}
shipRTex->clear(sf::Color::Transparent);
shipRTex->draw(sh, 3, sf::Triangles);
shipRTex->setSmooth(false);
shipRTex->display();
sf::Texture shipTex;
if(!shipTex.create(64,64)){
return -1;
}
shipTex = shipRTex->getTexture();
sf::Sprite ship(shipTex);
ship.setColor(sf::Color(255,255,255,255));
ship.setOrigin(32, 32);
ship.setScale(1.f/4.f, 1.f/4.f);
ship.setPosition((float)window.getSize().x/2, (float)window.getSize().y/2);
window.setVerticalSyncEnabled(true);
window.setFramerateLimit(60);
while (window.isOpen()){
sf::Event event;
while (window.pollEvent(event)){
if(event.type == sf::Event::Closed){
window.close();
}
}
window.clear(sf::Color(127,63,31,255));
window.draw(ship);
window.display();
}
delete[] sh;
delete shipRTex; //That pesky line
return 0;
}
Note: The application will have a memory leak, if render texture fails to be created.But as I said the dynamic allocation with new/delete is kind of depreciated in C++. If you don't have to create the render texture on the fly you could just create everything on the applications stack:
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
int main(){
sf::RenderWindow window(sf::VideoMode(400,300), "Placeholder", 7);
sf::Vertex sh[3];
sh[0] = sf::Vertex(sf::Vector2f(0,64), sf::Color(255,127,64,255));
sh[1] = sf::Vertex(sf::Vector2f(32,0), sf::Color(255,191,127,255));
sh[2] = sf::Vertex(sf::Vector2f(64,64), sf::Color(255,127,64,255));
sf::RenderTexture shipRTex;
if(!shipRTex.create(64,64)){
return -1;
}
shipRTex->clear(sf::Color::Transparent);
shipRTex.draw(sh, 3, sf::Triangles);
shipRTex.setSmooth(false);
shipRTex.display();
sf::Texture shipTex;
if(!shipTex.create(64,64)){
return -1;
}
shipTex = shipRTex.getTexture();
sf::Sprite ship(shipTex);
ship.setColor(sf::Color(255,255,255,255));
ship.setOrigin(32, 32);
ship.setScale(1.f/4.f, 1.f/4.f);
ship.setPosition((float)window.getSize().x/2, (float)window.getSize().y/2);
window.setVerticalSyncEnabled(true);
window.setFramerateLimit(60);
while (window.isOpen()){
sf::Event event;
while (window.pollEvent(event)){
if(event.type == sf::Event::Closed){
window.close();
}
}
window.clear(sf::Color(127,63,31,255));
window.draw(ship);
window.display();
}
return 0;
}
Note: Since everything is on the stack, there won't be any memory issue.
Or if you really need dynamic memory, then you should make use of the STL with vector and unique_ptr (or if unnecessary shared_ptr):
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <memory> // unique_ptr
#include <vector>
int main(){
sf::RenderWindow window(sf::VideoMode(400,300), "Placeholder", 7);
std::vector<sf::Vertex> sh(3);
sh[0] = sf::Vertex(sf::Vector2f(0,64), sf::Color(255,127,64,255));
sh[1] = sf::Vertex(sf::Vector2f(32,0), sf::Color(255,191,127,255));
sh[2] = sf::Vertex(sf::Vector2f(64,64), sf::Color(255,127,64,255));
std::unique_ptr<sf::RenderTexture> shipRTex(new sf::RenderTexture);
if(!shipRTex->create(64,64)){
return -1;
}
shipRTex->clear(sf::Color::Transparent);
shipRTex->draw(sh.data(), sh.size(), sf::Triangles);
shipRTex->setSmooth(false);
shipRTex->display();
sf::Texture shipTex;
if(!shipTex.create(64,64)){
return -1;
}
shipTex = shipRTex->getTexture();
sf::Sprite ship(shipTex);
ship.setColor(sf::Color(255,255,255,255));
ship.setOrigin(32, 32);
ship.setScale(1.f/4.f, 1.f/4.f);
ship.setPosition((float)window.getSize().x/2, (float)window.getSize().y/2);
window.setVerticalSyncEnabled(true);
window.setFramerateLimit(60);
while (window.isOpen()){
sf::Event event;
while (window.pollEvent(event)){
if(event.type == sf::Event::Closed){
window.close();
}
}
window.clear(sf::Color(127,63,31,255));
window.draw(ship);
window.display();
}
return 0;
}
Note: Since unique_ptr is an RAII object, the resources will automatically get released when the scope is left.
But I think your idea was to free the memory as soon as possible, thus when the render texture isn't needed anymore. This could also be easily done with smart pointers and some brackets:
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <memory> // unique_ptr
#include <vector>
int main(){
sf::RenderWindow window(sf::VideoMode(400,300), "Placeholder", 7);
sf::Texture shipTex;
if(!shipTex.create(64,64)){
return -1;
}
// RenderTexture scope
{
std::vector<sf::Vertex> sh(3);
sh[0] = sf::Vertex(sf::Vector2f(0,64), sf::Color(255,127,64,255));
sh[1] = sf::Vertex(sf::Vector2f(32,0), sf::Color(255,191,127,255));
sh[2] = sf::Vertex(sf::Vector2f(64,64), sf::Color(255,127,64,255));
std::unique_ptr<sf::RenderTexture> shipRTex(new sf::RenderTexture);
if(!shipRTex->create(64,64)){
return -1;
}
shipRTex->clear(sf::Color::Transparent);
shipRTex->draw(sh.data(), sh.size(), sf::Triangles);
shipRTex->setSmooth(false);
shipRTex->display();
shipTex = shipRTex->getTexture();
}
sf::Sprite ship(shipTex);
ship.setColor(sf::Color(255,255,255,255));
ship.setOrigin(32, 32);
ship.setScale(1.f/4.f, 1.f/4.f);
ship.setPosition((float)window.getSize().x/2, (float)window.getSize().y/2);
window.setVerticalSyncEnabled(true);
window.setFramerateLimit(60);
while (window.isOpen()){
sf::Event event;
while (window.pollEvent(event)){
if(event.type == sf::Event::Closed){
window.close();
}
}
window.clear(sf::Color(127,63,31,255));
window.draw(ship);
window.display();
}
return 0;
}
Would be interesting to see which versions work and which don't.