Array of object C++ - c++

In the image below (Character.cpp), may I know how to create only one Initialize method that can be called to stored many sprites? Do I need to change the Texture1,Sprite,PosX,PosY, etc to array?
The initialize method will be called in my MAIN.cpp. Sorry if the explaination is not good enough. That is just my idea of doing it but will there be a better ones instead of having so many arrays?
void Character::Initialize1(string image1, float PosX1, float PosY1, float CenterX1, float CenterY1)
{
D3DXCreateTextureFromFile(Pull->GETd3ddev(), image.c_str(), &Texture1);
D3DXCreateSprite(Pull->GETd3ddev(), &sprite1);
RECT SpriteRect1;
SpriteRect1.top = 0;
SpriteRect1.bottom = 127;
SpriteRect1.left = 0;
SpriteRect1.right = 128;
SpritePos1 = D3DXVECTOR2(PosX1, PosY1);
SpriteCenter1 = D3DXVECTOR2(CenterX1, CenterY1);
}
void Character::Initialize2(string image2, float PosX2, float PosY2, float CenterX2, float CenterY2)
{
D3DXCreateTextureFromFile(Pull->GETd3ddev(), image.c_str(), &Texture2);
D3DXCreateSprite(Pull->GETd3ddev(), &sprite2);
RECT SpriteRect2;
SpriteRect2.top = 0;
SpriteRect2.bottom = 14;
SpriteRect2.left = 0;
SpriteRect2.right = 14;
SpritePos2 = D3DXVECTOR2(PosX2, PosY2);
SpriteCenter2 = D3DXVECTOR2(CenterX2, CenterY2);
}

Create the necessary initialization method in your sprite class. Then in main() create your sprites and call the appropriate initialization methods. If using lots of Sprites, it will be probably handy to put the created sprites inside a vector in order to have less code for cleanup and probably other things.
A quick example for a Sprite class called SpriteConfig, which only contains position parameters.
#include <iostream>
#include <vector>
using namespace std;
class SpriteConfig {
public:
SpriteConfig() {
top = 0;
bottom = 0;
left = 0;
right = 0;
}
void setPos(float aTop, float aBottom, float aLeft, float aRight) {
mTop = aTop;
mBottom = aBottom;
mLeft = aLeft;
mRight = aRight;
}
private:
// position parameters
float mTop;
float mBottom;
float mLeft;
float mRight;
};
int main()
{
vector<SpriteConfig*> spriteConfigs;
SpriteConfig *sprCfg;
sprCfg = new SpriteConfig();
sprCfg->setPos(1,1,1,1);
spriteConfigs.push_back(sprCfg);
sprCfg = new SpriteConfig();
sprCfg->setPos(2,2,2,2);
spriteConfigs.push_back(sprCfg);
// We now have a number of Sprites
// Add code here to do something with it.
// ...
for(vector<SpriteConfig*>::iterator it = spriteConfigs.begin();
it != spriteConfigs.end();
++it) {
// cleanup
delete (*it);
(*it) = null;
}
return 0;
}

Related

Issues dynamic allocation of classes

