aboutsummaryrefslogtreecommitdiff
path: root/dxwindow/dxwindow.ixx
blob: 6efcc182810ef937f45b48b45390ba2a7e1d1233 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
module;

// Include Windows.h before GLFW to avoid macro redefinition warnings.
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

#define GLFW_INCLUDE_NONE  // Do not include OpenGL headers.
#include <GLFW/glfw3.h>

#define GLFW_EXPOSE_NATIVE_WIN32
#include <GLFW/glfw3native.h>

#include <cassert>
#include <cstdio>

export module dxwindow;

namespace dx {

char glfw_error[1024] = {};

void glfw_error_callback(int error, const char* description)
{
    sprintf_s(glfw_error, sizeof(glfw_error),
        "GLFW error %d: %s", error, description);
}

export {

class Window
{
public:
    ~Window()
    {
        if (m_window != nullptr)
        {
            glfwDestroyWindow(m_window);
        }
    }

    /// Creates the window.
    bool Initialise(int width, int height, const char* title)
    {
        // GLFW by default creates an OpenGL context with the window.
        // Use GLFW_NO_API to tell it not to do so.
        glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);

        if ((m_window = glfwCreateWindow(
            width, height, title, /*monitor=*/NULL, /*share=*/NULL)) == nullptr)
        {
            return false;
        }

        return true;
    }

    /// Returns the native window handle.
    /// If the window has not been initialized, returns an invalid handle.
    HWND GetWindowHandle()
    {
        if (!m_window)
        {
            return NULL;
        }
        return glfwGetWin32Window(m_window);
    }

    /// Updates the window by polling for user input.
    void Update()
    {
        assert(m_window);
        glfwPollEvents();
    }

    /// Returns true if the user tried to close the window, false otherwise.
    bool ShouldClose() const
    {
        assert(m_window);
        return glfwWindowShouldClose(m_window) == GLFW_TRUE;
    }

private:
    GLFWwindow* m_window = nullptr;
};

/// Initialise the window subsystem.
///
/// This function must be called at the start of your application before any
/// Windows are created.
bool WindowInitialise()
{
    glfwSetErrorCallback(glfw_error_callback);
    return glfwInit() == GLFW_TRUE;
}

/// Terminate the window subsystem.
///
/// This function should be called at the end of your application. Any existing
/// Windows are destroyed and are invalid beyond this call.
void WindowTerminate()
{
    glfwTerminate();
}

/// Returns the last Window error.
const char* GetWindowError()
{
    return glfw_error;
}

} // export

} // namespace dx