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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Ozcar

Pages: [1]
1
General / Re: Segfault on destructors of SFML objects
« on: November 01, 2013, 02:43:19 pm »
Thank you for your replies. I did find the reason the program kept segfaulting. I compiled my programs using a wrong flag (namely -D_GLIBCXX_DEBUG) which somehow broke up the compiling process. Removing that helped and the code works now as intended. Thank you so much for your time!

2
General / Re: Segfault on destructors of SFML objects
« on: October 31, 2013, 06:45:07 pm »
Sure thing! Letting SFML handle the RAII led me nowhere (which was the reason I implemented it myself in the first place, trying to circumvent the segfault), but here is a small main function which I use for testing. 

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

#include <iostream>
#include <string>
#include <vector>
#include <cmath>

#include "terrain.hh"

void eventHandler(sf::RenderWindow& mainWindow, sf::Sprite& sprite);

int main()
{
    std::srand((unsigned)time(0));
    sf::RenderWindow mainWindow;
    mainWindow.create(sf::VideoMode(800, 800), "Maptest", sf::Style::Resize | sf::Style::Close);
    mainWindow.setFramerateLimit(60);
   
    size_t width = 3200;
    size_t height = 800;
    Terrain newTerrain(width, height, 0.5, 100);
    sf::Texture texture;
    texture.loadFromImage(newTerrain.getMap());
    sf::Sprite sprite;
    sprite.setTexture(texture, true);
   
    while (mainWindow.isOpen()) {
        eventHandler(mainWindow, sprite);
        mainWindow.clear(sf::Color::Black);
        mainWindow.draw(sprite);
        mainWindow.display();
    }

    return 0;
}

void eventHandler(sf::RenderWindow& mainWindow, sf::Sprite& sprite) {
    // Create an event handler that monitors program events
    sf::Event event;
    while (mainWindow.pollEvent(event)) {
        // Create a switch to match these events, eg. user wants to close the window but
        // we want to save the gamestate before quitting or need to run thru some destructors first
        switch (event.type) {
            case sf::Event::Closed:

                mainWindow.close();
                break;
       
            case sf::Event::KeyPressed:
                if (event.key.code == sf::Keyboard::Left) {
                    sprite.move(-10, 0);
                }
                if (event.key.code == sf::Keyboard::Right) {
                    sprite.move(10, 0);
                }
                if (event.key.code == sf::Keyboard::Up) {
                    sprite.move(0, -5);
                }
                if (event.key.code == sf::Keyboard::Down) {
                    sprite.move(0, 5);
                }
               
            default:
                break;
        }
   
    }
}

It is worth noting that the code runs if you comment out the gold patch generation, only crashing on exit in that case. Including it segfaults before the program gets to event handling and you may need to force quit with xkill or the like.

3
General / Segfault on destructors of SFML objects (SOLVED)
« on: October 31, 2013, 06:12:14 pm »
Background

Hello! This is my first post on SFML forums, having been introduced to SFML about a week ago. I am making a 2d worms-like game in which I need a random map generator for two islands. For that I am using SFML::Image and SFML::Shape to dish out the map and add some rocklike structures (actually more like gold patches for the player to mine for money in bedrock). Unfortunately this approach SEGFAULTs at every instance my program tries to destruct an SFML object, ultimately at program exit if not sooner.

The code

Here is my version of the code, the exact place which raises the segfault is the calling of generate for terrainMap in the constructor of Terrain. The program faults between the end of generate and the return to the constructor, but more of that later.

Terrain.cc:
#include <SFML/Graphics.hpp> // SFML image

#include <iostream>     // std::cout
#include <vector>       // vector
#include <cstdlib>      // rand
#include <ctime>        // ctime
#include <cmath>        // cos, sin
#include <algorithm>    // max

#include "terrain.hh"

Terrain::Terrain()
{
        width = 0;
        height = 0;
}

Terrain::Terrain(size_t width, size_t height, double roughness, size_t waterLvl) {
        width = width;
        height = height;
        this->generate(width, height, roughness, waterLvl);
}

Terrain::~Terrain() {
    delete &terrainMap;
}

