In the event handling loop of SDL2, calling the method SDL_GetMouseState(&x,&y);
or using event.motion.x
and event.motion.y
for the relative mouse coordinates makes SDL2 responsiveness VERY SLUGGISH. Whats weird is SDL_GetMouseState()
is alot faster than event.motion.x and y
, however they are both unbearably bad. Is there any other way of getting the mouse pos? You can even try this. I setup a simple text program in SDL2 to test something responsive such as scrolling, where you offset the y values. Try with and without vsync and with and without getting the mouse pos this way. I am currently using linux mint.
Code: (You will need arial.ttf in your folder where the project is if using codeblocks like i am)
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <SDL2/SDL_image.h>
#include <string>
using std::string;
using std::to_string;
int main(int argc, char* argv[])
{
SDL_Init(SDL_INIT_VIDEO);
TTF_Init();
SDL_Window *window = SDL_CreateWindow("Test Program", 0, 30, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);// | SDL_WINDOW_SHOWN);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC );
SDL_Event event;
SDL_Point mousePos = {0,0};
///Fps vars
int fpsCounter, fpsStart, fpsEnd;
fpsStart = SDL_GetTicks();
fpsEnd = SDL_GetTicks();
fpsCounter = 0;
TTF_Font *fpsFont = TTF_OpenFont("arial.ttf", 30);
SDL_Surface *fpsSurface = TTF_RenderText_Blended(fpsFont, "FPS: ", {0,0,0});
SDL_Texture *fpsTexture = SDL_CreateTextureFromSurface(renderer, fpsSurface);
SDL_FreeSurface(fpsSurface);
int textW, textH, yVal;
yVal = 50;
SDL_QueryTexture(fpsTexture, NULL, NULL, &textW, &textH);
SDL_Rect fpsRect = {1000, yVal, textW, textH};
bool running = true;
while (running)
{
while ( SDL_PollEvent(&event) )
{
if (event.type == SDL_QUIT)
{
running = false;
break;
}
else if (event.type == SDL_MOUSEMOTION){
int x,y;
SDL_GetMouseState(&x,&y);
mousePos = {x,y};
break;
}
else if (event.type == SDL_MOUSEWHEEL){
if (event.wheel.y > 0){ ///Scrolling up here
yVal -= 50;
fpsRect.y = yVal;
break;
}
if (event.wheel.y < 0){ ///Scrolling down here
yVal += 50;
fpsRect.y = yVal;
break;
}
}
}
SDL_SetRenderDrawColor(renderer, 255,255,255,255);
SDL_RenderClear(renderer);
//Update every 0.5s (500ms)
fpsEnd = SDL_GetTicks();
fpsCounter += 2;
if ( (fpsEnd-fpsStart) > 500 ){
fpsStart = SDL_GetTicks();
SDL_DestroyTexture(fpsTexture);
///Change text
string newText = ("FPS: " + to_string(fpsCounter));
fpsSurface = TTF_RenderText_Blended(fpsFont, newText.c_str(), {0,0,0});
fpsTexture = SDL_CreateTextureFromSurface(renderer, fpsSurface);
SDL_FreeSurface(fpsSurface);
SDL_QueryTexture(fpsTexture, NULL, NULL, &textW, &textH);
fpsRect = {1000, yVal, textW, textH};
fpsCounter = 0;
}
SDL_RenderCopy(renderer, fpsTexture, NULL, &fpsRect);
SDL_RenderPresent(renderer);
}
SDL_DestroyTexture(fpsTexture);
TTF_CloseFont(fpsFont);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
TTF_Quit();
SDL_Quit();
return 0;
}
I don't agree that turning off VSYNC is a solution. It shouldn't be like this with VSYNC on regardless. It isn't like this in windows for some reason, it works fine there. Capping the FPS with SDL_Delay() to the refresh rate of the display also gives me the same problem.