C++/SDL2 IMG_Load Error (Out of memory) - c++

I am making a shoot'em up game and have been coming into a problem where the sprites won't load at all after a certain amount of time and continuously shooting. In my console, an error prints out:
"IMG_LOAD_ERROR : Out of memory" (The "IMG_LOAD_ERROR : " was my own thing)
I also use text (SDL_ttf) to display an ammo count.
The hypothesis I have now is that I always call the IMG_load function in the constructor of every enemy that is spawned, but I'm not even sure if that's what's causing it. There are quite a few more possibilities I can think of.
Also, I do free the textures when they are destroyed (when the enemy is out of health or leaves the screen).
Can someone help me understand this and help me fix it?

It seems that you are not destroying textures/images or renderes that you are not need.
SDL_DestroyTexture(img);
SDL_DestroyRenderer(renderer);
Simple example of drawing image, which i found https://gist.github.com/armornick/3434362.
My advice: You should load all textures or begin of application or when is needed, but it must be once. You must reuse every same image.
It would be nice to see code to find out, what is wrong with code.

Related

Multithreading CCLientDC possible?

the MFC application I'm currently working on is a little hobby project, supposed to look like the green code rain from the movie Matrix. My application has the window divided into thousands of little squares, each holding a letter and each of which might need a redraw to the screen after 25 milliseconds (one frame). Currently, I tried to do this with CClientDC::TextOutW. However, depending on how many of the tiles need an update, calling TextOutW for all the necessary tiles might take anywhere from 30 to 75 milliseconds, which is obviously way too long. The output looked great, but it was just progressing too slowly.
Then I tried to use some multithreading to do the redrawing, but for that, each thread needed access to the screen. I couldn't find any documentation on whether a CClientDC can be used by multiple threads or if multiple threads can have several CClientDCs at once, writing to the same device. The multithreaded apllication I wrote compiles and runs, but the output looks pretty garbled.
I might have made a mistake somewhere (I'm not that well-experienced with multithreading yet), but then again, I might be trying to push butter through stone here. Can anyone tell me if what I'm trying to do with the CClientDC is even possible?
If multithreaded output to the screen via CClientDC is not possible, does anyone have another idea how I could output about 2000 letters on different positions onto the screen in the timespan of 20 milliseconds?
Thanks in advance!

SFML Texture memory management

This is a C++ memory management problem thus I chose to ask here.
I am creating a game in SFML. I have used SDL before and managing my Textures was very straightforward but SFML works differently.
My project setup is something like so:
class Game
//create window and initialize game stuff
class Character
/*initializes its own textures and is also responsible for updating itself
as well as drawing itself*/
int main()
/*create an instance of Game -> Create an instance of Character and
runGame. I will implement the drawing and updating properly when I
implement a scene graph and scene nodes but for now updating and drawing is
done via global functions called by the Game Class*/
The challenge I faced was that using an sf::Texture in the Character class for the Sprite image results in a white rectangle being drawn. So the Character Sprite loses its Texture link and SFML just draws a white rectangle. To solve this I created a raw Texture pointer and Initialize it in the Character constructor. This works and the Sprite is drawn correct.
//inside character.hpp
sf::Texture *texture;
//in Character constructor
texture= new (sf::Texture);
This means I have to manage the memory and the code feels ugly.
I have tried this to manage the memory allocated (I think) to prevent a memory leak:
Character::~Character()
{ delete texturePtr; }
but that is wrong obviously.
I also tried to delete character.Texture at the end of main() when I exit the application but that causes an error also.
I then tried to do use a uinque_ptr inside the Character constructor:
std::unique_ptr<sf::Texture> texture(new sf::Texture);
//load Texture from Resource Manager instance
and this draws a nice navy blue-black rectangle instead of the Sprite Texture. I am not sure how or if I can declare and then later initialize a unique_ptr.
I think I am leaking memory and if so, how do I correctly use the smart pointers or manage my own memory properly?
I have added a bit more detail and code as I realized I was being vague. Also, I am querying the texture and using it to set the Sprite Rect dimensions so it is definitely being loaded, but just to be safe, I have a logger function that checks if any resource I call is loaded or not.
If the sf::Texture is a member of Character then it will not go out of scope until your Character instance does.
Use the debugger break points to follow what happens. Throw a break point in the destructor of Character and sf::Texture and walk through your startup and shutdown sequences. Or use Log to print messages like: "Character::~ called."
I think I am leaking memory and if so, how do I correctly use the smart pointers or manage my own memory properly?
Question all assumptions, including the one that you are loading the texture properly. Until you see the texture draw on screen, you don't have evidence that you have loaded it. (Unless you want a navy-blue rect. I don't know what you are trying to draw. I assume a character sprite.)
From SFML Docs:
The loadFromFile function can sometimes fail with no obvious reason. First, check the error message that SFML prints to the standard output (check the console). If the message is unable to open file, make sure that the working directory (which is the directory that any file path will be interpreted relative to) is what you think it is: When you run the application from your desktop environment, the working directory is the executable folder. However, when you launch your program from your IDE (Visual Studio, Code::Blocks, ...) the working directory might sometimes be set to the project directory instead. This can usually be changed quite easily in the project settings.
Until you see a leak in a leak detector, you really can't assume that you are leaking memory. There are 3rd party memory trackers you can add to your program.
Again, use a debug break point in sf::Texture destructor to stop execution and see exactly where you are deallocating (if this turns out to be the problem).
You really should read and follow Minimal, Complete, and Verifiable example. For all we know you could be doing something like this:
class Character{
sf::Sprite mySprite;
public:
Character(){
sf::texture aTex;
aTex.loadFromFile("c:\users\noob\Desktop\myawesomegame\stripper.png");
mySprite.setTexture(aTex);
}
}
// attempt 2
class Character{
sf::Sprite mySprite;
public:
Character(){
std::unique_ptr<sf::Texture> texture(new sf::Texture);
texture->loadFromFile("c:\users\noob\Desktop\myawesomegame\stripper.png");
mySprite.setTexture(*texture);
}
}
And the error would be obvious.

