I'm trying to get an SDL window to appear, but it doesn't seem to be working. The program will run, and the function to show the window will run with no errors, but nothing shows up on my screen. I only have an icon in the dock that says that the program is not responding. Here's my code:
int main(int argc, const char * argv[]) {
MainComponent mainComponent;
mainComponent.init();
char myVar;
cout << "Enter any key to quit...";
cin >> myVar;
return 0;
}
void MainComponent::init() {
//Initialize SDL
SDL_Init(SDL_INIT_EVERYTHING);
window = SDL_CreateWindow("My Game Window", 100, 100, 100, 100, SDL_WINDOW_SHOWN);
cout << screenWidth << " " << screenHeight << endl;
if(window == nullptr) {
cout << "Error could not create window" << SDL_GetError() << endl;
}
SDL_Delay(5000);
}
Here's a screenshot of the icon on the dock https://www.dropbox.com/s/vc01iqp0z07zs25/Screenshot%202016-02-02%2017.26.44.png?dl=0
Let me know if there's something I'm doing wrong, thanks!
SDL_Renderer should be initialized to handle the rendering. This is explained in detailed here What is a SDL renderer?.
Here's a modified code above with an initialized renderer;
#include <SDL2/SDL.h>
#include <iostream>
using namespace std;
class MainComponent
{
public:
void init();
~MainComponent();
private:
SDL_Window *window;
SDL_Renderer* renderer;
};
MainComponent::~MainComponent()
{
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
}
void MainComponent::init() {
//Initialize SDL
SDL_Init(SDL_INIT_EVERYTHING);
int screenWidth = 400;
int screenHeight = 300;
window = SDL_CreateWindow("My Game Window", 100, 100, screenWidth, screenHeight, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, 0);
cout << screenWidth << " " << screenHeight << endl;
if(window == nullptr) {
cout << "Error could not create window" << SDL_GetError() << endl;
}
//change the background color
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
// Clear the entire screen to our selected color.
SDL_RenderClear(renderer);
// Up until now everything was drawn behind the scenes.
// This will show the new, red contents of the window.
SDL_RenderPresent(renderer);
SDL_Delay(5000);
}
int main(int argc, const char * argv[]) {
MainComponent mainComponent;
mainComponent.init();
char myVar;
cout << "Enter any key to quit...";
cin >> myVar;
SDL_Quit();
return 0;
}
This should compile and run properly.
Hope that helps.
Related
I am doing a game using SDL.
The problem is that instead of getting image I see a black screen without any errors. And the most interesting thing that I've made another test project to see if I'll get an image and this one works excellent. In test project I have only main.cpp which does the same (not sure as i am getting black screen in my main project) and not using headers and this stuff.
Here is my code:
main.cpp(game project)
#include <SDL2\SDL.h>
#include <SDL2\SDL_image.h>
#include <iostream>
#include <stdio.h>
#include "RenderWindow.hpp"
int main(int argc, char** argv){
if (SDL_Init(SDL_INIT_VIDEO) > 0)
std::cout << "SDL_init has crushed" << SDL_GetError() << std::endl; // ініціалізація сдл
if (!(IMG_Init(IMG_INIT_PNG)))
std::cout << "IMG_init has failed. Error: " << IMG_GetError() << std::endl;
RenderWindow window("Game",640,480);
SDL_Texture* grassTexture = window.loadTexture("images/ground_grass_1.png");
bool gameRunning = true;
SDL_Event event;
while(gameRunning)
{
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
gameRunning = false;
}
window.clear();
window.render(grassTexture);
window.display();
}
window.cleanUp();
IMG_Quit();
SDL_Quit();
return 0;
}
RenderWindow.hpp
#pragma once
#include <SDL2\SDL.h>
#include <SDL2\SDL_image.h>
class RenderWindow
{
public:
RenderWindow(const char* p_title, int p_w, int p_h);
SDL_Texture* loadTexture(const char* p_filePath);
void cleanUp();
void clear();
void render(SDL_Texture* p_text);
void display();
private:
SDL_Window* window;
SDL_Renderer* renderer;
};
renderwindow.cpp
#include <SDL2\SDL.h>
#include <SDL2\SDL_image.h>
#include <iostream>
#include "RenderWindow.hpp"
RenderWindow::RenderWindow(const char* p_title, int p_w, int p_h)
:window(NULL), renderer(NULL) // присвоювання нульових поінтеров
{
window = SDL_CreateWindow(p_title,SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,p_w,p_h,SDL_WINDOW_SHOWN); // ініціалізація вікна
if(window == NULL)
std::cout << "Window failed to init" << SDL_GetError() << std::endl;
renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED); // ініціалізація рендера
if(renderer == NULL)
std::cout << "Renderer failed to init" << SDL_GetError() << std::endl;
}
SDL_Texture* RenderWindow::loadTexture(const char* p_filePath)
{
SDL_Texture* texture = NULL;
texture = IMG_LoadTexture(renderer,p_filePath);
if(texture = NULL)
std::cout << "Failed to load texture. Error: " << SDL_GetError() << std::endl;
return texture;
}
void RenderWindow::cleanUp()
{
SDL_DestroyWindow(window);
}
void RenderWindow::clear()
{
SDL_RenderClear(renderer);
}
void RenderWindow::render(SDL_Texture* p_tex)
{
SDL_RenderCopy(renderer,p_tex,NULL,NULL);
}
void RenderWindow::display()
{
SDL_RenderPresent(renderer);
}
and main.cpp(test project)
#include <SDL2/SDL.h> // include the SDL library
#include <SDL2/SDL_image.h> // include the SDL_image library for loading image files
#include <iostream>
int main(int argc, char* argv[]) {
// initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cout << "SDL initialization failed: " << SDL_GetError() << std::endl;
return 1;
}
// create the window
SDL_Window* window = SDL_CreateWindow("My Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
if (window == NULL) {
std::cout << "Failed to create window: " << SDL_GetError() << std::endl;
return 1;
}
// create the renderer
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
std::cout << "Failed to create renderer: " << SDL_GetError() << std::endl;
return 1;
}
// load the image file
SDL_Texture* texture = IMG_LoadTexture(renderer, "ground_grass_1.png");
if (texture == NULL) {
std::cout << "Failed to load image: " << SDL_GetError() << std::endl;
return 1;
}
// render the image
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
// wait for 5 seconds
SDL_Delay(5000);
// clean up
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
I am trying to set up an SDL project, however I am getting from following error message:
Renderer already associated with window
from the following function:
void Game::render()
{
renderer = SDL_CreateRenderer(window, -1, 0);
if (renderer == NULL)
std::cout << "Failed to create a renderer" << '\n' << "Error: " << SDL_GetError() << std::endl;
}
I have only made a window and a renderer once, and they are separate, so I have no idea why this could happen. I found another question on SO with the same error, but apparently he was having problems because SDL_GetWindowSurface() was being called but I am not calling that function. The following is my code. Thanks for helping.
game.h:
#pragma once
#include <iostream>
#include "SDL.h"
class Game
{
public:
bool init();
bool constructWindow
(
const char* windowName,
unsigned int xWindowPos,
unsigned int yWindowPos,
unsigned int windowWidth,
unsigned int windowHeight,
bool fullScreen = false
);
void render();
void update();
SDL_Window* getWindow();
bool handleEvents();
protected:
private:
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_Event event;
bool quit = false;
};
game.cpp:
#include "game.h"
bool Game::init()
{
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
return true;
else
std::cout << "Could not initialise SDL" << '\n' << "Error: " << SDL_GetError() << std::endl;
}
bool Game::constructWindow(const char* windowName, uint16_t xWindowPos, uint16_t yWindowPos
, uint16_t windowWidth, uint16_t windowHeight, bool fullScreen)
{
window = SDL_CreateWindow(windowName, xWindowPos, yWindowPos, windowWidth, windowHeight, fullScreen);
if (!window)
std::cout << "Could not create window" << '\n' << "Error: " << SDL_GetError() << std::endl;
return window;
}
void Game::render()
{
renderer = SDL_CreateRenderer(window, -1, 0);
if (!renderer)
std::cout << "Failed to create a renderer" << '\n' << "Error: " << SDL_GetError() << std::endl;
}
void Game::update()
{
SDL_RenderPresent(renderer);
}
SDL_Window* Game::getWindow()
{
return window;
}
bool Game::handleEvents()
{
while (SDL_PollEvent(&event))
if (event.type == SDL_QUIT)
quit = true;
return quit;
}
main.cpp
#include "game.h"
int main(int argc, char* argv[])
{
Game app;
if (app.init())
if (app.constructWindow("3D Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1200, 600))
while (!app.handleEvents())
{
app.render();
app.update();
}
SDL_DestroyWindow(app.getWindow());
SDL_Quit();
return EXIT_SUCCESS;
}
This is my .cpp file:
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
bool runningOnEmpty = false;
const char* title;
int xpos, ypos, width, height;
bool fullscreen = false;
SDL_Window *window;
SDL_Renderer *renderer;
void init(){
int flags = 0;
if(fullscreen){
flags = SDL_WINDOW_FULLSCREEN;
}
if(!SDL_Init(SDL_INIT_EVERYTHING)){
std::cout << "Sdl initialised!!\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){
std::cout << "renderer created!!\n";
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
}
runningOnEmpty = true;
} else {
runningOnEmpty = false;
}
if(TTF_Init()==-1) {
std::cout << "cannot init TTF: " << TTF_GetError() << "\n";
} else {
std::cout << "TTF initialized!" << "\n";
}
}
void render(){
SDL_RenderClear(renderer);
TTF_Font* rFont = TTF_OpenFont("./fonts/roboto.ttf", 20);
if(!rFont){
std::cout << "Cannot open font: " << TTF_GetError() << "\n";
}
SDL_Color White = {0, 0, 0};
SDL_Surface* surfaceMessage = TTF_RenderText_Solid(rFont, "Score: ", White);
if(surfaceMessage == NULL)
std::cout << "Cannot make surface!" << SDL_GetError() << "\n";
SDL_Texture* Message = SDL_CreateTextureFromSurface(renderer, surfaceMessage);
SDL_Rect mr;
mr.x = 50, mr.y = 50, mr.w = 100, mr.h = 100;
if(Message = NULL)
std::cout << "Cannot make texture!" << SDL_GetError() << "\n";
if(SDL_RenderCopy(renderer, Message, NULL, &mr))
std::cout << "Cannot render text!" << SDL_GetError() << "\n";
SDL_FreeSurface(surfaceMessage);
SDL_RenderPresent(renderer);
}
void clean(){
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
std::cout << "Game cleaned!\n";
}
void handleEvents(){
SDL_Event event;
SDL_PollEvent(&event);
switch(event.type){
case SDL_QUIT:
runningOnEmpty = false;
break;
default:
break;
}
}
int main(){
title = "Test";
xpos = SDL_WINDOWPOS_CENTERED;
ypos = SDL_WINDOWPOS_CENTERED;
width = 800, height = 900;
fullscreen = false;
init();
render();
while(runningOnEmpty){
handleEvents();
}
clean();
return 0;
}
It compiles without error, and when I run the executable it renders a white window, with no text on it(even if it should have some text).
The error comes when I try to use SDL_RenderCopy, and as I acknowledged using SDL_Error(), apparently the texture is invalid, even if I check it before using it.
This is the exact thing that I get in the console when running the code:
Sdl initialised!!
window created!!
renderer created!!
TTF initialized!
Cannot render text!Invalid texture
Game cleaned!
if(Message = NULL) is an assignment, not comparison, so your previous value of Message is lost and it is NULL after that, and that result is used as logic value (NULL == 0 == false, for that matter). Enabling compiler warnings should produce a message pinpointhing this specific problem, e.g. -Wall for gcc gives
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
if(Message = NULL)
To compare values, use == operator.
Also your texture goes out of scope without DestroyTexture, which is clearly a resource leak.
I'm trying to open a window with SDL2 in visual studio 2015. I've set a .bmp image in my code to display to the screen in a window, but when I run my code the program returns 0 and closes without a window. The .bmp image is in the project folder. How do you display the window?
#include <SDL.h>
#include <iostream>
int main(int argc, char* args[])
{
SDL_Window *window = nullptr;
SDL_Surface *windowSurface = nullptr;
SDL_Surface *imageSurface = nullptr;
if (SDL_Init(SDL_INIT_VIDEO) < 0)
std::cout << "Game Initialization error: " << SDL_GetError() << std::endl;
{
window = SDL_CreateWindow("Contrast Beta 0.0.1", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 920, SDL_WINDOW_HIDDEN | SDL_WINDOW_FULLSCREEN);
if (window == NULL)
std::cout << "Window Creation Failed, Error: " << SDL_GetError() << std::endl;
else
{
//Window Created
windowSurface = SDL_GetWindowSurface(window);
imageSurface = SDL_LoadBMP("Background.bmp");
if (imageSurface == NULL)
std::cout << "Error loading background: " << SDL_GetError() << std::endl;
else
{
SDL_BlitSurface(imageSurface, NULL, windowSurface, NULL);
SDL_UpdateWindowSurface(window);
SDL_Delay(2000);
}
}
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Remove SDL_WINDOW_HIDDEN; that's all.
There is the following code. The desired result is that a window is created and a filled circle is drawn:
#include <SDL2/SDL.h>
#include <iostream>
#include <SDL2/SDL2_gfxPrimitives.h>
int main()
{
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
if(SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
std::cout << "Could not initialise" << std::endl;
return 1;
}
window = SDL_CreateWindow("MyGame",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
480,
SDL_WINDOW_SHOWN);
if(!window)
{
std::cout << "Could not create the window" << std::endl;
return 1;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_RenderClear(renderer);
Sint16 circleR = 100;
Sint16 circleX = 300;
Sint16 circleY = 300;
SDL_Surface* windowSurface = SDL_GetWindowSurface(window);
Uint32 circleColour = SDL_MapRGB(windowSurface->format, 255, 0, 0);
int result = filledCircleColor(renderer, circleX, circleY, circleR, circleColour);
std::cout << "drawing the circle r " << circleR << " x " << circleX << " y " << circleY << " circleColour " << circleColour << std::endl;
std::cout << "draw circle result " << result << std::endl;
SDL_RenderPresent(renderer);
bool run = true;
while(run)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
{
run = false;
}
}
}
SDL_Quit();
return 0;
}
The problem is that the circle is not drawn - the window is all black.
The output:
drawing the circle r 100 x 300 y 300 circleColour 16711680
draw circle result 0
filledCircleColor returns 0 what should mean that there's no error.
What should be done so that the circle is drawn? I'm using SDL 2.0.2 on Ubuntu with SDL2 gfx extension.
About SDL_GetWindowSurface, the documentation says : "You may not combine this with 3D or the rendering API on this window."
For me, in your example, SDL_GetWindowSurface returns null.
The filledCircleColor() function takes a color of the form 0xRRGGBBAA.
It works after removing the surface part, and changing to :
int result = filledCircleColor(renderer, circleX, circleY, circleR, 0xFF0000FF);