I am having troubles with SDL_Texture
RPGTutorial.cpp
#include "stdafx.h"
int main(int argc, char *argv[])
{
bool quit = false;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = NULL;
window = SDL_CreateWindow("RPG Tutorial!", 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);
if (renderer == NULL)
{
std::cout << "Renderer is not being created!" << std::endl;
SDL_DestroyWindow(window);
system("PAUSE");
return 0;
}
SDL_Event* mainEvent = new SDL_Event();
SDL_Texture* grass = NULL;
grass = IMG_LoadTexture(renderer, "Grass.bmp");
if (grass == NULL)
{
std::cout << "Grass Image was not found!" << std::endl;
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
delete mainEvent;
system("PAUSE");
return 0;
}
SDL_Rect grass_rect;
grass_rect.x = 0;
grass_rect.y = 0;
grass_rect.w = 64 * 2;
grass_rect.h = 64 * 2;
while (!quit && mainEvent->type != SDL_QUIT)
{
SDL_PollEvent(mainEvent);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, grass, NULL, &grass_rect);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
delete mainEvent;
return 0;
}
stdafx.h
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_mixer.h>
#include <iostream>
I have the Grass.bmp in the RPGTutorial->RPGTutorial->Grass.bmp
When I compile it, it is successful. It runs through the code til I get to the part where it checks if(grass == NULL) and it goes through that and exits. Can someone help me know why my grass is not being set to the image when I have the image in the same folder that the .cpp files are in? I even tried adding an Image folder to hold it in, and it did not work either.
If you have the time, I recommend you take some time to go through the Lazyfoo tutorials they are fantastic. He mentions this issue in the second tutorial, "Getting an Image on the Screen."
Visual Studio changes your current working directory to the place where your .vcxproj file is. That will be the directory you want to place your resources in. If you're not sure where that is, you can use the _getcwd() function in the direct.h header MSDN Source For getcwd
Related
I have the following code in main.cpp:
#include <SDL2/SDL.h>
#include <iostream>
int main(){
SDL_Init(SDL_INIT_VIDEO);
bool quit = false;
SDL_Event event;
SDL_Window * window = SDL_CreateWindow("Chess",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 720, 640, 0);
SDL_Delay(100);
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_Surface * board = SDL_LoadBMP("board.bmp");
if (board == NULL) {
std::cout << "The image 'board.bmp' could not be loaded due to the following SDL error: " << SDL_GetError() << std::endl;
return 1;
}
else {
std::cout << "The image 'board.bmp' was loaded successfully" << std::endl;
}
SDL_Texture * board_texture = SDL_CreateTextureFromSurface(renderer, board);
if (board_texture == nullptr){
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
std::cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
SDL_RenderCopy(renderer, board_texture, NULL, NULL);
while (!quit)
{
SDL_WaitEvent(&event);
SDL_RenderPresent(renderer);
switch (event.type)
{
case SDL_QUIT:
quit = true;
break;
}
SDL_Delay(15);
}
SDL_DestroyTexture(board_texture);
SDL_FreeSurface(board);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Both error checks return nothing, and I can't figure out why.
Also, I build using:
g++ chess.cpp -o chess -I include -L lib -l SDL2-2.0.0
This seems to work for my Windows PC, but not on my Intel Macbook Pro. Are there any solutions/workarounds available?
As documentation says
The backbuffer should be considered invalidated after each present; do
not assume that previous contents will exist between frames. You are
strongly encouraged to call SDL_RenderClear() to initialize the
backbuffer before starting each new frame's drawing, even if you plan
to overwrite every pixel.
So it should be:
SDL_WaitEvent(&event);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, board_texture, NULL, NULL);
SDL_RenderPresent(renderer);
The program doesnt show the image in the window i have created , also i dont get any of the fail messages that i have set , which means the values are not null.
What is the problem?
Here is the code:
#include "SDL.h"
#include "SDL_image.h"
#include <iostream>
int main(int argc,char* argv[])
{
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Event event;
bool quit = false;
SDL_Surface *tmpsur = NULL;
SDL_Texture *tex = NULL;
SDL_Init(SDL_INIT_EVERYTHING);
window = SDL_CreateWindow("First window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, 0);
tmpsur = IMG_Load("assets/player.png");
if (tmpsur == NULL)
{
std::cout << "fail" << std::endl;
}
tex = SDL_CreateTextureFromSurface(renderer,tmpsur);
if (tex == NULL)
{
std::cout << "fail 2" << std::endl;
}
SDL_FreeSurface(tmpsur);
SDL_RenderPresent(renderer);
while (!quit)
{
while (SDL_PollEvent(&event) != 0)
{
if(event.type == SDL_QUIT)
{
quit = true;
}
}
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0;
}
You need to copy your texture onto the render target. Before presenting your renderer you need to call SDL_RenderCopy like this:
SDL_RenderCopy(renderer, text, nullptr, nullptr);
SDL_RenderPresent(renderer);
The nullptrs in the argument will make it copy the texture over all your target (the window).
Trying to load an image onto an SDL_Surface. However the surface is always black although the bmp is clearly not.
NOTE
This is a working SDL_Window and creating a surface pointer is successful, what is unsuccessful is loading "Kassadin.bmp" which is located in the Code::Blocks project folder. It displays a black surface.
ALL answers on this particular question have NOT solved this problem, before marking this as a duplicate.
#include <iostream>
#include <SDL.h>
#include <stdio.h>
using namespace std;
const int SCREEN_WIDTH = 700;
const int SCREEN_HEIGHT = SCREEN_WIDTH / 12 * 9;
//Create an SDL_Window pointer
SDL_Window* window = NULL;
//Create an SDL_Surface pointer
SDL_Surface* surface = NULL;
//SDL_Surface for an image
SDL_Surface* imgSurface = NULL;
bool init(){
//try init SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0){
cout << "Failed init SDL" << endl;
return false;
}else{
//create window title x pos y pos width height flags
//This doesnt include a surface ie it will be a plain window
window = SDL_CreateWindow("An SDL Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
}
if(window == NULL){
cout << "Failed creating SDL window" << endl;
return false;
}else{
// creates surface with an SDL_Window object
surface = SDL_GetWindowSurface(window);
}
return true;
}
bool loadMedia(){
imgSurface = SDL_LoadBMP("Kassadin.bmp");
return true;
}
void close(){
//Sets the SDL_Window pointer to NULL again
SDL_DestroyWindow(window);
window = NULL;
SDL_FreeSurface (imgSurface);
imgSurface = NULL;
//quits
SDL_Quit();
}
int main(int argc, char* argv[]){
if(!init()){
cout << "error init sdl" << endl;
}else{
if(!loadMedia){
cout << "Trouble loading media..." << endl;
}else{
SDL_BlitSurface(imgSurface, NULL, surface, NULL);
}
}
//This is so it's not just a static window ie it can update
SDL_UpdateWindowSurface(window);
SDL_Delay(5000);
close();
return 0;
}
Problemmatic line is
if(!loadMedia){
It is not a function call. What it does is checks address of function loadMedia is NULL, which is always false because function address assigned by linker (as opposed to funciton pointers which you manually assign at runtime).
As you mentioned codeblocks, I suppose you use gcc to compile your code. If only you've added at least -Wall flag (which is a very good practice) compiler would have warned you that you're doing something that very much looks like a mistake:
test2.cpp:70:9: warning: the address of ‘bool loadMedia()’ will always evaluate as ‘true’ [-Waddress]
so I was following this tutorial, and everything was going all smooth and dandy, until I encountered a problem, namely that I couldn't load a .bmp.
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
#include <iostream>
#include <SDL2/SDL_main.h>
using namespace std;
int main(int argc, char* argv[]) {
bool quit = false;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window;
window = SDL_CreateWindow("window", 100, 100, 1280, 720, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
if(window == NULL){
cout << "Disn't work, here is why: " << SDL_GetError()<< 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);
SDL_RenderCopy(renderer, grass_image, NULL, &grass_rect);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
delete mainEvent;
return 0;
}
When I try to compile the code (in Code::Blocks) it gives me the error of
Undefined reference to "IMG_LoadTexture"
Well, I tried to change IMG_LoadTexture(renderer, "grass.bmp"); to IMG_LoadTexture(renderer, "/the/full/path/of/grass.bmp");but this didn't work either. Same error. Have I written something wrong, or missed some part? Also, grass.bmp is in the same folder as main.cpp (the code above).
The error here says that you have declared a function but have not defined it - undefined reference.
Most probably it happened because you forgot to link against library SDL_image to which function IMG_LoadTexture belongs.
i've installed SDL to develop a program, and while on the test phase for this lib, the compiled code does not execute, and i mean it won't even open the cmd box. The weird thing is, it occasionally executes.
I'm using Eclipse Hellios with minGW32 and i686-w64-mingw32 on windows10.
My test code is:
#include <iostream>
#include <Windows.h>
#include <SDL2/SDL.h>
int main(int, char**)
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) return 1;
SDL_Window *window = SDL_CreateWindow("", 300, 100, 1024, 800, SDL_WINDOW_OPENGL);
if (window == NULL)
{
std::cout << "SDL init Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface *background = SDL_LoadBMP("Resources/Lilothyn.bmp");
if (background == NULL)
{
SDL_ShowSimpleMessageBox(0, "Background init error", SDL_GetError(), window);
return 1;
}
if (renderer == NULL)
{
SDL_ShowSimpleMessageBox(0, "Renderer init error", SDL_GetError(), window);
}
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, background);
if (texture == NULL)
{
SDL_ShowSimpleMessageBox(0, "Texture init error", SDL_GetError(), window);
}
SDL_RenderPresent(renderer);
SDL_Event event;
bool running = true;
while(running)
{
SDL_PollEvent(&event);
switch(event.type)
{
case SDL_QUIT:
running = false;
SDL_DestroyTexture(texture);
SDL_FreeSurface(background);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
break;
default: break;
}
}
return 0;
}
the odd thing is, i previously had "SDL_LoadBMP("Resources/TommyBMP.bmp");" and it executed properly. Changing a string shouldn't make the program stop working, both files are at the Debug/Resources folder so it can't be a case of not finding them...
note: further testing shows that a simple "hello world" has the same issue, so the problem will likely not be from SDL.
"help me obi wan, you're my only hope".