VTKActor not visible after render but visible on camera->resetview()

I am working on a qt-vtk project. We have a line drawing function. where straight lines are created between two mouse click position. But once actor is created it is not visible. I was calling render function just after adding the actor. But it didn't work. But if i do camera->resetview() lines become visible , but entire perspective changes. Where am i doing wrong ?
thanks
Rwik
This may not be relevant to you, but I had this exact same problem (in ActiViz [managed VTK]) and wrangled with it for a week, so I hope this helps someone out there. It turned out to be a problem with the location of the lines we wanted to draw on the canvas; they were too far away from the camera (on the Z axis) to be visible.
For us, we were trying to draw a cross on the viewing area wherever the user clicked. The data points were there, as were the actors and whatnot, but they would only be visible in the scene if you called resetCamera() and thusly changed the camera's configuration.
Initially, I blamed the custom interactor that we had to add to cirvumvent the default interactor's swallowing of MouseUp events (intended behavior). Investigation revealed that this seemed unlikely.
After this I shifted the blame onto the camera under the suspicion that perhaps the reset call was making a call to some kind of update method which I wasn't aware of. I called resetCamera() and then reverted the camera values to what they were initially.
When this was successfully done, it eventuated that the crosses would appear when the camera zoomed out and then disappear again as soon as it was set back, and it was at this point I realized that it was something to do with the scene.
At this point, I checked the methods we were using to retrieve the mouse location in 3D and realized that the z value was enormous and it was placing the points too far away as a byproduct of VTK's methods to convert 2D locations on the control to 3D locations in the scene and vice versa.
So after all that, a very mundane and avoidable mistake that originated from the methods renderer.DisplayToWorld() and WorldToDisplay().
This might not be everyone's problem, but I hope I've spared someone a week of fiddling around with VTK.
I think that's a bit hard to help, without see the code, but have you tried using
ui->qvtkwidget->update();
, where ui is the instance of your class derived from QMainWindow?

Pointers in C++ Class are getting scrambled

