Jake Wickham Jake Wickham - 9 months ago 30
C++ Question

SDL_PollEvent not responding to events

I'm creating a game in OpenGL and having issues with SDL_PollEvent not picking up all events, for instance, if I press and hold a key, I have to wait ~1-3 seconds before the program realises what I have just done. This is my main.cpp:

#include <GL/glew.h>
#include <GL/GL.h>
#include <SDL\SDL.h>
#include "Display.h"
#include "Mesh.h"
#include "Shader.h"
#include "Texture.h"
#include "Transform.h"
#include "Camera.h"
#include <iostream>

#define WIDTH 800
#define HEIGHT 600

int main(int argc, char *argv[])
{
Display Display(800, 600, "OpenGL");

Vertex vertices[] = { Vertex(glm::vec3(-0.5, -0.5, 0), glm::vec2(0.0, 0.0)),
Vertex(glm::vec3(0, 0.5, 0), glm::vec2(0.5, 1.0)),
Vertex(glm::vec3(0.5, -0.5, 0), glm::vec2(1.0, 0.0)), };

unsigned int indices[] = { 0,1,2 };

SDL_Init(SDL_INIT_EVERYTHING);

// Mesh Car("./res/Test2.obj");
// Mesh Test(vertices, sizeof(vertices) / sizeof(vertices[0]), indices, sizeof(indices)/sizeof(indices[0]));
Mesh Ground("./res/Ground2.obj");
Shader shader("./res/basicShader");
// Texture texture("./res/CarUV.png");
Texture test("./res/ground.jpg");
Camera camera(glm::vec3(0, 0, -14), 70.f, (float)WIDTH / (float)HEIGHT, 0.01f, 1000.0f);
Transform transform;
const Uint8 *keyState;

transform.GetPos().x = 0;
transform.GetPos().y = 0;
transform.GetPos().z = 0;
transform.GetRot().x = 80;
transform.GetRot().y = 0;
transform.GetRot().z = 0;

float counter = 0.0f;

while (!Display.IsClosed())
{

Display.Clear(0.0f, 0.15f, 0.3f, 1.0f);

float sinCounter = sinf(counter);
float cosCounter = cosf(counter);

SDL_Event ev;

while (SDL_PollEvent(&ev) != 0)
{
keyState = SDL_GetKeyboardState(NULL);

if (keyState[SDL_SCANCODE_W])
{
camera.MoveForward(1);
std::cout << "keypress" << std::endl;
}
else if (keyState[SDL_SCANCODE_S])
{
camera.MoveBackward(1);
}
if (keyState[SDL_SCANCODE_A])
{
camera.MoveRight(1);
}
else if (keyState[SDL_SCANCODE_D])
{
camera.MoveLeft(1);
}
if (keyState[SDL_SCANCODE_Y])
{
camera.RotateY(0.1);
}
if (keyState[SDL_SCANCODE_X])
{
camera.RotateX(0.1);
}
}

//transform.SetScale(glm::vec3(cosCounter, cosCounter, cosCounter));
shader.Bind();
test.Bind(0);
shader.Update(transform, camera);
//Car.draw();
Ground.draw();

Display.Update();
counter += 1.0f;
}
return 0;
}


All the functions do what they're named after and work properly.

EDIT:

I've done some testing and removing
Display.clear();
and
Display.update();
fixes the problem however this is not a viable solution.

EDIT 2:

Just as extra information the program originally worked, then I started fiddling around with it and the event handler screwed up.

Answer Source

As @HolyBlackCat has said in the comments, in this part of the code:

while (SDL_PollEvent(&ev) != 0)
{
    //if statements here 
}

The while loop is unnecessary, as you already have one in the form of:

while (!Display.IsClosed())
{
    //main game loop
}

And having another while loop inside will just cause issues.

Anyway hope this helps and please don't mark as the answer if @HolyBlackCat creates one or this doesn't work for you. Cheers.