Hello,
Had a quick question about RenderTexture, which I'm trying to understand better (off screen drawing).
I have a initialize class where I do this
init() {
...
if (!renderTexture.create(50*32, 50*32)) {
std::cout << "Error: creating renderTexture\n";
}
renderTexture.clear();
for (auto i = 0; i < 50; i++) {
for (auto j = 0; j < 50; j++) {
tiles[j][i].sprite.setPosition(tiles[j][i].pos);
renderTexture.draw(tiles[j][i].sprite);
}
}
renderTexture.display();
}
In my draw function, I have...
void draw(){
const sf::Texture& tex = renderTexture.getTexture();
m_window.clear();
m_window.draw(sf::Sprite(tex));
m_window.draw(m_player);
m_window.display();
}
Now here is the part it is messing up. I added a space key to change tile[10][10] to a red tile and try to update it all and it creates all the tiles (50x50 Map/32x32 Tiles) white (losing the texture) except the 10x10 tile.
void handleInput(){
...
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) {
// drawing uses the same functions
if (!renderTexture.create(50 * 32, 50 * 32)) { // may not need this?
std::cout << "error\n";
}
renderTexture.clear();
for (auto i = 0; i < 50; i++) {
for (auto j = 0; j < 50; j++) {
tiles[j][i].sprite.setPosition(tiles[j][i].pos);
if (i == 10 && j == 10)
tiles[j][i].sprite.setColor(sf::Color::Red);
renderTexture.draw(tiles[j][i].sprite);
}
}
renderTexture.display();
}
}
}
Any help would be appreciated, I'm just trying to learn how to use this more in this example since a few times I feel this concept would have been handy to know. I understand that it would be better to just put a red color sprite on top since this seems to be demanding to constantly run except the initial part.
Okay! :) I recreated the program and I have the same problem.
Game.h
{
struct Tile{ sf::Sprite sprite; sf::Vector2f pos; }
...
private:
sf::RenderTexture m_renderTexture;
std::vector<std::vector<Tile> m_TileMap;
}
Here is the Game.cpp code.
#include "Game.h"
#include <iostream>
const sf::Time Game::TimePerFrame = sf::seconds(1.f / 60.f);
const float TILE_SIZE = 32;
int MAP_WIDTH = 15;
int MAP_HEIGHT = 15;
Game::Game()
: m_window({WINDOW_SIZE.x,WINDOW_SIZE.y},"RenderTexture Example")
{
m_window.setPosition({ m_window.getPosition().x, 0 });
m_window.setVerticalSyncEnabled(true);
MAP_WIDTH = m_window.getSize().x / TILE_SIZE;
MAP_HEIGHT = m_window.getSize().y / TILE_SIZE;
sf::Texture tex;
tex.loadFromFile("media/grass.png");
m_renderTexture.create(MAP_WIDTH * TILE_SIZE, MAP_HEIGHT * TILE_SIZE);
for (auto i = 0; i < MAP_HEIGHT; i++) {
m_tileMap.emplace_back();
for (auto j = 0; j < MAP_WIDTH; j++) {
auto newTile = new Tile;
newTile->sprite.setTexture(tex);
newTile->pos = sf::Vector2f{ j * TILE_SIZE ,i * TILE_SIZE };
m_tileMap[i].push_back(*newTile);
}
}
m_renderTexture.clear();
for (auto& tile : m_tileMap) {
for (auto& it : tile) {
it.sprite.setPosition(it.pos);
m_renderTexture.draw(it.sprite);
}
}
m_renderTexture.display();
}
void Game::run()
{
sf::Clock clock;
sf::Time timeSinceLastUpdate = sf::Time::Zero;
while (m_window.isOpen()) {
const sf::Time elapsedTime = clock.restart();
timeSinceLastUpdate += elapsedTime;
while(timeSinceLastUpdate > TimePerFrame) {
timeSinceLastUpdate -= TimePerFrame;
processEvents();
update(TimePerFrame);
}
render();
}
}
void Game::processEvents()
{
sf::Event event{};
while (m_window.pollEvent(event)) {
switch (event.type) {
case sf::Event::KeyPressed:
handlePlayerInput(event.key.code, true);
if(event.key.code == sf::Keyboard::Escape)
m_window.close();
break;
case sf::Event::KeyReleased:
handlePlayerInput(event.key.code, false);
break;
case sf::Event::Closed:
if(event.type == sf::Event::Closed)
m_window.close();
break;
default: break;
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) {
m_tileMap[5][5].sprite.setColor(sf::Color::Red);
m_renderTexture.clear();
for (auto& tile : m_tileMap) {
for (auto& it : tile) {
it.sprite.setPosition(it.pos);
m_renderTexture.draw(it.sprite);
}
}
m_renderTexture.display();
}
}
void Game::update(sf::Time elapsedTime)
{
}
void Game::render()
{
m_window.clear();
auto& texture = m_renderTexture.getTexture();
m_window.draw(sf::Sprite(texture));
m_window.display();
}
void Game::handlePlayerInput(const sf::Keyboard::Key key, const bool isPressed) {
}
EDIT: And just to tell you the problem again. When I hit space to set tileMap[5][5] sprite color to red. The screen goes all white where the tiles once were and a red square (not tile sprite) shows up.
SOLVED: Okay, I just set the texture to a member variable and added it in the "keypressed(space)" section and I got it to work. I'd like to ask an additional question. Because I realized this worked without ever using m_renderTexture.clear() and m_renderTexture.display(). When exactly would I need to use this? I thought I used it every time I draw to a sf::RenderTexture?