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

Author Topic: Integer Division by Zero Exception when Drawing Shape?  (Read 4019 times)

0 Members and 1 Guest are viewing this topic.

packetpirate

  • Newbie
  • *
  • Posts: 11
    • View Profile
Integer Division by Zero Exception when Drawing Shape?
« on: November 22, 2013, 07:45:48 am »
I honestly have no idea what I'm doing anymore... I tried making both the texture and shape part of my class so I wouldn't have to create the shape on the fly in each draw() call, which would improve speed, but I can't seem to get it to work. At first, I thought it was the sprite itself not initializing properly once I assign the loaded texture to it, but the debugger seems to point me to the line in which I'm drawing the shape itself, rather than the line on which I draw the sprite. The shape itself hasn't given me problems before, so I don't know... maybe it IS the sprite...... can someone take a look at my class and tell me if I just done goof'd somewhere with the texture and sprite?

Tile.h
#ifndef TILE_H
#define TILE_H

#include <SFML/Graphics.hpp>

enum TileState {
        HIDDEN,
        REVEALED,
        VISIBLE
};

class Tile {
        private:
                float cx;
                float cy;
                sf::RectangleShape shape;
                sf::Texture texture;
                sf::Sprite sprite;

                TileState state;
        public:
                static const float TILE_SIZE;

                Tile();
                Tile(float x, float y);
                Tile(float x, float y, const char * filename);
                virtual ~Tile();

                void ChangeState(TileState newState);
                void Draw(sf::RenderWindow* window);
};

#endif
 

Tile.cpp
#include "Tile.h"
#include <cstdlib>

const float Tile::TILE_SIZE = 64.0f;

Tile::Tile() {
        Tile(0.0f, 0.0f);
}

Tile::Tile(float x, float y) {
        Tile(x, y, NULL);
}

Tile::Tile(float x, float y, const char * filename) {
        this->cx = x;
        this->cy = y;

        this->shape = sf::RectangleShape(sf::Vector2f(Tile::TILE_SIZE, Tile::TILE_SIZE));
        this->shape.setPosition((x - (Tile::TILE_SIZE / 2)), (y - (Tile::TILE_SIZE / 2)));
        this->shape.setFillColor(sf::Color(0, 0, 0, 255));

        if(filename != NULL) {
                // Load the texture.
                if(!this->texture.loadFromFile(filename)) {
                        // There was an error loading the texture...
                        printf("Error loading file: %s", filename);
                } else {
                        this->sprite.setTexture(this->texture);
                        this->sprite.setPosition((this->cx - (Tile::TILE_SIZE / 2)), (this->cy - (Tile::TILE_SIZE / 2)));
                        this->sprite.setScale((Tile::TILE_SIZE / this->texture.getSize().x), (Tile::TILE_SIZE / this->texture.getSize().y));
                }
        }

        this->state = TileState::HIDDEN;
}

Tile::~Tile() {
       
}

void Tile::ChangeState(TileState newState) {
        this->state = newState;
        if(newState == TileState::REVEALED) this->shape.setFillColor(sf::Color(0, 0, 0, 200));
}

void Tile::Draw(sf::RenderWindow* window) {
        if(!this->state == TileState::HIDDEN) {
                window->draw(this->sprite);
                if(this->state == TileState::REVEALED) window->draw(this->shape);
        }
}
 

I really appreciate any help, because C++ really gives me a headache sometimes. No wonder I gave it up for Java two years ago...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Integer Division by Zero Exception when Drawing Shape?
« Reply #1 on: November 22, 2013, 08:15:07 am »
Quote
Tile::Tile() {
    Tile(0.0f, 0.0f);
}

Tile::Tile(float x, float y) {
    Tile(x, y, NULL);
}
You can only call a constructor from another constructor in C++11. If your compiler doesn't support C++11 (or is not configured to use it), you'll end up with uninitialized variables.

Quote
if(!this->state == TileState::HIDDEN)
! has priority over ==, so the correct way to write this statement would be:

if(!(this->state == TileState::HIDDEN))

Or...

if(this->state != TileState::HIDDEN)
Laurent Gomila - SFML developer

