Bonjour,
je suis en train de tester un shader d'éclairage 2D avec SFML. Pour cela, je calcule une lightmap dans une sf::RenderTexture en utilisant le shader, puis je l'affiche dans la fenêtre pour voir sa tête.
Le hic, c'est que lorsque je redimensionne la fenêtre, je perd en FPS, alors que mon shader est sensé être exécuté sur la même résolution, celle de ma sf::RenderTexture...
Je me suis rendu compte que window.display() consommait plus de temps que mon code de rendu, et c'est là que le ralentissement arrive Oo
Quelqu'un aurait-il un avis sur ce souci de performance? Ai-je oublié quelque-chose?
Voici le projet complet (c'est pas très gros) :
http://zylannprods.fr/dl/Light2D.zipOu le code C++ :
#include <SFML/Graphics.hpp>
#include <iostream>
#define SIZE 512
using namespace std;
int main()
{
cout << "Hello world!" << endl;
sf::RenderWindow window(sf::VideoMode(SIZE, SIZE), "Lights");
//window.setFramerateLimit(60);
const sf::View & view = window.getDefaultView();
// Load filter map
sf::Texture filterMap;
if(!filterMap.loadFromFile("filterMap.png"))
{
std::cout << "E: couldn't load filterMap" << std::endl;
return -1;
}
// Create light map
sf::RenderTexture lightMap;
if(!lightMap.create(SIZE,SIZE))
{
std::cout << "E: couldn't create light map" << std::endl;
return -1;
}
lightMap.setView(view);
lightMap.clear(sf::Color::Black);
lightMap.display();
// Load shader
sf::Shader shader;
if(!shader.loadFromFile("light.vert", "light.frag"))
{
std::cout << "E: failed to load shader" << std::endl;
return -1;
}
sf::Vector2f lightPosition;
sf::Sprite lightMapSprite;
lightMap.setSmooth(true);
lightMapSprite.setTexture(lightMap.getTexture());
sf::Sprite filterMapSprite;
filterMap.setSmooth(true);
filterMapSprite.setTexture(filterMap);
shader.setParameter("filterMap", filterMap);
sf::Clock renderClock;
sf::Clock secondClock;
float renderTime = 0;
float flipTime = 0;
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
window.close();
break;
default:
break;
}
}
sf::Vector2i mousePos = sf::Mouse::getPosition(window);
mousePos.y = SIZE - mousePos.y;
lightPosition = 0.9f*lightPosition + 0.1f*window.mapPixelToCoords(mousePos);
//
// Begin render
//
renderClock.restart();
// Calculate lightmap
// Activate shader
sf::Shader::bind(&shader);
shader.setParameter("lightPos", lightPosition);
// Use a white rect covering all the viewport to render the light
sf::RectangleShape fillRect(sf::Vector2f(800,600));
fillRect.setFillColor(sf::Color(255,255,255));
lightMap.draw(fillRect);
lightMap.display();
// Disable shader
sf::Shader::bind(0);
window.clear(sf::Color(8,8,8));
// Display filterMap or lightMap by pressing spacebar
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Space))
{
// Draw filterMap if space is pressed
window.draw(filterMapSprite);
}
else
{
// Draw the lightmap otherwise
window.draw(lightMapSprite);
}
renderTime = renderClock.getElapsedTime().asMilliseconds();
//
// End render, flip window
//
renderClock.restart();
window.display();
flipTime = renderClock.getElapsedTime().asMilliseconds();
if(secondClock.getElapsedTime().asSeconds() >= 1)
{
std::cout << "I: "
"Render time: " << renderTime << "ms, "
"Flip time: " << flipTime << "ms" << std::endl;
secondClock.restart();
}
}
return 0;
}
Autre problème plus accessoire : j'affiche une texture ou la lightmap en fonction de l'appui sur la touche espace, mais dans les deux cas ça affiche toujours la lightmap Oo