For some reason SDL refuses to render an image. I don't see why and it's really bogging down my progress on a 2d game i'm developing. Everything is linked properly and such. Here's my code:
//main.cpp
#include "main.h"
void game::createWindow(const int SCREEN_W, const int SCREEN_H, const char* SCREEN_NAME)
{
buffer = SDL_SetVideoMode(SCREEN_W, SCREEN_H, 0, NULL);
SDL_WM_SetCaption(SCREEN_NAME, NULL);
}
void game::enterLoop()
{
while(Running == true)
{
SDL_BlitSurface(zombie, NULL, buffer, NULL);
SDL_Flip(buffer);
while(SDL_PollEvent(&gameEvent))
{
if(gameEvent.type == SDL_QUIT)
{
Running = false;
}
}
}
}
void game::loadContent()
{
zombie = SDL_LoadBMP("zombie.bmp");
}
int main(int argc, char* argv[])
{
game gameObj;
SDL_Init(SDL_INIT_EVERYTHING);
gameObj.createWindow(960, 600, "uShootZombies");
gameObj.loadContent();
gameObj.enterLoop();
SDL_Quit();
return 0;
}
//main.h
#include <SDL.h>
#include <fstream>
#include <string>
using namespace std;
class game
{
public:
void createWindow(const int SCREEN_W, const int SCREEN_H, const char* SCREEN_NAME);
void enterLoop();
void loadContent();
game()
{
Running = true;
}
~game()
{
SDL_FreeSurface(buffer);
SDL_FreeSurface(background);
SDL_FreeSurface(player);
SDL_FreeSurface(zombie);
}
private:
SDL_Surface* buffer;
SDL_Surface* background;
SDL_Surface* player;
SDL_Surface* zombie;
SDL_Event gameEvent;
bool Running;
};NU
I just copied all of your code to use in code::blocks and it works fine.
Of course I was using my own .bmp file which I named "zombie.bmp"
Are you sure your .bmp file is ok?
Be aware that if you originally save it as a .jpeg file or something like that, then simply renamed it to .bmp, it won't work (And it won't throw an error either)
It must be originally saved as a bmp.
That is all I can think of.
It seems that Sour Lemon has already solved your problem, but I still thought it would be worth pointing out that the above code doesn't perform any checks to make sure that your zombie image was actually loaded correctly.
You should be doing something like this:
void game::loadContent()
{
zombie = SDL_LoadBMP("zombie.bmp");
if (zombie == NULL) {
ReportError(SDL_GetError());
}
}
Related
I've bee trying to make a class for a window and I'm not sure why this error shows up.
I've been also trying to add the functions and everything else manually into the "main.cpp" file to check if openGl is working, and it does, but when I try to make a openGl object, it's not working.
Maybe the problem it's easy to spot, but I can't figure it out.(sorry I'm just trying to learn here :3 )
Here is my code:
The header file
#pragma once
#include <iostream>
#include <GLFW/glfw3.h>
class Window {
private:
const char* p_title;
int p_width;
int p_height;
GLFWwindow* window;
public:
Window(const char* title, int width, int height);
~Window();
bool close();
void update();
private:
void init();
};
The .cpp file
#include "window .h"
Window::Window(const char* title, int width, int height)
{
p_title = title;
p_width = width;
p_height = height;
init();
}
Window::~Window()
{
glfwTerminate();
}
bool Window::close()
{
return glfwWindowShouldClose(window);
}
void Window::update()
{
glfwPollEvents();
glfwSwapBuffers(window);
}
void Window::init()
{
window = glfwCreateWindow(p_width, p_height, p_title, NULL, NULL);
if (!window) {
std::cout << "The window could not be created\n";
glfwTerminate();
}
glfwMakeContextCurrent(window);
}
If it helps, here is the debugger:
Some background if you care/if it helps. I am pretty knew to programming and C++, I tried to learn it a couple times before but couldn't stay interested. As I couldn't think of an interesting project to do as I learn. Eventually I thought of making a game engine(dumb idea for a noob, but it will be a good learning experience and I'm interested in doing it.), so I searched for a series on making one to get an idea and found TheChernoProject's series and here I am.
I'm trying to make a make a window in GLFW and C++ but it keeps failing, I have no idea what to do.
Main.cpp
#include "src\graphics\window.h"
int main() {
using namespace tmge;
using namespace graphics;
Window window("Test", 1280, 720);
while (!window.windowClosed()) {
window.update();
}
return 0;
}
Window.h
#pragma once
#include <GLFW\glfw3.h>
#include <iostream>
namespace tmge { namespace graphics {
class Window {
private:
GLFWwindow *privateWindow;
int privateWidth, privateHeight;
const char *privateTitle;
bool privateWindowClosed();
public:
Window(const char *title, int width, int height);
~Window();
bool init();
void update() const;
bool windowClosed() const;
};
} }
Window.cpp
#include "window.h"
namespace tmge { namespace graphics {
Window::Window(const char *title, int width, int height) {
privateTitle = title;
privateWidth = width;
privateHeight = height;
if (!init()) {
glfwTerminate();
}
}
Window::~Window() {
glfwTerminate();
}
bool Window::init() {
if (!glfwInit) {
std::cout << "GLFW initialaztion failed" << std::endl;
return false;
}
privateWindow = glfwCreateWindow(privateWidth, privateHeight, privateTitle, NULL, NULL);
if (!privateWindow) {
std::cout << "Failed to create GLFW window" << std::endl;
return false;
}
glfwMakeContextCurrent(privateWindow);
return true;
}
bool Window::windowClosed() const{
return glfwWindowShouldClose(privateWindow);
}
void Window::update() const{
glfwPollEvents();
glfwSwapBuffers(privateWindow);
}
} }
Today I started a C++/SDL2 Snake clone, and I've been looking for ways to make my code neater, -particularly with classes. I tried to put all the SDL code used for the window/display in a class. When I run the code, the window closes instantly. From the error tests I set up in display.cpp, it also tells me through the console that SDL_UpdateWindowSurface() (in display.update()) is always returning -1. Why does this happen when I rearrange my code like this?
With this code I load an image in main() and display it through my class' function applySurface(). The idea is to have classes/objects for the game's grid/board, the snake, etc., -each calling applySurface() for their own images. Feel free to tell me if this is a bad idea altogether.
main.cpp:
#include <SDL.h>
#include "display.h"
SDL_Event event;
SDL_Surface* image = nullptr;
int main(int argc, char* args[])
{
Display display;
display.loadImage("image.bmp");
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
return false;
bool quit = false;
while (!quit)
{
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
quit = true;
}
display.applySurface(0, 0, image, display.windowSurface);
display.update();
}
SDL_FreeSurface(image);
SDL_Quit();
return 0;
}
display.h:
#pragma once
#include <SDL.h>
#include <string>
#include <iostream>
class Display
{
public:
SDL_Window* window;
SDL_Surface* windowSurface;
Display();
SDL_Surface *loadImage(std::string fileName);
void applySurface(int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *clip = nullptr);
void update();
~Display();
private:
const int WINDOW_WIDTH = 612;
const int WINDOW_HEIGHT = 632;
const int SCREEN_BPP = 2;
};
display.cpp:
#pragma once
#include "display.h"
Display::Display()
{
window = SDL_CreateWindow("Snake", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
if (window == NULL)
std::cout << "Error: SDL_CreateWindow failed." << std::endl;
windowSurface = SDL_GetWindowSurface(window);
}
SDL_Surface* Display::loadImage(std::string fileName)
{
SDL_Surface* loadedImage = NULL;
SDL_Surface* optimizedImage = NULL;
loadedImage = SDL_LoadBMP(fileName.c_str());
if (loadedImage != NULL)
{
optimizedImage = SDL_ConvertSurface(loadedImage, windowSurface->format, 0);
SDL_FreeSurface(loadedImage);
if (optimizedImage != NULL)
SDL_SetColorKey(optimizedImage, SDL_TRUE, SDL_MapRGB(optimizedImage->format, 255, 255, 255));
}
return optimizedImage;
}
void Display::applySurface(int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *clip)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, clip, destination, &offset);
}
void Display::update()
{
if (SDL_UpdateWindowSurface(window) == -1)
std::cout << "Error: SDL_UpdateWindowSurface() failed." << std::endl;
}
Display::~Display()
{
SDL_FreeSurface(windowSurface);
windowSurface = NULL;
SDL_DestroyWindow(window);
window = NULL;
}
This is a valid use of classes to structure your code. SDL_Init needs to come before any other SDL functions, which means you're best off moving SDL_Init to the top of main or adding it to the display constructor. If you add it to the beginning of the display constructor this means that you can only have one display class object running at a time, which would likely be fine in this case.
I looked for some tutorials for game development, I found one where I'm supposed to create a pong clone, but I can't even create the window, I get the following:
"Unhandled exception at 0xEEFFEE01 in Pang.exe: 0xC0000005: Access violation reading location 0xEEFFEE01."
I'm using SFML 1.6 and Visual Studio 2013.
Here is my code.
Game.cpp
#include "stdafx.h"
#include "Game.h"
void Game::Start(void)
{
if (_gameState != Uninitialized)
return;
_mainWindow.Create(sf::VideoMode(1024, 768, 32), "Pang!");
_gameState = Game::Playing;
while (!IsExiting())
{
GameLoop();
}
_mainWindow.Close();
}
bool Game::IsExiting()
{
if (_gameState == Game::Exiting)
return true;
else
return false;
}
void Game::GameLoop()
{
sf::Event currentEvent;
while (_mainWindow.GetEvent(currentEvent))
{
switch (_gameState)
{
case Game::Playing:
{
_mainWindow.Clear(sf::Color(255, 0, 0));
_mainWindow.Display();
if (currentEvent.Type == sf::Event::Closed)
{
_gameState = Game::Exiting;
}
break;
}
}
}
}
Game::GameState Game::_gameState = Uninitialized;
sf::RenderWindow Game::_mainWindow;
Game.h
#pragma once
#include "SFML/Window.hpp"
#include "SFML/Graphics.hpp"
class Game
{
public:
static void Start();
private:
static bool IsExiting();
static void GameLoop();
enum GameState {
Uninitialized, ShowingSplash, Paused,
ShowingMenu, Playing, Exiting
};
static GameState _gameState;
static sf::RenderWindow _mainWindow;
};
Pang.cpp
#include "stdafx.h"
#include "Game.h"
int _tmain(int argc, _TCHAR* argv[])
{
Game::Start();
return 0;
}
I know there's some code that has nothing to do with my problem, the error occurs when it reaches this line in Game.cpp
_mainWindow.Display();
I'm new on this so any help, any good tutorials or starting point to start learning will be good.
Some general SFML advice: Update to SFML 2.0, especially if you are using VS2013. Here are the official SFML tutorials http://www.sfml-dev.org/tutorials/2.0/
It looks like you just copied your code from here http://en.sfml-dev.org/forums/index.php?topic=10855.0 if this is true you should have realized that the code did not work, if not then the person who copied the code and used it in their tutorial should have noticed, and the fact they didn't is worrying about the state of the rest of their tutorials
Okay so the issue is you can't have a static RenderWindow, and with that your entire game class should not be static, it just isn't good programming practice. What you need to do is remove the static identifier from every declaration in your Game.h header file. For instance:
This
static void Start();
Needs to look like this
void Start();
Next, your Pang.cpp should look like this
//#include "stdafx.h" you don't need this precompiled header
#include "Game.h"
int main(int argc, char* argv[])
{
Game myGame;
myGame.Start();
return 0;
}
I recently got started trying to use SFML. For some reason my simple program will not render the window. I've tried throwing everything into main to see if there was an error in my code that had to do with multiple files etc. but to no avail.
I'll launch my program and nothing will appear.
What's the problem?
//main.h
#ifndef MAIN_H
#define MAIN_H
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <fstream>
using namespace std;
using namespace sf;
class game
{
public:
void startLoop(int SCREEN_W, int SCREEN_H, string SCREEN_NAME);
void log(const string logging);
game()
{
QUIT = false;
pendingFile.open("Log.txt", ios::out);
pendingFile << "---Brain Bread Log---";
}
~game()
{
pendingFile.close();
}
private:
bool QUIT;
ofstream pendingFile;
};
#endif
//main.cpp
#include "main.h"
void game::log(const string logging)
{
pendingFile << logging;
}
void game::startLoop(int SCREEN_W, int SCREEN_H, string SCREEN_NAME)
{
Window Game(VideoMode(SCREEN_W, SCREEN_H, 32), SCREEN_NAME);
while(QUIT == false)
{
Game.Display();
}
}
int main(int argc, char* argv[])
{
game gameObj;
gameObj.startLoop(800, 600, "Brain Bread");
return 0;
}
I tried your code and it behaves exactly as I expect it to - that is to say that an iconless window with a black body pops up and it doesn't respond to events. Is that what you're getting? If not, you might need to rebuild SFML.
You might want to try introducing event-handling so that your startLoop looks more like this:
void game::startLoop(int SCREEN_W, int SCREEN_H, string SCREEN_NAME)
{
// Init stuff
while (Game.IsOpened())
{
sf::Event newEvent;
while (Game.GetEvent(newEvent))
{
// Process event
}
// Do graphics stuff
Game.Display();
}
}