packetpirate

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Integer Division by Zero Exception when Drawing Shape?
« Reply #2 on: November 22, 2013, 03:47:57 pm »
Ah, I guess I've been spoiled by Java syntax. And as far as the ! operator, I knew that, but I must have been sleepier than I thought when I wrote that, because that's not the way I usually form expressions. However, I'm still getting the Integer Division by Zero exception even after I made a single constructor with default parameters. The only place I'm dividing at all is when I set the scale of the sprite, but how could the texture be blank if the sprite's information is only set if the texture is loaded properly?

Tile.h
#ifndef TILE_H
#define TILE_H

#include <SFML/Graphics.hpp>

enum TileState {
        HIDDEN,
        REVEALED,
        VISIBLE
};

class Tile {
        private:
                float cx;
                float cy;
                sf::RectangleShape shape;
                sf::Texture texture;
                sf::Sprite sprite;

                TileState state;
        public:
                static const float TILE_SIZE;

                Tile(float x = 0.0f, float y = 0.0f, const char * filename = NULL);
                virtual ~Tile();

                void ChangeState(TileState newState);
                void Draw(sf::RenderWindow* window);
};

#endif
 

Tile.cpp
#include "Tile.h"
#include <cstdlib>

const float Tile::TILE_SIZE = 48.0f;

Tile::Tile(float x, float y, const char * filename) {
        this->cx = x;
        this->cy = y;

        this->shape = sf::RectangleShape(sf::Vector2f(Tile::TILE_SIZE, Tile::TILE_SIZE));
        this->shape.setPosition((x - (Tile::TILE_SIZE / 2)), (y - (Tile::TILE_SIZE / 2)));
        this->shape.setFillColor(sf::Color(0, 0, 0, 255));

        if(filename != NULL) {
                // Load the texture.
                if(!this->texture.loadFromFile(filename)) {
                        // There was an error loading the texture...
                        printf("Error loading file: %s", filename);
                } else {
                        this->sprite.setTexture(this->texture);
                        this->sprite.setPosition((this->cx - (Tile::TILE_SIZE / 2)), (this->cy - (Tile::TILE_SIZE / 2)));
                        this->sprite.setScale((Tile::TILE_SIZE / this->texture.getSize().x), (Tile::TILE_SIZE / this->texture.getSize().y));
                }
        }

        this->state = TileState::HIDDEN;
}

Tile::~Tile() {
       
}

void Tile::ChangeState(TileState newState) {
        this->state = newState;
        if(newState == TileState::REVEALED) this->shape.setFillColor(sf::Color(0, 0, 0, 200));
}

void Tile::Draw(sf::RenderWindow* window) {
        if(this->state != TileState::HIDDEN) {
                window->draw(this->sprite);
                if(this->state == TileState::REVEALED) window->draw(this->shape);
        }
}
 

Also, when I check the variables in the debugger, the texture's size is exactly what it should be... 48... so how could I be getting division by zero?
« Last Edit: November 22, 2013, 04:08:29 pm by packetpirate »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Integer Division by Zero Exception when Drawing Shape?
« Reply #3 on: November 22, 2013, 05:16:24 pm »
Use your debugger, and watch the call stack as well as the value of local variables.
Laurent Gomila - SFML developer

packetpirate

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Integer Division by Zero Exception when Drawing Shape?
« Reply #4 on: November 22, 2013, 05:35:17 pm »
It occurs on the line that draws the shape, which makes no sense, because there's no integer division involved in the creation or modification of the shape... none of the local variables seem to have any suspicious values. If there's something obvious I'm missing, please point it out, because I never seem to get anywhere with the debugger.

EDIT: It doesn't even seem to be the shape, either. I tried commenting out the line that draws the shape, and even tried commenting out the line that sets the scale of the sprite, but the exception still occurs. I noticed, in the few times that the window stayed open long enough, that nothing was "drawn" and I was seeing white squares. Google tells me this is indicative of a problem loading the sprite, but I'm using the same code I was using when I was loading the sprite in every draw() call, with the only difference being that instead of creating a new sprite object every call, the Sprite object is stored in the Tile object and initialized only if there is no problem loading the texture... WHAT IS WRONG?! I'm going insane...
« Last Edit: November 22, 2013, 05:39:03 pm by packetpirate »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
AW: Integer Division by Zero Exception when Drawing Shape?
« Reply #5 on: November 22, 2013, 05:40:33 pm »
It means your texture is corrupted, i.e. it's size is 0, thus an internal call in the texture will try to divide by size and thus by zero.