void Terrain::generate(size_t width, size_t height, double roughness, size_t waterLvl) {
    terrainMap.create(width, height, sf::Color::White);
        double displacementFactor = 1.0 * height / 2;

    // Here editing the amount of initial cells determines the amount of mountains
    // Use [Number you want] + 1
        std::vector<int> heightMap(3, 0);
    // Create waterlevel
        for (size_t x = 0; x < width; x++) {
                for (size_t y = 0; y < waterLvl; y++) {
                        terrainMap.setPixel(x, height - y, sf::Color::Blue);
                }
        }
        // Create sand
        for (int i = 0; i < 6; i++) {
                heightMap = split(heightMap, displacementFactor);
                displacementFactor *= roughness;
        }
        // Draw sand
        double segmentWidth = (width / (2 * heightMap.size()));
        for (size_t x = 0; x < heightMap.size() - 1; x++) {
                double slope = (heightMap[x + 1] - heightMap[x]) / segmentWidth;
                for (size_t xMap = 0; xMap < segmentWidth; xMap++) {
                        for (size_t y = 0; y < heightMap[x] + slope * xMap; y++) {
                                terrainMap.setPixel(width / 4 + x * segmentWidth + xMap, height - y, sf::Color::Green);
                        }
                }
        }
       
        // Clear and initialize the heightMap (again)
        heightMap.clear();
    heightMap.resize(3);
       
        // Create stone
    displacementFactor = 0.7 * height / 2;
   
    for (int i = 0; i < 6; i++) {
        heightMap = split(heightMap, displacementFactor);
        displacementFactor *= roughness;
    }
    // Draw stone
    segmentWidth = (width / (2 * heightMap.size()));
    for (size_t x = 0; x < heightMap.size() - 1; x++) {
        double slope = (heightMap[x + 1] - heightMap[x]) / segmentWidth;
        for (size_t xMap = 0; xMap < segmentWidth; xMap++) {
            for (size_t y = 0; y < heightMap[x] + slope * xMap; y++) {
                terrainMap.setPixel(width / 4 + x * segmentWidth + xMap, height - y, sf::Color::Black);
            }
        }
    }

    // Create gold patches
    size_t xGold, yGold;
    sf::ConvexShape shape;
    shape.setPointCount(6);
    size_t max_patches = size_t(width / 500);
    for(size_t i = 0; i < max_patches; i++){
        xGold = rand() % width; yGold = rand() % height;
        if (getMaterial(xGold, yGold) == Terrain::Material::STONE || getMaterial(xGold, yGold) == Terrain::Material::SAND){             //if random point on map is STONE, make an elliptical gold patch around it
            for (size_t i = 0; i < 6; i++) {
                size_t radius = rand() % 60 + 1;
                shape.setPoint(i, sf::Vector2f( xGold + radius * cos(30*i), yGold + radius * sin(30 * i)));
            }
            for (size_t i = 0; i < shape.getPointCount() - 1; i++) {
                terrainMap.setPixel(shape.getPoint(i).x, shape.getPoint(i).y, sf::Color::Yellow);
            }
        }
    }   <<<<<<<<< GDB OUTPUT PASTED FROM HERE ONWARDS
}

   
// Generate the mountain ridge with midpoint dislocation algorithm
std::vector<int> Terrain::split(std::vector<int> heightMap, double displacementFactor) {
        std::vector<int> newHeightMap(2 * heightMap.size() - 1);
        for (size_t i = 0; i < heightMap.size() - 1; i++) {
                // Calculate midpoint heights
                double midpoint = (heightMap[i] + heightMap[i + 1]) / 2;
        double fRand = (double)rand() / (double)RAND_MAX;
                double displacement = fRand * displacementFactor;
                // Force island shape
                if (i == 0) {
                        if (displacement < 0) {
                displacement *= -1;
                        }
                }
                newHeightMap[2 * i] = heightMap[i];
                newHeightMap[2 * i + 1] = midpoint + displacement;
        }
        return newHeightMap;
}

