[..] rather than trying to hack randomly in the existing code until it works.
You're right! So, let's go back to your initial suggestion:
You just have to use the same view on both the window and the render-texture, and draw the render-texture on the window with the default view.
I changed to code back to this solution.
(code inside spoiler)
#include <iostream>
#include <SFML/Graphics.hpp>
int main() {
sf::RenderWindow window{{640, 480}, "Test"};
sf::RenderTexture buffer;
buffer.create(window.getSize().x, window.getSize().y);
sf::View view;
view.setSize(sf::Vector2f{window.getSize()});
view.setViewport({0.f, 0.f, 1.f, 1.f});
view.setCenter({320.f, 240.f});
// used to draw enlightened area
sf::VertexArray array{sf::Quads};
array.append({{0.f, 0.f}});
array.append({{640.f, 0.f}});
array.append({{640.f, 480.f}});
array.append({{0.f, 480.f}});
for (std::size_t i = 0u; i < 4u; ++i) {
array[i].texCoords = array[i].position;
array[i].color = sf::Color::Red;
}
sf::Shader shader;
shader.loadFromFile("light.frag", sf::Shader::Fragment);
sf::CircleShape shape(50);
shape.setFillColor(sf::Color::Blue);
shape.setOrigin({50.f, 50.f});
shape.setPosition({320.f, 240.f});
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
}
// handle zoom and moving
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) { view.zoom(1.025f); }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::E)) { view.zoom(0.975f); }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { view.move(0.f, -5.f); }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { view.move(-5.f, 0.f); }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { view.move(0.f, 5.f); }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { view.move(5.f, 0.f); }
// create light texture
buffer.clear({25, 25, 25});
buffer.setView(view);
sf::RenderStates states;
states.blendMode = sf::BlendAdd;
states.shader = &shader;
shader.setParameter("intensity", 255u);
shader.setParameter("center", shape.getPosition());
shader.setParameter("radius", 500.f);
buffer.draw(array, states);
buffer.display();
sf::Sprite sprite{buffer.getTexture()};
// draw scene
window.clear(sf::Color::White);
window.setView(view);
window.draw(shape);
window.setView(window.getDefaultView());
window.draw(sprite, sf::BlendMultiply);
window.display();
}
}
So the render texture is not moving with the view, it stays where it is, because the sprite seems to be located to (0,0) and is drawn with the default view, so it is really drawn to (0,0). Because the customized view is moving, the sprite keeps staying.
From my point of view, this seems correct in the first place. But the customized view shows parts which are not covered by the render texture. That's why I tried to use a different approach: Draw lights onto render texture with default view but move light sources' centers using the customized view's center and size as
shader.setParameter("center", shape.getPosition() - view.getCenter() + view.getSize() / 2.f);
Why is that hacking? It seems to be a clear solution (at least to me): The render texture is moved with the (customized) view by drawing the render texture to the window using this view. This would also move the light source's origins with the "camera", but the shape aren't moving. So adjusting those light's positions seems logical to me.
Of course, that "moving the lights backwards" can be done by the view, when drawing onto the texture using the view. The view should (at least I think so^^) move all it's content backwards, so that moving to right, the objects move to the left - because the screen itself isn't moving on my desk
I think here's the difference: Moving the lights backwards vs. moving the view forwards isn't the same, because moving the lights makes allows the shader to draw the enlightened area from another perspective. Moving the view keeps this static and only moves the view, so everything outside the view remains dark.
What's wrong with my thoughts?
Kind regards
Glocke
/EDIT: I attached two images: Both show the render texture before drawing it (I saved it to file).
First: Texture without moving the view. Second: Texture after moving the view.
The area at the right of the second enlightened area needs to be enlightened too. But this cannot be done so, because the render texture itself is not "drawn differently", it's just moved by the view.
Same with zooming (but I think we should cover moving first)