This commit is contained in:
Matt Coster 2021-07-31 19:04:20 +09:00 committed by GitHub
commit daf9266afd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 270 additions and 1 deletions

View File

@ -28,6 +28,12 @@ option(GLFW_BUILD_TESTS "Build the GLFW test programs" ${GLFW_STANDALONE})
option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON)
option(GLFW_INSTALL "Generate installation target" ON)
option(GLFW_VULKAN_STATIC "Assume the Vulkan loader is linked with the application" OFF)
option(GLFW_HPP "Use the glfw3.hpp wrapper for C++" OFF)
if (GLFW_HPP)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 17)
endif()
include(GNUInstallDirs)
include(CMakeDependentOption)
@ -294,6 +300,11 @@ if (GLFW_INSTALL)
install(DIRECTORY include/GLFW DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h)
if (GLFW_HPP)
install(DIRECTORY include/GLFW DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN glfw3.hpp)
endif()
install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake"
"${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake"
DESTINATION "${GLFW_CONFIG_PATH}")

View File

@ -3,7 +3,13 @@
# (i.e. Pages) list in the generated documentation
set(GLFW_DOXYGEN_SOURCES
"include/GLFW/glfw3.h"
"include/GLFW/glfw3native.h"
"include/GLFW/glfw3native.h")
if (GLFW_HPP)
list(APPEND GLFW_DOXYGEN_SOURCES "include/GLFW/glfw3.hpp")
endif()
list(APPEND GLFW_DOXYGEN_SOURCES
"docs/main.dox"
"docs/news.dox"
"docs/quick.dox"

177
include/GLFW/glfw3.hpp Normal file
View File

@ -0,0 +1,177 @@
#ifndef _glfw3_hpp_
#define _glfw3_hpp_
#ifndef GLFW_HPP_NAMESPACE
#define GLFW_HPP_NAMESPACE glfw
#endif
#ifdef GLFW_HPP_NO_STD_STRING
#define GLFW_HPP_STRING char const *
#else
#define GLFW_HPP_STRING std::string
#endif
#include <GLFW/glfw3.h>
#include <functional>
#include <optional>
#include <string>
#include <system_error>
#include <vector>
namespace GLFW_HPP_NAMESPACE {
namespace _private {
#ifdef GLFW_HPP_NO_STD_STRING
inline GLFW_HPP_STRING makeString_(char const *str) { return str; }
inline char const *cString_(GLFW_HPP_STRING const &str) { return str; }
#else
inline GLFW_HPP_STRING makeString_(char const *str) { return std::string(str); }
inline char const *cString_(GLFW_HPP_STRING const &str) { return str.c_str(); }
#endif
}
using ErrorFun = GLFWerrorfun;
struct Size {
int width;
int height;
};
enum class ErrorCode {
noError = GLFW_NO_ERROR,
notInitialized = GLFW_NOT_INITIALIZED,
noCurrentContext = GLFW_NO_CURRENT_CONTEXT,
invalidEnum = GLFW_INVALID_ENUM,
invalidValue = GLFW_INVALID_VALUE,
outOfMemory = GLFW_OUT_OF_MEMORY,
apiUnavailable = GLFW_API_UNAVAILABLE,
versionUnavailable = GLFW_VERSION_UNAVAILABLE,
platformError = GLFW_PLATFORM_ERROR,
formatUnavailable = GLFW_FORMAT_UNAVAILABLE,
noWindowContext = GLFW_NO_WINDOW_CONTEXT,
cursorUnavailable = GLFW_CURSOR_UNAVAILABLE,
featureUnavailable = GLFW_FEATURE_UNAVAILABLE,
featureUnimplemented = GLFW_FEATURE_UNIMPLEMENTED,
};
}
namespace std {
template <>
struct is_error_code_enum<GLFW_HPP_NAMESPACE::ErrorCode> : public true_type {};
}
namespace GLFW_HPP_NAMESPACE {
class ErrorCategory : public std::error_category {
public:
const char *name() const _NOEXCEPT override {
return nullptr;
}
std::string message(int __ev) const override {
return std::string();
}
};
inline std::error_code make_error_code(ErrorCode code) {
return {static_cast<int>(code), ErrorCategory()};
}
class Error : public std::system_error {
public:
ErrorCode const code;
private:
Error(ErrorCode const code, GLFW_HPP_STRING const &description) :
std::system_error(std::error_code{code}, description),
code{code} {}
static std::optional<Error> get_() {
char const *description;
auto code = static_cast<ErrorCode const>(glfwGetError(&description));
if (code == ErrorCode::noError) {
return std::optional<Error>{};
}
return Error(code, description ? _private::makeString_(description) : "");
}
static void getAndThrow_() {
auto const err = get_();
if (err) {
throw err.value();
}
}
friend class GLFW;
friend class Window;
};
class Window {
public:
Window(Size const &size, GLFW_HPP_STRING const &title) :
size_{size},
title_{title},
handle_{glfwCreateWindow(size.width, size.height, _private::cString_(title), nullptr, nullptr)} {
Error::getAndThrow_();
}
void makeContextCurrent() const {
glfwMakeContextCurrent(this->handle_);
}
[[nodiscard]] bool shouldClose() const {
return glfwWindowShouldClose(this->handle_);
}
void swapBuffers() const {
glfwSwapBuffers(this->handle_);
}
GLFWwindow *handle_;
private:
Size size_;
GLFW_HPP_STRING title_;
};
class GLFW {
public:
GLFW() {
if (!glfwInit()) {
Error::getAndThrow_();
}
}
explicit GLFW(ErrorFun errorCallback) : GLFW() {
this->errorCallback = errorCallback;
glfwSetErrorCallback(this->errorCallback);
}
virtual ~GLFW() {
glfwTerminate();
}
Window createWindow(Size const &size, GLFW_HPP_STRING const &title) {
return Window{size, title};
}
void swapInterval(int const interval) {
glfwSwapInterval(interval);
}
void waitEvents() {
glfwWaitEvents();
}
private:
ErrorFun errorCallback{};
};
}
#endif /* _glfw3_h_ */

View File

@ -42,6 +42,10 @@ add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD_GL})
add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${GLAD_VULKAN})
add_executable(window WIN32 MACOSX_BUNDLE window.c ${GLAD_GL})
if (GLFW_HPP)
add_executable(title_cpp WIN32 MACOSX_BUNDLE title.cpp ${GLAD_GL})
endif()
target_link_libraries(empty Threads::Threads)
target_link_libraries(threads Threads::Threads)
if (RT_LIBRARY)
@ -54,6 +58,10 @@ set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks tearing threads
set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen
cursor)
if (GLFW_HPP)
list(APPEND GUI_ONLY_BINARIES title_cpp)
endif()
set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
C_STANDARD 99
FOLDER "GLFW3/Tests")
@ -79,6 +87,10 @@ if (APPLE)
set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title")
set_target_properties(window PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Window")
if (GLFW_HPP)
set_target_properties(title_cpp PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title (C++)")
endif()
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION}

63
tests/title.cpp Normal file
View File

@ -0,0 +1,63 @@
//========================================================================
// UTF-8 window title test (C++ version)
// Copyright (c) Matt Coster <matt@mtcoster.net>
// Based on the original C version by Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
//
// This test sets a UTF-8 window title
//
//========================================================================
#include <glad/gl.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.hpp>
#include <cstdlib>
#include <iostream>
static void error_callback(int error, const char* description) {
std::cerr << "Error " << error << ": " << description << "\n";
}
int main() {
try {
auto glfwInst = glfw::GLFW(&error_callback);
auto window = glfwInst.createWindow({400, 400}, "English 日本語 русский язык 官話");
window.makeContextCurrent();
gladLoadGL(glfwGetProcAddress);
glfwInst.swapInterval(1);
while (!window.shouldClose()) {
glClear(GL_COLOR_BUFFER_BIT);
window.swapBuffers();
glfwInst.waitEvents();
}
} catch (glfw::Error const &err) {
std::cerr << "GLFW error: " << err.what() << "\n";
std::exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}