gpt4 book ai didi

c++ - SDL 事件处理延迟

转载 作者:行者123 更新时间:2023-11-28 06:09:50 24 4
gpt4 key购买 nike

我在两次按键之间出现了严重的(1-2 秒)延迟。

这是 main.cpp(滞后的输入处理):

#include <iostream>

#include "src/Input/InputManager.h"
#include "src/Graphics/Display.h"

#define LOG(x) std::cout << x << std::endl;

using namespace Rambug;

int main(int arc, char** argv)
{
Graphics::Display display(900, 600, "Rambug Engine Tester", true);
display.createDisplay();

SDL_Event event;
Input::InputManager inputManager;

// "Game" Loop
while (!display.isClosed())
{
display.update();

glClearColor(0.0f, 0.02f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

while (SDL_PollEvent(&event))
{
if (event.type == SDL_KEYDOWN)
{
std::cout << "Keydowner" << std::endl;
}
if (event.type == SDL_KEYUP)
{
std::cout << "Keyupper" << std::endl;
}
}

// inputManager.update();
}

display.destroyDisplay();

system("PAUSE");
return 0;
}

这是 Display.cpp,当我运行相同的代码(SDL_KEYDOWN、SDL_KEYUP)时,它运行完美,没有任何延迟,我只是在那里运行 SDL_QUIT。

#include "Display.h"

namespace Rambug
{
namespace Graphics
{
Display::Display(int width, int height, std::string title, bool log)
{
m_displayWidth = width;
m_displayHeight = height;
m_displayTitle = title;
m_log = log;
m_window = nullptr;
}

Display::Display()
{

}

Display::~Display()
{

}

void Display::createDisplay()
{
// Initialize SDL
SDL_Init(SDL_INIT_EVERYTHING);

// Setting attributes to our window
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_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

// Create window
m_window = SDL_CreateWindow((m_displayTitle.c_str()), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_displayWidth, m_displayHeight, SDL_WINDOW_OPENGL);

// Error Check Window
if (m_window == nullptr)
{
if (m_log)
std::cerr << "Window could not be created!" << std::endl;
}
else
{
if (m_log)
std::cout << "Window Created Successfully With SDL!" << std::endl;
}

// Create OpenGL Context
m_glContext = SDL_GL_CreateContext(m_window);

// Initialize GLEW
glewExperimental = GL_TRUE;
GLenum status = glewInit();

if (glewExperimental)
{
if (m_log)
std::cout << "Glew Experimental: On" << std::endl;
}

// Error Check GLEW
if (status != GLEW_OK)
{
if (m_log)
{
std::cerr << "GLEW could not be initialized!" << std::endl;
}
}
else
{
if (m_log)
{
std::cout << "GLEW Was Initilized Successfully!" << std::endl;
}
}

// Log OpenGL Version Number
if (m_log)
{
std::cout << "Using OpenGL Version: " << glGetString(GL_VERSION) << std::endl;
}

m_closed = false;
}

void Display::destroyDisplay()
{
SDL_GL_DeleteContext(m_glContext);
SDL_DestroyWindow(m_window);
SDL_Quit();
}

void Display::update()
{
SDL_GL_SwapWindow(m_window);

// Check for Input
while (SDL_PollEvent(&m_sdlEvent))
{
if (m_sdlEvent.type == SDL_QUIT)
{
m_closed = true;
}
}
}

bool Display::isClosed()
{
return m_closed;
}
}
}

我也尝试过使用输入管理器类进行试验,但都是一样的:延迟。更新方法是我在 main.cpp 中调用的方法(我相信它被注释掉了)

#include "InputManager.h"
#include <iostream>

#define LOG(x) std::cout << x << std::endl;

namespace Rambug
{
namespace Input
{
InputManager::InputManager()
{

}

InputManager::~InputManager()
{

}

void InputManager::keyPressed(unsigned int keyCode)
{
m_keyMap[keyCode] = true;
}

void InputManager::keyReleased(unsigned int keyCode)
{
m_keyMap[keyCode] = false;
}

bool InputManager::isKeyDown(unsigned int keyCode)
{
auto it = m_keyMap.find(keyCode);

if (it != m_keyMap.end())
{
return it->second;
}
else
{
return false;
}
}

void InputManager::update()
{
while (SDL_PollEvent(&m_event))
{
switch (m_event.type)
{
case SDL_KEYDOWN:
LOG("SDL_KEYDOWN");
keyPressed(m_event.key.keysym.sym);
break;
case SDL_KEYUP:
LOG("SDL_KEYUP");
keyReleased(m_event.key.keysym.sym);
break;
}
}
}
}
}

因此 InputManager 和 main.cpp 有很大的延迟,而 Display.cpp 运行完美。是因为我不能运行 SDL_PollEvents 两次吗?

最佳答案

Is it because I cannot run SDL_PollEvents twice?

您的问题不是我所期望的,但是,是的,运行 SDL_PollEvents 两次是个坏主意。 SDL 保留一个事件堆栈,它会在您的程序运行时添加到其中。 SDL_PollEvents 从堆栈中弹出事件,直到它为空。结果,运行两个轮询循环,一个将删除另一个将看不到的事件。盲目运气(或执行瓶颈)将决定哪个循环更有可能看到任何特定事件发生。 (参见 http://wiki.libsdl.org/SDL_PollEvent)。

如果您真的想运行两个轮询循环,您可以在默认情况下存储未处理的事件,并在每次循环后使用 SDL_PushEvent 将事件列表推回:http://wiki.libsdl.org/SDL_PushEvent

这就是说,我很惊讶您的事件在延迟后“通过”:我希望它们消失。你在按住键吗?然后,您的操作系统按键重复延迟可能就是您所看到的,之后事件队列在每个循环之间被淹没。您可能需要检查按键事件的重复标志:http://wiki.libsdl.org/SDL_KeyboardEvent

我会说这指向一个设计问题。你应该问问自己,为什么 Display 会委托(delegate) Game 结束?将此事实与其他所有内容一起告知显示器不是更明智吗?

关于c++ - SDL 事件处理延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31502440/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com