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

Author Topic: Objects won't draw  (Read 2594 times)

0 Members and 2 Guests are viewing this topic.

hach-que

  • Newbie
  • *
  • Posts: 6
    • MSN Messenger - hachque@roket-productions.com
    • AOL Instant Messenger - hachque
    • Yahoo Instant Messenger - hachque
    • View Profile
    • http://www.roket-enterprises.com/
Objects won't draw
« on: November 14, 2009, 12:55:48 pm »
I have a very strange issue and I fear that it might be because I'm unintentionally breaking something.  It occurs after I resize the window at which point, my object won't draw anymore..

Notes:
This *is* a modified version of SFML.  I added a function to get the position of the window on the screen using the Windows API.  Nothing that should seriously affect anything (since it's just a simply matter of call the WinAPI function and return as sf::Vector2i).

Main Application File:
Code: [Select]
#include <SFML/Graphics.hpp>
#include <cmath>
#include <iostream>
#include "CrossPlatform.h"
#include "irrArray.h"
#include "guiWindowStyler.h"
#include "sysWindowHandler.h"

// Object list
irr::core::array<guiDisplayableObject*> displayableObjects;

int main(int argc, char *argv[])
{
// Create our libraries for use in Fusion
CrossPlatform * crossPlatformOperations = new CrossPlatform();
sysWindowHandler * windowHandler = 0;

// Start up SFML
sf::RenderWindow App(sf::VideoMode(800, 600, 32), "Fusion Desktop Client", sf::Style::None);

// Setup the window handler
windowHandler = new sysWindowHandler(crossPlatformOperations, &App);

// Add the window styler
displayableObjects.push_back(new guiWindowStyler(crossPlatformOperations, &App));

// Define the colour we are going to use.
sf::Color MainBackground = sf::Color(51,51,51);

// Main Application Loop
while (App.IsOpened())
{
// Handle Events
sf::Event Event;
while (App.GetEvent(Event))
{
// Window closed or escape key pressed : exit
if ((Event.Type == sf::Event::Closed) ||
  ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape)))
{
App.Close();
break;
}

// Window movement request
if ((Event.Type == sf::Event::MouseButtonPressed && Event.MouseButton.Button == sf::Mouse::Left) &&
(Event.MouseButton.X >= App.GetWidth()-5 || Event.MouseButton.Y >= App.GetHeight()-5 || Event.MouseButton.X <= 5))
{
windowHandler->HandleMovement(Event);
}
else if ((Event.Type == sf::Event::MouseButtonPressed && Event.MouseButton.Button == sf::Mouse::Left) &&
(Event.MouseButton.Y <= 36))
{
windowHandler->HandleResize(Event);
}
if ((Event.Type == sf::Event::MouseButtonReleased && Event.MouseButton.Button == sf::Mouse::Left))
{
windowHandler->HandleReset();
}
}

if (windowHandler->OnStep())
{
// Returns true if a resize event occurred.
// .. commented out ..
}

// Draw some graphics
for (int i = 0; i < displayableObjects.size(); i++ )
{
std::cout << "Displaying object " << i << "." << std::endl;
displayableObjects[i]->OnDraw();
}

App.Display();
}

return 0;
}


GUI Object which I'm drawing:
Code: [Select]
#include "guiWindowStyler.h"