Do you copy the texture somewhere, for some reason this can corrupt the texture (sometimes).
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

packetpirate

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Integer Division by Zero Exception when Drawing Shape?
« Reply #6 on: November 22, 2013, 05:47:26 pm »
Yes, I copied the texture from another folder to the folder in which it's being loaded from, but like I said, this code was working fine before and loading the image properly... I don't think the image is corrupt. I even have screenshots to prove that I was able to draw it before.

And besides, when looking at the local variables when the debugger comes up, the texture's size variable says 48 for both x and y, which is what they should be...

EDIT: Checked further back in the call stack to see which tile was causing the crash, and when I checked that Tile variable's texture, it had size of 0... so why did it say 48 when it reached the draw call? And how could it be corrupt or loading improperly? I'm doing NOTHING different from before with the exception of the scope of the Sprite variable...
« Last Edit: November 22, 2013, 05:54:06 pm by packetpirate »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
AW: Integer Division by Zero Exception when Drawing Shape?
« Reply #7 on: November 22, 2013, 05:53:38 pm »
I wasn't talking about the image, but about the texture in memory ;)

Well then, make sure you have the debug libs of SFML with debug symbols, then set a break point at the draw call and when it stops step into the function call to determine where the error is within SFML's code.
The only division I know is with the texture size. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

packetpirate

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: AW: Integer Division by Zero Exception when Drawing Shape?
« Reply #8 on: November 22, 2013, 05:55:35 pm »
I wasn't talking about the image, but about the texture in memory ;)

Well then, make sure you have the debug libs of SFML with debug symbols, then set a break point at the draw call and when it stops step into the function call to determine where the error is within SFML's code.
The only division I know is with the texture size. ;)

I just edited my post, but in case you don't see that, I checked further back in the call stack and the texture size for the one that's causing the crash is zero... but how? Like I said, I'm doing NOTHING different from how I was creating the sprite before with the exception of its scope being part of the Tile object, rather than being created with each draw() call.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
AW: Integer Division by Zero Exception when Drawing Shape?
« Reply #9 on: November 22, 2013, 06:06:23 pm »
Maybe a bug. Since it's reproductable you could track the object and go through the code step by step, at best you add the size to the watch list, that way, you'll find out where exactly the size changes. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

packetpirate

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Integer Division by Zero Exception when Drawing Shape?
« Reply #10 on: November 22, 2013, 06:18:15 pm »
I have no idea what to do... and to top it off, when I try to build in release mode, it keeps telling me there are unresolved externals, which leads me to believe that it can't find the libraries... but the release libraries are in the directory I specified and I know I typed them correctly... if it can find the debug libraries, why not the release libraries? I'm using the static libraries........ I can't stand all this linker and building BS.

And looking through the vector of Tiles, some of them seem to have textures with the proper size, and some seem to have numbers specified in e+ notation...

What am I doing wrong?!

packetpirate

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Integer Division by Zero Exception when Drawing Shape?
« Reply #11 on: November 22, 2013, 06:27:54 pm »
Using this code works, by the way, and loads the image just fine with no fuss...

Tile.h
#ifndef TILE_H
#define TILE_H

#include <SFML/Graphics.hpp>

enum TileState {
        HIDDEN,
        REVEALED,
        VISIBLE
};

class Tile {
        private:
                float cx;
                float cy;
                sf::RectangleShape shape;
                sf::Texture texture;
                //sf::Sprite sprite;

                TileState state;
        public:
                static const float TILE_SIZE;

                Tile(float x = 0.0f, float y = 0.0f, const char * filename = NULL);
                virtual ~Tile();

                void ChangeState(TileState newState);
                void Draw(sf::RenderWindow* window);
};

#endif
 

Tile.cpp
#include "Tile.h"
#include <cstdlib>

const float Tile::TILE_SIZE = 48.0f;

