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

Author Topic: Image texture only drawn with some sprites, rest are white.  (Read 1003 times)

0 Members and 1 Guest are viewing this topic.

SenorWilson

  • Newbie
  • *
  • Posts: 2
    • View Profile
Hi All,

I'm trying to draw sprites that use an image as a texture, but when drawing some of the sprites do not draw properly and render as white blocks. Also, sometimes on a RenderWindow.draw an EXC_ARITHMETIC (code EXC_i386_DIV) signal is raised.

Screen shot of a 10x10 grid of sprites drawn with a single source image: http://imgur.com/1CH9u9F

The sf::Image pointer is being stored in an unordered_map (imageMap) which is a game state member variable.

Code for addImageResource:
bool PlayState::addImageResource(const std::string imagePath)
{
    // Check if image already exists
    if (imageMap.find(imagePath) != imageMap.end())
        return true;
   
   
    // Load image from file
    sf::Image *img = new sf::Image();
    if (!img->loadFromFile(imagePath))
        return false;
   
    // Insert pointer and return insert success
    return imageMap.insert(std::make_pair(imagePath, img)).second;
}
 

Code for getResourceImage:
sf::Image * PlayState::getImageResource(const std::string imagePath)
{
    auto it = imageMap.find(imagePath);
    if (it == imageMap.end())
        return nullptr;    // Image not found
    else
        return it->second; // Return value from iterator
}
 

PlayState constructor:

PlayState::PlayState(sf::RenderWindow& window, sf::View& camera) :
    gameWindow (window), gameCamera(camera)
{
    /* Load images */
    if (!addImageResource("Block.png"))
        std::cout << "Failed to load Block.png" << std::endl;
       
    /* Create blocks */
    for (int i = 0; i < 10; i++)
        for (int j = 0; j < 10; j++)
            blocks.emplace_back(sf::Vector2f(i * 30.0f, j * 30.0f), getImageResource("Block.png"));
}
 


Code for Block constructor: (Note: sprite and texture are both member variables of Block)
Block::Block(sf::Vector2f position, sf::Image *image)
{
    if (image != nullptr)
        texture.loadFromImage(*image);
    sprite.setTexture(texture, true);
    sprite.setPosition(position);
}
 

Draw method (also the code where EXC_ARITHMETIC comes from):
void Block::draw(sf::RenderWindow& window)
{
    window.draw(sprite);
}
 

I've made sure that every Block is getting the correct pointer to the image, and the Image is not deleted until a cleanup method is called for the game state. I'm not sure what would cause these issues but any help would be appreciated.

Thanks
« Last Edit: May 20, 2014, 08:00:38 am by SenorWilson »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10990
    • View Profile
    • development blog
    • Email
Re: Image texture only drawn with some sprites, rest are white.
« Reply #1 on: May 20, 2014, 09:05:05 am »
What's your system spec (CPU/GPU/OS)?
Is your GPU driver uptodate?

You should not manually manage the memory of the image, instead you should use RAII (read this on why), shouldn't be hard to change it, you'll just have to store smart pointers instead of raw pointers.

I'd suggest you use & store textures directly instead of the images, unless you have a very specific use case for images itself. As such the textures would be stored in the map and the players would only get a reference to them.

For the errors you see, I don't see anything at a first glimpse that would cause them. EXC_i386_DIV means that there's somewhere a division by zero. So the only thing I could think of is that the pointer gets somehow invalidated, but you'll have to debug it yourself. Just track the pointers and when it crashes provide the backtrace.
« Last Edit: May 20, 2014, 11:15:59 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

SenorWilson

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Image texture only drawn with some sprites, rest are white.
« Reply #2 on: May 20, 2014, 09:30:01 am »
Quote
What's your system spec (CPU/GPU/OS)?
Is your GPU driver uptodate?

OS:   OS X 10.9.2
CPU: Intel Core i7 2.66 Ghz
GPU: NVIDIA GeForce GT 330M 512 MB

Quote
You should not manually manage the memory of the image, instead you should use RAII (read this on why), shouldn't be hard to change it, you'll just have to store smart pointers instead of raw pointers.

Just started with C++ and SFML a few days ago, but have background with C and various object oriented languages, but haven't got around to reading about smart pointers. Thanks for the article!

Quote
I'd suggest you use & store textures directly instead of the images, unless you have a very specific use case for images itself. As such the textures would be stored in the map and the players would only get a reference to them.

Sounds like a good idea.

Quote
For the errors you see, I don't see anything at a first glimpse that would cause the. EXC_i386_DIV means that there's somewhere a division by zero. So the only thing I could think of is that the pointer gets somehow invalidated, but you'll have to debug it yourself. Just track the pointers and when it crashes provide the backtrace.

Will do. I'm guessing it has to do with this image stuff but that is just speculation.

Thanks for the advice.
« Last Edit: May 20, 2014, 09:50:49 am by SenorWilson »