guiWindowStyler::guiWindowStyler(CrossPlatform * crossPlatformOperations, sf::RenderWindow * application)
{
this->TitleBar = sf::Shape::Rectangle(0, 0, 800, 36, sf::Color(75,75,75));
if (!this->Image.LoadFromFile("images/roketgames/header.png"))
return;
this->TitleBarBackG = sf::Sprite(Image);
this->TitleBarBackG.Resize(800,this->TitleBarBackG.GetSize().y);
if (!this->BGImageTile.LoadFromFile("images/roketgames/bg.png"))
return;

// Set Background Graphic
this->BGImage = sf::Image(crossPlatformOperations->GetScreenDimensions().x,crossPlatformOperations->GetScreenDimensions().y);

int w = 95;
int h = 95;
int mx = crossPlatformOperations->GetScreenDimensions().x;
int my = crossPlatformOperations->GetScreenDimensions().y;
for (int a = 0; a < mx + w; a += w)
{
for (int b = 0; b < my + h; b += h)
{
this->BGImage.Copy(this->BGImageTile,a,b,sf::IntRect(0,0,95,95));
}
}

this->BackG = sf::Sprite(BGImage);

this->BorderLeft = sf::Shape::Rectangle(0, 0, 5, 600, sf::Color(75,75,75));
this->BorderRight = sf::Shape::Rectangle(795, 0, 800, 600, sf::Color(75,75,75));
this->BorderBottom = sf::Shape::Rectangle(0, 595, 800, 600, sf::Color(75,75,75));
this->LineOuterBorderTop = sf::Shape::Line(0, 0, 800, 0, 1, sf::Color(130,130,130));
this->LineOuterBorderLeft = sf::Shape::Line(1, 0, 1, 600, 1, sf::Color(130,130,130));
this->LineOuterBorderBottom = sf::Shape::Line(0, 599, 800, 599, 1, sf::Color(60,60,60));
this->LineOuterBorderRight = sf::Shape::Line(800, 0, 800, 600, 1, sf::Color(60,60,60));

this->application = application;
this->crossPlatformOperations = crossPlatformOperations;
}

guiWindowStyler::~guiWindowStyler(void)
{
}

void guiWindowStyler::OnDraw(void)
{
this->application->Draw(this->BackG);
this->application->Draw(this->BorderLeft);
this->application->Draw(this->BorderRight);
this->application->Draw(this->BorderBottom);
this->application->Draw(this->TitleBar);
this->application->Draw(this->TitleBarBackG);
this->application->Draw(this->LineOuterBorderBottom);
this->application->Draw(this->LineOuterBorderRight);
this->application->Draw(this->LineOuterBorderTop);
this->application->Draw(this->LineOuterBorderLeft);
}

/***** THIS FUNCTION IS NOT CALLED (IS COMMENTED OUT IN MAIN FILE AFTER onStep ******/
void guiWindowStyler::OnResize(void)
{
this->TitleBarBackG.Resize(this->application->GetWidth(),this->TitleBarBackG.GetSize().y);
this->BorderLeft = sf::Shape::Rectangle(0, 0, 5, this->application->GetHeight(), sf::Color(75,75,75));
this->BorderRight = sf::Shape::Rectangle(this->application->GetWidth()-5, 0, this->application->GetWidth(), this->application->GetHeight(), sf::Color(75,75,75));
this->BorderBottom = sf::Shape::Rectangle(0, this->application->GetHeight()-5, this->application->GetWidth(), this->application->GetHeight(), sf::Color(75,75,75));
this->LineOuterBorderTop = sf::Shape::Line(0, 0, this->application->GetWidth(), 0, 1, sf::Color(130,130,130));
this->LineOuterBorderLeft = sf::Shape::Line(1, 0, 1, this->application->GetHeight(), 1, sf::Color(130,130,130));
this->LineOuterBorderBottom = sf::Shape::Line(0, this->application->GetHeight()-1, this->application->GetWidth(), this->application->GetHeight()-1, 1, sf::Color(60,60,60));
this->LineOuterBorderRight = sf::Shape::Line(this->application->GetWidth(), 0, this->application->GetWidth(), this->application->GetHeight(), 1, sf::Color(60,60,60));
}


Window handler:
Code: [Select]
#include "sysWindowHandler.h"

sysWindowHandler::sysWindowHandler(CrossPlatform * crossPlatformOperations, sf::RenderWindow * application)
{
this->WindowMoving = false;
this->WindowResizing = false;
this->WindowResizeXRight = false;
this->WindowResizeXLeft = false;
this->WindowResizeY = false;
this->application = application;
this->crossPlatformOperations = crossPlatformOperations;
}

sysWindowHandler::~sysWindowHandler(void)
{
}

