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

Author Topic: [Solved] SFML 2.0: strange rendering issue.  (Read 2406 times)

0 Members and 1 Guest are viewing this topic.

Mikebissle

  • Newbie
  • *
  • Posts: 10
    • MSN Messenger - freezingblue
    • Yahoo Instant Messenger - mikebissle
    • View Profile
[Solved] SFML 2.0: strange rendering issue.
« on: October 07, 2011, 09:59:06 pm »
I installed SFML 2.0 Wednesday, and I've been tinkering around with it trying to make a basic shooter game.

After I press Start on the title screen, instead of the game screen, a scaled-to-screen and upside down version of the ship sprite is rendered. The weird this is, when I put the game in fullscreen and then back to windowed mode, it displays as it should. Even weirder? The huge sprite is rendered even I comment out the line to draw it in the game loop. o.O

I used to use Allegro and have a very specific way of coding that's probably not really intuitive to anyone but me. It makes me unsure of what code to post, but I'll try.

Graphic structure:
Code: [Select]

#include "Graphic.h"

//For future reference, I typdef-d sf::Image as Bitmap and sf::Texture as Image if anything looks confusing.

Graphic::Graphic(string file) {
  img.LoadFromFile(file);
    img.SetSmooth(false);
    spr.SetTexture(img);  

  x = spr.GetPosition().x;
  y = spr.GetPosition().y;
  w = spr.GetSize().x;  
  h = spr.GetSize().y;
  n = spr.GetRotation();
}

Graphic::Graphic(short w, short h) {
  img.Create(w, h);
  img.SetSmooth(false);
  spr.SetTexture(img);

  x = spr.GetPosition().x;
  y = spr.GetPosition().y;
  w = spr.GetSize().x;  
  h = spr.GetSize().y;
  n = spr.GetRotation();
}

void Graphic::Copy(Canvas &bb) {
  img = bb.buff.GetTexture();
  spr.SetTexture(img);
  Bitmap bmp = img.CopyToImage();
  bmp.SaveToFile("filer.png");
}

void Graphic::Blit(Canvas &buff = *Buffer) {
  buff.Draw(*this);
}

//Irrelevant code...


Canvas/Buffer structure:

Code: [Select]

Canvas *Buffer;

Canvas::Canvas(short ww, short hh) : w(ww), h(hh), x(0), y(0) {  
   buff.Create(w, h);
     buff.Clear(CLEAR);  //sf::Color(255, 0 , 255)
   spr.SetTexture(buff.GetTexture());
}

//Irrelevant code...

void Canvas::Tint(Color cc){
  spr.SetColor(cc);
}

//since it's a template, it's really in the h. file. Posted for clarity.
 template<class Object>
   void Draw(Object &gfx) {
    buff.Draw(gfx.spr); // buff is a sf::RenderTexture
    buff.Display();
  }

void Canvas::Refresh() {
  buff.Display();
  spr.SetTexture(buff.GetTexture());
}

void Canvas::Clear() {
  buff.Clear(CLEAR);  
}


Transition structure:
Code: [Select]

void Fader::Logic() {
  if (start.r > target.r) start.r -= speed;
  else if (start.r < target.r) start.r += speed;

  if (start.g > target.g) start.g -= speed;
  else if (start.g < target.g) start.g += speed;

  if (start.b > target.b) start.b -= speed;
  else if (start.b < target.b) start.b += speed;

  if (start.a > target.a) start.a -= speed;
  else if (start.a < target.a) start.a += speed;

  if (target.r == start.r && target.g == start.g &&
      target.b == start.b && target.a == start.a)
        GoToNext();
}

void Fader::Input() {
}

void Fader::Drawing() {
  Buffer->Clear();
  Copy->Blit();
  Buffer->Tint(start);
 
}