I've got a lot of code that's driving me really crazy right now.
I'm working with OpenGL, building a GUI framework which utilizes several different types of objects. I have Image classes which load *.png files and store image information in the form of a GLuint texture reference. I have Panel and Button classes with pointers to the image classes they should be displaying. I have a Hud class with std::vectors of Panel and Button pointers. Finally, I have an Engine class that contains one Hud class, all my Button and Panel classes, and Image pointers. When the constructor is run, each of the Image pointers is initialized using:
imgMy = new Image;
Once all the images have been initialized, I run my load functions:
imgMy->loadImage("imgMy.png");
Of course, I delete the Images when I close the program.
My problem is that some of the images are getting "crossed." I have about thirty images right now, and a couple of the buttons are apparently pointing to the wrong images. I have checked my code thoroughly, and it appears to be solid. I believe this is a memory bug since the buttons which display the incorrect images are inconsistent. Sometimes they display the correct images, sometimes different buttons are displaying the wrong images. I wish I could show my code here, but it's pretty massive.
The reason I'm using Image pointers in my Engine class instead of actual Image objects is that I'm afraid of the Buttons pointing to invalid memory if the Engine class is resized, or its memory rearranged. I suspect there's a much better approach to what I'm trying to accomplish, and I'd appreciate any advice along those lines.
Use a debugger that lets you put a watchpoint on the relevant imgMys, and then the debugger will tell you where they're being modified. That is probably the easiest way to track it down.
You may also want to try valgrind, but this doesn't sound like the type of problem valgrind will find.
Firstly, you should not use two-phase initialization without a really good reason. This is not a really good reason. Pass the filename in the constructor. Also, always use smart pointers.
You could simply use const to enforce it.
class Button {
const std::unique_ptr<Image> img;
public:
Button(std::string filename)
: img(new Image(filename)) {}
};
Secondly, I don't quite grok your overriding architecture, as you don't describe it in any real detail, but I'm unsure of the need of new here.
Sounds like memory corruption. You should consider using some memory debugger like valgrind or some other alternative. If you have any issues using pointers, those tools will help you track them down.
I suspect that you're keeping a list of button references and a list of image references somehow and that they are not always created in the same order, hence the cross over images.
Strictly speaking you should create your a button and it's image in order, assigning the image file at creation time.

Odd MFC/GDI behaviour (blank image) that doesn't appear when screen is recorded

There is this weird bug in my program that I'm trying to fix, but I'm really at a loss for what it could be. This part of my program has a dialog which shows previews of various items using MFC/GDI. When I scroll through different items, sometimes the preview image just disappears and goes blank. However, it:
Only happens on some machines
Apparently happens on both Windows 7 and XP
Doesn't happen on the same item every time
Item IS STILL THERE when one takes a screenshot, but it is blank when viewing it normally.
Seems to happen at random places throughout the code when I'm attempting to trace through it with breakpoints. It's not always in the same location that the screen goes from image to blank, which leads me to believe that it's not happening in the same thread as my main thread, even though that's really the only thread that's not blocked at that point. That means that it's happening in a windows thread or something, doesn't it?
I'm assuming it's a race condition of some sort, but the behaviour of the preview in screenshots, in particular, rather confuses me. Why would it be fine when taking a screenshot but be blank when viewing it on screen? Is there some mechanic of the "printscreen" that bypasses what's displyed or updated on the screen?
I realize that I haven't given much information and that people obviously can't help much, but if anyone could think of ANYTHING, it would be much appreciated :)
Thanks!
Another theory: GDI resource leak
If you forget to free your GDI objects, weird things start to happen - including unpainted areas.
Run taskmgr.exe and add the "GDI Objects" column.
Run your software and monitor the GDI object count. Does it stabilize?
If your GDI Object count does not stabilize, look in your relevant WM_PAINT handlers.
Here's an example of a GDI leak:
void CMyWnd::OnPaint()
{
CPaintDC dc(this);
dc.SelectObject(&font);
}
Selected GDI objects must always be deselected:
void CMyWnd::OnPaint()
{
CPaintDC dc(this);
CFont *pOldFont = dc.SelectObject(&font);
// Use font
dc.SelectObject(pOldFont);
}
When you record your screen, are you reading the desktop using GDI apis? In that case, any hardware-accelerated surface may become black (or possibly white). To test this, you can disable hardware acceleration for your graphics card. If your recorder starts working then you've found the culprit!
To record these non-GDI surfaces you probably need to read the surface using DirectX/OpenGL. I would start with this article: http://www.codeproject.com/KB/dialog/screencap.aspx