I'm just starting to learn SDL, and I'm following one of the tutorials I've found, I wrote a simpl code to render a bmp pic to the screen but its not working, the the problem is that the SDL_CreateRenderer is not created (the pointer keeps pointing to nullptr)
dint main (int argc, char* atgs[]) {
int a = 0;
if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
std::cout << SDL_GetError() << std::endl;
return 1;
}
a = 1;
SDL_Window *win = nullptr;
win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
if (win = nullptr) {
std::cout << SDL_GetError() << std::endl;
return 1;
}
SDL_Renderer *ren = nullptr;
ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (ren == nullptr) {
std::cout << SDL_GetError() << std::endl;
return 1;
}
SDL_Surface *bmp = nullptr;
std::cout << "hello";
bmp = SDL_LoadBMP("c:/hello.bmp");
if (bmp == nullptr) {
std::cout << SDL_GetError() << std::endl;
return 1;
}
SDL_Texture *tex = nullptr;
tex = SDL_CreateTextureFromSurface(ren, bmp);
SDL_FreeSurface(bmp);
SDL_RenderClear(ren);
SDL_RenderCopy(ren, tex, NULL, NULL);
SDL_RenderPresent(ren);
SDL_Delay(2000);
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
ren keeps being null, any idea, why?
I though it was because of the computer but I didn't found any problems online, I'm using win 8.1, intel hd4000 graphic card and visual studio 2012.
thx :)
When you create the SDL_Window you perform a check to see if it is null. This is a good thing to do but in your if statement, instead of using an equals comparison operator == you used an assignment operator =
win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
if (win = nullptr) { // This should be if (win == nullptr) {
std::cout << SDL_GetError() << std::endl;
return 1;
}
This allocates null to the win variable and causes SDL_CreateRenderer to return null since that requires a valid SDL_Window
Related
I'm currently trying to set up a few C++ libraries for a future project. Namely, SDL2.
Here's my code:
#include <iostream>
#include <fstream>
#include <SDL.h>
int SCREEN_WIDTH = 457;
int SCREEN_HEIGHT = 497;
const char* imgpath = "Sprite.bmp";
std::string errmsg;
SDL_Window* window = NULL;
SDL_Surface* screensurface = NULL;
SDL_Surface* image = NULL;
SDL_Rect rect;
struct {
bool wdown;
bool adown;
bool sdown;
bool ddown;
bool edown;
bool escdown;
} kpresses;
void clearkpresses() {
kpresses.wdown = false;
kpresses.adown = false;
kpresses.sdown = false;
kpresses.ddown = false;
kpresses.edown = false;
kpresses.escdown = false;
}
void setrect() {
rect.x = 0;
rect.y = 0;
rect.w = 457;
rect.h = 497;
}
bool gameinit() {
std::ofstream errfile;
errfile.open("errlog.txt");
clearkpresses();
setrect();
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0 ) {
errmsg = "SDL could not initialize! SDL_Error:";
std::cout << errmsg << SDL_GetError() << std::endl;
errfile << errmsg << SDL_GetError() << std::endl;
errfile.std::ofstream::close();
return false;
}
screensurface = SDL_GetWindowSurface(window);
window = SDL_CreateWindow("Transcend", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if( window == NULL ){
errmsg = "Window could not be created! SDL_Error:";
std::cout << errmsg << SDL_GetError() << std::endl;
errfile << errmsg << SDL_GetError() << std::endl;
errfile.std::ofstream::close();
return false;
}
image = SDL_LoadBMP(imgpath);
if (image == NULL) {
errmsg = "Media unable to load! IMG Error: ";
std::cout << errmsg << SDL_GetError() << std::endl;
errfile << errmsg << SDL_GetError() << std::endl;
errfile.std::ofstream::close();
return false;
}
return true;
}
void gamehalt()
{
SDL_DestroyWindow(window);
window = NULL;
SDL_Quit();
}
int main(int argc, char* args[]) {
if (!gameinit()) {
gamehalt();
return 0;
}
bool quit = false;
SDL_Event event;
while (!quit) {
while (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT) {
quit = true;
}
switch(event.type) {
case SDLK_w:
kpresses.wdown = true;
case SDLK_a:
kpresses.adown = true;
case SDLK_s:
kpresses.sdown = true;
case SDLK_d:
kpresses.ddown = true;
case SDLK_e:
kpresses.edown = true;
case SDLK_ESCAPE:
kpresses.escdown = true;
}
}
//TODOUpdate
//TODORender
SDL_BlitSurface(image, NULL, screensurface, &rect);
SDL_UpdateWindowSurface(window);
//reset
clearkpresses();
}
gamehalt();
return 0;
}
Compiled, assembled, and linked with this windows cmd command:
g++ Main.cpp -static-libgcc -static-libstdc++ -I..\include\SDL2\include\SDL2 -I..\include\SDL2_image\include\SDL2 -L..\include\SDL2\lib -L..\include\SDL2_image\lib -w -lmingw32 -lSDL2main -lSDL2 -o ../Transcend.exe
It compiles and runs with no errors, but only displays a blank screen.
The problem is that you are trying to get the window surface, but the window isn't already created.
Please swap those two lines:
screensurface = SDL_GetWindowSurface(window);
window = SDL_CreateWindow("Transcend", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
This way:
window = SDL_CreateWindow("Transcend", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
screensurface = SDL_GetWindowSurface(window);
I am following a french tutorial in order to learn C programming, and I am right now facing the exercice of making a timer, which updates every 100 milliseconds. Since the tutorial is for SDL and I am using SDL2, I am mixing it with some knowledge found on Internet.
If anyone here has time and know some SDL2/SDL_TTF, can you try to solve this ?
The function nulos() is a way to find it the initialization worked out.
To resume, my two problems are : the window closes itself at about 2 seconds and I can't click on the close option, and the second one is my text not showing.
Have a Good Day !
int compteur()
{
SDL_Window *pWindow = NULL;
SDL_Renderer *pRenderer = NULL;
SDL_Texture *pTexture = NULL;
SDL_Surface *pSurface = NULL;
SDL_Surface *pTexte = NULL;
SDL_Event event;
TTF_Font *pFont = NULL;
SDL_Color black = {0, 0, 0};
SDL_Color white = {255, 255, 255};
SDL_Rect position = {200, 200, 0, 0};
int bPlay = 1;
int tempsActuel = 0;
int tempsPrecedent = 0;
int compteur = 0;
char temps[20];
temps[0] = '\0';
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
{
fprintf(stderr, "Erreur SDL_Init : %s ", SDL_GetError());
exit(EXIT_FAILURE);
}
TTF_Init();
pWindow = SDL_CreateWindow("COMPTEUR.C", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
pRenderer = SDL_CreateRenderer(pWindow, -1, SDL_RENDERER_ACCELERATED);
pSurface = SDL_GetWindowSurface(pWindow);
if(nulos(pWindow, pRenderer, pSurface) != 0)
exit(EXIT_FAILURE);
pFont = TTF_OpenFont("images/Gabriola.ttf", 40);
if(pFont == NULL)
{
fprintf(stderr, "Error TTF_OpenFont : %s ", TTF_GetError());
exit(EXIT_FAILURE);
}
TTF_SetFontStyle(pFont, TTF_STYLE_ITALIC | TTF_STYLE_UNDERLINE);
tempsActuel = SDL_GetTicks();
sprintf(temps, "Temps : %d", compteur);
pTexte = TTF_RenderText_Shaded(pFont, temps, black, white);
while(bPlay != 0)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
bPlay = 0;
break;
}
SDL_FillRect(pSurface, NULL, SDL_MapRGB(pSurface->format, black.r, black.g, black.b));
SDL_RenderClear(pRenderer);
tempsActuel = SDL_GetTicks();
if(tempsActuel - tempsPrecedent >= 100)
{
compteur += 100;
sprintf(temps, "Temps : %d", compteur);
pTexte = TTF_RenderText_Shaded(pFont, temps, black, white);
tempsPrecedent = tempsActuel;
}
SDL_BlitSurface(pTexte, NULL, pSurface, &position);
SDL_FreeSurface(pTexte);
pTexture = SDL_CreateTextureFromSurface(pRenderer, pSurface);
SDL_RenderCopy(pRenderer, pTexture, NULL, NULL);
SDL_RenderClear(pRenderer);
}
SDL_DestroyRenderer(pRenderer);
SDL_FreeSurface(pSurface);
SDL_DestroyRenderer(pRenderer);
SDL_DestroyWindow(pWindow);
TTF_Quit();
SDL_Quit();
return EXIT_SUCCESS;
}
int nulos(SDL_Window *w, SDL_Renderer *r, SDL_Surface *s)
{
if(w == NULL)
{
fprintf(stderr, "Erreur SDL_CreateWindow : %s ", SDL_GetError());
return -1;
}
else if(r == NULL)
{
fprintf(stderr, "Erreur SDL_CreateRenderer : %s ", SDL_GetError());
return -1;
}
else if(s == NULL)
{
fprintf(stderr, "Erreur SDL_GetWindowSurface : %s ", SDL_GetError());
return -1;
}
return 0;
}
Okay I have resolved the first problem, it was just a careless mistake. It should have been :
SDL_RenderPresent(pRenderer);
Instead of
SDL_RenderClear(pRenderer);
However the window still closes by itself...
Okay I did it ! For anyone wondering, here's the "good" programming. I put a SDL_PollEvent and moved pTexte elsewhere :
#include "main.h"
int compteur()
{
SDL_Window *pWindow = NULL;
SDL_Renderer *pRenderer = NULL;
SDL_Texture *pTexture = NULL;
SDL_Surface *pSurface = NULL;
SDL_Surface *pTexte = NULL;
SDL_Event event;
TTF_Font *pFont = NULL;
SDL_Color black = {0, 0, 0};
SDL_Color white = {255, 255, 255};
SDL_Rect position;
SDL_bool bQuit = SDL_FALSE;
int tempsActuel = 0;
int tempsPrecedent = 0;
int compteur = 0;
char temps[20];
temps[0] = '\0';
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
fprintf(stderr, "Erreur SDL_Init : %s ", SDL_GetError());
exit(EXIT_FAILURE);
}
TTF_Init();
pWindow = SDL_CreateWindow("COMPTEUR.C", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
pRenderer = SDL_CreateRenderer(pWindow, -1, SDL_RENDERER_ACCELERATED);
SDL_RenderClear(pRenderer);
pSurface = SDL_GetWindowSurface(pWindow);
if(pWindow == NULL || pRenderer == NULL || pSurface == NULL)
{
fprintf(stderr, "Erreur : %s ", SDL_GetError());
exit(EXIT_FAILURE);
}
pFont = TTF_OpenFont("images/Gabriola.ttf", 40);
if(pFont == NULL)
{
fprintf(stderr, "Error TTF_OpenFont : %s ", TTF_GetError());
exit(EXIT_FAILURE);
}
TTF_SetFontStyle(pFont, TTF_STYLE_ITALIC | TTF_STYLE_UNDERLINE);
tempsActuel = SDL_GetTicks();
sprintf(temps, "Temps : %d", compteur);
pTexte = TTF_RenderText_Shaded(pFont, temps, black, white);
if(pTexte == NULL)
{
fprintf(stderr, "Error TTF_RenderText_Shaded : %s ", TTF_GetError());
exit(EXIT_FAILURE);
}
while(!bQuit) //SDL_FALSE == 0
{
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
bQuit = SDL_TRUE;
break;
}
}
tempsActuel = SDL_GetTicks();
if(tempsActuel - tempsPrecedent >= 100)
{
compteur += 100;
sprintf(temps, "Temps : %d", compteur);
tempsPrecedent = tempsActuel;
}
position.x = 180;
position.y = 210;
pTexte = TTF_RenderText_Shaded(pFont, temps, white, black);
SDL_FillRect(pSurface, NULL, SDL_MapRGB(pSurface->format, black.r, black.g, black.b));
SDL_BlitSurface(pTexte, NULL, pSurface, &position);
SDL_FreeSurface(pTexte);
pTexture = SDL_CreateTextureFromSurface(pRenderer, pSurface);
if(pTexture == NULL)
{
fprintf(stderr, "Error SDL_CreateTextureFromSurface : %s ", SDL_GetError());
exit(EXIT_FAILURE);
}
SDL_RenderCopy(pRenderer, pTexture, NULL, NULL);
SDL_RenderPresent(pRenderer);
}
SDL_Delay(20);
SDL_FreeSurface(pSurface);
if(pTexture != NULL)
SDL_DestroyTexture(pTexture);
if(pRenderer != NULL)
SDL_DestroyRenderer(pRenderer);
if(pWindow != NULL)
SDL_DestroyWindow(pWindow);
TTF_Quit();
SDL_Quit();
return EXIT_SUCCESS;
}
Unfortunately I do not get a picture but only a white screen. I am currently learning c ++ and sdl.
error message:
SDL_image Error: Couldn't open test.jpg
I am using Visual Studio on a Windows 10 computer.
#include <SDL.h>
#include <SDL_image.h>
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;;
string ExePath() {
char buffer[MAX_PATH];
GetModuleFileName(NULL, buffer, MAX_PATH);
string::size_type pos = string(buffer).find_last_of("\\/");
return string(buffer).substr(0, pos);
}
int main(int argc, char* args[]) {
cout << "my directory is " << ExePath() << "\n";
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
std::cout << "SDL load fail" << std::endl;
return -1;
}
SDL_Window* window = SDL_CreateWindow("Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 500, 500, SDL_WINDOW_SHOWN);
if (window == NULL) {
std::cout << "Window load fail." << std::endl;
return -1;
}
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
std::cout << "Renderer load fail." << std::endl;
return -1;
}
SDL_Texture* background = IMG_LoadTexture(renderer, "test.jpg");
if (background == NULL) {
printf("SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError());
SDL_Delay(5000);
return -1;
}
SDL_Rect pos;
pos.x = 20;
pos.y = 30;
pos.w = 460;
pos.h = 300;
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, background, NULL, &pos);
SDL_RenderPresent(renderer);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
atexit(SDL_Quit);
return 0;
}
I have already tried the absolute path. The picture is also in the correct folder. Smaller pictures, jpeg, png. I do not know.
SDL Image is a separate library. You should initialize it befor using it. Something like this:
////...
int imgFlags = IMG_INIT_JPG; // or IMG_INIT_PNG;
// not sure about the imgFlags parameter, read the docs.
if( !( IMG_Init( imgFlags ) & imgFlags ) )
{
printf("SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
}
/// the rest is the same...
SDL_Texture* background = IMG_LoadTexture(renderer, "test.jpg");
if (background == NULL) {
printf("SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError());
SDL_Delay(5000);
return -1;
}
/// ...
Some reference https://discourse.libsdl.org/t/help-with-initializing-sdl-image/23601
EDIT: And for the "one step closer": I think your delay is in the wrong place.
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, background, NULL, &pos);
SDL_RenderPresent(renderer);
SDL_Delay(5000); //////// For example try putting int here
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
atexit(SDL_Quit);
std::cout << "Bye!" << std::endl;
return 0;
I've been trying to create a simple C++ game in Visual Studio 2017, but I can't even get a simple black screen. The window comes up white and unresponsive, is anyone able to help? I've been learning from a free course on Udemy, it has been working up until now. My code is below.
#include <iostream>
#include <SDL.h>
#include <string>
using namespace std;
int main(int argc, char* argv[]) {
const int screenWidth = 800;
const int screenLength = 600;
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
cout << "SDL init faliure" << endl;
return 0;
}
SDL_Window *window = SDL_CreateWindow("Particle Fire", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screenWidth, screenLength, SDL_WINDOW_SHOWN);
SDL_Delay(100000);
if (window == NULL) {
SDL_Quit();
return 2;
}
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
SDL_Texture * texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC, screenWidth, screenLength);
if (renderer == NULL) {
cout << "Could not produce renderer";
SDL_DestroyWindow(window);
SDL_Quit();
return 3;
}
if (texture == NULL) {
cout << "Could not produce texture";
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 3;
}
Uint32 *buffer = new Uint32[screenWidth*screenLength];
memset(buffer, 0xFF, screenWidth*screenLength*sizeof(Uint32));
for (int i=0; i < screenWidth*screenLength; i++) {
buffer[i = 0xFFFF0000];
}
SDL_UpdateTexture(texture, NULL, buffer, screenWidth * sizeof(Uint32));
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
bool quit = false;
SDL_UpdateTexture(texture, NULL, buffer, screenWidth * sizeof(Uint32));
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer,texture , NULL, NULL);
SDL_RenderPresent(renderer);
SDL_Event event;
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = true;
} }
}
delete buffer;
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
I've tried changing everything, but it doesn't work.
You have a 100 second delay immediately after you created the window SDL_Delay(100000);.
Also, you need to change buffer[i = 0xFFFF0000] to buffer[i] = 0xFFFF0000. The first only sets i and leaves the buffer unchanged. The second makes the pixel yellow.
So here's my code:
#include "stdafx.h"
int main(int argc, char *argv[])
{
bool quit = false;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = NULL;
window = SDL_CreateWindow("RPG GAME", 100, 100, 600, 400, SDL_WINDOW_SHOWN );
if (window = NULL)
{
std::cout << "Window couldn't be created" << std::endl;
return 0;
}
SDL_Renderer* renderer = NULL;
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_Event* mainEvent = new SDL_Event();
SDL_Texture* grass_image = NULL;
grass_image = IMG_LoadTexture(renderer, "grass.bmp");
SDL_Rect grass_rect;
grass_rect.x = 10;
grass_rect.y = 50;
grass_rect.w = 250;
grass_rect.h = 250;
while (!quit && mainEvent->type != SDL_QUIT)
{
SDL_PollEvent(mainEvent);
SDL_RenderClear(renderer);
//Cia darom
SDL_RenderCopy(renderer, grass_image, NULL, &grass_rect);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
delete mainEvent;
return 0;
}
Whenever I run the application, the window pops up but it's fully white, I've recently set up a dual monitor, and now having some issues while playing GIFs, but I think it doesn't matter. Thank you!
You need to distinguish between '=' and '=='. As in
if (window = NULL) // bad news cause you just nuked window
versus
if (window == NULL) // is window null?