完整代码:https://github.com/DXT00/Hazel_study/tree/43029244f0870d32f021dda6ac2d0e42f8563dc6/Hazel
除了ImGuiLayer需要事件响应外,Hazel也需要记录按下了哪一个键并做程序上的处理:
创建一个Input类---》static (整个Hazel只有一个Input Manager)
Input.h
#pragma once
#include "Hazel/Core.h"
namespace Hazel {
class HAZEL_API Input {
public:
static bool IsKeyPress(int keycode) { return s_Instance->IsKeyPressImpl(keycode); }
protected:
virtual bool IsKeyPressImpl(int keycode) = 0;
private:
static Input* s_Instance;
};
}
我们的WindowsInput 类需要获取 WindowsWindow的 m_Window
--》在WindowsWindow的基类Window中添加一个获取 子类的 m_Window的接口
Window.h
virtual void* GetNativeWindow() const = 0;
注:这里的返回值是void*,可以指向任何类型的窗口,在WindowsWindow中 GetNativeWindow()返回的就是GLFWwindow*
WindowsWindow.h
inline virtual void* GetNativeWindow() const { return m_Window; }
WindowsInput.cpp
可以看到这里返回的是 void* window,然而 glfwGetKey需要的是GLFWwindow,所以做一个static_cast
bool WindowsInput::IsKeyPressedImpl(int keycode)
{
auto window = static_cast<GLFWwindow *>(Application::Get().GetWindow().GetNativeWindow());
auto status = glfwGetKey(window, keycode);
return status == GLFW_PRESS || status == GLFW_REPEAT;
}
}
继续添加其他Input接口
Input.h
#pragma once
#include "Hazel/Core.h"
namespace Hazel {
class HAZEL_API Input {
public:
inline static bool IsKeyPressed(int keycode) { return s_Instance->IsKeyPressedImpl(keycode); }
inline static bool IsMouseButtonPressed(int button) { return s_Instance->IsMouseButtonPressedImpl(button); }
inline static float GetMouseX() { return s_Instance->GetMouseXImpl(); }
inline static float GetMouseY() { return s_Instance->GetMouseYImpl(); }
protected:
virtual bool IsKeyPressedImpl(int keycode) = 0;
virtual bool IsMouseButtonPressed(int button) = 0;
virtual float GetMouseXImpl()= 0;
virtual float GetMouseYImpl() = 0;
private:
static Input* s_Instance;
};
}
WindowsWIndow.cpp
#include "hzpch.h"
#include "WindowsInput.h"
#include "Hazel/Application.h"
#include <GLFW/glfw3.h>
namespace Hazel{
WindowsInput::WindowsInput()
{
}
WindowsInput::~WindowsInput()
{
}
bool WindowsInput::IsKeyPressedImpl(int keycode)
{
auto window = static_cast<GLFWwindow *>(Application::Get().GetWindow().GetNativeWindow());
auto status = glfwGetKey(window, keycode);
return status == GLFW_PRESS || status == GLFW_REPEAT;
}
bool WindowsInput::IsMouseButtonPressedImpl(int button)
{
auto window = static_cast<GLFWwindow *>(Application::Get().GetWindow().GetNativeWindow());
auto status = glfwGetMouseButton(window, button);
return status == GLFW_PRESS ;
}
std::pair<float, float> WindowsInput::GetMousePositionImpl()
{
auto window = static_cast<GLFWwindow *>(Application::Get().GetWindow().GetNativeWindow());
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
return {xpos,ypos};
}
float WindowsInput::GetMouseXImpl()
{
auto window = static_cast<GLFWwindow *>(Application::Get().GetWindow().GetNativeWindow());
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
return float(xpos);
}
float WindowsInput::GetMouseYImpl()
{
auto window = static_cast<GLFWwindow *>(Application::Get().GetWindow().GetNativeWindow());
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
return float(ypos);
}
}
同时返回posx,posy
std::pair<float, float> WindowsInput::GetMousePositionImpl()
{
auto window = static_cast<GLFWwindow *>(Application::Get().GetWindow().GetNativeWindow());
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
return {xpos,ypos};
}
在c++17中可以这样使用:
std::pair<float, float> WindowsInput::GetMousePositionImpl()
{
auto window = static_cast<GLFWwindow *>(Application::Get().GetWindow().GetNativeWindow());
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
return {xpos,ypos};
}
float WindowsInput::GetMouseXImpl()
{
auto[x, y] = GetMousePositionImpl();
return x;
}
float WindowsInput::GetMouseYImpl()
{
auto[x, y] = GetMousePositionImpl();
return y;
}
Input* s_instance 在WindowsWindow.cpp 实例化:
#include "hzpch.h"
#include "WindowsInput.h"
#include "Hazel/Application.h"
#include <GLFW/glfw3.h>
namespace Hazel{
Input* Input::s_Instance = new WindowsInput();
WindowsInput::WindowsInput()
{
}
WindowsInput::~WindowsInput()
{
}
bool WindowsInput::IsKeyPressedImpl(int keycode)
{
auto window = static_cast<GLFWwindow *>(Application::Get().GetWindow().GetNativeWindow());
auto status = glfwGetKey(window, keycode);
return status == GLFW_PRESS || status == GLFW_REPEAT;
}
bool WindowsInput::IsMouseButtonPressedImpl(int button)
{
auto window = static_cast<GLFWwindow *>(Application::Get().GetWindow().GetNativeWindow());
auto status = glfwGetMouseButton(window, button);
return status == GLFW_PRESS ;
}
std::pair<float, float> WindowsInput::GetMousePositionImpl()
{
auto window = static_cast<GLFWwindow *>(Application::Get().GetWindow().GetNativeWindow());
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
return {xpos,ypos};
}
float WindowsInput::GetMouseXImpl()
{
auto[x, y] = GetMousePositionImpl();
return x;
}
float WindowsInput::GetMouseYImpl()
{
auto[x, y] = GetMousePositionImpl();
return y;
}
}
Application::Run()
调用Input类:
void Application:: Run() {
while (m_Running) {
glClearColor(1, 0, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
for (Layer *layer:m_LayerStack)
{
layer->OnUpdate();
}
auto[x, y] = Input::GetMousePosition();
HZ_CORE_TRACE("{0},{1}", x, y);
m_Window->OnUpdate();
}
}
F5运行: