So, I picked up SDL and started writing a simple game. There is some problem I'm very confused about when I try to draw two textures to the screen using SDL_RenderCopy. The important part is inside the while(!quit) where there are two SDL_RenderCopy calls. For some reason only the second one draws something on the screen. Here's my code:
#include <SDL.h>
#include <SDL_image.h>
#include <stdio.h>
const int SCREEN_WIDTH = 1280;
const int SCREEN_HEIGHT = 720;
enum TEXTURES{
T_GRASS,
T_ALL
};
bool init();
bool loadMedia(const int texture, char* path);
void close();
SDL_Texture* loadTexture(char* path);
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_Texture* textures[] = {NULL};
int main(int argc, char* args[]){
if(!init())
printf("Failed to initialize!\n");
else
if(!loadMedia(T_GRASS, "images/tGrass.png"))
printf("Failed to load media!\n");
else{
bool quit = false;
SDL_Event e;
while(!quit){
while(SDL_PollEvent(&e) != 0)
if(e.type == SDL_QUIT)
quit = true;
SDL_RenderClear(renderer);
SDL_Rect pos;
pos.h = 16;
pos.w = 16;
pos.x = 0;
pos.y = 0;
SDL_Rect pos1;
pos1.h = 16;
pos1.w = 16;
pos.x = 16;
pos.y = 16;
SDL_RenderCopy(renderer,textures[T_GRASS],NULL,&pos);
SDL_RenderCopy(renderer,textures[T_GRASS],NULL,&pos1);
SDL_RenderPresent(renderer);
}
}
close();
return 0;
}
bool init(){
bool success = true;
if(SDL_Init(SDL_INIT_VIDEO) < 0){
printf("SDL could not initialize! Error: %s\n", SDL_GetError());
success = false;
}else{
if(!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"))
printf("WARNING: Linear texture filtering not enabled!\n");
window = SDL_CreateWindow("openZ", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(window == NULL){
printf("Window could not be created! Error: %s\n", SDL_GetError());
success = false;
}else{
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if(renderer == NULL){
printf("Render could not be created! Error: %s\n", SDL_GetError());
success = false;
}else{
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
int imgFlags = IMG_INIT_PNG;
if(!(IMG_Init(imgFlags) & imgFlags)){
printf("SDL Image could not initialize! Error: %s\n", SDL_GetError());
success = false;
}
}
}
}
return success;
}
bool loadMedia(const int texture, char* path){
bool success = true;
textures[texture] = loadTexture(path);
if(textures[texture] == NULL){
printf("Failed to load texture image %s!\n", path);
success = false;
}
return success;
}
void close(){
for(int i = 0; i < T_ALL; i++){
SDL_DestroyTexture(textures[i]);
textures[i] = NULL;
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
window = NULL;
renderer = NULL;
IMG_Quit();
SDL_Quit();
}
SDL_Texture* loadTexture(char* path){
SDL_Texture* newTexture = NULL;
SDL_Surface* loadedSurface = IMG_Load(path);
if(loadedSurface == NULL){
printf("Unable to load image %s! Error: %s\n", path, IMG_GetError());
}else{
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
if(newTexture == NULL)
printf("Unable to create texture from %s! Error: %s\n", path, SDL_GetError());
SDL_FreeSurface(loadedSurface);
}
return newTexture;
}
Sorry! My bad.. turns out I had 2 typos which made the two textures render over each other. I wrote:
SDL_Rect pos;
pos.h = 16;
pos.w = 16;
pos.x = 0;
pos.y = 0;
SDL_Rect pos1;
pos1.h = 16;
pos1.w = 16;
pos.x = 16;
pos.y = 16;
where it should have been:
SDL_Rect pos;
pos.h = 16;
pos.w = 16;
pos.x = 0;
pos.y = 0;
SDL_Rect pos1;
pos1.h = 16;
pos1.w = 16;
pos1.x = 16;
pos1.y = 16;
^^ the last too lines were referencing the wrong rectangle.
Related
I'm using SDL2, following LazyFoo's tutorial. I've reached the loading TTF Fonts part and I've seemingly followed everything he did, except adding two extra TTF_Font and SDL_Renderer parameters
bool LTexture::loadFromRenderedText(TTF_Font *&gFont, std::string textureText, SDL_Color textColor, SDL_Renderer *&gRenderer)
{
//Get rid of preexisting texture
free();
//Render text surface
SDL_Surface* textSurface = TTF_RenderText_Solid( gFont, textureText.c_str(), textColor );
if( textSurface == NULL )
{
printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() );
}
else
{
//Create texture from surface pixels
mTexture = SDL_CreateTextureFromSurface( gRenderer, textSurface );
if( mTexture == NULL )
{
printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() );
}
else
{
//Get image dimensions
mWidth = textSurface->w;
mHeight = textSurface->h;
}
//Get rid of old surface
SDL_FreeSurface( textSurface );
}
return 1;
}
This is the function, and this is where it's called:
gFont = TTF_OpenFont( "Font/comicSans.ttf", 28 );
if( gFont == NULL )
{
printf( "Failed to load COMIC_SANS font! SDL_ttf Error: %s\n", TTF_GetError() );
success = false;
}
else
{
//Render text
SDL_Color textColor = { 0, 0, 0 };
if( !gTextTexture.loadFromRenderedText(gFont, "Hello I am hot", textColor, gRenderer));
{
printf( "Failed to render text texture!\n" );
success = false;
}
}
if succes is false, the program prints "Failed loading media"
This is the output I get from running the program, notice how there are no actual SDL or TTF errors, only the one that appears when loadFromRendereredText returns false, which it doesn't, as I have set it to return 1:
Failed to render text texture!
Failed to load media!
The only actual difference from my files and LazyFoo's files are that my LTexture class is in a separate file than main, and that's why for some reason I couldn't use gFont and gRenderer (global variables)
Any idea what might be causing this?
FULL CODE:
main.cpp:
/*This source code copyrighted by Lazy Foo' Productions (2004-2019)
and may not be redistributed without written permission.*/
//Using SDL and standard IO
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <stdio.h>
#include <string>
#include "LTexture.h"
bool init();
bool loadMedia();
void close();
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
SDL_Renderer* gRenderer = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
TTF_Font *gFont = NULL;
LTexture gTextTexture;
//Screen dimension constants
const int SCREEN_WIDTH = 500;
const int SCREEN_HEIGHT = 500;
int main(int argc, char* args[])
{
//Start up SDL and create window
if( !init() )
{
printf( "Failed to initialize!\n" );
}
else
{
//Load media
if( !loadMedia() )
{
printf( "Failed to load media!\n" );
}
else
{
//Main loop flag
bool quit = false;
//Event handler
SDL_Event event;
//While application is running
while( !quit )
{
//Handle events on queue
while( SDL_PollEvent( &event ) != 0 )
{
//User requests quit
if( event.type == SDL_QUIT )
{
quit = true;
}
}
//Clear screen
SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear( gRenderer );
gTextTexture.render(gRenderer, (SCREEN_WIDTH - gTextTexture.getWidth()) / 2, (SCREEN_HEIGHT - gTextTexture.getHeight()) / 2);
//Update screen
SDL_RenderPresent( gRenderer );
}
}
}
//Free resources and close SDL
close();
return 0;
}
bool init()
{
//Initialization flag
bool success = true;
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Create window
gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if( gWindow == NULL )
{
printf( "Window could not be created! SDL Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Create renderer for window
gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if( gRenderer == NULL )
{
printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Initialize renderer color
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
//Initialize PNG loading
int imgFlags = IMG_INIT_PNG;
if( !( IMG_Init( imgFlags ) & imgFlags ) )
{
printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
success = false;
}
//Initialize SDL_ttf
if( TTF_Init() == -1 )
{
printf( "SDL_ttf could not initialize! SDL_ttf Error: %s\n", TTF_GetError() );
success = false;
}
}
}
}
return success;
}
bool loadMedia()
{
//Loading success flag
bool success = true;
//Open the font
gFont = TTF_OpenFont( "Font/comicSans.ttf", 28 );
if( gFont == NULL )
{
printf( "Failed to load COMIC_SANS font! SDL_ttf Error: %s\n", TTF_GetError() );
success = false;
}
else
{
//Render text
SDL_Color textColor = { 0, 0, 0 };
if( !gTextTexture.loadFromRenderedText(gFont, "Hello I am hot", textColor, gRenderer));
{
printf( "Failed to render text texture!\n" );
success = false;
}
}
return success;
}
void close()
{
//Free loaded images
gTextTexture.free();
//Destroy window
SDL_DestroyRenderer( gRenderer );
SDL_DestroyWindow( gWindow );
TTF_CloseFont(gFont);
gWindow = NULL;
gRenderer = NULL;
gFont = NULL;
//Quit SDL subsystems
TTF_Quit();
IMG_Quit();
SDL_Quit();
}
LTexture.h:
#ifndef LTEXTURE_INCLUDED
#define LTEXTURE_INCLUDED
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <stdio.h>
#include <string>
//Texture wrapper class
class LTexture
{
public:
//Initializes variables
LTexture();
//Deallocates memory
~LTexture();
//Loads image at specified path
bool loadFromFile( std::string path, SDL_Renderer *&gRenderer);
//Loads image from string text
bool loadFromRenderedText(TTF_Font *&gFont, std::string textureText, SDL_Color textColor, SDL_Renderer *&gRenderer);
//Deallocates texture
void free();
//Set color modulation
void setColor( Uint8 red, Uint8 green, Uint8 blue );
//Set blending
void setBlendMode( SDL_BlendMode blending );
//Set alpha modulation
void setAlpha( Uint8 alpha );
//Renders texture at given point
void render(SDL_Renderer *&gRenderer, int x, int y, SDL_Rect *clip = NULL, double angle = 0.0, SDL_Point* center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE );
//Gets image dimensions
int getWidth(){return mWidth;}
int getHeight(){return mHeight;}
private:
//The actual hardware texture
SDL_Texture* mTexture;
//Image dimensions
int mWidth;
int mHeight;
};
#endif // LTEXTURE_INCLUDED
LTexture.cpp:
#include "LTexture.h"
LTexture::LTexture()
{
mTexture = NULL;
mWidth = 0;
mHeight = 0;
}
LTexture::~LTexture()
{
//Deallocate resources
free();
}
bool LTexture::loadFromFile(std::string path, SDL_Renderer *&gRenderer)
{
free();
SDL_Texture* newTexture = NULL;
SDL_Surface *loadedSurface = IMG_Load(path.c_str());
if(loadedSurface == NULL)
{
printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError());
}
else
{
//Color key image
SDL_SetColorKey( loadedSurface, SDL_TRUE, SDL_MapRGB( loadedSurface->format, 0, 0xFF, 0xFF ) );
newTexture = SDL_CreateTextureFromSurface(gRenderer, loadedSurface);
if(newTexture == NULL)
{
printf( "Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError() );
}
else
{
mWidth = loadedSurface->w;
mHeight = loadedSurface->h;
}
SDL_FreeSurface( loadedSurface );
}
mTexture = newTexture;
return mTexture != NULL;
}
bool LTexture::loadFromRenderedText(TTF_Font *&gFont, std::string textureText, SDL_Color textColor, SDL_Renderer *&gRenderer)
{
//Get rid of preexisting texture
free();
//Render text surface
SDL_Surface* textSurface = TTF_RenderText_Solid( gFont, textureText.c_str(), textColor );
if( textSurface == NULL )
{
printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() );
}
else
{
//Create texture from surface pixels
mTexture = SDL_CreateTextureFromSurface( gRenderer, textSurface );
if( mTexture == NULL )
{
printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() );
}
else
{
//Get image dimensions
mWidth = textSurface->w;
mHeight = textSurface->h;
}
//Get rid of old surface
SDL_FreeSurface( textSurface );
}
return 1;
}
void LTexture::free()
{
if(mTexture != NULL){
SDL_DestroyTexture(mTexture);
mTexture = NULL;
mWidth = 0;
mHeight = 0;
}
}
void LTexture::setColor( Uint8 red, Uint8 green, Uint8 blue )
{
//Modulate texture
SDL_SetTextureColorMod( mTexture, red, green, blue );
}
void LTexture::setBlendMode( SDL_BlendMode blending )
{
//Set blending function
SDL_SetTextureBlendMode( mTexture, blending );
}
void LTexture::setAlpha( Uint8 alpha )
{
//Modulate texture alpha
SDL_SetTextureAlphaMod( mTexture, alpha );
}
void LTexture::render(SDL_Renderer *&gRenderer, int x, int y, SDL_Rect *clip, double angle, SDL_Point *center, SDL_RendererFlip flip)
{
//Set rendering space and render to screen
SDL_Rect renderQuad = { x, y, mWidth, mHeight };
if( clip != NULL )
{
renderQuad.w = clip->w;
renderQuad.h = clip->h;
}
SDL_RenderCopyEx( gRenderer, mTexture, clip, &renderQuad, angle, center, flip );
}
The problem is the semicolon at the end of your if statement.
if( !gTextTexture.loadFromRenderedText(gFont, "Hello I am hot", textColor, gRenderer));
{
printf( "Failed to render text texture!\n" );
success = false;
}
That semicolon will create an empty statement for that if block, it will cause your
{
printf( "Failed to render text texture!\n" );
success = false;
}
to always execute. It's like this,
if(.....)
;
{
....
}
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;
}
I've written small sdl application. Problem is that is crashes almost everything when I launch it. Every window loses title bar. Application sometimes pops up, sometimes doesn't. If it does, pressing q (key for quitting) closes it but other windows remains 'broken'. Only way to get rid of this is to logout and then log in again.
Here's code:
#include <bits/stdc++.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
const int screen_x = 800;
const int screen_y = 600;
SDL_Window* window = nullptr;
SDL_Texture* textures[3];
SDL_Texture* currentTexture = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_Event event;
bool running = true;
SDL_Texture* loadTexture(const char* path)
{
SDL_Texture* texture = nullptr;
SDL_Surface* load = IMG_Load(path);
if (!load)
{
printf("Failed to load image %s. Error: %s\n", path, IMG_GetError());
}
else
{
texture = SDL_CreateTextureFromSurface(renderer, load);
if (!texture)
{
printf("Failed to convert surface from %s. Error: %s\n", path, SDL_GetError());
}
SDL_FreeSurface(load);
}
return texture;
}
bool loadMedia()
{
bool success = true;
currentTexture = textures[0] = loadTexture("./img/1.png");
if (!textures[0])
{
printf("Failed to load texture\n");
success = false;
}
textures[1] = loadTexture("./img/2.png");
if (!textures[1])
{
printf("Failed to load texture\n");
success = false;
}
textures[2] = loadTexture("./img/3.png");
if (!textures[2])
{
printf("Failed to load texture\n");
success = false;
}
return success;
}
bool init()
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
printf("Error: %s\n", SDL_GetError());
return false;
}
else
{
window = SDL_CreateWindow("SDL with linux", 0, 0, screen_x, screen_y, SDL_WINDOW_SHOWN);
if (!window)
{
printf("Error: %s\n", SDL_GetError());
return false;
}
else
{
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer)
{
printf("Error: %s\n", SDL_GetError());
return false;
}
else
{
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
int imgFlags = IMG_INIT_PNG;
if ((IMG_Init(imgFlags) & imgFlags) != imgFlags)
{
printf("Error: %s\n", SDL_GetError());
return false;
}
}
}
}
return true;
}
void close()
{
for (unsigned i = 0; i < 3; i++)
{
SDL_DestroyTexture(textures[i]);
textures[i] = nullptr;
}
SDL_DestroyRenderer(renderer);
renderer = nullptr;
SDL_DestroyWindow(window);
window = nullptr;
IMG_Quit();
SDL_Quit();
}
int main(int argc, char** argv)
{
if (!init())
{
printf("Initialization error\n");
}
else
{
if (!loadMedia())
{
printf("Media loading error\n");
}
else
{
while (running)
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
running = false;
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_q:
running = false;
break;
case SDLK_1:
currentTexture = textures[0];
break;
case SDLK_2:
currentTexture = textures[1];
break;
case SDLK_3:
currentTexture = textures[2];
break;
}
break;
}
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, currentTexture, nullptr, nullptr);
SDL_RenderPresent(renderer);
SDL_Delay(80);
}
}
}
close();
return 0;
}
Makefile:
CC = g++
CFlags = -Wall -std=c++11
Input = main.cpp
Output = -o ./bin/prog
Linker = -lSDL2 -lSDL2_image -lSDL2_ttf -lSDL2_mixer
all:
$(CC) $(Input) $(CFlags) $(Linker) $(Output)
Screenshot showing behavior of application
Im sorry this is going to be more like a comment but i dont have 50 reputation to comment in questions . Can you provide a screenshot of the window?
If not then try using SDL_WINDOWPOS_CENTERED at the x and y axis then see if the window is showing up. Please share if this worked
As you can see below there is bmp image but its background color is white:
How can i change it to be for example black (without editing the bmp image itself)?
Here I have code to show bmp image on window:
#include <iostream>
#include "SDL.h"
using namespace std;
int main(int argc, char *args[])
{
SDL_Window *window = nullptr;
SDL_Renderer *renderer = nullptr;
SDL_Surface *surface = nullptr;
SDL_Texture *texture = nullptr;
SDL_Event event;
SDL_Rect positionRect;
SDL_Rect dimensionRect;
positionRect.x = 0;
positionRect.y = 0;
positionRect.w = 100;
positionRect.h = 100;
dimensionRect.x = 0;
dimensionRect.y = 0;
dimensionRect.w = 300;
dimensionRect.h = 300;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
return 1;
}
if (SDL_CreateWindowAndRenderer(500, 500, SDL_WINDOW_OPENGL, &window, &renderer)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window and renderer: %s", SDL_GetError());
return 1;
}
surface = SDL_LoadBMP("sample.bmp");
if (!surface) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create surface from image: %s", SDL_GetError());
return 1;
}
texture = SDL_CreateTextureFromSurface(renderer, surface);
if (!texture) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture from surface: %s", SDL_GetError());
return 1;
}
SDL_FreeSurface(surface);
surface = nullptr;
while (1) {
SDL_PollEvent(&event);
if (event.type == SDL_QUIT) {
break;
}
//SDL_SetRenderDrawColor(renderer, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, &positionRect, &dimensionRect);
SDL_RenderPresent(renderer);
}
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
You should add these 2 lines,
Uint32 colorkey = SDL_MapRGB(surface->format, 255, 255, 255);
SDL_SetColorKey(surface, SDL_TRUE, colorkey);
before this line in your code
texture = SDL_CreateTextureFromSurface(renderer, surface);
So I just started doing some SDL tutorials and I got to one when suddenly I get an error message saying "ld: library not found for -lstring". Says the same thing about stdio.
I tried adding the paths and libraries. I use the MacOS X C++ Linker (MacOSX GCC Tool Chain) but I just can't seem to get it to work. Any ideas?
I'm on Eclipse btw.
/*
* Main.cpp
*
* Created on: 29 jan 2014
* Author: CaptainAwesome
*/
//Using SDL and standard IO
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
#include <string>
//Starts up SDL and creates window
bool init();
//Loads media
bool loadMedia();
//Free media and shuts down SDL
void close();
//Loads individual image
SDL_Surface* loadSurface(std::string path);
//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
enum KeyPressSurfaces
{
KEY_PRESS_SURFACE_DEFAULT,
KEY_PRESS_SURFACE_UP,
KEY_PRESS_SURFACE_DOWN,
KEY_PRESS_SURFACE_LEFT,
KEY_PRESS_SURFACE_RIGHT,
KEY_PRESS_SURFACE_TOTAL
};
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//The image that corresponds to a keypress
SDL_Surface* gKeyPressSurfaces[ KEY_PRESS_SURFACE_TOTAL];
//The image we will load and show on the screen
SDL_Surface* gCurrentSurface = NULL;
bool init()
{
//Init flag
bool success = true;
//Init SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Create window
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(gWindow == NULL)
{
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Get window surface
gScreenSurface = SDL_GetWindowSurface( gWindow );
}
}
return success;
}
SDL_Surface* loadSurface(std::string path)
{
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
if(loadedSurface == NULL)
{
printf("Unable to load image %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
}
return loadedSurface;
}
bool loadMedia()
{
//Load success flag
bool success = true;
//Load default surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT] = loadSurface("Assets/maxresdefault.jpg");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT] == NULL)
{
printf("Unable to load default image %s\n!");
success = false;
}
//Load up surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_UP] = loadSurface("Assets/1.jpg");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_UP] == NULL)
{
printf("Unable to load up image %s\n!");
success = false;
}
//Load down surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN] = loadSurface("Assets/duty_calls");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN] == NULL)
{
printf("Unable to load down image %s\n!");
success = false;
}
//Load up surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT] = loadSurface("Assets/mario-land.jpg");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT] == NULL)
{
printf("Unable to load left image %s\n!");
success = false;
}
//Load up surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT] = loadSurface("Assets/ML.jpg");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT] == NULL)
{
printf("Unable to load right image %s\n!");
success = false;
}
return success;
}
void close()
{
//Deallocate surface
SDL_FreeSurface(gCurrentSurface);
gCurrentSurface = NULL;
//Destroooooy window
SDL_DestroyWindow(gWindow);
gWindow = NULL;
//Quit SDL subsystems
SDL_Quit();
}
int main (int argc, char* args[])
{
//Start up SDL and create window
if(!init())
{
printf("Fail to init!\n");
}
else
{
//Load media
if(!loadMedia())
{
printf("Failed to load media!\n");
}
else
{
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//Set default current surface
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT];
//While app is running
while(!quit)
{
while(SDL_PollEvent(&e) != 0)
{
//User presses esc
if(e.type == SDL_QUIT)
{
quit = true;
}
//User presses a key (up, down, left, right)
else if(e.type)
{
//Select surfaces based on key pressed
switch(e.key.keysym.sym)
{
case SDLK_UP:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_UP];
break;
case SDLK_DOWN:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN];
break;
case SDLK_LEFT:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT];
break;
case SDLK_RIGHT:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT];
break;
case SDLK_ESCAPE:
quit = true;
break;
default:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT];
break;
}
}
//Apply image
SDL_BlitScaled(gCurrentSurface, NULL, gScreenSurface, NULL);
//Update surface
SDL_UpdateWindowSurface(gWindow);
}
}
}
}
//Free resources and close SDL
close();
return 0;
}