I'm learning the basics of creating a window using SDL2 by following a tutorial. The code works just fine, and even compiles correctly, however on runtime it gives the error message 'Assertion failure at SDL_RenderClear_REAL'.
I've tried reinstalling SDL2, as well as moving it to the user library folder on my mac, but neither of these fixed the issue
main.cpp
#include "game.hpp"
Game *game = nullptr;
int main() {
game = new Game();
game->init("GUI", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, false);
while (game->running()) {
game->handleEvents();
game->update();
game->render();
}
game->clean();
return 0;
}
game.cpp
#include "game.hpp"
Game::Game(){}
Game::~Game(){}
void Game::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen) {
int flags = 0;
if (fullscreen == true) {
flags = SDL_WINDOW_FULLSCREEN;
}
if (SDL_Init(SDL_INIT_EVERYTHING) == 0) {
std::cout << "Sub-systems initialized\n";
window = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
if (window) {
std::cout << "Window created.\n";
}
renderer = SDL_CreateRenderer(window, -1, 0);
if (renderer) {
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
std::cout << "Renderer created\n";
}
isRunning = true;
} else {
isRunning = false;
}
}
void Game::handleEvents() {
SDL_Event event;
SDL_PollEvent(&event);
switch (event.type) {
case SDL_QUIT:
isRunning = false;
break;
default:
break;
}
}
void Game::update() {
cnt++;
std::cout << cnt << "\n";
}
void Game::render() {
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
void Game::clean() {
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
std::cout << "Game cleaned\n";
}
game.hpp
#ifndef game_hpp
#define game_hpp
#include "SDL2/SDL.h"
#include <iostream>
class Game {
public:
Game();
~Game();
void init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen);
void handleEvents();
void update();
void render();
void clean();
bool running() { return isRunning; }
private:
int cnt = 0;
bool isRunning;
SDL_Window *window;
SDL_Renderer *renderer;
};
#endif
After narrowing down the code, it seems that the issue is limited to SL_RenderClear. Here's the exact message it produces in the console:
2019-08-20 15:26:15.508900-0500 GUI[26436:7287503] WARN:
Assertion failure at SDL_RenderClear_REAL (/Users/valve/release/SDL/SDL2-2.0.10-source/src/render/SDL_render.c:2235), triggered 1 time:
'renderer && renderer->magic == &renderer_magic'
Program ended with exit code: 42
How can I fix this issue?
EDIT: Added full code to help identify the problem.
A basic "hello world" of creating a window and clearing the color on the screen for SDL requires a few boilerplate initialization steps
Initialize SDL
Create a SDL_Window
Create a SDL_Renderer
After which you can do
SDL_RenderClear and use SDL_RenderDrawColor to set a custom color to make it more obvious that it is properly clearing the Renderer.
Without error checking this would look something like:
SDL_Init(flags);
SDL_Window* window = SDL_CreateWindow("window title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, more_flags);
SDL_SetRenderDrawColor(renderer, red, green, blue, alpha);
SDL_RenderClear(renderer);
Also remember to call SDL_Delay(ms) if you want the program to not immediately close before you get a chance to see the window.
Related
I have been trying to make a pong clone as a first c++ "big" project, and I am encountering several problems.
First of all, this is my code so far:
game.hpp:
#pragma once
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <iostream>
class Game
{
public:
Game();
~Game();
// GAME VARIABLES
const int WIDTH=720, HEIGHT=720, FONT_SIZE=32;
int running, lastTime;
int frameCount, timerFPS, lastFrame, fps;
// GAME TOOLS
SDL_Window *window;
SDL_Renderer *renderer;
TTF_Font *font;
SDL_Color color;
// GAME OBJECTS:
SDL_Rect rPaddle, lPaddle, Ball, scoreBoard;
// GAME FUNCTIONS:
void initRects(); // AFTER YOU HAVE A WORKING VERSION, TRY TO MOVE TO CONSTRUCTOR
void render();
void run();
};
game.cpp:
#include "game.hpp"
Game::Game()
{
running = 1;
if(SDL_Init(SDL_INIT_EVERYTHING)<0)
std::cerr << "SDL FAILED: SDL_INIT_EVERYTHING: " << SDL_GetError() << std::endl;
if(SDL_CreateWindowAndRenderer(WIDTH, HEIGHT, 0, &window, &renderer)<0)
std::cerr << "SDL FAILED: SDL_CreateWindowAndRenderer: " << SDL_GetError() << std::endl;
TTF_Init();
font = TTF_OpenFont("PreschoolBits.ttf", FONT_SIZE);
color.r=color.g=color.b=255;
}
Game::~Game()
{
TTF_CloseFont(font);
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
}
void Game::initRects()
{
lPaddle.x=32; lPaddle.h=HEIGHT/5;
lPaddle.y=(HEIGHT/2)-(lPaddle.h/2);
lPaddle.w=12;
rPaddle=lPaddle;
rPaddle.x=WIDTH-rPaddle.w-32;
Ball.w=Ball.h=16;
}
void Game::render()
{
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
frameCount++;
timerFPS=SDL_GetTicks()-lastFrame;
if(timerFPS<(1000/60))
SDL_Delay(timerFPS<((1000/60)-timerFPS));
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0);
SDL_RenderFillRect(renderer, &lPaddle);
SDL_RenderFillRect(renderer, &rPaddle);
SDL_RenderFillRect(renderer, &Ball);
SDL_RenderPresent(renderer);
}
void Game::run()
{
initRects();
while(running)
{
lastFrame=SDL_GetTicks();
if(lastFrame>=(lastTime+1000))
{
lastTime=lastFrame;
fps=frameCount;
frameCount=0;
}
render();
SDL_Delay(2000);
running=0;
}
}
pong.cpp:
#include "game.hpp"
int main()
{
Game game;
game.run();
return 0;
}
Now, when I try to render the render the rectangles, they don't show up. So I tried to remove them and just render colors on screen.
Both before and after the SDL_RenderClear I wrote:
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
But the window still showed up black, no matter what I tried.
What could I be doing wrong?
To make a filled Rect you must create a rect object:SDL_Rect MyRectName, Set its values to whatever you want:MyRectName.(w,h,x,y) = MyValue, and then to render, run SDL_RenderFillRect(MyRenderer, MyRectName);.
So I'm just trying to set up a game loop and window, but it won't even start with a blank screen. When I run it, it gives me an error every time I try to use any function from SDL. I have the .dll in the same folder as the project files and in the Debug folder. I'm pretty sure I have them linked in the project properties, too, but I don't know. When I'm in visual studio, I can hover over the functions and it has the declarations of them (I think)
SDL2\include is in VC++ Directories -> Include Directories
SDL2\lib\x64 is in VC++ Directories -> Library Directories
SDL2\include is also in C/C++ -> General -> Additional Include Directories
SDL2\lib\x64 is also in Linker -> General -> Additional Library Directories
SDL.lib and SDLmain.lib are both in Linker -> Input -> Additional Dependencies
edit: forgot to show project properties
This is Game.hpp
#include "SDL.h"
#include <iostream>
class Game
{
public:
Game();
~Game();
void init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen);
void handleEvents();
void update();
void render();
void clean();
bool running() { return isRunning; }
private:
int cnt = 0;
bool isRunning;
SDL_Window *window;
SDL_Renderer *renderer;
};
This is Game.cpp
#include "Game.hpp"
Game::Game()
{}
Game::~Game()
{}
void Game::init(const char *title, int xpos, int ypos, int width, int height, bool fullscreen)
{
int flags = 0;
if (fullscreen)
{
flags = SDL_WINDOW_FULLSCREEN;
}
if (SDL_Init(SDL_INIT_EVERYTHING) == 0)
{
std::cout << "Subsystems initialized" << std::endl;
window = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
if (window)
{
std::cout << "Window created" << std::endl;
}
renderer = SDL_CreateRenderer(window, -1, 0);
if (renderer)
{
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
std::cout << "Renderer created" << std::endl;
}
isRunning = true;
} else {
isRunning = false;
}
}
void Game::handleEvents()
{
SDL_Event event;
SDL_PollEvent(&event);
switch (event.type)
{
case SDL_QUIT:
isRunning = false;
break;
default:
break;
}
}
void Game::update()
{
cnt++;
std::cout << cnt << std::endl;
}
void Game::render()
{
SDL_RenderClear(renderer);
//add stuff to render
SDL_RenderPresent(renderer);
}
void Game::clean()
{
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
std::cout << "Game cleaned" << std::endl;
}
And this is main.cpp
#include "Game.hpp"
Game *game = nullptr;
int main(int argc, char *argv[]) {
game = new Game();
game->init("Maxgame", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, false);
while (game->running()) {
game->handleEvents();
game->update();
game->render();
}
game->clean();
return 0;
}
And these are the
errors
I'm getting.
You could set Linker -> Advanced -> Target Machine -> MachineX64 in Properties.
I'm following this tutorial on youtube:
https://www.youtube.com/watch?v=44tO977slsU
and he links a video on how to install SDL2, I follow that video, and I followed this one as well. But when I compile it keeps coming up with SDL2/SDL not found? I'm not sure how to fix this
Here is my code so far
MAIN.CPP
#include "Game.hpp"
Game *game =nullptr;
int main(int argc, const char * argv[]) {
game = new Game();
game->init("Nijigen-Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, false);
while (game->running()) {
game->handleEvents();
game->update();
game->render();
}
game->clean();
return 0;
}
Game.cpp
#include "Game.hpp"
Game::Game()
{}
Game::~Game()
{}
void Game::init(const char *title, int xpos, int ypos, int width, int height, bool fullscreen)
{
int flags = 0;
if(fullscreen)
{
flags = SDL_WINDOW_FULLSCREEN;
}
if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
{
std::cout << "Subsystems Initiated!..." << std::endl;
window = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
if(window)
{
std::cout << "Window Created!..." << std::endl;
}
renderer = SDL_CreateRenderer(window, -1, 0);
if(renderer)
{
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
std::cout << "Renderer Created!..." << std::endl;
}
isRunning = true;
} else {
isRunning = false;
}
}
void Game::handleEvents()
{
SDL_Event event;
SDL_PollEvent(&event);
switch (event.type) {
case SDL_QUIT:
isRunning = false;
break;
default:
break;
}
}
void Game::update()
{}
void Game::render()
{
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
void Game::clean()
{
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
std::cout << "Game Cleaned" << std::endl;
}
** And Game.hpp**
#ifndef Game_hpp
#define Game_hpp
#include "SDL2/SDL.h"
#include <iostream>
class Game {
public:
Game();
~Game();
void init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen);
void handleEvents();
void update();
void render();
void clean();
bool running() { return isRunning; }
private:
bool isRunning;
SDL_Window *window;
SDL_Renderer *renderer;
};
#endif /* Game_hpp */
I'm currently using this tutorial: https://www.youtube.com/watch?v=44tO977slsU&list=PLhfAbcv9cehhkG7ZQK0nfIGJC_C-wSLrx&index=3
But I've been getting this error on the first line that I don't know how to address as a beginner.
It says it's unresolved externals
I've been trying to look at some of the windows config advice, but I don't know how to apply it to this tutorial.
here's the code:
#include "Header.hpp"
Game::Game(){}
Game::~Game(){}
void Game::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen)
{
int flags = 0;
if (fullscreen) { flags = SDL_WINDOW_FULLSCREEN; }
if (SDL_Init(SDL_INIT_EVERYTHING) == 0) {
std::cout << "Subsystems initialized" << std::endl;
window = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
if (window) { std::cout << "Windows created" << std::endl; }
renderer = SDL_CreateRenderer(window, -1, 0);
if (renderer) {
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
std::cout << "renderer created" << std::endl;
}
isRunning == true; } else { isRunning == false; }
}
void Game::handleEvents() {
SDL_Event event;
SDL_PollEvent(&event);
switch (event.type) {
case SDL_QUIT:
isRunning = false;
break;
default:
break;
}
}
void Game::update() { count++; std::cout << count << std::endl; }
void Game::render() {
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
void Game::clean() {
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
std::cout << "Game cleaned" << std::endl;
}
this is is the header file, if it'll help:
#ifndef Header_hpp
#define Header_hpp
#include <iostream>
#include "SDL.h"
class Game {
public:
Game();
~Game();
void init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen);
void handleEvents();
void update();
void render();
void clean();
bool running(){ return isRunning; }
private:
int count = 0;
bool isRunning;
SDL_Window *window;
SDL_Renderer *renderer;
};
#endif / * Header_hpp */
I'm genuinely clueless on what could be causing this so I guess I'll include the main.cpp as well if something can be found there:
#include "Header.hpp"
Game* game = nullptr;
int main(int argc, const char * argv[]) {
game = new Game();
game->init("Birchengine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, false);
while (game->running()) {
game->handleEvents();
game->update();
game->render();
}
game->clean();
return 0;
}
What could be the cause of this error, and how do I prevent it in the future?
I have recently started a game project in C++ using SDL2. I have created a class for the Game and included an init function which initializes SDL and creates a window. My code complies normally with 0 errors and warnings. However, when I run the executable file, I am not able to terminate the program nor a window appears.
My Code:
game.cc
#include "Game.hh"
#include <iostream>
using namespace std;
// Constructing Funtions
Game::Game()
{}
Game::~Game()
{}
// Initializing Function
void Game::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen)
{
int flags = 0;
// Check to see if Fullscreen Mode has been called
if(fullscreen)
flags = SDL_WINDOW_FULLSCREEN;
if(SDL_Init(SDL_INIT_EVERYTHING) == 1) {
cout << "Initialization Complete" << endl;
// Create the Window
window = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
// Create the Renderer
renderer = SDL_CreateRenderer(window, -1, 0);
if (renderer) {
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
}
// Set Is Running to True
isRunning = true;
} else {
isRunning = false;
}
}
// Looping Funtions
void Game::eventHandler()
{
// Initialize EventHandler & Get Event Type
SDL_Event event;
SDL_PollEvent(&event);
// Process Events
switch (event.type) {
case SDL_QUIT:
isRunning = false;
break;
default:
break;
}
}
void Game::update()
{}
void Game::render()
{
// Clear Renderer
SDL_RenderClear(renderer);
// Render Shit
SDL_RenderPresent(renderer);
}
void Game::clean()
{
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
cout << "Game Quit Successfuly" << endl;
}
bool Game::running()
{
return isRunning;
}
Game.hh
#ifndef GAME_HH
#define GAME_HH
#include "SDL.h"
class Game {
public:
// Constructor and Deconstructor
Game();
~Game();
// Initializing Functions
void init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen);
// Looping Commands
void eventHandler();
void update();
void render();
void clean();
// Application Running Checker
bool running();
private:
bool isRunning;
SDL_Window* window;
SDL_Renderer* renderer;
};
#endif
And finally main.cc
#include <iostream>
#include "Game.hh"
Game *game = nullptr;
int main()
{
game = new Game;
game->init("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, false);
do {
game->eventHandler();
game->update();
game->render();
} while(game->running());
game->clean();
}
Any Ideas?
EDIT: found a fix to the issue, I made the public function running return the private isRunning variable. However, now the issue is that the code returns "Game Quit Successfully" w/out initiating anything...