I am currently trying to refresh my c++ skills with implementing a snake-game. I have created following class - relevant code snippet:
snake_class.h
#include <string>
#include <vector>
#include <windows.h>
typedef struct coordinates {
int x;
int y;
};
class Snake {
public:
std::vector<coordinates> body;
Snake(const int MAX_HEIGHT, const int MAX_WIDTH, const int initLengthSnake);
void updateSnakeBody(coordinates newDirection, int startingPoint);
};
... and with the corresponding code snippet of the .cpp-file:
snake_class.cpp
#include <vector>
#include "snake_class.h"
Snake::Snake(const int MAX_HEIGHT, const int MAX_WIDTH, const int initLengthSnake) {
for (int snakeLength = 0; snakeLength < initLengthSnake; snakeLength++) {
coordinates currentBodyPoint = { (MAX_WIDTH + initLengthSnake) / 2 - snakeLength, (MAX_HEIGHT) / 2 };
body.push_back(currentBodyPoint);
}
}
void Snake::updateSnakeBody(coordinates newDirection, int startingPoint) {
coordinates currentBodyPoint = body[startingPoint];
body[startingPoint].x += newDirection.x;
body[startingPoint].y += newDirection.y;
if (startingPoint + 1 < body.size()) {
coordinates nextDirection = { currentBodyPoint.x - body[startingPoint + 1].x,
currentBodyPoint.y - body[startingPoint + 1].y };
updateSnakeBody(nextDirection, startingPoint + 1);
}
}
My main-method looks like the following:
bool crashed = false;
int main()
{
//init-part for windows and snake length
const int windowHeight = 20;
const int windowWidth = 25;
const int initSnakeLength = 4;
//init part for snake game to move and some stock variables
coordinates direction = { 1, 0 };
bool initNeeded = false;
//snake init
Snake* snake = new Snake(windowWidth, windowHeight, initSnakeLength);
while (true) {
if (initNeeded) {
crashed = false;
Snake* snake = new Snake(windowWidth, windowHeight, initSnakeLength);
initNeeded = false;
}
if (!crashed) {
(*snake).updateSnakeBody(direction, 0);
crashed = true;
}
else {
delete snake;
initNeeded = true;
}
}
return 0;
}
Build is successfull and the first round of the game works as expected. When I feedback to the game, that I want to play another round, then the new snake class is constructed once again inside the if (initNeeded) {...}-condition. The vector also got the size of 4 after the construction.
But as soon as the program enters the line
(*snake).updateSnakeBody(direction, 0);
I retrieve the error-message vector subsrictp out of range and somehow the vector got the size 0.
I know, that I do not need to dynamically allocate a new class for getting the game to run as intended, but I wanted to try it out in this way.
I cannot really figure out why the new class behaves like that and hope some of you could help me resolving that issue!
Thanks in advance!
You construct two different snakes, one in the main scope, on in the scope of the if statement. Then you create two pointers to these, with the same name. You need to sort this out!
while (true) {
if (initNeeded) {
crashed = false;
Snake* snake = new Snake(windowWidth, windowHeight, initSnakeLength);
initNeeded = false;
}
This snake pointer cannot be accessed from anywhere else. Whatever you are trying to do, this must be wrong.
Perhaps this is what you meant to do
//declare snake pointer
Snake* snake;
while (true) {
if (initNeeded) {
crashed = false;
// set pointer to a new snake
snake = new Snake(windowWidth, windowHeight, initSnakeLength);
initNeeded = false;
}

Pointer address changed - function

I have this code:
class pointLineVCN
{
public:
int v, vc, vn;
pointLineVCN(){};
pointLineVCN(int v, int vc, int vn)
{
this->v = v;
this ->vc = vc;
this->vn = vn;
}
};
pointLineVCN* newPoint;
void Triangulation3D(pointLineVCN* point, short numOfPoints)
{
newPoint = new pointLineVCN[(numOfPoints - 2) * 3];
//Code which changes newPoint
point = newPoint;
cout<<point<<endl;
}
And on the main:
pointLineVCN *vertices = new pointLineVCN[meshes[meshNum].face[*positionSaverFN].numOfPoints];
for (int i = 0; i < meshes[meshNum].face[*positionSaverFN].numOfPoints; i++)
{
sscanf(bufferStr.c_str(), "%i/%i/%i", &faceVec, &faceTex, &faceNor);
vertices[i].v = faceVec - 1;
vertices[i].vc = faceTex - 1;
vertices[i].vn = faceNor - 1;
}
Triangulation3D(vertices, meshes[meshNum].face[*positionSaverFN].numOfPoints);
cout<<vertices<<endl;
The problem is point address changes after Triangulation3D ends. On the cout calls the output is two different addresses.
I have seen another question about this problem and the solution is using pointLineVCN** point but it did not helped.
It's changing because you're changing it:
point = newPoint;
if you don't want to change it, then don't do it.

Rotating sprites relative to it's container has bug while moving

I've been working on making my game engine, and I've been having A LOT of trouble dealing with rotating a sprite relative to a container. (it's used to overlay multiple sprites and be able to easily change their location relative to the center of the object. I need to be able to rotate the object and keep their relative location proper).
I've got it pretty much working. I can rotate the sprite, and all the sprites relative locations stay the same. I can even do this while moving the sprite (it will move AND rotate at the same time). Unless the sprite starts moving again while the sprite is turning. When this happens, the sprite continues to keep it's orientation relative to the container, but will jump back to it's original X/Y location relative to the container.
I stripped down my code to provide a stand alone example program, and the bug persists. To test it, you'll need SFML 2.1, and the following source code
main.cpp
#include<SFML\Graphics.hpp>
#include<vector>
#include"sprite_holder.h"
int main()
{
sf::RenderWindow window(sf::VideoMode(640, 640), "Things don't work so gewd :<");
std::vector<sprite_holder> sprite_holders;
sprite_holders.push_back(sprite_holder(50,50));
sprite_holders.push_back(sprite_holder(150,100));
sprite_holders.push_back(sprite_holder(250,50));
sprite_holders.push_back(sprite_holder(350,50));
sprite_holders.push_back(sprite_holder(450,100));
sprite_holders.push_back(sprite_holder(550,50));
float move1 = -100;
float move2 = -100;
float move3 = -100;
float move4 = -100;
sf::Clock timer;
sprite_holders[3].adjust_child_pos(1,0,20,0);
sprite_holders[4].adjust_child_pos(-1,0,20,0);
sprite_holders[5].adjust_child_pos(-1,0,20,0);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear(sf::Color(255,0,255));
for(unsigned int i = 0; i < sprite_holders.size(); i++) {
sprite_holders[i].update(timer.getElapsedTime().asMilliseconds());
for(unsigned int j = 0; j < sprite_holders[i].sprites.size(); j++) {
window.draw(sprite_holders[i].sprites[j].first);
}
}
// This block of code will make the left-most sprite_holder move up and down constantly
if(sprite_holders[0].transform_complete(POSITION)) {
move1 *= -1;
sprite_holders[0].adjust_pos(0,move1,1200);
}
// This block of code will make the sprite_holder second from the left spin constantly
if(sprite_holders[1].transform_complete(ANGLE)) sprite_holders[1].adjust_angle(360,800);
// This block of code will make the sprite_holder third from the left move up and down AND spin constantly
if(sprite_holders[2].transform_complete(ANGLE)) sprite_holders[2].adjust_angle(360,800);
if(sprite_holders[2].transform_complete(POSITION)) {
move2 *= -1;
sprite_holders[2].adjust_pos(0,move2,1200);
}
// This block of code will make the sprite_holder third from the right move up and down constantly
if(sprite_holders[3].transform_complete(POSITION)) {
move3 *= -1;
sprite_holders[3].adjust_pos(0,move3,1200);
}
// This block of code will make the sprite_holder second from the right spin constantly
if(sprite_holders[4].transform_complete(ANGLE)) sprite_holders[4].adjust_angle(360,800);
// This block of code will make the right-most sprite_holder move up and down AND spin constantly
if(sprite_holders[5].transform_complete(ANGLE)) sprite_holders[5].adjust_angle(360,800);
if(sprite_holders[5].transform_complete(POSITION)) {
move4 *= -1;
sprite_holders[5].adjust_pos(0,move4,1200);
}
window.display();
}
return 0;
}
sprite_holder.cpp
#include "sprite_holder.h"
sprite_holder::sprite_holder(float x, float y)
{
xPos = x;
yPos = y;
cAngle = 0;
lastUpdateTime = -1;
// These are here so I could remove some functions to make tracking the error down much simpler.
// Ignore everything from here till the end of the constructor. It's just loading the sprites and texures
// into memory, initializing the offsets to 0, and setting the initial positions
sf::Sprite sprite1;
sf::Texture texture1;
texture1.loadFromFile("heart_back.png");
textures.push_back(texture1);
sprite1.setTexture(textures.back());
sprite1.setPosition(xPos,yPos);
sf::Vector2u spriteSize = textures.back().getSize();
sprite1.setOrigin(spriteSize.x/2, spriteSize.y/2);
offset offset1;
offset1.xOffset = 0;
offset1.yOffset = 0;
offset1.angleOffset = 0;
offset1.tiltOffset = 0;
sf::Sprite sprite2;
sf::Texture texture2;
texture2.loadFromFile("heart.png");
textures.push_back(texture2);
sprite2.setTexture(textures.back());
sprite2.setPosition(xPos,yPos);
spriteSize = textures.back().getSize();
sprite2.setOrigin(spriteSize.x/2, spriteSize.y/2);
offset offset2;
offset2.xOffset = 0;
offset2.yOffset = 0;
offset2.angleOffset = 0;
offset2.tiltOffset = 0;
sprites.push_back(std::make_pair(sprite1,offset1));
sprites.push_back(std::make_pair(sprite2,offset2));
}
// This is called every frame the window is redrawn.
// (note, the reason I calculate everything based on the timeElapsed since last draw is because
// I don't want the application's speed to be bound to it's framerate)
void sprite_holder::update(int timeElapsed)
{
// Because SFML hates textures for some reason, I'd normally have classes containing the sf::Texture, and keep pointer instances of
// said classes. But since that'd complicate the code a little, I'm just re-loading the image every time I need to draw it. That
// keeps the sprites from being white boxes.
for(unsigned int i = 0; i < sprites.size(); i++) sprites[i].first.setTexture(textures[i]);
int transformToRemove = -1;
for(unsigned int i = 0; i<transforms.size(); i++) {
if(transforms[i].first.startTime == -1) transforms[i].first.startTime = timeElapsed; // This makes anything transforms created before the first update use the proper start time
float percentComplete = (float)(timeElapsed - transforms[i].first.startTime) / transforms[i].first.duration; // this calculates what percentage of the transform's time duration has passed
if(transforms[i].first.type == POSITION) {
if( calculate_transform_pos(percentComplete,i) == true ) transformToRemove = i; // This will calculate the x and y value for the current completion percentage of the transform and remove it if it's 100% complete
render_children_pos(); // This sets all the sf::Sprites to their proper location reletive to the sprite_holder
} else {
// This will calculate the angle value for the current completion percentage of the transform and remove it if it's 100% complete
if( calculate_transform_angle(percentComplete,i) == true ) transformToRemove = i;
render_children_angle(); // This sets all the sf::Sprites to their proper location reletive to the sprite_holder
}
}
lastUpdateTime = timeElapsed;
if(transformToRemove != -1) transforms.erase(transforms.begin()+transformToRemove);
}
// This is a function that will let you know if a given transformation has finished.
// It's used so you can do something as soon as a transformation is complete.
// (an example would be to make a sprite rotate forever by telling it to spin by 360 degrees,
// whenever it's finished spinning by 360 degrees)
bool sprite_holder::transform_complete(transform_type type, int spriteIndex)
{
if(lookup_transform(type,spriteIndex) == -1) return true;
return false;
}
// This will move the sprite_holder's center point by
// the x and y values provided. The argument "duration"
// provides a time in miliseconds the movement will take.
// (note, children will keep their reletive position to the sprite_holder)
void sprite_holder::adjust_pos(float x, float y, int duration)
{
int transformIndex = lookup_transform(POSITION);
if(transformIndex == -1) {
transformIndex = transforms.size();
transform newTransform;
newTransform.type = POSITION;
transforms.push_back(std::make_pair(newTransform,-1));
}
transforms[transformIndex].first.startingA = xPos;
transforms[transformIndex].first.startingB = yPos;
transforms[transformIndex].first.targetA = x + xPos;
transforms[transformIndex].first.targetB = y + yPos;
transforms[transformIndex].first.duration = duration;
transforms[transformIndex].first.startTime = lastUpdateTime;
}
// This will rotate the sprite_holder by the angle
// value provided. The argument "duration" provides
// a time in miliseconds the rotation will take.
// (note, children will keep their reletive position and angle to the sprite_holder)
void sprite_holder::adjust_angle(float angle, int duration)
{
int transformIndex = lookup_transform(ANGLE);
if(transformIndex == -1) {
transformIndex = transforms.size();
transform newTransform;
newTransform.type = ANGLE;
transforms.push_back(std::make_pair(newTransform,-1));
}
transforms[transformIndex].first.startingA = cAngle;
transforms[transformIndex].first.targetA = angle + cAngle;
transforms[transformIndex].first.duration = duration;
transforms[transformIndex].first.startTime = lastUpdateTime;
}
// This will move the sf::Sprite specified by spriteIndex
// by the x and y values provided. This movement will last
// as long as the provided duration argument.
void sprite_holder::adjust_child_pos(int spriteIndex, float x, float y, int duration)
{
if (spriteIndex == -1) spriteIndex = sprites.size()-1;
int transformIndex = lookup_transform(ANGLE,spriteIndex);
if(transformIndex == -1) {
transformIndex = transforms.size();
transform newTransform;
newTransform.type = POSITION;
transforms.push_back(std::make_pair(newTransform,spriteIndex));
}
transforms[transformIndex].first.startingA = sprites[spriteIndex].second.xOffset;
transforms[transformIndex].first.startingB = sprites[spriteIndex].second.yOffset;
transforms[transformIndex].first.targetA = x + sprites[spriteIndex].second.xOffset;
transforms[transformIndex].first.targetB = y + sprites[spriteIndex].second.yOffset;
transforms[transformIndex].first.duration = duration;
transforms[transformIndex].first.startTime = lastUpdateTime;
}
// This will rotate the sf::Sprite specified by spriteIndex
// by the angle value provided. This movement will last
// as long as the provided duration argument.
void sprite_holder::adjust_child_angle(int spriteIndex, float angle, int duration)
{
if (spriteIndex == -1) spriteIndex = sprites.size()-1;
int transformIndex = lookup_transform(ANGLE,spriteIndex);
if(transformIndex == -1) {
transformIndex = transforms.size();
transform newTransform;
newTransform.type = ANGLE;
transforms.push_back(std::make_pair(newTransform,spriteIndex));
}
transforms[transformIndex].first.startingA = sprites[spriteIndex].second.tiltOffset;
transforms[transformIndex].first.targetA = angle + sprites[spriteIndex].second.tiltOffset;
transforms[transformIndex].first.duration = duration;
transforms[transformIndex].first.startTime = lastUpdateTime;
}
// This function is called every time a transform updates either an sf::Sprite or the sprite_holder's position
// note: the reason angleOffset is set here is because the reletive angle to the sprite_holder only changes when it's
// reletive position does. It doesn't matter how much you rotate the sprite_holder, the reletive angle of the sf::Sprite is the same
void sprite_holder::render_children_pos()
{
for(unsigned int i = 0; i < sprites.size(); i++) {
sprites[i].first.setPosition(xPos+sprites[i].second.xOffset, yPos+sprites[i].second.yOffset);
sf::Vector2f spritePos = sprites[i].first.getPosition();
sprites[i].second.angleOffset = atan2(spritePos.y - yPos, spritePos.x - xPos);
}
}
void sprite_holder::render_children_angle()
{
for(unsigned int i = 0; i < sprites.size(); i++) {
sf::Vector2f spritePos = sprites[i].first.getPosition();
float radius = sqrt(pow((xPos - spritePos.x), 2) + pow((yPos - spritePos.y), 2)); // xPos and yPos are the container's x and y position
float angle = sprites[i].second.angleOffset + (cAngle /180*3.14); // cAngle is the container's angle
float newX = xPos + radius * cos(angle);
float newY = yPos + radius * sin(angle);
sprites[i].first.setPosition(newX, newY); // this sets the sprite's x and y coordinates
sprites[i].first.setRotation(cAngle + sprites[i].second.tiltOffset); // this sets the spries rotation around it's local axis. it only affects the sprite's orientation, not position
}
}
// This function returns the index of the transform.
// If you give it a spriteIndex value, it'll look for transforms
// bound to an sf::Sprite contained within the sprite_holder.
// Otherwise, it'll look for transforms bound to the sprite_holder.
int sprite_holder::lookup_transform(transform_type type, int spriteIndex)
{
int result = -1;
for(unsigned int i = 0; i < transforms.size(); i++) {
if(transforms[i].first.type == type) {
if(transforms[i].second == spriteIndex) result = i;
break;
}
}
return result;
}
// This returns the value a given percent between the start and end value
// It's so I can calculate what is 33.2687% between 36.2 and 55, or some other such
// nonesense that occurs when moving things around
float sprite_holder::percentage_along_distance(float startValue,float endValue, float percentComplete)
{
return ((1-percentComplete) * startValue) + (percentComplete * endValue);
}
// This function will set either an sf::Sprite or a sprite_holder (the transform provided by transformIndex tells it which to set)
// to the proper location a given percentage through the transformation.
// For example, if the start point of the transform is 0,0, the end point is 0,10, and we tell it we're 50% done with the transform
// it'll set the proper entity to 0,5
bool sprite_holder::calculate_transform_pos(float percentComplete, int transformIndex) // returns true when the transform is finished
{
float x;
float y;
if(percentComplete < 1) {
x = percentage_along_distance(transforms[transformIndex].first.startingA, transforms[transformIndex].first.targetA, percentComplete);
y = percentage_along_distance(transforms[transformIndex].first.startingB, transforms[transformIndex].first.targetB, percentComplete);
} else {
x = transforms[transformIndex].first.targetA;
y = transforms[transformIndex].first.targetB;
}
if(transforms[transformIndex].second == -1) {
xPos = x;
yPos = y;
} else {
int spriteIndex = transforms[transformIndex].second;
sprites[spriteIndex].second.xOffset = x;
sprites[spriteIndex].second.yOffset = y;
}
if(percentComplete >= 1) return true;
return false;
}
// This does the same as calculate_transform_pos, but with angles. I'm planning on merging the two functions, but haven't yet come up with a good way to go about it.
bool sprite_holder::calculate_transform_angle(float percentComplete, int transformIndex) // returns true when the transform is finished
{
float angle;
if(percentComplete < 1) {
angle = percentage_along_distance(transforms[transformIndex].first.startingA, transforms[transformIndex].first.targetA, percentComplete);
} else {
angle = transforms[transformIndex].first.targetA;
}
if(transforms[transformIndex].second == -1) {
cAngle = angle;
} else {
int spriteIndex = transforms[transformIndex].second;
sprites[spriteIndex].second.tiltOffset = angle;
}
if(percentComplete >= 1) return true;
return false;
}
offset.h
#ifndef _LBMOON_OFFSET_H
#define _LBMOON_OFFSET_H
struct offset
{
float xOffset;
float yOffset;
float angleOffset;
float tiltOffset;
};
#endif
sprite_holder.h
#ifndef _LBMOON_SPRITE_H
#define _LBMOON_SPRITE_H
#include<SFML\Graphics.hpp>
#include<vector>
#include<string>
#include<utility>
#include <math.h>
#include "transform.h"
#include "offset.h"
class sprite_holder
{
public:
// General Interface Functions
sprite_holder(float x, float y);
void update(int timeElapsed);
bool transform_complete(transform_type type, int spriteIndex=-1);
// Shell functions (transform the whole sprite)
void adjust_pos(float x, float y, int duration);
void adjust_angle(float angle, int duration);
// Child functions (transform a specific drawable)
// note: when passing drawIndex, -1 means the top drawable
void adjust_child_pos(int spriteIndex, float x, float y, int duration);
void adjust_child_angle(int spriteIndex, float angle, int duration);
std::vector<std::pair<sf::Sprite,offset>> sprites;
std::vector<sf::Texture> textures;
protected:
int lookup_transform(transform_type type, int spriteIndex = -1);
void render_children_pos();
void render_children_angle();
float percentage_along_distance(float startValue,float endValue, float percentComplete);
float xPos;
float yPos;
float cAngle;
int lastUpdateTime;
std::vector<std::pair<transform,int>> transforms;
private:
bool calculate_transform_pos (float percentComplete, int transformIndex); // returns true when the transform is finished
bool calculate_transform_angle(float percentComplete, int transformIndex); // returns true when the transform is finished
};
#endif
transform.h
#ifndef _LBMOON_TRANSFORM_H
#define _LBMOON_TRANSFORM_H
enum transform_type{UNKNOWN=-1,POSITION=0,SCALE,ANGLE};
struct transform
{
transform_type type;
int startTime;
int duration;
float startingA;
float startingB;
float targetA;
float targetB;
};
#endif
You'll also want to put the following images with the program:
http://legacyblade.com/images/heart.png
http://legacyblade.com/images/heart_back.png
I've been working on getting this class working for a couple weeks now, and after testing all day to find the source of this particularly baffling error, I've come up dry. So thanks for reading this! Any help you could provide would be amazing.

Segmentation Fault - altering struct (within another struct's) variables

I have this, in my header:
struct Surface {
char *objectName;
int xPos;
int yPos;
SDL_Surface *surface;
};
struct WorldSurface {
Surface *surface = new Surface[MAX_SURFACES];
int counter = 0;
int current = 0;
};
WorldSurface *worldSurface;
I then initialize the worldSurface in the .cpp:
WorldSurface *worldSurface = new WorldSurface[MAX_LEVELS];
And this function, I can't get to work no matter what, have tried messing around with = NULL, pointers, the -> instead of .'s... (do have in mind I'm not very savvy of pointer subjects)
void drawClass::addSurface(char* objectName, char* surfaceFile, int xPos, int yPos, int drawLevel) {
int cnt = worldSurface[drawLevel].counter;
worldSurface[drawLevel].surface[cnt].objectName = objectName;
worldSurface[drawLevel].surface[cnt].surface = load_image(surfaceFile);
worldSurface[drawLevel].surface[cnt].xPos = xPos;
worldSurface[drawLevel].surface[cnt].yPos = yPos;
worldSurface[drawLevel].counter++;
}
It's 10 worldSurfaces, each containing 50 surface structs, and I want to acess the struct, which is inside the worldSurface[drawLevel], and the surface struct I want to access is known in the worldSurface, in the .counter variable. But all of the acesses to the underlying surface struct fail with segmentation fault, and I have no clue why...
Thanks for the help!
Your WorldSurface isn't defined nor initialized properly:
struct WorldSurface {
Surface *surface = new Surface[MAX_SURFACES];
int counter = 0;
int current = 0;
};
You can't initialize your data in place along with the declaration of the class. You need to do this in a constructor, e.g.:
struct WorldSurface {
Surface *surface;
int counter;
int current;
};
...
WorldSurface::WorldSurface():
counter(0),current(0),surface(new Surface[MAX_SURFACES]){}

The OpenCV lib with c++ - in Detail cv::Mat::at causes SIGSEGV on large images

I am currently writing an application in c++ using the openCV-lib (version 2.1).
The task was to implement a small database as a students project, using some of the features of this library. My very own implementations of the median-filter and the boxcar-filter use the cv::Mat::at method to access single pixels in a given image with both reading and writing operations.
The curious thing about this is: It works just perfect on smaller images.
but only larger images it allways generates a SIGSEGV, allways on the same coordinates.
Is this a know bug or am i really doing something wrong?
here are the most significants functions i wrote:
class point {
public:
int x,y;
};
class ImageEntry {
friend class ImageDB;
private:
string _key;
string _filename;
Mat *_data;
ImageEntry* _next;
void show(void);
public:
void operator<<(ImageFilter* x);
~ImageEntry();
ImageEntry(string filename, string key);
Vec3b GetPoint(int x, int y);
point GetSize(void);
void SetPoint(int x, int y, Vec3b color);
};
point ImageEntry::GetSize(void) {
point iRet;
iRet.x = _data->cols;
iRet.y = _data->rows;
return iRet;
}
Vec3b ImageEntry::GetPoint(int x, int y) {
Vec3b iRet;
iRet = _data->at<Vec3b>(x,y);
return iRet;
}
void ImageEntry::SetPoint(int x, int y, Vec3b color) {
_data->at<Vec3b>(x,y) = color;
}
void MedianFilter::filterImage(ImageEntry* img) {
Vec3b Points[9];
Vec3b NewColor;
unsigned char ActChan[9];
point range = img->GetSize();
for (int act_x = 1; act_x < (range.x - 1); act_x++) {
for (int act_y = 1; act_y < range.y - 1; act_y++) {
Points[0] = img->GetPoint(act_x-1,act_y-1);
Points[1] = img->GetPoint(act_x,act_y-1);
Points[2] = img->GetPoint(act_x+1,act_y-1);
Points[3] = img->GetPoint(act_x-1,act_y);
Points[4] = img->GetPoint(act_x,act_y);
Points[5] = img->GetPoint(act_x+1,act_y);
Points[6] = img->GetPoint(act_x-1,act_y+1);
Points[7] = img->GetPoint(act_x,act_y+1);
Points[8] = img->GetPoint(act_x+1,act_y+1);
for (int act_color = 0; act_color < 3; act_color++) {
for (int i = 0; i < 9; i++) ActChan[i] = Points[i][act_color];
SelSort9(ActChan);
NewColor[act_color] = ActChan[4];
}
img->SetPoint(act_x,act_y,NewColor);
}
}
}
I would really appreciate any suggestion.
Thank you for your time!
If you take a look at the function at(), which you use in the SetPoint() method, in the documentation of OpenCv, it says:
template<typename _Tp> _Tp& Mat::at(int i, int j)
Return reference to the specified matrix element.
Parameters:
i – The 0-based row index
j – The 0-based column index
Furthermore, if you look at your GetSize() method, you set iRet.y = _data->rows and then in the method filterImage() use a for loop to loop from act_y = 1 to iRet.y. The second loop, loops through the rows. At the end of this method you call SetPoint(act_x, act_y), which on its turn calls at(act_x, act_y) basically.
Recall that act_y was an index of a row, but is now being used as index of a column. I hope this suggestion is all you need to solve your problem.