Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - peiha

Pages: [1]
1
Graphics / 2D bitmap font rendering: issue with performance
« on: October 18, 2011, 01:05:30 pm »
Hey all,

The deal is to create sort of roguelike game engine using SFML. the first step is of course loading the bitmap font and printing stuff into screen. The actual printing and showing works fine but the performance is a real issue here.

Would any of you have any idea what's actually the problem in my code? Can it be improved somehow?

There's the link to whole thing, its not big, four files in total
http://www.cs.uta.fi/~a231769/source.zip

Any suggestions are appreciated. I find SFML quite nice compared to SDL and I would love using it on my project.

If people rather look at code in the post, I don't mind putting it up but for now I left it out 'cos even tho there isn't _that_ much stuff there, it still takes some space..


(EDIT)

It seems even drawing rectangle using sf::Shape::Rectangle drops fps from 1000 to 10 :P

anyways: here are parts of the code:

Mainloop:

Code: [Select]

int main()
{

    // Create main window
rl::System::init( 1024, 768 );
rl::System::window = new sf::RenderWindow( sf::VideoMode( 1024, 768 ), "SFML Graphics" );

rl::System::showFps( true );
rl::Surface::root->setFont( "data/fonts/arial8x8.png", 8, 8 );
//rl::System::window->SetFramerateLimit( 60 );

    // Start game loop
    while (rl::System::window->IsOpened())
    {
        // Process events
        sf::Event Event;
        while (rl::System::window->GetEvent(Event))
        {
            // Close window : exit
            if (Event.Type == sf::Event::Closed)
                rl::System::window->Close();
        }

        // Clear screen
        rl::System::window->Clear();

// Print stuff ito surface
for( int y = 0; y < 96; y++ )
for( int x = 0; x < 128; x++ ) {
rl::Surface::root->setChar( x, y, 'M' );
rl::Surface::root->setBack( x, y, sf::Color( 0 + x, 120, 0 + x) );
}

        // Finally, display the rendered frame on screen
        rl::System::flush();
    }

    return EXIT_SUCCESS;
}



Rendering function:
System.cpp
Code: [Select]

void rl::System::flush() {


for( int y = 0; y < rl::Surface::root->sHeight; y++ )
for( int x = 0; x < rl::Surface::root->sWidth; x++ ) {

rl::SurfaceData * dat = rl::Surface::root->content[ x + y * rl::Surface::root->sWidth ];

int X1 = x * rl::Surface::root->cWidth;
int Y1 = y * rl::Surface::root->cHeight;

window->Draw( sf::Shape::Rectangle( X1, Y1, X1 + rl::Surface::root->cWidth, Y1 + rl::Surface::root->cHeight, dat->back ) );

if( dat->c != ' ' ) {

int srcx = (dat->c % 16 )*rl::Surface::root->cWidth;
int srcy = (dat->c / 16 )*rl::Surface::root->cHeight;

dat->sprite.SetSubRect( sf::IntRect( srcx, srcy, srcx + rl::Surface::root->cWidth, srcy + rl::Surface::root->cHeight ) );
dat->sprite.SetX( x * rl::Surface::root->cWidth + 0.5f );
dat->sprite.SetY( y * rl::Surface::root->cHeight + 0.5f );

window->Draw( dat->sprite );
}


}

if( show_fps ) {
static char buf[128];
memset(buf, 0, 128);
sprintf(buf, "FPS: %3.1f", game_fps );
text_fps.SetText( buf );
window->Draw( text_fps );
}

window->Display();

game_fps = 1.f / window->GetFrameTime();
}


Surface code, which holds the information of the font and stuff to draw on the screen

Surface.h
Code: [Select]

#ifndef _RL_SURFACE_H_
#define _RL_SURFACE_H_

#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#include "System.h"

namespace rl {

class System;

class SurfaceData {
public:
SurfaceData() {
this->back = sf::Color( 0, 0, 0 );
this->fore = sf::Color( 255, 255, 255 );
this->c = ' ';
}
sf::Color back;
sf::Color fore;
sf::Sprite sprite;
int c;
};

class Surface {
public:
Surface();
Surface( int width, int height );

void setFont( std::string file, int cWidth, int cHeight );
void setChar( int x, int y, int ascii );
void setBack( int x, int y, sf::Color color );

static Surface * root;
friend class rl::System;

private:
std::vector< SurfaceData*> content;
sf::Image tileset;
sf::Image glyphs[128];

int cWidth;
int cHeight;
int sWidth;
int sHeight;

};


};


#endif


Surface.cpp
Code: [Select]



#include "Surface.h"

#include <iostream>
#include <string>

rl::Surface * rl::Surface::root;

rl::Surface::Surface() {
}

rl::Surface::Surface( int width, int height ) {
this->sWidth = width;
this->sHeight = height;

for( int i = 0; i < width * height; i++ )
this->content.push_back( new SurfaceData() );
}

void rl::Surface::setFont( std::string file, int cWidth, int cHeight ) {
this->cWidth = cWidth;
this->cHeight = cHeight;

if( !this->tileset.LoadFromFile( file.c_str() ) ) {
std::cerr << "Error loading font";
exit( -1 );
}

this->tileset.CreateMaskFromColor( sf::Color( 0, 0, 0 ) );

for( int i = 0; i < this->sWidth * this->sHeight; i++ ) {
this->content[ i ]->sprite.SetImage( this->tileset );
}
}

void rl::Surface::setChar( int x, int y, int ascii ) {
this->content[ x + y * this->sWidth ]->c = ascii;
}

void rl::Surface::setBack( int x, int y, sf::Color color ) {
this->content[ x + y * this->sWidth ]->back = color;
}
[/code]

Pages: [1]
anything