I'm using SDL 2.0.8 and SDL_image 2.0.3. I've written a small program which renders on screen 2 textures.
When I start the programme my computer is lagging so much that I can't close the programme window. I gave this programme to my friend and when he opened it, he got the same lag as me. We thought that something in my code is bad. We analyzed the code and we saw literally nothing wrong. Then I remembered that I wrote similar code last year and everything was running well. I downloaded it because I had it in the cloud and we ran it. This programme was also lagging. That was totally weird for us. Our graphics cards had 100% utilization because I didn't set framerate lock or vsync.
My computer:
AMD Ryzen 7 2700x #4.3GHz
AMD Radeon R9 390
16 GB RAM DDR4 3000MHz
My friend's computer:
AMD Ryzen 7 1700 #3.6GHz
NVidia GTX 770
16 GB RAM DDR4 3200MHz
I can add that commenting render function in loop removes lags.
EDIT:
It happens only when graphics card utilization is around 100%. Probably when the processor is too weak to run it so fast that graphics card is fully loaded, problem would not ocurr.
Here is code:
Main.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "Client.h"
int main(int argc, char** argv)
{
// Redict strerr to file
freopen("ErrorFile.log", "w", stderr);
Client * c = new Client();
c->start(40);
system("pause");
return 0;
}
Client.h
#pragma once
#include "Graphics.h"
#include <time.h>
class Client
{
public:
Client()
{
gptr = new Graphics();
}
~Client()
{
delete gptr;
gptr = NULL;
}
// -Triggers needed components and starts client
void start(int tickrate)
{
gptr->init();
loop(tickrate);
}
private:
void loop(int tickrate)
{
clock_t start;
clock_t timer;
start = clock();
while (!quit)
{
timer = clock();
while (start + tickrate <= timer)
{
//TODO Mechanics update
start += tickrate;
}
while (SDL_PollEvent(&gptr->e) != 0)
{
if (gptr->e.type == SDL_QUIT)
quit = true;
}
gptr->render();
}
}
private:
Graphics * gptr;
bool quit = false;
};
Graphics.h
#pragma once
#include "Texture.h"
class Graphics
{
public:
void init()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
fprintf(stderr, "Cannot init SDL. Error: %s\n", SDL_GetError());
exit(-1);
}
//Set texture filtering to linear
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"))
{
printf("Warning: Linear texture filtering not enabled!");
}
window = SDL_CreateWindow("Client", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN);
if (window == NULL)
{
fprintf(stderr, "Cannot create window. Error: %s\n", SDL_GetError());
exit(-1);
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL)
{
fprintf(stderr, "Cannot create renderer. Error: %s\n", SDL_GetError());
exit(-1);
}
SDL_RenderClear(renderer);
//Init PNG loading
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
fprintf(stderr, "Cannot init PNG loading. Error: %s\n", IMG_GetError());
exit(-1);
}
loadMedia();
}
void render()
{
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(renderer);
textures[MAP].render(renderer, 0, 0);
textures[CHARACTER].render(renderer, 0, 0);
SDL_RenderPresent(renderer);
}
private:
bool loadMedia()
{
bool success = true;
if (!textures[MAP].loadTexture("res/map.png", renderer))
success = false;
if (!textures[CHARACTER].loadTexture("res/link.png", renderer))
success = false;
return success;
}
public:
SDL_Event e;
private:
SDL_Renderer * renderer;
Texture textures[TOTAL_TEXTURES];
SDL_Window * window;
};
Texture.h
#pragma once
#include <SDL.h>
#include <SDL_image.h>
#include <cstdio>
enum TextureEnum
{
MAP,
CHARACTER,
TOTAL_TEXTURES
};
class Texture
{
public:
Texture()
{
texture = NULL;
width = 0;
height = 0;
}
bool loadTexture(const char* path, SDL_Renderer * renderer)
{
bool success = true;
free();
SDL_Surface* loadedSurface = IMG_Load(path);
if (loadedSurface == NULL)
{
fprintf(stderr, "Cannot load image %s. SDL_image Error: %s\n", path, IMG_GetError());
printf("Cannot load image %s. SDL_image Error: %s\n", path, IMG_GetError());
SDL_FreeSurface(loadedSurface);
success = false;
}
else
{
SDL_SetColorKey(loadedSurface, SDL_TRUE, SDL_MapRGB(loadedSurface->format, 0, 0xFF, 0xFF));
texture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
width = loadedSurface->w;
height = loadedSurface->h;
if (texture == NULL)
{
fprintf(stderr, "Cannot create texture from %s. SDL Error: %s\n", path, SDL_GetError());
printf("Cannot create texture from %s. SDL Error: %s\n", path, SDL_GetError());
success = false;
}
}
SDL_FreeSurface(loadedSurface);
return success;
}
void free()
{
if (texture != NULL)
{
SDL_DestroyTexture(texture);
texture == NULL;
width = 0;
height = 0;
}
}
void render(SDL_Renderer * renderer, int x, int y)
{
SDL_Rect quad = { x, y, width, height };
SDL_RenderCopy(renderer, texture, NULL, &quad);
}
private:
SDL_Texture * texture;
int width;
int height;
};
After updating to the newest Windows 10 version problem did not ocurr.
Related
I want to create a simple program that lets me move around a little sprite with some music.
I'm able to bring up a window, my next step is getting some music. I have everything setup properly as when I build my main.exe with make it builds perfectly. I've narrowed the issue down to the first instance when the mixer is used in the line Mix_OpenAudio(48000, AUDIO_S16SYS, 2, 1024.
I'm not sure why it's not working, but when this line is included, the program simply doesn't open the window and ends the program. On the contrary, when the line isn't included, then the window opens just fine. I've provided a screencap to further illustrate:
Here is my main.cpp code:
#include <iostream>
#include <SDL2/SDL.h>
#include <SDl2/SDL_mixer.h>
//Define window size
const int WIDTH = 800;
const int HEIGHT = 600;
bool init();
void closeWindow();
SDL_Window *window = NULL;
bool init() {
window = SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_ALLOW_HIGHDPI);
if (NULL == window) {
std::cout << "Could not create window: " << SDL_GetError() << std::endl;
return 1;
}
else {
return 0;
}
}
void closeWindow() {
SDL_DestroyWindow(window);
SDL_Quit();
return;
}
int main(int argc, char *argv[]) {
/* Initialize the SDL library */
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
exit(2);
}
/* Opens the audio device */
if (Mix_OpenAudio(48000, AUDIO_S16SYS, 2, 1024) < 0 ) {
fprintf(stderr, "Warning: Couldn't set 48000Hz 16-bit audio\n- Reason: %s\n", SDL_GetError());
}
init();
SDL_Event windowEvent;
while(true) {
if(SDL_PollEvent(&windowEvent)) {
if (SDL_QUIT == windowEvent.type) {
break;
}
}
}
closeWindow();
Mix_CloseAudio();
return EXIT_SUCCESS;
}
How do I fix this issue?
Here's my header file:
#ifndef SOMETHING_H
#define SOMETHING_H
#include <SDL.h>
#include <stdio.h>
#include <string>
#pragma once
class Something {
public:
//Screen dimension constants
int SCREEN_WIDTHS;
int SCREEN_HEIGHTS;
//Starts up SDL and creates window
bool inits();
//Loads media
bool loadMediases();
//Frees media and shuts down SDL
void closes();
Something(int height);
int mains();
//Loads individual image
SDL_Surface* loadSurfaces(std::string path);
//The window we'll be rendering to
SDL_Window* gWindows;
//The surface contained by the window
SDL_Surface* gScreenSurfaces;
//The images that correspond to a keypress
SDL_Surface* gKeyPressSurfaceses[5];
//Current displayed image
SDL_Surface* gCurrentSurfaces;
};
#endif
Here's my cpp file:
//Using SDL, standard IO, and strings
#include <SDL.h>
#include <stdio.h>
#include <string>
#include "Something.h"
class Something {
public:
//Screen dimension constants
int SCREEN_WIDTHS = 640;
int SCREEN_HEIGHTS = 480;
//Key press surfaces constants
enum KeyPressSurfaceses
{
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* gWindows = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurfaces = NULL;
//The images that correspond to a keypress
SDL_Surface* gKeyPressSurfaceses[KEY_PRESS_SURFACE_TOTAL];
//Current displayed image
SDL_Surface* gCurrentSurfaces = NULL;
Something(int height) {
SCREEN_HEIGHTS = height;
}
bool inits()
{
//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
gWindows = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTHS, SCREEN_HEIGHTS, SDL_WINDOW_SHOWN);
if (gWindows == NULL)
{
printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Get window surface
gScreenSurfaces = SDL_GetWindowSurface(gWindows);
}
}
return success;
}
bool loadMedias()
{
//Loading success flag
bool success = true;
//Load default surface
gKeyPressSurfaceses[KEY_PRESS_SURFACE_DEFAULT] = loadSurfaces("resources/images/press.bmp");
if (gKeyPressSurfaceses[KEY_PRESS_SURFACE_DEFAULT] == NULL)
{
printf("Failed to load default image!\n");
success = false;
}
//Load up surface
gKeyPressSurfaceses[KEY_PRESS_SURFACE_UP] = loadSurfaces("resources/images/up.bmp");
if (gKeyPressSurfaceses[KEY_PRESS_SURFACE_UP] == NULL)
{
printf("Failed to load up image!\n");
success = false;
}
//Load down surface
gKeyPressSurfaceses[KEY_PRESS_SURFACE_DOWN] = loadSurfaces("resources/images/down.bmp");
if (gKeyPressSurfaceses[KEY_PRESS_SURFACE_DOWN] == NULL)
{
printf("Failed to load down image!\n");
success = false;
}
//Load left surface
gKeyPressSurfaceses[KEY_PRESS_SURFACE_LEFT] = loadSurfaces("resources/images/left.bmp");
if (gKeyPressSurfaceses[KEY_PRESS_SURFACE_LEFT] == NULL)
{
printf("Failed to load left image!\n");
success = false;
}
//Load right surface
gKeyPressSurfaceses[KEY_PRESS_SURFACE_RIGHT] = loadSurfaces("resources/images/right.bmp");
if (gKeyPressSurfaceses[KEY_PRESS_SURFACE_RIGHT] == NULL)
{
printf("Failed to load right image!\n");
success = false;
}
return success;
}
void closes()
{
//Deallocate surfaces
for (int i = 0; i < KEY_PRESS_SURFACE_TOTAL; ++i)
{
SDL_FreeSurface(gKeyPressSurfaceses[i]);
gKeyPressSurfaceses[i] = NULL;
}
//Destroy window
SDL_DestroyWindow(gWindows);
gWindows = NULL;
//Quit SDL subsystems
SDL_Quit();
}
SDL_Surface* loadSurfaces(std::string path)
{
//Load image at specified path
SDL_Surface* loadedSurface = SDL_LoadBMP(path.c_str());
if (loadedSurface == NULL)
{
printf("Unable to load image %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
}
return loadedSurface;
}
int mains(int argc, char* args[])
{
//Start up SDL and create window
if (!inits())
{
printf("Failed to initialize!\n");
}
else
{
//Load media
if (!loadMedias())
{
printf("Failed to load media!\n");
}
else
{
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//Set default current surface
gCurrentSurfaces = gKeyPressSurfaceses[KEY_PRESS_SURFACE_DEFAULT];
//While application is running
while (!quit)
{
//Handle events on queue
while (SDL_PollEvent(&e) != 0)
{
//User requests quit
if (e.type == SDL_QUIT)
{
quit = true;
}
//User presses a key
else if (e.type == SDL_KEYDOWN)
{
//Select surfaces based on key press
switch (e.key.keysym.sym)
{
case SDLK_UP:
gCurrentSurfaces = gKeyPressSurfaceses[KEY_PRESS_SURFACE_UP];
break;
case SDLK_DOWN:
gCurrentSurfaces = gKeyPressSurfaceses[KEY_PRESS_SURFACE_DOWN];
break;
case SDLK_LEFT:
gCurrentSurfaces = gKeyPressSurfaceses[KEY_PRESS_SURFACE_LEFT];
break;
case SDLK_RIGHT:
gCurrentSurfaces = gKeyPressSurfaceses[KEY_PRESS_SURFACE_RIGHT];
break;
default:
gCurrentSurfaces = gKeyPressSurfaceses[KEY_PRESS_SURFACE_DEFAULT];
break;
}
}
}
//Apply the current image
SDL_BlitSurface(gCurrentSurfaces, NULL, gScreenSurfaces, NULL);
//Update the surface
SDL_UpdateWindowSurface(gWindows);
}
}
}
//Free resources and close SDL
closes();
return 0;
}
};
Why does it keep throwing a "Class" type redefinition error? How can I fix this? I've tried everything but I just run into more problems. I saw some posts relating the issue to defining the class twice, but getting rid of the class definition in the cpp and using classname::functionname just causes more errors.
I know this is a stupid problem to have, I'm a beginning C++ programmer using tutorials and Visual Studio.
In your .cpp file you have completely redeclared class Something. That's not how you do it if you want to just put the implementations of functions in the .cpp file.
The syntax in there should be like:
bool Something::inits()
{
// implementation ...
}
bool Something::loadMedias()
{
// implementation ...
}
And so on
I keep getting this issue when I run my program. My images fail to load in with the error: "Invalid texture". The program used to work fine. I'm working on it in linux ubuntu with all of my drivers updated. Here is the code where the renderer is made and the images are loaded.
//init.h
//#pragma once
#ifndef INIT_H
#define INIT_H
static const int SCREEN_WIDTH = 480;
static const int SCREEN_HEIGHT = 480;
static SDL_Surface* currentSurface = NULL;
static SDL_Window* window = NULL;
static SDL_Surface* screenSurface = NULL;
static SDL_Renderer* renderer = NULL;
//static SDL_Surface *SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 0, SDL_ANYFORMAT);
bool init();
void close();
//void SetColor(int value);
#endif // INIT_H
//init.cpp
//#include "stdafx.h"
#include <stdio.h>
#include "tchar.h"
#include <SDL2/SDL.h>
#include <iostream>
#include <SDL2/SDL_image.h>
#include "main.h"
#include "init.h"
#include "load.h"
//#include <conio.h>
//#include <Windows.h>
#include <string>
#include <SDL2/SDL_ttf.h>
#include <cmath>
bool init()
{
bool boot = 1;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
//SetColor(4);
printf("SDL failed to initialize \n");
//SetColor(7);
boot = 0;
}
else {
printf("SDL initialized!\n");
window = SDL_CreateWindow("Light Development Project", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
if (window == NULL)
{
//SetColor(4);
printf("SDL failed to create the window \n");
//SetColor(7);
boot = 0;
}
else {
printf("Window created!\n");
//screenSurface = SDL_GetWindowSurface(window);
printf("Screen surface created!\n");
}
printf("Initializing SDL_image...\n");
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
//SetColor(4);
printf("Failed to initialize SDL_image\n");
//SetColor(7);
boot = 0;
}
else {
printf("SDL_image initialized!\n");
}
printf("Initializing TTF...\n");
if (TTF_Init() == -1)
{
//SetColor(4);
printf("Failed to initialize TTF\n");
//SetColor(7);
boot = 0;
}
else {
printf("TTF initialized!\n");
}
printf("Creating renderer...\n");
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL)
{
//SetColor(4);
printf("Failed to create renderer. Error: %s\n", SDL_GetError());
//SetColor(7);
boot = 0;
} else
printf("Renderer created!\n");
printf("Setting render draw color...\n");
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
printf("Render draw color set!\n");
}
//printf("Done!\n");
return boot;
}
void close()
{
printf("\nShutting down...\nFreeing SDL surfaces...\nDetroying textures and renderers...\n");
SDL_DestroyTexture(texture);
texture = NULL;
SDL_DestroyRenderer(renderer);
renderer = NULL;
printf("SDL surfaces, textures, and renderers freed from memory!\nDestroying SDL window...\n");
SDL_DestroyWindow(window);
//TTF_CloseFont(font);
//font = NULL;
window = NULL;
printf("SDL window detroyed!\nQuitting SDL subsystems...\n");
IMG_Quit();
SDL_Quit();
//TTF_Quit();
printf("All SDL subsystems shutdown!\n");
}
/*void SetColor(int value) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), value);
/*
1: Blue
2: Green
3: Cyan
4: Red
5: Purple
6: Yellow (Dark)
7: Default white
8: Gray/Grey
9: Bright blue
10: Brigth green
11: Bright cyan
12: Bright red
13: Pink/Magenta
14: Yellow
15: Bright white
}
*/
//load.h
//#pragma once
#ifndef LOAD_H
#define LOAD_H
enum KeyPressSurfacese
{
KEY_PRESS_SURFACE_DEFUALT,
KEY_PRESS_SURFACE_UP,
KEY_PRESS_SURFACE_DOWN,
KEY_PRESS_SURFACE_LEFT,
KEY_PRESS_SURFACE_RIGHT,
KEY_PRESS_SURFACE_TOTAL
};
class cTexture {
public:
cTexture();
~cTexture();
bool loadFromFile(std::string path);
void free();
void render(int x, int y, SDL_Rect* clip = NULL, double angle = 0.0, SDL_Point* center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE);
void loadFromRenderedText(std::string text, SDL_Color color);
void setColor(Uint8 red, Uint8 green, Uint8 blue);
void setBlendMode(SDL_BlendMode blending);
void setAlpha(Uint8 alpha);
int getWidth();
int getHeight();
private:
SDL_Texture * hTexture;
int hWidth;
int hHeight;
};
static cTexture keyPresses[KEY_PRESS_SURFACE_TOTAL];
static cTexture sprite;
static cTexture text;
static SDL_Texture* loadTexture(std::string path);
static SDL_Rect spriteClips[4];
//TTF_Font* font = NULL;
static SDL_Color textColor = { 0, 0, 0 };
void loadAssets();
#endif //LOAD_H
//load.cpp
//#include "stdafx.h"
#include <stdio.h>
#include "tchar.h"
#include <SDL2/SDL.h>
#include <iostream>
#include <SDL2/SDL_image.h>
#include "main.h"
#include "init.h"
#include "load.h"
//#include <conio.h>
//#include <Windows.h>
#include <string>
#include <SDL2/SDL_ttf.h>
#include <cmath>
cTexture::cTexture()
{
//printf("Constructing texture wrapper class...\n");
hTexture = NULL;
hWidth = 0;
hHeight = 0;
}
cTexture::~cTexture()
{
//printf("Destroying texture wrapper class...\n");
free();
}
void cTexture::free()
{
//if (hTexture != NULL)
SDL_DestroyTexture(hTexture);
hTexture = NULL;
hWidth = 0;
hHeight = 0;
}
bool cTexture::loadFromFile(std::string path)
{
free();
SDL_Texture* newTexture = NULL;
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
if(newTexture == NULL)
//printf("fail. error: %s\n", SDL_GetError());
hWidth = loadedSurface->w;
hHeight = loadedSurface->h;
SDL_FreeSurface(loadedSurface);
hTexture = newTexture;
return hTexture != NULL;
}
void cTexture::render(int x, int y, SDL_Rect * clip, double angle, SDL_Point * center, SDL_RendererFlip flip)
{
//SDL_Rect renderQuad = { x, y, hWidth, hHeight };
SDL_Rect renderQuad = { x, y, 480, 480 };
if (clip != NULL)
{
renderQuad.w = clip->w;
renderQuad.h = clip->h;
}
SDL_RenderCopyEx(renderer, hTexture, clip, &renderQuad, angle, center, flip);
}
/*
void cTexture::loadFromRenderedText(std::string text, SDL_Color color)
{
free();
SDL_Surface* textSurface = TTF_RenderText_Solid(font, text.c_str(), textColor);
hTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
hWidth = textSurface->w;
hHeight = textSurface->h;
SDL_FreeSurface(textSurface);
}
*/
void cTexture::setColor(Uint8 red, Uint8 green, Uint8 blue)
{
SDL_SetTextureColorMod(hTexture, red, green, blue);
}
void cTexture::setBlendMode(SDL_BlendMode blending)
{
SDL_SetTextureBlendMode(hTexture, blending);
}
void cTexture::setAlpha(Uint8 alpha)
{
SDL_SetTextureAlphaMod(hTexture, alpha);
}
int cTexture::getWidth() { return hWidth; }
int cTexture::getHeight() { return hHeight; }
void loadAssets()
{
printf("Loading image assets in loadAssets()...\n");
if (!keyPresses[KEY_PRESS_SURFACE_DEFUALT].loadFromFile("carrot.png"))
{
//SetColor(4);
printf("Failed to load image. Error: %s\n", SDL_GetError());
//SetColor(7);
} else
printf("Image loaded\n");
if(!keyPresses[KEY_PRESS_SURFACE_UP].loadFromFile("smIamLU.jpg"))
{
//SetColor(4);
printf("Failed to load image\n");
//SetColor(7);
}
else {
//keyPresses[KEY_PRESS_SURFACE_UP].setBlendMode(SDL_BLENDMODE_BLEND);
printf("Image loaded\n");
}
if(!keyPresses[KEY_PRESS_SURFACE_DOWN].loadFromFile("down.bmp"))
{
//SetColor(4);
printf("Failed to load image\n");
//SetColor(7);
} else
printf("Image loaded\n");
if(!keyPresses[KEY_PRESS_SURFACE_LEFT].loadFromFile("left.bmp"))
{
//SetColor(4);
printf("Failed to load image\n");
//SetColor(7);
}else
printf("Image loaded\n");
if(!keyPresses[KEY_PRESS_SURFACE_RIGHT].loadFromFile("right.bmp"))
{
//SetColor(4);
printf("Failed to load image\n");
//SetColor(7);
}else
printf("Image loaded\n");
if (!sprite.loadFromFile("foo.png"))
{
//SetColor(4);
printf("Failed to load image\n");
//SetColor(7);
}else
printf("Image loaded\n");
spriteClips[0].x = 0;
spriteClips[0].y = 0;
spriteClips[0].w = 64;
spriteClips[0].h = 205;
spriteClips[1].x = 64;
spriteClips[1].y = 0;
spriteClips[1].w = 64;
spriteClips[1].h = 205;
spriteClips[2].x = 128;
spriteClips[2].y = 0;
spriteClips[2].w = 64;
spriteClips[2].h = 205;
spriteClips[3].x = 192;
spriteClips[3].y = 0;
spriteClips[3].w = 64;
spriteClips[3].h = 205;
//font = TTF_OpenFont("Ubuntu-L.ttf", 28);
//text.loadFromRenderedText("text", textColor);
printf("Done!\n");
}
With the renderer I've tried making it with differnt flags such as SDL_RENDERER_ACCELERATED or SDL_RENDERER_SOFTWARE but neither work. The error is specifically coming from the load.cpp file
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
This is the line that fails. The error generated by SDL reads "Invalid texture". The renderer is declared correctly but I can't get it to work.
I'm so confused why it isn't working because it used to work fine. I abandoned the project for a few months and it was working when I stopped, came back, and now it doesn't work. Not to mention that I had a bunch of more problems that I already worked out, but this one I can't.
I figured it out and it's the strangest fix I've ever done. I added an error check for the renderer in the load function and it started working again. If I remove the error check if statement it goes back to not working. Seems like a strange bug but I'm glad it's working again.
i'm trying to create a manual color key with pixel manipulation in SDL2, but when i execute the program, the color key doesn't work, these pixels become white, but not transparent.
I tried to Lock the surface and set the surface blendmode, but doesn't work too.
Code:
// IO includes
#include <iostream>
// String includes
#include <string>
// SDL includes
#include <SDL.h>
#include <SDL_image.h>
// Screen constants
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
using namespace std;
// Window variables
SDL_Window *window = NULL;
SDL_Surface *windowSurface = NULL;
// Image surfaces
SDL_Surface *background = NULL;
SDL_Surface *image = NULL;
// Functions
bool initializeSDL();
SDL_Surface *loadSurfaceFromFile(string path);
void SetColorKey(SDL_Surface *surface, Uint32 color);
bool LoadFiles();
void FreeMemory();
// SDL_main
int main(int argc, char* argv[]){
// Try to initialize and load files
if(initializeSDL() == false){
FreeMemory();
return -1;
}
if(LoadFiles() == false){
FreeMemory();
return -1;
}
// Blit images
SDL_BlitSurface(background, NULL, windowSurface, NULL);
SDL_BlitSurface(image, NULL, windowSurface, new SDL_Rect(70, 277, image->w, image->h));
// Update screen
SDL_UpdateWindowSurface(window);
// Loop
SDL_Event ev;
while(true){
if(SDL_PollEvent(&ev) && ev.type == SDL_QUIT) break;
}
return 0;
}
bool initializeSDL(){
// Try to initialize the video
if( SDL_Init(SDL_INIT_VIDEO) < 0 ){
// Print error
cout << "Error to initialize the video: " << SDL_GetError() << endl;
return false;
}
// Try to create the window
window = SDL_CreateWindow("Surface", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(window == NULL){
// Print error
cout << "Error to create the window: " << SDL_GetError() << endl;
return false;
}
// Try to initialize PNG format
int imgFlags = IMG_INIT_PNG;
if(! (IMG_Init(imgFlags) &imgFlags) ) return false;
// Get the window surface
windowSurface = SDL_GetWindowSurface(window);
// If everything is fine, return true
return true;
}
SDL_Surface* loadSurfaceFromFile(string path){
// Create a temporary surface
SDL_Surface *tmpSurface = NULL;
// Create an optimized surface
SDL_Surface *optimizedSurface = NULL;
// Try to load the tmpSurface
tmpSurface = IMG_Load(path.c_str());
if(tmpSurface == NULL){
// Print error
cout << "Error to load the image: " << SDL_GetError() << endl;
return NULL;
}
// Try to optimize the surface
optimizedSurface = SDL_ConvertSurface(tmpSurface, windowSurface->format, NULL);
SDL_FreeSurface(tmpSurface); // Free tmpSurface memory
delete tmpSurface; // Delete the tmpSurface
if(optimizedSurface == NULL){
// Print error
cout << "Error to optimize the image: " << SDL_GetError() << endl;
}
return optimizedSurface;
}
void SetColorKey(SDL_Surface *surface, Uint32 color){
Uint32 *pixels = (Uint32*)surface->pixels;
int pixelCount = (surface->pitch/4) * surface->h;
Uint32 transparent = SDL_MapRGBA(image->format, 255, 255, 255, 0);
for(int i=0;i<pixelCount;i++){
if(pixels[i] == color){
pixels[i] = transparent;
}
}
}
bool LoadFiles(){
// Try to load the background
background = loadSurfaceFromFile("background.bmp");
if(background == NULL) return false;
// Try to load the image
image = loadSurfaceFromFile("image.png");
if(image == NULL) return false;
// Set manual color key to image
SetColorKey(image, SDL_MapRGB(image->format, 0, 255, 255));
return true;
}
void FreeMemory(){
SDL_FreeSurface(background);
SDL_FreeSurface(image);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
}
I was playing around in SDL2 when I discovered something really strange. I'm trying to draw an optimized texture, but it won't work. The code which turns a surface to a texture doesn't work. According to the documentation, SDL_GetError() should give me the error, but it doesn't return anything... Any help would be appreciated! Here's the code:
Main.cpp:
#include "SDLHelper.h"
#include "Player.h"
#define WIDTH 640
#define HEIGHT 480
#define NAME "TILES BOI!"
int main(int args, char* argv[]){
SDL_Window* gWindow;
SDL_Renderer* gRenderer;
if(!init(NAME, WIDTH, HEIGHT, &gWindow, &gRenderer)){
printf("Failed to initialize!\n");
}else{
bool quit = false;
SDL_Event e;
Player* player = new Player(100, 100, 0, 0);
player->texture = loadTexture("sprites/people/male_walkcycle.png", &gRenderer);
while(!quit){
while(SDL_PollEvent(&e) != 0){
if(e.type == SDL_QUIT){
quit = true;
}
}
SDL_RenderClear(gRenderer);
SDL_RenderCopy(gRenderer, player->texture, &(player->currentTexturePos), &(player->position));
SDL_RenderPresent(gRenderer);
}
close(&gWindow, &gRenderer);
}
return 0;
}
SDLHelper.h:
#ifndef SDLHELPER_H
#define SDLHELPER_H
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
bool init(const char* name, int width, int height, SDL_Window** window, SDL_Renderer** renderer);
SDL_Texture* loadTexture(const char* path, SDL_Renderer** renderer);
void close(SDL_Window** gWindow, SDL_Renderer** gRenderer);
#endif
SDLHelper.cpp:
#include "SDLHelper.h"
bool init(const char* name, int width, int height, SDL_Window** window, SDL_Renderer** renderer){
bool success = true;
if(SDL_Init(SDL_INIT_EVERYTHING) < 0){
printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
success = false;
}else{
if(!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")){
printf("Warning: Linear texture filtering is not enabled!\n");
}
*window = SDL_CreateWindow(name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN);
if(*window == NULL){
printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}else{
*renderer = SDL_CreateRenderer(*window, -1, SDL_RENDERER_ACCELERATED);
if(*renderer == NULL){
printf("Renderer could not be created! SDL 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! SDL_Image Error: %s\n",IMG_GetError());
success = false;
}
}
}
}
return success;
}
SDL_Texture* loadTexture(const char* path, SDL_Renderer** renderer){
SDL_Texture* newTexture = NULL;
SDL_Surface* loaded = IMG_Load(path);
if(loaded == NULL){
printf("Unable to load image %s! SDL_Image Error: %s\n", path, IMG_GetError());
}else{
newTexture == SDL_CreateTextureFromSurface(*renderer, loaded);
if(newTexture == NULL){
printf("Unable to create texture from %s! SDL Error: %s\n", path, SDL_GetError());
}
SDL_FreeSurface(loaded);
}
return newTexture;
}
void close(SDL_Window** gWindow, SDL_Renderer** gRenderer){
SDL_DestroyRenderer(*gRenderer);
SDL_DestroyWindow(*gWindow);
*gWindow = NULL;
*gRenderer = NULL;
//Quit SDL subsystems
IMG_Quit();
SDL_Quit();
}
Player.h:
#ifndef PLAYER_H
#define PLAYER_H
#include <SDL2/SDL.h>
class Player
{
public:
Player(int h, int m, int x, int y);
~Player();
SDL_Texture* texture;
SDL_Rect position;
SDL_Rect currentTexturePos;
int health;
int mana;
const char* name = "Bobby";
};
#endif
Player.cpp:
#include "Player.h"
Player::Player(int h, int m, int x, int y){
health = h;
mana = m;
position.x = x;
position.y = y;
position.h = 64;
position.w = 64;
currentTexturePos.x = 64;
currentTexturePos.y = 0;
currentTexturePos.h = 64;
currentTexturePos.w = 64;
}
Player::~Player(){
SDL_DestroyTexture(texture);
texture = NULL;
}
Makefile:
CC = g++
FLAGS = -w -lSDL2 -lSDL2_image
OBJECTS = main.cpp SDLHelper.cpp Player.cpp
NAME = tileBasedRPG
all: $(OBJECTS)
$(CC) $(OBJECTS) $(FLAGS) -o $(NAME)
clean:
rm -rf *.o
You never assigned newTexture:
newTexture == SDL_CreateTextureFromSurface(*renderer, loaded);
when it meant to be
newTexture = SDL_CreateTextureFromSurface(*renderer, loaded);