Quelques problèmes ...
- Le mélange des appels de l'API Windows (pour la position de la souris) peut être une partie du problème. Oubliez les appels winAPI et utilisez simplement la position de la souris SDL.
- J'ai testé votre programme sous linux, j'ai donc dû supprimer les éléments winAPI. Le résultat semble être "correct".
- Tu le fais. no réinitialiser
endTicks
après avoir fait un rendu. Donc, après la première fois, il sera appelé sur chaque la boucle extérieure. Donc, c'est martelage le moteur de rendu.
- Mieux vaut faire la boucle d'événement à l'extérieur de du bloc de rendu.
- AFAICT, il n'est pas nécessaire de (re)prendre la position de la souris. La dernière position du dernier événement de mouvement est suffisante.
J'ai produit quelques versions pour montrer progressivement les corrections :
- Il suffit de supprimer les appels winAPI.
- Déplacer la boucle d'événement en dehors du rendu
if
et mettre endTicks
correctement.
- Utilisez simplement la position de la souris à partir du dernier événement de mouvement.
- Version finale, entièrement nettoyée ( sans
#if 0
).
Dans le code ci-dessous, j'utilise cpp
conditionnels pour indiquer l'ancien et le nouveau code (par exemple) :
#if 0
// old code
#else
// new code
#endif
#if 1
// new code
#endif
(1) Voici le code remanié. Ce juste a supprimé les appels winAPI :
#if 0
#include <windows.h>
#endif
#include "SDL2/SDL.h"
#define ARRAY_CONSINT (const int[])
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
void
drawRectangle(SDL_Renderer *renderer, SDL_Rect rect, const int clr[], int fill)
{
SDL_SetRenderDrawColor(renderer, clr[0], clr[1], clr[2], clr[3]);
if (fill == 0)
SDL_RenderDrawRect(renderer, &rect);
else
SDL_RenderFillRect(renderer, &rect);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
}
int
main(int argc, char *args[])
{
struct Mouse_s {
int X;
int Y;
};
int lQuit;
#if 0
POINT Windows_Mouse;
#endif
SDL_Window *gWindow;
SDL_Surface *screenSurface;
SDL_Renderer *renderer;
Uint32 startTicks;
Uint32 endTicks;
Uint32 DeltaTime;
int showFPS;
struct Mouse_s SDL_Mouse;
struct Mouse_s Motion_Mouse;
lQuit = 0;
SDL_Mouse.X = 0;
SDL_Mouse.Y = 0;
Motion_Mouse.X = 0;
Motion_Mouse.Y = 0;
startTicks = 0;
endTicks = 0;
DeltaTime = 0;
SDL_Init(SDL_INIT_EVERYTHING);
gWindow = SDL_CreateWindow("Window", -1, -1, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
#if 0
renderer = SDL_CreateRenderer(gWindow, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
#else
renderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);
#endif
screenSurface = SDL_GetWindowSurface(gWindow);
SDL_UpdateWindowSurface(gWindow);
while (lQuit == 0) {
startTicks = SDL_GetTicks();
DeltaTime = startTicks - endTicks;
if (DeltaTime > 1000 / 60.0) {
// endTicks = SDL_GetTicks();
SDL_RenderClear(renderer);
SDL_Event EventHandler;
while (SDL_PollEvent(&EventHandler) != 0) {
if (EventHandler.type == SDL_QUIT)
lQuit = 1;
else if (EventHandler.type == SDL_MOUSEMOTION) {
Motion_Mouse.X = EventHandler.motion.x;
Motion_Mouse.Y = EventHandler.motion.y;
}
}
SDL_GetMouseState(&SDL_Mouse.X, &SDL_Mouse.Y);
const SDL_Rect rect = { SDL_Mouse.X, SDL_Mouse.Y - 50, 100, 50 };
drawRectangle(renderer, rect, ARRAY_CONSINT {
255, 0, 0, 255}, 0);
#if 0
GetCursorPos(&Windows_Mouse);
const SDL_Rect rect2 = { Windows_Mouse.x, Windows_Mouse.y - 50,
70, 40 };
#else
const SDL_Rect rect2 = { SDL_Mouse.X, SDL_Mouse.Y - 50, 70, 40 };
#endif
drawRectangle(renderer, rect2, ARRAY_CONSINT {
0, 255, 0, 255}, 0);
const SDL_Rect rect3 = { Motion_Mouse.X, Motion_Mouse.Y - 50,
40, 30 };
drawRectangle(renderer, rect3, ARRAY_CONSINT {
0, 0, 255, 255}, 0);
SDL_RenderPresent(renderer);
}
}
return 0;
}
(2) Voici une version avec la plupart des autres correctifs que j'ai mentionnés (par exemple, la configuration endTicks
correctement). Il toujours fait SDL_GetMouseState
. Il s'agit de semble pour être un peu plus lisse :
#if 0
#include <windows.h>
#endif
#include "SDL2/SDL.h"
#define ARRAY_CONSINT (const int[])
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
void
drawRectangle(SDL_Renderer * renderer, SDL_Rect rect, const int clr[], int fill)
{
SDL_SetRenderDrawColor(renderer, clr[0], clr[1], clr[2], clr[3]);
if (fill == 0)
SDL_RenderDrawRect(renderer, &rect);
else
SDL_RenderFillRect(renderer, &rect);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
}
int
main(int argc, char *args[])
{
struct Mouse_s {
int X;
int Y;
};
int lQuit;
#if 0
POINT Windows_Mouse;
#endif
SDL_Window *gWindow;
SDL_Surface *screenSurface;
SDL_Renderer *renderer;
Uint32 startTicks;
Uint32 endTicks;
Uint32 DeltaTime;
int showFPS;
struct Mouse_s SDL_Mouse;
struct Mouse_s Motion_Mouse;
lQuit = 0;
SDL_Mouse.X = 0;
SDL_Mouse.Y = 0;
Motion_Mouse.X = 0;
Motion_Mouse.Y = 0;
startTicks = 0;
endTicks = 0;
DeltaTime = 0;
SDL_Init(SDL_INIT_EVERYTHING);
gWindow = SDL_CreateWindow("Window", -1, -1, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
#if 0
renderer = SDL_CreateRenderer(gWindow, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
#else
renderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);
#endif
screenSurface = SDL_GetWindowSurface(gWindow);
SDL_UpdateWindowSurface(gWindow);
while (lQuit == 0) {
// NOTE/FIX: do this on every loop
#if 1
SDL_Event EventHandler;
while (SDL_PollEvent(&EventHandler) != 0) {
if (EventHandler.type == SDL_QUIT)
lQuit = 1;
else if (EventHandler.type == SDL_MOUSEMOTION) {
Motion_Mouse.X = EventHandler.motion.x;
Motion_Mouse.Y = EventHandler.motion.y;
}
}
#endif
startTicks = SDL_GetTicks();
DeltaTime = startTicks - endTicks;
if (DeltaTime > 1000 / 60.0) {
// NOTE/FIX: set endTicks to prevent _excessive_ rendering
#if 1
endTicks = startTicks;
#endif
SDL_RenderClear(renderer);
// NOTE/BUG: do this _outside_ the rendering time and do _not_ do it after
// the render clear
#if 0
SDL_Event EventHandler;
while (SDL_PollEvent(&EventHandler) != 0) {
if (EventHandler.type == SDL_QUIT)
lQuit = 1;
else if (EventHandler.type == SDL_MOUSEMOTION) {
Motion_Mouse.X = EventHandler.motion.x;
Motion_Mouse.Y = EventHandler.motion.y;
}
}
#endif
SDL_GetMouseState(&SDL_Mouse.X, &SDL_Mouse.Y);
const SDL_Rect rect = { SDL_Mouse.X, SDL_Mouse.Y - 50, 100, 50 };
drawRectangle(renderer, rect, ARRAY_CONSINT {
255, 0, 0, 255}, 0);
#if 0
GetCursorPos(&Windows_Mouse);
const SDL_Rect rect2 = { Windows_Mouse.x, Windows_Mouse.y - 50,
70, 40 };
#else
const SDL_Rect rect2 = { SDL_Mouse.X, SDL_Mouse.Y - 50, 70, 40 };
#endif
drawRectangle(renderer, rect2, ARRAY_CONSINT {
0, 255, 0, 255}, 0);
const SDL_Rect rect3 = { Motion_Mouse.X, Motion_Mouse.Y - 50,
40, 30 };
drawRectangle(renderer, rect3, ARRAY_CONSINT {
0, 0, 255, 255}, 0);
SDL_RenderPresent(renderer);
}
}
return 0;
}
(3) Voici une version qui juste utilise la position de la souris à partir du dernier événement de mouvement :
#if 0
#include <windows.h>
#endif
#include "SDL2/SDL.h"
#define ARRAY_CONSINT (const int[])
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
void
drawRectangle(SDL_Renderer * renderer, SDL_Rect rect, const int clr[], int fill)
{
SDL_SetRenderDrawColor(renderer, clr[0], clr[1], clr[2], clr[3]);
if (fill == 0)
SDL_RenderDrawRect(renderer, &rect);
else
SDL_RenderFillRect(renderer, &rect);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
}
int
main(int argc, char *args[])
{
struct Mouse_s {
int X;
int Y;
};
int lQuit;
#if 0
POINT Windows_Mouse;
#endif
SDL_Window *gWindow;
SDL_Surface *screenSurface;
SDL_Renderer *renderer;
Uint32 startTicks;
Uint32 endTicks;
Uint32 DeltaTime;
int showFPS;
#if 0
struct Mouse_s SDL_Mouse;
#endif
struct Mouse_s Motion_Mouse;
lQuit = 0;
#if 0
SDL_Mouse.X = 0;
SDL_Mouse.Y = 0;
#endif
Motion_Mouse.X = 0;
Motion_Mouse.Y = 0;
startTicks = 0;
endTicks = 0;
DeltaTime = 0;
SDL_Init(SDL_INIT_EVERYTHING);
gWindow = SDL_CreateWindow("Window", -1, -1, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
#if 0
renderer = SDL_CreateRenderer(gWindow, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
#else
renderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);
#endif
screenSurface = SDL_GetWindowSurface(gWindow);
SDL_UpdateWindowSurface(gWindow);
while (lQuit == 0) {
// NOTE/FIX: do this on every loop
#if 1
SDL_Event EventHandler;
while (SDL_PollEvent(&EventHandler) != 0) {
if (EventHandler.type == SDL_QUIT)
lQuit = 1;
else if (EventHandler.type == SDL_MOUSEMOTION) {
Motion_Mouse.X = EventHandler.motion.x;
Motion_Mouse.Y = EventHandler.motion.y;
}
}
#endif
startTicks = SDL_GetTicks();
DeltaTime = startTicks - endTicks;
if (DeltaTime > 1000 / 60.0) {
// NOTE/FIX: set endTicks to prevent _excessive_ rendering
#if 1
endTicks = startTicks;
#endif
SDL_RenderClear(renderer);
// NOTE/BUG: do this _outside_ the rendering time and do _not_ do it after
// the render clear
#if 0
SDL_Event EventHandler;
while (SDL_PollEvent(&EventHandler) != 0) {
if (EventHandler.type == SDL_QUIT)
lQuit = 1;
else if (EventHandler.type == SDL_MOUSEMOTION) {
Motion_Mouse.X = EventHandler.motion.x;
Motion_Mouse.Y = EventHandler.motion.y;
}
}
#endif
// NOTE/BUG: no need to reget mouse position -- the motion event has it
#if 0
SDL_GetMouseState(&SDL_Mouse.X, &SDL_Mouse.Y);
#endif
const SDL_Rect rect = { Motion_Mouse.X, Motion_Mouse.Y - 50,
100, 50 };
drawRectangle(renderer, rect, ARRAY_CONSINT {
255, 0, 0, 255}, 0);
#if 0
GetCursorPos(&Windows_Mouse);
const SDL_Rect rect2 = { Windows_Mouse.x, Windows_Mouse.y - 50,
70, 40 };
#else
const SDL_Rect rect2 = { Motion_Mouse.X, Motion_Mouse.Y - 50,
70, 40 };
#endif
drawRectangle(renderer, rect2, ARRAY_CONSINT {
0, 255, 0, 255}, 0);
const SDL_Rect rect3 = { Motion_Mouse.X, Motion_Mouse.Y - 50,
40, 30 };
drawRectangle(renderer, rect3, ARRAY_CONSINT {
0, 0, 255, 255}, 0);
SDL_RenderPresent(renderer);
}
}
return 0;
}
(4) Une version entièrement nettoyée :
#include "SDL2/SDL.h"
#define ARRAY_CONSINT (const int[])
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
void
drawRectangle(SDL_Renderer *renderer, SDL_Rect rect, const int clr[], int fill)
{
SDL_SetRenderDrawColor(renderer, clr[0], clr[1], clr[2], clr[3]);
if (fill == 0)
SDL_RenderDrawRect(renderer, &rect);
else
SDL_RenderFillRect(renderer, &rect);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
}
int
main(int argc, char *args[])
{
struct Mouse_s {
int X;
int Y;
};
int lQuit;
SDL_Window *gWindow;
SDL_Surface *screenSurface;
SDL_Renderer *renderer;
Uint32 startTicks;
Uint32 endTicks;
Uint32 DeltaTime;
int showFPS;
struct Mouse_s Motion_Mouse;
lQuit = 0;
Motion_Mouse.X = 0;
Motion_Mouse.Y = 0;
startTicks = 0;
endTicks = 0;
DeltaTime = 0;
SDL_Init(SDL_INIT_EVERYTHING);
gWindow = SDL_CreateWindow("Window", -1, -1, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);
screenSurface = SDL_GetWindowSurface(gWindow);
SDL_UpdateWindowSurface(gWindow);
while (lQuit == 0) {
SDL_Event EventHandler;
while (SDL_PollEvent(&EventHandler) != 0) {
if (EventHandler.type == SDL_QUIT)
lQuit = 1;
else if (EventHandler.type == SDL_MOUSEMOTION) {
Motion_Mouse.X = EventHandler.motion.x;
Motion_Mouse.Y = EventHandler.motion.y;
}
}
startTicks = SDL_GetTicks();
DeltaTime = startTicks - endTicks;
if (DeltaTime > 1000 / 60.0) {
endTicks = startTicks;
SDL_RenderClear(renderer);
const SDL_Rect rect = { Motion_Mouse.X, Motion_Mouse.Y - 50,
100, 50 };
drawRectangle(renderer, rect, ARRAY_CONSINT {
255, 0, 0, 255}, 0);
const SDL_Rect rect2 = { Motion_Mouse.X, Motion_Mouse.Y - 50,
70, 40 };
drawRectangle(renderer, rect2, ARRAY_CONSINT {
0, 255, 0, 255}, 0);
const SDL_Rect rect3 = { Motion_Mouse.X, Motion_Mouse.Y - 50,
40, 30 };
drawRectangle(renderer, rect3, ARRAY_CONSINT {
0, 0, 255, 255}, 0);
SDL_RenderPresent(renderer);
}
}
return 0;
}