void sysWindowHandler::HandleMovement(sf::Event Event)
{
this->WindowResizing = true;
if (Event.MouseButton.X >= this->application->GetWidth()-5)
this->WindowResizeXRight = true;
if (Event.MouseButton.X <= 5)
{
this->WindowResizeXLeft = true;
this->WindowOriginalPosition = this->application->GetPosition();
}
if (Event.MouseButton.Y >= this->application->GetHeight()-5)
this->WindowResizeY = true;
this->WindowResizingMouseFirstPos = this->crossPlatformOperations->GetCursorPositionInScreenCoords();
this->WindowOriginalSize = sf::Vector2<int>(this->application->GetWidth(),this->application->GetHeight());
}

void sysWindowHandler::HandleResize(sf::Event Event)
{
this->WindowMoving = true;
this->WindowMovingMouseFirstPos = this->crossPlatformOperations->GetCursorPositionInScreenCoords();
this->WindowOriginalPosition = this->application->GetPosition();
}

void sysWindowHandler::HandleReset()
{
this->WindowMoving = false;
this->WindowResizing = false;
this->WindowResizeXLeft = false;
this->WindowResizeXRight = false;
this->WindowResizeY = false;
}

bool sysWindowHandler::OnStep()
{
if (this->WindowMoving == true)
{
sf::Vector2<long> currentMousePosition = this->crossPlatformOperations->GetCursorPositionInScreenCoords();
this->application->SetPosition(this->WindowOriginalPosition.x + (currentMousePosition.x - this->WindowMovingMouseFirstPos.x),this->WindowOriginalPosition.y + (currentMousePosition.y - this->WindowMovingMouseFirstPos.y));
}
if (this->WindowResizing == true)
{
sf::Vector2<long> currentMousePosition = this->crossPlatformOperations->GetCursorPositionInScreenCoords();
unsigned int newX = this->application->GetWidth();
unsigned int newY = this->application->GetHeight();
if (this->WindowResizeXRight)
newX = this->WindowOriginalSize.x + (currentMousePosition.x - this->WindowResizingMouseFirstPos.x);
if (this->WindowResizeY)
newY = this->WindowOriginalSize.y + (currentMousePosition.y - this->WindowResizingMouseFirstPos.y);
if (this->WindowResizeXLeft)
{
newX = this->WindowOriginalSize.x - (currentMousePosition.x - this->WindowResizingMouseFirstPos.x);
this->application->SetPosition(this->WindowOriginalPosition.x + (currentMousePosition.x - this->WindowResizingMouseFirstPos.x),this->WindowOriginalPosition.y);
}
this->application->SetView(sf::View(sf::FloatRect(0,0,newX,newY)));
this->application->SetSize(newX,newY);

return true;
}
return false;
}


On debug build, the object is not drawn.  On release build, the application crashes when I try to resize (hence the reason I think I'm doing something I'm not meant to).  Can anyone help?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Objects won't draw
« Reply #1 on: November 14, 2009, 01:18:44 pm »
Did you run the debugger?

Can you try to extract only the relevant parts of your code, so that it is easier to examine?
Laurent Gomila - SFML developer

hach-que

  • Newbie
  • *
  • Posts: 6
    • MSN Messenger - hachque@roket-productions.com
    • AOL Instant Messenger - hachque
    • Yahoo Instant Messenger - hachque
    • View Profile
    • http://www.roket-enterprises.com/
Objects won't draw
« Reply #2 on: November 15, 2009, 01:38:08 am »
The problem is that I think I'm corrupting memory.  According to the debugger, the App.Draw functions are called on the right RenderWindow instance, it's just that SFML never actually draws what was requested onto the screen.

EDIT: Debugger shows an invalid view region after resizing so I suspect it's:

Code: [Select]
this->application->SetView(sf::View(sf::FloatRect(0,0,newX,newY)));

in the window handler's onStep function.  I have no idea why this would cause a problem (unless the sf::View is deleted after the function ends and the RenderWindow only maintains a reference to it).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Objects won't draw
« Reply #3 on: November 15, 2009, 09:17:42 am »
Quote
unless the sf::View is deleted after the function ends and the RenderWindow only maintains a reference to it

This is exactly what happens ;)
Your view must remain alive as long as it is linked to the render window.
Laurent Gomila - SFML developer