I'm working on a sort of ascii canvas for a game. I assumed it would be more efficient to to use a spritesheet of ascii glyphs in cp437 style to draw the ascii art. I needed a way to color the background and foreground of the glyphs so I'm using a fragment shader. Using the shader drops me to 7 fps. Not using the shader, I get about 131.
Am I doing something incorrectly? Is it just too expensive to loop through a vector of strings (and each character in the string), calculate the position of the glyph on the sheet, set the texture position, and then draw the sprite with a shader for each character?
int main() {
sf::RenderWindow renderWindow(sf::VideoMode(1280, 720), "Demo Game");
sf::Texture texture;
texture.loadFromFile("Resources/courier_8x16.png");
texture.setSmooth(false);
sf::Sprite sprite(texture);
sf::Shader shader;
m_shader.loadFromFile("cycle.frag", sf::Shader::Fragment);
m_shader.setUniform("texture", sf::Shader::CurrentTexture);
sf::Clock clock;
sf::Time timeSinceLastUpdate = sf::Time::Zero;
std::vector<std::string> chars = std::vector<std::string>(50, std::string(100, 'X'));
while (renderWindow.isOpen())
{
processEvents();
timeSinceLastUpdate += clock.restart();
while (timeSinceLastUpdate > TimePerFrame)
{
timeSinceLastUpdate -= TimePerFrame;
processEvents();
update(TimePerFrame);
}
//render();
renderWindow.clear();
for (int y = 0; y < chars.size(); y++)
{
for (int x = 0; x < chars[y].size(); x++)
{
//bg and fg colors will be in a 2D vector and used here
shader.setUniform("foreground", sf::Glsl::Vec4(std::Color.White));
shader.setUniform("background", sf::Glsl::Vec4(std::Color.Black));
//uses decimal value of char and dimensions
//to find location of appropriate glyph in sprite sheet
sprite.setTextureRect(sf::IntRect((chars[y][x] % 16) * 8, (chars[y][x] / 16) * 16, 8, 16));
sprite.setPosition(x * 8, y * 16);
renderWindow.draw(sprite, &shader);
}
}
renderWindow.display();
}
}
shader code:
uniform vec4 foreground;
uniform vec4 background;
uniform sampler2D texture;
void main()
{
vec4 pixel = texture2D(texture, gl_TexCoord[0].xy);
if (pixel.r < .1)
pixel = background;
else
pixel = foreground;
gl_FragColor = pixel;
}
Here's the sprite sheet: (all the paragraph symbols are just placeholders)