SFML community forums
Help => Graphics => Topic started by: drcrow on March 05, 2011, 05:51:53 pm
-
I've written a simple sokoban game and I'm trying to draw colored tiles for graphic using sfml.
I think i did everything right, but I'm getting an incredibly slow framerate.
Here's the most importan sfml part of my program:
#ifndef SOKOBANSTATE_H
#define SOKOBANSTATE_H
#include "gamstate.h"
#include "board.h"
class SokobanState: public GameState {
private:
static const int TILESIZE=16;
static const int VIEWWIDTH=Game::WINDOWWIDTH/TILESIZE;
static const int VIEWHEIGHT=Game::WINDOWHEIGHT/TILESIZE;
sf::Sprite mShadow[VIEWWIDTH][VIEWHEIGHT];
sf::View mWorldView;
sf::RenderWindow& window;
sf::View& defaultView;
sf::Image mGroundImage, mBoxImage, mPlayerImage, mWallImage;
sf::Sprite mGroundSprite, mBoxSprite, mTargetSprite, mPlayerSprite, mWallSprite;
Board mBoard;
public:
SokobanState(Game* game):
GameState(game),
mWorldView(sf::FloatRect(0, 0, VIEWWIDTH, VIEWHEIGHT)),
window(pGame->mWindow),
defaultView(window.GetDefaultView())
{
mGroundSprite.Resize(1,1);
mGroundSprite.SetColor(sf::Color(200, 100, 0));
mBoxSprite.Resize(1,1);
mBoxSprite.SetColor(sf::Color(255, 255, 50));
mPlayerSprite.Resize(1,1);
mPlayerSprite.SetColor(sf::Color(255, 0, 0));
mWallSprite.Resize(1,1);
mWallSprite.SetColor(sf::Color(150, 150, 150));
mTargetSprite.Resize(1,1);
mTargetSprite.SetColor(sf::Color(30, 200, 30));
for(int i=0; i<VIEWWIDTH; ++i){
for(int j=0; j<VIEWHEIGHT; ++j){
sf::Sprite* sprite=&mShadow[i][j];
sprite->SetPosition(i, j);
sprite->Resize(1,1);
sprite->SetColor(sf::Color(0, 0, 0, 70+rand()%105));
}
}
}
// virtual void init(){}
// virtual void pause(){}
// virtual void resume(){}
virtual void handleEvent(sf::Event event){
// Escape key pressed
if (event.Type == sf::Event::KeyPressed){
if (event.Key.Code == sf::Key::Escape)
pGame->mStateManager.popState();
else if (event.Key.Code == sf::Key::Up)mBoard.move(Board::UP);
else if (event.Key.Code == sf::Key::Down)mBoard.move(Board::DOWN);
else if (event.Key.Code == sf::Key::Left)mBoard.move(Board::LEFT);
else if (event.Key.Code == sf::Key::Right)mBoard.move(Board::RIGHT);
}
}
// virtual void update(){}
virtual void draw(){
window.SetView(mWorldView);
window.Clear(sf::Color::White);
for(int i=0; i<Board::WORLDWIDTH; ++i){
for(int j=0; j<Board::WORLDHEIGHT; ++j){
sf::Sprite* sprite=&mWallSprite;
char tile=mBoard.getTile(i, j);
if(tile&Board::WALL) 1;
else if(tile&Board::INVALIDTILE)1;
else if(tile&Board::PLAYER) sprite=&mPlayerSprite;
else if(tile&Board::BOX) sprite=&mBoxSprite;
else if(tile&Board::SPACE) sprite=&mGroundSprite;
else if(tile&Board::TARGET) sprite=&mTargetSprite;
else 1;
sprite->SetPosition(i, j);
window.Draw(*sprite);
}
}
}
};
#endif
This draws a 40x25 world on my netbook at ~2-3 fps.
I'm not even using images for rendering so why is this so incredibly slow?
At the menu screen i'm rendering a whole 1024x600 image at 100fps
any ideas?
-
I'd hate to say it, but it's probably the netbook graphics chip that's the problem; especially if it's Intel. They have absolutely abysmal opengl support.
I have an Asus netbook model and all SFML programs are pretty much unusable on it running at the same 2~5 fps.
-
I tried making similar opengl-calls, although not the correct ones, they were approximately as stressfull as they will be if i implement my own opengl drawing methods.
I noticed there's the sf::shape class, is this faster than an sf::sprite with no image?
I could also write my own subclass of sf::Drawable so that i have full control of what is drawn. What's the best approach?
EDIT: Forgot to mention: The opengl calls did almost nothing to the fps.
EDIT2: With nothing I mean that it's still ~70fps
EDIT3:
Okay, i tried subclassing sf::Drawable, but i'm having a bit of trouble. Can anyone tell me what's wrong with the following code?
#ifndef PIXEL_H
#define PIXEL_H
#include <SFML/Graphics.hpp>
#include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Graphics/Drawable.hpp>
class Pixel: public sf::Drawable {
virtual void Render(sf::RenderTarget& Target) const{
sf::Color color = GetColor();
glColor4i(color.r, color.g, color.b, color.a); //using this line gives no tile at all
// glColor3i(0xff, 0xff, 0xff); //when i use this line, i get a black tile
glRecti(0,0,1,1);
}
};
#endif