Terrain::Material Terrain::getMaterial(const size_t x, const size_t y) {
        sf::Color pixel = terrainMap.getPixel(x, y);
    if (pixel == sf::Color::Blue) {
        return WATER;
    }
    if (pixel == sf::Color::Green) {
        return SAND;
    }
    if (pixel == sf::Color::Black) {
        return STONE;
    }
    if (pixel == sf::Color::Yellow) {
        return GOLD;
    }
    return AIR;
}


Terrain.hh:
#ifndef ART_13_TERRAIN
#define ART_13_TERRAIN

#include <SFML/Graphics.hpp> // SFML image
#include <vector> // vector
#include <cstdlib> //rand

   /**
        * This is the class for generating and modifying the terrain image
        * Terrain is constructed from an image representing the different materials.
        * The physics library is used to erode the class after initial generating.
        */


class Terrain {
public:
        enum Material {
                STONE,
                SAND,
                AIR,
                WATER,
        GOLD
    };
        // Constructor
        Terrain();
        // Constructor with parameters
        Terrain(size_t width, size_t height, double roughness, size_t waterLvl);
        // CpyConstructor - DELETED
        Terrain(const Terrain& terrain) = delete;
        // Destructor
        ~Terrain();
        // Generate rough terrain
        void generate(size_t width, size_t height, double roughness, size_t waterLvl);
        // Recursive function for splitting the heightmap
        std::vector<int> split(std::vector<int> heightMap, double roughness);
        // Erode sand until stationary
        void erode();
    // Get the map
    sf::Image getMap() {
        return terrainMap;
    }
        // Get map width
        size_t getWidth() {
                return width;
        }
        // Get map height
        size_t getHeight() {
                return height;
        }
        // Returns the material of given pixel
        Material getMaterial(const size_t x, const size_t y);
   
    sf::Image emptyImage();
private:
        sf::Image terrainMap;
        size_t width;
        size_t height;
};

#endif

 

I compile this with SFML 2.1 and GCC (compile++ is my alias for compiling c++ with std=c++11 and all the warnings enabled)

compile++ main main.cc terrain.cc -I/home/Developement/SMFL2.1 -lsfml-graphics -lsfml-window -lsfml-system
 

GDB

As I said earlier the code seems to segfault just as it returns from the generate-method. This is the GDB output from my code from line 95 (end of generate, marked in the code for your enjoyment) onwards using gdb's step command:

Breakpoint 1, Terrain::generate (this=0x7fffffffe290, width=3200, height=800, roughness=0.5, waterLvl=100) at terrain.cc:95
95          }
(gdb) step
sf::ConvexShape::~ConvexShape (this=0x7fffffffdfc0, __in_chrg=<optimized out>) at /usr/local/include/SFML/Graphics/ConvexShape.hpp:42
42      class SFML_GRAPHICS_API ConvexShape : public Shape
(gdb)
std::__debug::vector<sf::Vector2<float>, std::allocator<sf::Vector2<float> > >::~vector (this=0x7fffffffe150, __in_chrg=<optimized out>)
    at /usr/include/c++/4.7/debug/vector:140
140           ~vector() _GLIBCXX_NOEXCEPT { }
(gdb)
__gnu_debug::_Safe_sequence<std::__debug::vector<sf::Vector2<float>, std::allocator<sf::Vector2<float> > > >::~_Safe_sequence (this=0x7fffffffe168,
    __in_chrg=<optimized out>) at /usr/include/c++/4.7/debug/safe_sequence.h:112
112         class _Safe_sequence : public _Safe_sequence_base
(gdb)
__gnu_debug::_Safe_sequence_base::~_Safe_sequence_base (this=0x7fffffffe168, __in_chrg=<optimized out>) at /usr/include/c++/4.7/debug/safe_base.h:199
199         { this->_M_detach_all(); }
(gdb)

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7527f60 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
 

This seems to me like the destructor for convexShape failed, but how? I am by no means an expert C++ coder and just now working my way out from pure standard libraries but I can't get my head around to which could be the source of this. If this is an error in my understanding of SFML/C++ altogether it would help to get it solved now rather than 2000 more lines into the code. Thank you ever so much for your time!

Pages: [1]