Compare commits

...

3 Commits

Author SHA1 Message Date
bd1373e415 add GL3 context 2023-09-18 01:13:22 +09:00
98316b0709 improve EnvFixtureWithTasking by making default-constructible 2023-09-18 01:12:43 +09:00
0760866176 add new thirdparty lib, SDL2 2023-09-17 23:05:53 +09:00
6 changed files with 227 additions and 9 deletions

View File

@ -5,11 +5,13 @@ target_link_libraries(nf7_core
luajit luajit
nf7_config nf7_config
nf7_iface nf7_iface
SDL2
sqlite sqlite
uvw uvw
) )
target_sources(nf7_core target_sources(nf7_core
PRIVATE PRIVATE
gl3/context.cc
luajit/context.cc luajit/context.cc
luajit/lambda.cc luajit/lambda.cc
luajit/thread.cc luajit/thread.cc
@ -18,6 +20,7 @@ target_sources(nf7_core
uv/parallelism.cc uv/parallelism.cc
version.cc version.cc
PUBLIC PUBLIC
gl3/context.hh
luajit/context.hh luajit/context.hh
luajit/lambda.hh luajit/lambda.hh
luajit/thread.hh luajit/thread.hh
@ -39,6 +42,7 @@ target_sources(nf7_core
add_executable(nf7_core_test) add_executable(nf7_core_test)
target_sources(nf7_core_test target_sources(nf7_core_test
PRIVATE PRIVATE
gl3/context_test.cc
luajit/context_test.cc luajit/context_test.cc
luajit/context_test.hh luajit/context_test.hh
luajit/lambda_test.cc luajit/lambda_test.cc

132
core/gl3/context.cc Normal file
View File

@ -0,0 +1,132 @@
// No copyright
#include "core/gl3/context.hh"
#include <SDL.h>
#include <atomic>
#include <chrono>
#include <thread>
#include <iostream>
#include "iface/common/exception.hh"
#include "iface/subsys/concurrency.hh"
#include "iface/subsys/logger.hh"
#include "iface/subsys/parallelism.hh"
#include "core/logger.hh"
namespace nf7::core::gl3 {
class Context::Impl final : public std::enable_shared_from_this<Impl> {
public:
explicit Impl(Env& env)
try : concurrency_(env.GetOr<subsys::Concurrency>()),
logger_(env.GetOr<subsys::Logger>(NullLogger::kInstance)) {
sdl_video_ = !SDL_Init(SDL_INIT_VIDEO);
if (!sdl_video_) {
throw Exception {"SDL init failure"};
}
SetUpGL();
SetUpWindow();
} catch (const Exception&) {
TearDown();
throw;
}
public:
void Main() noexcept {
SDL_GL_MakeCurrent(win_, gl_);
SDL_GL_SetSwapInterval(1);
while (alive_) try {
SDL_GL_SwapWindow(win_);
} catch (Exception& e) {
logger_->Warn("error while GL3 window main loop");
}
concurrency_->Exec(
[this, self = shared_from_this()](auto&) { TearDown(); });
}
void Exit() noexcept {
alive_ = false;
}
private:
void SetUpGL() noexcept;
void SetUpWindow();
void TearDown() noexcept {
if (nullptr != gl_) {
SDL_GL_DeleteContext(gl_);
}
if (nullptr != win_) {
SDL_DestroyWindow(win_);
}
if (sdl_video_) {
SDL_Quit();
}
}
private:
const std::shared_ptr<subsys::Concurrency> concurrency_;
const std::shared_ptr<subsys::Logger> logger_;
std::atomic<bool> alive_ {true};
bool sdl_video_ {false};
SDL_Window* win_ {nullptr};
void* gl_ {nullptr};
};
Context::Context(Env& env)
: subsys::Interface("nf7::core::gl3::Context"),
impl_(std::make_shared<Impl>(env)) {
env.Get<subsys::Parallelism>()->Exec([impl = impl_](auto&) { impl->Main(); });
}
Context::~Context() noexcept {
impl_->Exit();
}
void Context::Impl::SetUpGL() noexcept {
# if defined(__APPLE__)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
# else
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
# endif
}
void Context::Impl::SetUpWindow() {
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
constexpr auto flags {
SDL_WINDOW_OPENGL
| SDL_WINDOW_RESIZABLE
| SDL_WINDOW_ALLOW_HIGHDPI
};
win_ = SDL_CreateWindow(
"Dear ImGui SDL2+OpenGL3 example",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
1280, 720,
flags);
if (nullptr == win_) {
throw Exception {"failed to create new window"};
}
gl_ = SDL_GL_CreateContext(win_);
if (nullptr == gl_) {
throw Exception {"failed to create new GL context"};
}
}
} // namespace nf7::core::gl3

31
core/gl3/context.hh Normal file
View File

@ -0,0 +1,31 @@
// No copyright
#pragma once
#include <memory>
#include "iface/subsys/interface.hh"
#include "iface/env.hh"
namespace nf7::core::gl3 {
class Context : public subsys::Interface {
private:
class Impl;
public:
# if defined(__APPLE__)
static constexpr const char* kGlslVersion = "#version 150";
# else
static constexpr const char* kGlslVersion = "#version 130";
# endif
public:
explicit Context(Env&);
~Context() noexcept override;
private:
std::shared_ptr<Impl> impl_;
};
} // namespace nf7::core::gl3

47
core/gl3/context_test.cc Normal file
View File

@ -0,0 +1,47 @@
// No copyright
#include "core/gl3/context.hh"
#include <gtest/gtest.h>
#include <chrono>
#include "iface/subsys/concurrency.hh"
#include "iface/env_test.hh"
using namespace std::literals;
class Gl3Context : public nf7::test::EnvFixtureWithTasking {
public:
Gl3Context() noexcept : skip_(nullptr == std::getenv("NF7_TEST_GL3")) { }
public:
void SetUp() override {
if (skip_) {
GTEST_SKIP();
} else {
nf7::test::EnvFixtureWithTasking::SetUp();
}
}
void TearDown() override {
if (!skip_) {
nf7::test::EnvFixtureWithTasking::TearDown();
}
}
private:
const bool skip_;
};
TEST_F(Gl3Context, Initialization) {
auto ctx = std::make_shared<nf7::core::gl3::Context>(env());
env().Get<nf7::subsys::Concurrency>()->Push(nf7::SyncTask {
std::chrono::time_point_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now())+1000ms,
[&](auto&) { ctx = nullptr; },
});
ConsumeTasks();
}

View File

@ -120,7 +120,7 @@ class EnvFixtureWithTasking : public EnvFixture {
}; };
public: public:
explicit EnvFixtureWithTasking(SimpleEnv::FactoryMap&& fmap) explicit EnvFixtureWithTasking(SimpleEnv::FactoryMap&& fmap = {})
: EnvFixture(std::move(fmap)), : EnvFixture(std::move(fmap)),
sq_(std::make_shared<SimpleTaskQueue<SyncTask>>()), sq_(std::make_shared<SimpleTaskQueue<SyncTask>>()),
aq_(std::make_shared<SimpleTaskQueue<AsyncTask>>()), aq_(std::make_shared<SimpleTaskQueue<AsyncTask>>()),

View File

@ -2,6 +2,15 @@ set(BUILD_TESTING OFF)
include(FetchContent) include(FetchContent)
# ---- gtest (BSD-3-Clause)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.13.0
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
# ---- luajit (MIT) # ---- luajit (MIT)
FetchContent_Declare( FetchContent_Declare(
luajit luajit
@ -11,14 +20,9 @@ FetchContent_Declare(
FetchContent_Populate(luajit) FetchContent_Populate(luajit)
include(luajit.cmake) include(luajit.cmake)
# ---- gtest (BSD-3-Clause) # ---- SDL2 (zlib)
FetchContent_Declare( find_package(SDL2 REQUIRED GLOBAL)
googletest add_library(SDL2 ALIAS SDL2::SDL2)
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.13.0
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
# ---- SQLite (public domain) # ---- SQLite (public domain)
FetchContent_Declare( FetchContent_Declare(