Tile::Tile(float x, float y, const char * filename) {
        this->cx = x;
        this->cy = y;

        this->shape = sf::RectangleShape(sf::Vector2f(Tile::TILE_SIZE, Tile::TILE_SIZE));
        this->shape.setPosition((x - (Tile::TILE_SIZE / 2)), (y - (Tile::TILE_SIZE / 2)));
        this->shape.setFillColor(sf::Color(0, 0, 0, 255));

        if(filename != NULL) {
                // Load the texture.
                if(!this->texture.loadFromFile(filename)) {
                        // There was an error loading the texture...
                        printf("Error loading file: %s", filename);
                } /*else {
                        this->sprite.setTexture(this->texture);
                        this->sprite.setPosition((this->cx - (Tile::TILE_SIZE / 2)), (this->cy - (Tile::TILE_SIZE / 2)));
                        this->sprite.setScale((Tile::TILE_SIZE / this->texture.getSize().x), (Tile::TILE_SIZE / this->texture.getSize().y));
                }*/

        }

        this->state = TileState::HIDDEN;
}

Tile::~Tile() {
       
}

void Tile::ChangeState(TileState newState) {
        this->state = newState;
        if(newState == TileState::REVEALED) this->shape.setFillColor(sf::Color(0, 0, 0, 200));
}

void Tile::Draw(sf::RenderWindow* window) {
        if(this->state != TileState::HIDDEN) {
                //if(!(&this->sprite == NULL)) window->draw(this->sprite);
                sf::Sprite sprite;
                sprite.setTexture(this->texture);
                sprite.setPosition((this->cx - (Tile::TILE_SIZE / 2)), (this->cy - (Tile::TILE_SIZE / 2)));
                sprite.setScale((Tile::TILE_SIZE / this->texture.getSize().x), (Tile::TILE_SIZE / this->texture.getSize().y));
                window->draw(sprite);
                if(this->state == TileState::REVEALED) window->draw(this->shape);
        }
}
 

So what's the huge difference that's causing the problem?

packetpirate

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Integer Division by Zero Exception when Drawing Shape?
« Reply #12 on: November 22, 2013, 08:40:00 pm »
Ok, so I had the idea that maybe loading the same texture so many times might be causing issues, so I created a texture manager class to load the texture once, and then pass a pointer to it to the Tile class constructor to be used in setting the texture of the sprite in the Tile class, and... IT WORKS! Here's the texture manager class I created.

TextureManager.h
#ifndef TEXTUREMANAGER_H
#define TEXTUREMANAGER_H

#include <SFML/Graphics.hpp>
#include <map>

class TextureManager {
        private:
                std::map<const char *, sf::Texture> textures;

        public:
                TextureManager();
                virtual ~TextureManager();

                void AddTexture(const char * filename, const char * identifier);
                sf::Texture* GetTexture(const char * identifier);
};

#endif
 

TextureManager.cpp
#include "TextureManager.h"
#include <cstdlib>

TextureManager::TextureManager() {

}

TextureManager::~TextureManager() {

}

void TextureManager::AddTexture(const char * filename, const char * identifier) {
        sf::Texture texture;
        if(!texture.loadFromFile(filename)) {
                // There was an error loading the image...
                printf("Error loading image from file: %s", filename);
        } else {
                this->textures[identifier] = texture;
        }
}

sf::Texture* TextureManager::GetTexture(const char * identifier) {
        return &(this->textures[identifier]);
}
 

And then in the Init() function of my SFMLApp class (creates the SFML window and handles the game information), I simply do this...

// Load the textures into the texture manager.
this->textureManager.AddTexture("WoodTexture01.png", "Wood01");
 

And then, to load that texture into the sprite of each tile, I simply pass a pointer to the texture to the Tile class constructor, and do this...

if(texture != NULL) {
        // Set the sprite's texture.
        this->sprite.setTexture(*texture);
        this->sprite.setPosition((this->cx - (Tile::TILE_SIZE / 2)), (this->cy - (Tile::TILE_SIZE / 2)));
        this->sprite.setScale((Tile::TILE_SIZE / texture->getSize().x), (Tile::TILE_SIZE / texture->getSize().y));
}
 

Now... maybe I can finally get on with the rest of my tile engine?

wintertime

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
Re: Integer Division by Zero Exception when Drawing Shape?
« Reply #13 on: November 22, 2013, 11:18:40 pm »
Do not copy the sf::Texture by value into the map! The copy constructor is doing a slow gpu->main memory->gpu copying and the operator= calls it.
If you want to store it by value create it directly inside a container, if you are sure it does not move it. Or add smart pointers to the container.