PollEvent not working without mouse movement[SDL] - c++

PollEvent is bypassed if mouse isn't moving within window or any key is not pressed when supposed to run animation. Here's the code:
SDL_Init(SDL_INIT_EVERYTHING);
int imgFlags = IMG_INIT_PNG | IMG_INIT_JPG;
if (IMG_Init(imgFlags) != imgFlags)
{
std::cout << IMG_GetError() << std::endl;
}
window = SDL_CreateWindow("NRG", 200, 200, 800, 600, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED| SDL_RENDERER_PRESENTVSYNC);
isRunning = true;
while (isRunning)
{
while (SDL_PollEvent(&ev))
{
heroImg = LoadTxt("image.png", renderer);
SDL_QueryTexture(heroImg, NULL, NULL, &textureWidth, &textureHeight);
frameWidth = textureWidth / 3;
frameHeight = textureHeight / 4;
heroRct.x = 0;
heroRct.y = 0;
heroRct.h = frameHeight;
heroRct.w = frameWidth;
frameTime++;
if (60 / frameTime == 4)
{
frameTime = 0;
heroRct.x += frameWidth;
if (heroRct.x >= textureWidth)
heroRct.x = 0;
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, heroImg, &heroRct, NULL);
SDL_RenderPresent(renderer);
}
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
window = NULL;
windowSurface = NULL;
renderer = NULL;
SDL_Quit();
Other stuff like SDL_Event ev; is included in .h file

For anybody with the same problem:
Put your render etc. outside of the while (SDL_PollEvent(&ev)) loop :)
Stupid mistake, pretty hard to solve for begginer :)

Related

How to load multiple images in SDL_image and SDL2?

