@@ -8,7 +8,7 @@ option(USE_CLANG_TIDY "Use clang-tidy for additional checks" OFF) | |||
if(USE_CLANG_TIDY) | |||
set(CMAKE_CXX_CLANG_TIDY | |||
clang-tidy | |||
"--header-filter=(libswan|core.mod|src)/.*" | |||
"--header-filter=(libswan|libcygnet|core.mod|src)/.*" | |||
--checks=-*,bugprone-*,cert-*,performance-*,clang-analyzer-*,-cert-dcl16-c,-cert-err58-cpp,-clang-analyzer-optin.cplusplus.VirtualCall) | |||
endif() | |||
@@ -57,16 +57,17 @@ endif() | |||
# Remove once Clang 9.1 or something comes out. | |||
add_compile_options(-Wno-c99-extensions) | |||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib;${CMAKE_INSTALL_PREFIX}/lib64;${CMAKE_INSTALL_PREFIX}/swan/libswan;${CMAKE_INSTALL_PREFIX}/swan/third-party") | |||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib;${CMAKE_INSTALL_PREFIX}/lib64;${CMAKE_INSTALL_PREFIX}/swan/libswan;${CMAKE_INSTALL_PREFIX}/swan/libcygnet;${CMAKE_INSTALL_PREFIX}/swan/third-party") | |||
add_subdirectory(third-party) | |||
add_subdirectory(tracy-tools) | |||
add_subdirectory(libswan) | |||
add_subdirectory(libcygnet) | |||
add_subdirectory(core.mod) | |||
add_executable(swan | |||
src/main.cc) | |||
target_link_libraries(swan libswan ${libraries}) | |||
target_link_libraries(swan libswan libcygnet ${libraries}) | |||
add_executable(perlin-test EXCLUDE_FROM_ALL | |||
src/perlin-test.cc) | |||
@@ -76,6 +77,10 @@ add_executable(lighting-test EXCLUDE_FROM_ALL | |||
src/lighting-test.cc) | |||
target_link_libraries(lighting-test libswan PNG::PNG ${libraries}) | |||
add_executable(cygnet-test EXCLUDE_FROM_ALL | |||
src/cygnet-test.cc) | |||
target_link_libraries(cygnet-test libcygnet ${libraries}) | |||
set(assets | |||
assets/icon.png | |||
assets/music/happy-1.wav) |
@@ -0,0 +1,10 @@ | |||
add_library(libcygnet SHARED | |||
src/Context.cc | |||
src/Window.cc) | |||
target_include_directories(libcygnet | |||
PUBLIC "include" | |||
PRIVATE "include/cygnet") | |||
set_target_properties(libcygnet PROPERTIES OUTPUT_NAME cygnet) | |||
target_link_libraries(libcygnet GLESv2 ${libraries}) | |||
install(TARGETS libcygnet DESTINATION swan/libcygnet) |
@@ -0,0 +1,11 @@ | |||
#pragma once | |||
namespace Cygnet { | |||
class Context { | |||
public: | |||
Context(); | |||
~Context(); | |||
}; | |||
} |
@@ -0,0 +1,25 @@ | |||
#pragma once | |||
#include <memory> | |||
namespace Cygnet { | |||
struct WindowState; | |||
class Window { | |||
public: | |||
Window(const char *name, int w, int h); | |||
~Window(); | |||
void makeCurrent(); | |||
void clear(); | |||
void flip(); | |||
void onResize(int w, int h); | |||
private: | |||
std::unique_ptr<WindowState> state_; | |||
int w_; | |||
int h_; | |||
}; | |||
} |
@@ -0,0 +1,54 @@ | |||
#pragma once | |||
#include <stdexcept> | |||
#include <SDL_opengles2.h> | |||
#include <SDL.h> | |||
namespace Cygnet { | |||
struct SDLError: public std::exception { | |||
SDLError(std::string msg): message(std::move(msg)) {} | |||
std::string message; | |||
const char *what() const noexcept override { | |||
return message.c_str(); | |||
} | |||
}; | |||
struct GLError: public std::exception { | |||
GLError(std::string msg): message(std::move(msg)) {} | |||
std::string message; | |||
const char *what() const noexcept override { | |||
return message.c_str(); | |||
} | |||
}; | |||
inline const char *glErrorString(int err) { | |||
#define errcase(x) case x: return #x | |||
switch (err) { | |||
errcase(GL_NO_ERROR); | |||
errcase(GL_INVALID_ENUM); | |||
errcase(GL_INVALID_VALUE); | |||
errcase(GL_INVALID_OPERATION); | |||
errcase(GL_INVALID_FRAMEBUFFER_OPERATION); | |||
errcase(GL_OUT_OF_MEMORY); | |||
default: return "(unknown)"; | |||
} | |||
#undef errcase | |||
} | |||
inline void sdlCheck(bool ok) { | |||
if (!ok) { | |||
throw SDLError(SDL_GetError()); | |||
} | |||
} | |||
inline void glCheck() { | |||
GLenum err = glGetError(); | |||
if (err != GL_NO_ERROR) { | |||
throw GLError(glErrorString(err)); | |||
} | |||
} | |||
} |
@@ -0,0 +1,23 @@ | |||
#include "Context.h" | |||
#include <SDL.h> | |||
namespace Cygnet { | |||
Context::Context() { | |||
SDL_Init(SDL_INIT_VIDEO); | |||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); | |||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); | |||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); | |||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); | |||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); | |||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); | |||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 16); | |||
} | |||
Context::~Context() { | |||
SDL_Quit(); | |||
} | |||
} |
@@ -0,0 +1,59 @@ | |||
#include "Window.h" | |||
#include <SDL.h> | |||
#include <SDL_opengles2.h> | |||
#include "util.h" | |||
namespace Cygnet { | |||
struct WindowState { | |||
SDL_Window *window; | |||
SDL_GLContext glctx; | |||
}; | |||
Window::Window(const char *name, int w, int h): | |||
state_(std::make_unique<WindowState>()), w_(w), h_(h) { | |||
state_->window = SDL_CreateWindow(name, | |||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, | |||
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | | |||
SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_OPENGL); | |||
sdlCheck(state_->window != NULL); | |||
state_->glctx = SDL_GL_CreateContext(state_->window); | |||
glCheck(); | |||
makeCurrent(); | |||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |||
glEnable(GL_BLEND); | |||
glCheck(); | |||
onResize(w, h); | |||
} | |||
Window::~Window() { | |||
} | |||
void Window::makeCurrent() { | |||
SDL_GL_MakeCurrent(state_->window, state_->glctx); | |||
glCheck(); | |||
} | |||
void Window::clear() { | |||
glClear(GL_COLOR_BUFFER_BIT); | |||
glCheck(); | |||
} | |||
void Window::flip() { | |||
SDL_GL_SwapWindow(state_->window); | |||
glCheck(); | |||
} | |||
void Window::onResize(int w, int h) { | |||
w_ = w; | |||
h_ = h; | |||
glViewport(0, 0, w, h); | |||
glCheck(); | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
#include <cygnet/Context.h> | |||
#include <cygnet/Window.h> | |||
#include <SDL.h> | |||
int main() { | |||
Cygnet::Context ctx; | |||
Cygnet::Window win("Cygnet Test", 640, 480); | |||
while (true) { | |||
SDL_Event evt; | |||
while (SDL_PollEvent(&evt)) { | |||
switch (evt.type) { | |||
case SDL_QUIT: | |||
goto exit; | |||
} | |||
} | |||
win.flip(); | |||
} | |||
exit: | |||
; | |||
} |