void Fader::GoToNext() {
 
  Buffer->Tint();
  if (next == END)
     Screen->Close();
   else if (next == TITLE)
      Queue = new Title();
   else if (next == ENGINE)
      Queue = new Engine();
  /* delete this;*/
}


Engine class:
Code: [Select]

#include "Engine.h"


Engine::Engine() : Started(no) {
    you.Make("Ship2.png"); //Calls the constructor of the Graphic structure
    you.spr.SetOrigin(14, 14);

}

Engine::~Engine(void) {
}

void Engine::Logic() {
 /*   Bitmap bmp = Screen->Capture();
    bmp.SaveToFile("wtf.png");
 */
}

void Engine::Input() {
 static sf::Clock Timer;

  if (Pressed.Tap(KEY_ENTER)) {
    delete this;
    Queue = new Fader(TITLE);
  }
   
 if (Pressed.Press(KEY_LEFT))
   you.MoveX(-3);
 if (Pressed.Hold(KEY_RIGHT))
  you.MoveX(+3);
  if (Pressed.Hold(KEY_DOWN))
   you.MoveY(+3);
 if (Pressed.Hold(KEY_UP))
   you.Rotate(-5);
 Timer.Reset();
}

void Engine::Drawing() {
  Buffer->Clear();
  Graphic *Sky = new Graphic("Night Sky.png");
    Sky->Blit();
    you.Blit(); //The error draws this even when  commented out! Wut?
  delete Sky;
}


Core class:
Code: [Select]

Irrelevant code...

void Core::Drawing() {  
  Screen->Clear(); // Screen is a sf::RenderWindow*
  Queue->Drawing();
  Buffer->Refresh();
  Screen->Draw(Buffer->spr);
  Screen->Display();
}


Assuming it's not a bug, it has to have something to do with the way I'm clearing and displaying the RenderTexture, likely doing something in the wrong order. Help!  :(

Mikebissle

  • Newbie
  • *
  • Posts: 10
    • MSN Messenger - freezingblue
    • Yahoo Instant Messenger - mikebissle
    • View Profile
[Solved] SFML 2.0: strange rendering issue.
« Reply #1 on: October 08, 2011, 10:08:11 am »
Awesome! I figured out the problem myself! It seems like SFML didn't like when I set the Sprite directly to the texture of the RenderTexture. So basically anywhere in my code that read:


Code: [Select]
spr.SetTexture(buff.GetTexture());

I changed to:

Code: [Select]

Image img = buff.GetTexture();
spr.SetTexture(img);


VoilĂ ! Though I still do not understand why it rendered a sprite whose drawing function had not been called... that was actually borderline creepy.

Lee R

  • Jr. Member
  • **
  • Posts: 86
    • View Profile
[Solved] SFML 2.0: strange rendering issue.
« Reply #2 on: October 08, 2011, 01:46:04 pm »
I suspect your program is exhibiting undefined behaviour, most likely caused by pointer molestation. Seeing a construct such as "delete this" makes me wince slightly.

Mikebissle

  • Newbie
  • *
  • Posts: 10
    • MSN Messenger - freezingblue
    • Yahoo Instant Messenger - mikebissle
    • View Profile
[Solved] SFML 2.0: strange rendering issue.
« Reply #3 on: October 08, 2011, 08:56:45 pm »
Aside from the topic, but you would be right--calling 'delete this' in the transition class when the game was shutting down causes undefined behavior because the Queue pointer it was assigned to was still getting called in the game loop. But that's been resolved, too. :)

Lee R

  • Jr. Member
  • **
  • Posts: 86
    • View Profile
[Solved] SFML 2.0: strange rendering issue.
« Reply #4 on: October 08, 2011, 09:25:09 pm »
Even that wasn't the cause, I still think there is something fishy going on.

It seem likely that you got "lucky" with some code changes which just happen not to trample memory in such an obvious way. If the solution you provided really is what makes the difference between a well defined program and uncalled code randomly executing, then there is something seriously wrong with SFML.