I've been trying to load 2 images in a SDL window, like a player and an enemy, but SDL2_image loads only one image at a time
here's my code :
#include<iostream>
#define SDL_MAIN_HANDLED
#include<SDL2/SDL.h>
#include<SDL2/SDL_image.h>
using namespace std;
SDL_Texture* load(SDL_Renderer* ren, const char* path, SDL_Rect rect)
{
SDL_Texture* img = IMG_LoadTexture(ren, path);
if (img == NULL)
cout << SDL_GetError() << endl;
SDL_RenderClear(ren);
SDL_RenderCopy(ren, img, NULL, &rect);
SDL_RenderPresent(ren);
return img;
}
int main()
{
SDL_Init(SDL_INIT_EVERYTHING);
IMG_Init(IMG_INIT_PNG);
SDL_Window* window = SDL_CreateWindow("SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 460, 380, SDL_WINDOW_RESIZABLE);
SDL_Surface* icon = IMG_Load("sdl.png");
SDL_SetWindowIcon(window, icon);
SDL_Renderer* ren = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_Rect rect,r2;
rect.x = 0; r2.x = 65;
rect.y = 0; r2.y = 80;
rect.w = 64; r2.w = 64;
rect.h = 64; r2.h = 64;
SDL_Texture* img = load(ren, "player.png", rect);
SDL_Delay(2000);
SDL_Texture* tex = load(ren, "enemy.png", r2);
SDL_Event events; bool running = true;
while (running == true)
{
if (SDL_PollEvent(&events))
{
if (events.type == SDL_QUIT)
{
running = false;
break;
}
}
}
IMG_Quit();
SDL_Quit();
return 0;
}
I used SDL_Delay to demonstrate what happens
it loads "player.png" first and then after 2 seconds, it loads "enemy.png"
I wanted to load both at the same time but I couldn't
Please help!
solved, it was due to SDL_RenderClear

SDL2 PointInRect If Statement not working

I'm making a little game as a small project but I can't get an if statement to do anything. If I make it !statement it works though. I run this if statement to find which cube on the "grid" (An array or cubes I render in a for loop I didn't show) the mouse clicked on. I use C++ and SDL2 on a Mac. This is my code:
#include <iostream>
#include <SDL2/SDL.h>
void RenderRects(SDL_Renderer *renderer);
void ToggleRect(int MouseX, int MouseY);
struct Grid
{
bool IsActive;
SDL_Rect Rect;
};
Grid grid[228960];
int main()
{
bool IsRunning = true;
bool IsRunningSim;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *window = SDL_CreateWindow("My Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1000, 780, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
int h, w;
SDL_MaximizeWindow(window);
SDL_GetRendererOutputSize(renderer, &w, &h);
while (IsRunning)
{
// std::cout << w << std::endl;
// std::cout << h << std::endl;
SDL_Event ev;
while (SDL_PollEvent(&ev))
{
if (ev.type == SDL_QUIT)
{
IsRunning = false;
}
if (ev.type == SDL_MOUSEBUTTONDOWN)
{
int x, y;
SDL_GetMouseState(&x, &y);
ToggleRect(x, y);
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
//rendering
RenderRects(renderer);
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
void RenderRects(SDL_Renderer *renderer)
{
for (int i = 0; i < 1440; i += 10)
{
for (int j = 0; j < 795; j += 10)
{
SDL_Rect Rect = {i, j, 10, 10};
grid[i].Rect = Rect;
SDL_SetRenderDrawColor(renderer, 100, 100, 100, 225);
SDL_RenderDrawRect(renderer, &grid[i].Rect);
}
}
}
void ToggleRect(int MouseX, int MouseY)
{
SDL_Point MousePos;
MousePos.x = MouseX;
MousePos.y = MouseY;
for (int i = 0; i < 228961; i++)
{
if (SDL_PointInRect(&MousePos, &grid[i].Rect)) //This is the if that doesn't work.
{
std::cout << i << std::endl;
}
}
}
I have fixed this. I had to change my method of drawing since it was drawing over the rect and then showing after I changed its color. There was also an issue with generating the Rects that was probably effect it.

SDL window shows incorrectly. On linux terminal

This is basically my code here, very simple just to load an image to display. But the first thing I open a window surface, the surface has characters like 'X','S' out of nowhere:
int main( int argc, char* args[] )
{
SDL_Init( SDL_INIT_VIDEO );
SDL_Surface* screen = SDL_SetVideoMode( WINDOW_WIDTH, WINDOW_HEIGHT, 0,
SDL_HWSURFACE | SDL_DOUBLEBUF );
SDL_WM_SetCaption( WINDOW_TITLE, 0 );
SDL_Surface* bitmap = SDL_LoadBMP("bat.bmp");
// Part of the bitmap that we want to draw
SDL_Rect source;
source.x = 24;
source.y = 63;
source.w = 65;
source.h = 44;
// Part of the screen we want to draw the sprite to
SDL_Rect destination;
destination.x = 100;
destination.y = 100;
destination.w = 65;
destination.h = 44;
SDL_Event event;
bool gameRunning = true;
int i=1000;
while (i)
{
if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
gameRunning = false;
}
}
SDL_BlitSurface(bitmap, &source, screen, &destination);
SDL_Flip(screen);
i--;
}
SDL_FreeSurface(bitmap);
SDL_Quit();
return 0;
}

IMG_Load doesn't work

I was watching this series = https://www.youtube.com/watch?v=2NVgHrOFneg
and for some reason for the guy in the video the code works but for me it compiles fine but doesn't load an image. I really don't know what to do.
#include "SDL.h"
#include <iostream>
#include "SDL_image.h"
SDL_Texture *LoadTexture(std::string filePath, SDL_Renderer *renderTarget) //texture optimization function
{
SDL_Texture *texture = nullptr;
SDL_Surface *surface = IMG_Load(filePath.c_str());
if (surface == NULL)
std::cout << "Error 1" << std::endl;
else
{
texture = SDL_CreateTextureFromSurface(renderTarget, surface);
if (texture == NULL)
std::cout << "Error 2" << std::endl;
}
SDL_FreeSurface(surface);
return texture;
}
int main(int, char *argv[])
{
const int FPS = 144;
int frameTime = 0;
SDL_Window *window = nullptr;
SDL_Texture *currentImage= nullptr;
SDL_Renderer *renderTarget = nullptr;
SDL_Rect playerRect;
int frameWidth, frameHeight;
int textureWidth, textureHeight;
SDL_Init(SDL_INIT_VIDEO );
int imgFlags = IMG_INIT_PNG | IMG_INIT_JPG;
if (!(IMG_Init(imgFlags) != imgFlags))
{
std::cout << "Error: " << IMG_GetError() << std::endl;
}
window = SDL_CreateWindow("SDL Pong", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1024, 720, SDL_WINDOW_SHOWN);
renderTarget = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
currentImage = LoadTexture("Untitled.jpg", renderTarget);
SDL_QueryTexture(currentImage, NULL, NULL, &textureWidth, &textureHeight);
SDL_SetRenderDrawColor(renderTarget, 0xFF, 0, 0, 0xFF);
frameWidth = textureWidth / 3;
frameHeight = textureHeight / 4;
playerRect.x = playerRect.y = 0;
playerRect.y = frameWidth;
playerRect.h = frameHeight;
bool isRunning = true; //game loop
SDL_Event ev;
while (isRunning)
{
while (SDL_PollEvent(&ev) != 0)
{
if (ev.type == SDL_QUIT)
isRunning = false;
}
frameTime++;
if (FPS / frameTime == 4)
{
frameTime = 0;
playerRect.x += frameWidth;
if (playerRect.x >= textureWidth)
playerRect.x =0;
}
SDL_RenderClear(renderTarget);
SDL_RenderCopy(renderTarget, currentImage, &playerRect, NULL);
SDL_RenderPresent(renderTarget);
}
SDL_DestroyWindow(window);
SDL_DestroyTexture(currentImage);
SDL_DestroyRenderer(renderTarget);
window = nullptr;
renderTarget = nullptr;
currentImage = nullptr;
SDL_Quit();
return 0;
}
This is the error message: http://imgur.com/LHMdt5F
IMG_Init returns bitfield of formats that was initialised. If resulting bitfield doesn't contain every format that was requested in flags, something gone wrong.
if (!(IMG_Init(imgFlags) != imgFlags)) checks if there is no error. Then you're trying to get error message, but there were no errors. Remove negation operator.
When you create the .exe and run it from an IDE it often stores the executable in a ../bin/.. directory. If Untitled.jpg is in the same directory as your source files, it will not find it.
SDL_GetBasePath(); will return the base path to your files. Check it out docs for it.
The string from SDL_GetBasePath() + "Untitled.jpg" will find and open the file.

SDL2 AntiAliasing

How to turn on antialiasing in SDL2, when using SDL_RenderCopyEx?
I find some articles that suggest to use:
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2);
and
glEnable(GL_MULTISAMPLE);
But this makes no effect. Any ideas?
int Buffers, Samples;
SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &Buffers );
SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &Samples );
cout << "buf = " << Buffers << ", samples = " << Samples;
returns
buf = -858993460, samples = -858993460.
EDIT: CODE:
#include <windows.h>
#include <iostream>
#include <SDL2/include/SDL.h>
#include <SDL2/include/SDL_image.h>
using namespace std;
int main( int argc, char * args[] )
{
// Inicjacja SDL'a
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
// Tworzenie okna
SDL_Window *win = nullptr;
win = SDL_CreateWindow("abc", 100, 100, 800, 600, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if (win == nullptr)
{
std::cout << SDL_GetError() << std::endl;
system("pause");
return 1;
}
int Buffers, Samples;
SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &Buffers );
SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &Samples );
cout << "buf = " << Buffers << ", samples = " << Samples << ".";
// Create Renderer
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;
}
// Create texture
SDL_Texture *tex = nullptr;
tex = IMG_LoadTexture(ren, "circle.png");
SDL_SetTextureAlphaMod(tex, 100);
SDL_Rect s,d;
SDL_Point c;
s.x = s.y = 0;
s.w = s.h = 110;
d.x = 320;
d.y = 240;
d.w = d.h = 110;
c.x = c.y = 55;
// Event Queue
SDL_Event e;
bool quit = false;
int angle = 0;
while(!quit)
{
while (SDL_PollEvent(&e)){
//If user closes he window
if (e.type == SDL_KEYDOWN)
quit = true;
}
angle += 2;
float a = (angle/255.0)/M_PI*180.0;
// Render
SDL_RenderClear(ren);
SDL_RenderCopyEx(ren, tex, &s, &d, a, &c, SDL_FLIP_NONE);
SDL_RenderPresent(ren);
}
// Release
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
// Quit
SDL_Quit();
return 0;
}
Do not worry about style or errors related to memory deallocation, etc. It was a quick sketch to test the possibility SDL'a
If you're looking for an answer that doesn't require opengl use, then this may be of use:
SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" );
https://wiki.libsdl.org/SDL_HINT_RENDER_SCALE_QUALITY
As far as I can tell by trying it out, the values are not set until the context is created, so if you run your SDL_GL_GetAttribute lines before creating the window you will get un-initialised values back as you are doing at present.
So to get correct values use the SDL_GL_GetAttribute call after creating a context and it should work fine.
Let me know how you get on, and if you need any more help/information I will help as I can.
Addendum:
You look like you have created the window before setting its properties, I have pasted some modified code, which should run fine (apologies, I can't test it until I get access to my home PC).
Rearranged code:
#include <windows.h>
#include <iostream>
#include <SDL2/include/SDL.h>
#include <SDL2/include/SDL_image.h>
#include <gl/include/glew.h>
using namespace std;
void myInit()
{
// SDL Init
SDL_Init(SDL_INIT_EVERYTHING);
// Settings
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
glEnable(GL_MULTISAMPLE);
}
int main( int argc, char * args[] )
{
myInit();
// Window Create
SDL_Window *win = nullptr;
win = SDL_CreateWindow("abc", 100, 100, 800, 600, SDL_WINDOW_SHOWN);
if(win == nullptr) return 1;
// Create Renderer
SDL_Renderer *ren = nullptr;
ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (ren == nullptr) return 1;
int Buffers, Samples;
SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &Buffers );
SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &Samples );
cout << "buf = " << Buffers << ", samples = " << Samples << ".";
// Create texture
SDL_Texture *tex = nullptr;
tex = IMG_LoadTexture(ren, "circle.png");
SDL_SetTextureAlphaMod(tex, 100);
SDL_SetTextureColorMod(tex, 255,0,0);
SDL_Rect s,d;
SDL_Point c;
s.x = s.y = 0;
s.w = s.h = 110;
d.x = 320;
d.y = 240;
d.w = d.h = 220;
c.x = c.y = 110;
// Event Queue
SDL_Event e;
bool quit = false;
int angle = 45.0*M_PI/180;
while(!quit)
{
while (SDL_PollEvent(&e)){
//If user closes the window
if (e.type == SDL_QUIT)
quit = true;
}
// Render
SDL_RenderClear(ren);
SDL_RenderCopyEx(ren, tex, &s, &d, angle, &c, SDL_FLIP_NONE);
SDL_RenderPresent(ren);
}
// Release
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
// Quit
SDL_Quit();
return 0;
}