Initial commit
This commit is contained in:
commit
6073e7d3f6
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
build
|
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
[submodule "vendor/bgfx.cmake"]
|
||||
path = vendor/bgfx.cmake
|
||||
url = https://github.com/bkaradzic/bgfx.cmake
|
||||
[submodule "vendor/CrossWindow"]
|
||||
path = vendor/CrossWindow
|
||||
url = https://github.com/alaingalvan/CrossWindow
|
67
CMakeLists.txt
Normal file
67
CMakeLists.txt
Normal file
@ -0,0 +1,67 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
project(weasel)
|
||||
|
||||
include(cmake/bgfx_shaders.cmake)
|
||||
|
||||
set(SOURCE_FILES
|
||||
weasel.hpp
|
||||
core/app.hpp
|
||||
core/app.cpp
|
||||
core/event.hpp
|
||||
core/event.cpp
|
||||
ec/entity.hpp
|
||||
ec/component.hpp
|
||||
ec/comp/sprite_component.hpp
|
||||
ec/comp/sprite_component.cpp
|
||||
gfx/renderer.hpp
|
||||
gfx/renderer.cpp
|
||||
gfx/texture.hpp
|
||||
gfx/vertex.hpp
|
||||
util/color.hpp
|
||||
util/color.cpp
|
||||
util/n_ary_tree.hpp
|
||||
util/n_ary_tree.tpp
|
||||
util/vector.hpp
|
||||
win/system_events.hpp
|
||||
win/system_events.cpp
|
||||
win/window.hpp
|
||||
win/window.cpp
|
||||
)
|
||||
|
||||
list(TRANSFORM SOURCE_FILES PREPEND src/)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
add_subdirectory(vendor/CrossWindow)
|
||||
add_subdirectory(vendor/bgfx.cmake)
|
||||
|
||||
add_shader_cmd(
|
||||
FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/gfx/shader/mesh/mesh.vsh
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader/mesh.vsh.bin
|
||||
TYPE VERTEX)
|
||||
|
||||
add_shader_cmd(
|
||||
FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/gfx/shader/mesh/mesh.fsh
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader/mesh.fsh.bin
|
||||
TYPE FRAGMENT)
|
||||
|
||||
add_custom_target(compile_shaders ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/shader/mesh.vsh.bin ${CMAKE_CURRENT_BINARY_DIR}/shader/mesh.fsh.bin)
|
||||
|
||||
add_library(weasel ${SOURCE_FILES})
|
||||
|
||||
target_include_directories(weasel PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
|
||||
target_compile_features(weasel PUBLIC cxx_std_17)
|
||||
|
||||
target_link_libraries(weasel CrossWindow bgfx bx)
|
||||
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(weasel
|
||||
Dwmapi)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(CrossWindow PRIVATE _WIN32_WINNT=0x0A00)
|
||||
|
||||
add_subdirectory(examples)
|
57
cmake/bgfx_shaders.cmake
Normal file
57
cmake/bgfx_shaders.cmake
Normal file
@ -0,0 +1,57 @@
|
||||
# Configure a command to compile a single shader
|
||||
# add_shader_cmd(
|
||||
# FILE file
|
||||
# OUTPUT output
|
||||
# TYPE type
|
||||
#)
|
||||
function (add_shader_cmd)
|
||||
cmake_parse_arguments(SHADER "" "FILE;OUTPUT;TYPE;LANG" "" ${ARGN})
|
||||
message(${SHADER_FILE} ${SHADER_OUTPUT} ${SHADER_TYPE} ${SHADER_LANG})
|
||||
|
||||
set(BGFX_PATH ${CMAKE_CURRENT_SOURCE_DIR}/vendor/bgfx.cmake/bgfx)
|
||||
set(VARYING_DEF "C:/Users/romer/Documents/Projects/weasel/src/gfx/shader/varying.def.sc")
|
||||
|
||||
message("checking platform")
|
||||
if(WIN32)
|
||||
set(SHADERC_PLATFORM_ARG WINDOWS)
|
||||
message("platform = " ${SHADERC_PLATFORM_ARG})
|
||||
elseif(APPLE)
|
||||
set(SHADERC_PLATFORM_ARG OSX)
|
||||
elseif(UNIX)
|
||||
set(SHADERC_PLATFORM_ARG LINUX)
|
||||
endif()
|
||||
|
||||
# shaderc_parse(
|
||||
# FILE filename
|
||||
# OUTPUT filename
|
||||
# FRAGMENT|VERTEX|COMPUTE
|
||||
# ANDROID|ASM_JS|IOS|LINUX|NACL|OSX|WINDOWS
|
||||
# [PROFILE profile]
|
||||
# [O 0|1|2|3]
|
||||
# [VARYINGDEF filename]
|
||||
# [BIN2C filename]
|
||||
# [INCLUDES include;include]
|
||||
# [DEFINES include;include]
|
||||
# [DEPENDS]
|
||||
# [PREPROCESS]
|
||||
# [RAW]
|
||||
# [VERBOSE]
|
||||
# [DEBUG]
|
||||
# [DISASM]
|
||||
# [WERROR]
|
||||
# )
|
||||
shaderc_parse(SHADERC_ARGS
|
||||
FILE ${SHADER_FILE}
|
||||
OUTPUT ${SHADER_OUTPUT}
|
||||
${SHADER_TYPE}
|
||||
${SHADERC_PLATFORM_ARG}
|
||||
PROFILE ${SHADER_LANG}
|
||||
VARYINGDEF ${VARYING_DEF}
|
||||
INCLUDES ${BGFX_PATH}/src
|
||||
)
|
||||
|
||||
list( APPEND SHADER_COMPILE_CMD shaderc ${SHADERC_ARGS} )
|
||||
add_custom_command(
|
||||
OUTPUT ${SHADER_OUTPUT}
|
||||
COMMAND ${SHADER_COMPILE_CMD})
|
||||
endfunction()
|
6
examples/0_hello_world/CMakeLists.txt
Normal file
6
examples/0_hello_world/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
project(example_0_hello_world)
|
||||
|
||||
add_executable(${PROJECT_NAME} main.cpp)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} weasel)
|
||||
#target_link_directories(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/src)
|
25
examples/0_hello_world/main.cpp
Normal file
25
examples/0_hello_world/main.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include <weasel.hpp>
|
||||
|
||||
class hello_world : public wsl::app {
|
||||
public:
|
||||
void init() override {
|
||||
wsl::entity::entity e;
|
||||
hierarchy.root.add_child(e);
|
||||
hierarchy.root.add_child(e);
|
||||
hierarchy.root.add_child(e);
|
||||
hierarchy.root.child_at(0).add_child(e);
|
||||
|
||||
renderer.draw_test_triangle();
|
||||
window.internal_window.get()->setSize(640,480);
|
||||
}
|
||||
|
||||
void update() override {
|
||||
renderer.draw();
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
hello_world app;
|
||||
app.start("Hello World", 640, 480);
|
||||
return 0;
|
||||
}
|
5
examples/1_double_pendulum/CMakeLists.txt
Normal file
5
examples/1_double_pendulum/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
project(example_1_double_pendulum)
|
||||
|
||||
add_executable(${PROJECT_NAME} main.cpp)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} weasel)
|
30
examples/1_double_pendulum/main.cpp
Normal file
30
examples/1_double_pendulum/main.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include <weasel.hpp>
|
||||
|
||||
class double_pendulum : public wsl::app {
|
||||
public:
|
||||
void init() override {
|
||||
wsl::entity::entity e;
|
||||
hierarchy.root.add_child(e);
|
||||
hierarchy.root.add_child(e);
|
||||
hierarchy.root.add_child(e);
|
||||
hierarchy.root.child_at(0).add_child(e);
|
||||
|
||||
renderer.queue_triangle(
|
||||
wsl::vec2f{320.0f, 480.0f},
|
||||
wsl::vec2f{0.0f, 0.0f},
|
||||
wsl::vec2f{640.0f, 0.0f},
|
||||
wsl::color::red
|
||||
);
|
||||
window.internal_window.get()->setSize(640,480);
|
||||
}
|
||||
|
||||
void update() override {
|
||||
renderer.draw();
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
double_pendulum app;
|
||||
app.start("Double Pendulum", 640, 480);
|
||||
return 0;
|
||||
}
|
2
examples/CMakeLists.txt
Normal file
2
examples/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
||||
add_subdirectory(0_hello_world)
|
||||
add_subdirectory(1_double_pendulum)
|
34
src/core/app.cpp
Normal file
34
src/core/app.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
#include "core/app.hpp"
|
||||
|
||||
wsl::app::app() : renderer(&window), hierarchy(wsl::entity::entity{}) {}
|
||||
|
||||
void wsl::app::start(const char* title, unsigned int width,
|
||||
unsigned int height) {
|
||||
if (window.init(title, width, height) && renderer.init(wsl::gfx::api::opengl)) {
|
||||
is_running = true;
|
||||
window.events.quit.add_listener([&]() {
|
||||
window.close();
|
||||
is_running = false;
|
||||
});
|
||||
init();
|
||||
init_entities();
|
||||
while (is_running) {
|
||||
renderer.clear(color::solid{0x00, 0x00, 0x00});
|
||||
window.events.update();
|
||||
update();
|
||||
update_entities();
|
||||
renderer.update();
|
||||
}
|
||||
} else
|
||||
std::cout << "error opening window" << std::endl;
|
||||
}
|
||||
|
||||
void wsl::app::init_entities() {
|
||||
for (wsl::n_ary_tree<wsl::entity::entity>::node& leaf : hierarchy) {
|
||||
std::cout << &leaf << ": " << leaf.value.uid << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void wsl::app::update_entities() {
|
||||
|
||||
}
|
31
src/core/app.hpp
Normal file
31
src/core/app.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "gfx/renderer.hpp"
|
||||
#include "win/window.hpp"
|
||||
#include "util/n_ary_tree.hpp"
|
||||
#include "ec/entity.hpp"
|
||||
|
||||
namespace wsl {
|
||||
|
||||
class app {
|
||||
public:
|
||||
app();
|
||||
window window;
|
||||
gfx::renderer renderer;
|
||||
|
||||
void start(const char* title, unsigned int width, unsigned int height);
|
||||
|
||||
wsl::n_ary_tree<wsl::entity::entity> hierarchy;
|
||||
protected:
|
||||
virtual void init() = 0;
|
||||
virtual void update() = 0;
|
||||
void init_entities();
|
||||
void update_entities();
|
||||
|
||||
private:
|
||||
bool is_running;
|
||||
};
|
||||
|
||||
} // namespace wsl
|
13
src/core/event.cpp
Normal file
13
src/core/event.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "core/event.hpp"
|
||||
|
||||
void wsl::event::event::add_listener(std::function<void()> callback_fn) {
|
||||
listeners.push_back(callback_fn);
|
||||
}
|
||||
|
||||
void wsl::event::event::update() {
|
||||
if (dispatch_condition()) dispatch();
|
||||
}
|
||||
|
||||
void wsl::event::event::dispatch() {
|
||||
for (std::function<void()> fn : listeners) fn();
|
||||
}
|
33
src/core/event.hpp
Normal file
33
src/core/event.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace wsl {
|
||||
|
||||
namespace event {
|
||||
|
||||
class event {
|
||||
public:
|
||||
void add_listener(std::function<void()> callback_fn);
|
||||
|
||||
/**
|
||||
* @brief Check if event meet the requirement to notify the listening
|
||||
* functions
|
||||
*/
|
||||
void update();
|
||||
|
||||
protected:
|
||||
virtual bool dispatch_condition() = 0;
|
||||
|
||||
private:
|
||||
std::vector<std::function<void()>> listeners;
|
||||
/**
|
||||
* @brief Fire up the event and invoke the listening functions
|
||||
*/
|
||||
void dispatch();
|
||||
};
|
||||
|
||||
} // namespace event
|
||||
|
||||
} // namespace wsl
|
21
src/ec/comp/sprite_component.cpp
Normal file
21
src/ec/comp/sprite_component.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include <bgfx/bgfx.h>
|
||||
#include <bx/math.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <array>
|
||||
|
||||
#include "util/color.hpp"
|
||||
#include "util/vector.hpp"
|
||||
#include "win/window.hpp"
|
||||
|
||||
#include "sprite_component.hpp"
|
||||
|
||||
void wsl::entity::comp::sprite::init() {
|
||||
//renderer.draw_sprite()
|
||||
}
|
||||
|
||||
void wsl::entity::comp::sprite::update(double delta_time) {}
|
||||
|
||||
void wsl::entity::comp::sprite::render() {}
|
24
src/ec/comp/sprite_component.hpp
Normal file
24
src/ec/comp/sprite_component.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "ec/component.hpp"
|
||||
#include "gfx/renderer.hpp"
|
||||
|
||||
namespace wsl {
|
||||
|
||||
namespace entity {
|
||||
|
||||
namespace comp {
|
||||
|
||||
class sprite : component {
|
||||
public:
|
||||
gfx::renderer renderer;
|
||||
void init();
|
||||
|
||||
void update(double delta_time);
|
||||
void render();
|
||||
};
|
||||
|
||||
} // namespace comp
|
||||
} // namespace entity
|
||||
|
||||
} // namespace wsl
|
16
src/ec/component.hpp
Normal file
16
src/ec/component.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
namespace wsl {
|
||||
|
||||
namespace entity {
|
||||
|
||||
class component {
|
||||
public:
|
||||
virtual void init() = 0;
|
||||
virtual void update(double delta_time) = 0;
|
||||
virtual void render() = 0;
|
||||
};
|
||||
|
||||
} // namespace entity
|
||||
|
||||
} // namespace wsl
|
44
src/ec/entity.hpp
Normal file
44
src/ec/entity.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "ec/component.hpp"
|
||||
|
||||
namespace wsl {
|
||||
|
||||
namespace entity {
|
||||
|
||||
class entity {
|
||||
public:
|
||||
const unsigned long uid = get_new_uid();
|
||||
static unsigned long get_new_uid() { return last_uid++; }
|
||||
|
||||
template <typename T, typename... Args>
|
||||
void add_component(Args... args) {
|
||||
components.push_back(std::make_shared<T>(args...));
|
||||
}
|
||||
|
||||
void init() {
|
||||
for (std::shared_ptr<component> component : components)
|
||||
component->init();
|
||||
}
|
||||
|
||||
void update(double delta_time) {
|
||||
for (std::shared_ptr<component> component : components)
|
||||
component->update(delta_time);
|
||||
}
|
||||
|
||||
void render() {
|
||||
for (std::shared_ptr<component> component : components)
|
||||
component->render();
|
||||
}
|
||||
|
||||
private:
|
||||
inline static unsigned long last_uid = 0;
|
||||
std::vector<std::shared_ptr<component>> components;
|
||||
};
|
||||
|
||||
} // namespace entity
|
||||
|
||||
} // namespace wsl
|
146
src/gfx/renderer.cpp
Normal file
146
src/gfx/renderer.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
#include "renderer.hpp"
|
||||
|
||||
bool wsl::gfx::renderer::init(api graphics_api) {
|
||||
bgfx::Init bgfx_init;
|
||||
bgfx_init.platformData.nwh = window->internal_window->getHwnd();
|
||||
this->graphics_api = graphics_api;
|
||||
bgfx_init.type = bgfx_renderer_type(graphics_api);
|
||||
xwin::UVec2 window_size = window->internal_window->getWindowSize();
|
||||
// bgfx_init.resolution.width = window_size.x;
|
||||
// bgfx_init.resolution.height = window_size.y;
|
||||
bgfx_init.resolution.width = 640;
|
||||
bgfx_init.resolution.height = 480;
|
||||
bgfx_init.resolution.reset = BGFX_RESET_VSYNC;
|
||||
return bgfx::init(bgfx_init);
|
||||
}
|
||||
|
||||
void wsl::gfx::renderer::clear(color::solid clear_color) {
|
||||
bgfx::touch(0);
|
||||
bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, clear_color,
|
||||
1.0f, 0);
|
||||
vec2u size = window->size();
|
||||
bgfx::setViewRect(0, 0, 0, size.x, size.y);
|
||||
}
|
||||
|
||||
void wsl::gfx::renderer::update() { bgfx::frame(); }
|
||||
|
||||
void wsl::gfx::renderer::draw() {
|
||||
std::cout << "draw call" << std::endl;
|
||||
|
||||
vec2u size = window->size();
|
||||
float view[16], proj[16];
|
||||
bx::mtxIdentity(view);
|
||||
bx::mtxOrtho(proj, 0.0f, size.x, 0.0f, size.y, -1.0f, 1.0f, 0.0f, false);
|
||||
bgfx::setViewTransform(0, view, proj);
|
||||
|
||||
bgfx::setVertexBuffer(0, vbo, 0, 8);
|
||||
bgfx::setIndexBuffer(ibo, 0, 3);
|
||||
bgfx::setState(BGFX_STATE_DEFAULT);
|
||||
bgfx::submit(0, program, 0, BGFX_DISCARD_ALL);
|
||||
}
|
||||
|
||||
void wsl::gfx::renderer::queue_triangle(vec2f point_1, vec2f point_2,
|
||||
vec2f point_3,
|
||||
color::solid fill_color) {
|
||||
bgfx::VertexLayout vertex_layout;
|
||||
|
||||
triangle = new gfx::vsh::triangle(
|
||||
vec3f{320.0f, 480.0f, 0.0f}, (vec4f)(color::transparent)fill_color,
|
||||
vec3f{0.0f, 0.0f, 0.0f}, (vec4f)(color::transparent)fill_color,
|
||||
vec3f{640.0f, 0.0f, 0.0f}, (vec4f)(color::transparent)fill_color);
|
||||
|
||||
vertex_layout.begin(bgfx_renderer_type(graphics_api));
|
||||
vertex_layout.add(bgfx::Attrib::Enum::Position, 3,
|
||||
bgfx::AttribType::Enum::Float);
|
||||
vertex_layout.add(bgfx::Attrib::Enum::Color0, 4,
|
||||
bgfx::AttribType::Enum::Float);
|
||||
vertex_layout.end();
|
||||
|
||||
vbo = create_vertex_buffer(triangle->vertices, triangle->size(), vertex_layout);
|
||||
ibo = create_index_buffer(indices, sizeof(indices));
|
||||
|
||||
program =
|
||||
bgfx::createProgram(load_shader("C:/Users/romer/Documents/Projects/"
|
||||
"weasel/build/shader/mesh.vsh.bin"),
|
||||
load_shader("C:/Users/romer/Documents/Projects/"
|
||||
"weasel/build/shader/mesh.fsh.bin"),
|
||||
false);
|
||||
}
|
||||
|
||||
void wsl::gfx::renderer::queue_triangle(vec2f point_1, vec2f point_2,
|
||||
vec2f point_3,
|
||||
color::solid color_1, color::solid color_2,
|
||||
color::solid color_3) {
|
||||
bgfx::VertexLayout vertex_layout;
|
||||
|
||||
triangle = new gfx::vsh::triangle(
|
||||
vec3f{320.0f, 480.0f, 0.0f}, (vec4f)(color::transparent)color_1,
|
||||
vec3f{0.0f, 0.0f, 0.0f}, (vec4f)(color::transparent)color_2,
|
||||
vec3f{640.0f, 0.0f, 0.0f}, (vec4f)(color::transparent)color_3);
|
||||
|
||||
vertex_layout.begin(bgfx_renderer_type(graphics_api));
|
||||
vertex_layout.add(bgfx::Attrib::Enum::Position, 3,
|
||||
bgfx::AttribType::Enum::Float);
|
||||
vertex_layout.add(bgfx::Attrib::Enum::Color0, 4,
|
||||
bgfx::AttribType::Enum::Float);
|
||||
vertex_layout.end();
|
||||
|
||||
vbo = create_vertex_buffer(triangle->vertices, triangle->size(), vertex_layout);
|
||||
ibo = create_index_buffer(indices, sizeof(indices));
|
||||
|
||||
program =
|
||||
bgfx::createProgram(load_shader("C:/Users/romer/Documents/Projects/"
|
||||
"weasel/build/shader/mesh.vsh.bin"),
|
||||
load_shader("C:/Users/romer/Documents/Projects/"
|
||||
"weasel/build/shader/mesh.fsh.bin"),
|
||||
false);
|
||||
}
|
||||
|
||||
bgfx::ShaderHandle wsl::gfx::renderer::load_shader(const std::string& path) {
|
||||
std::ifstream ifs(path);
|
||||
std::stringstream buffer;
|
||||
buffer << ifs.rdbuf();
|
||||
ifs.close();
|
||||
std::cout << buffer.str() << std::endl;
|
||||
return bgfx::createShader(
|
||||
bgfx::copy(buffer.str().c_str(), buffer.str().size()));
|
||||
}
|
||||
|
||||
bgfx::RendererType::Enum wsl::gfx::renderer::bgfx_renderer_type(api wsl_api) {
|
||||
switch (graphics_api) {
|
||||
case api::automatic:
|
||||
return bgfx::RendererType::Enum::Count;
|
||||
break;
|
||||
case api::d3d11:
|
||||
return bgfx::RendererType::Enum::Direct3D11;
|
||||
break;
|
||||
case api::d3d12:
|
||||
return bgfx::RendererType::Enum::Direct3D12;
|
||||
break;
|
||||
case api::metal:
|
||||
return bgfx::RendererType::Enum::Metal;
|
||||
break;
|
||||
case api::opengl:
|
||||
return bgfx::RendererType::Enum::OpenGL;
|
||||
break;
|
||||
case api::opengles:
|
||||
return bgfx::RendererType::Enum::OpenGLES;
|
||||
break;
|
||||
case api::vulkan:
|
||||
return bgfx::RendererType::Enum::Vulkan;
|
||||
break;
|
||||
default:
|
||||
return bgfx::RendererType::Enum::Noop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bgfx::IndexBufferHandle wsl::gfx::renderer::create_index_buffer(
|
||||
const void* indices, std::size_t size) {
|
||||
return bgfx::createIndexBuffer(bgfx::makeRef(indices, size));
|
||||
}
|
||||
|
||||
bgfx::VertexBufferHandle wsl::gfx::renderer::create_vertex_buffer(
|
||||
const void* vertices, std::size_t size, bgfx::VertexLayout layout) {
|
||||
return bgfx::createVertexBuffer(bgfx::makeRef(vertices, size), layout);
|
||||
}
|
70
src/gfx/renderer.hpp
Normal file
70
src/gfx/renderer.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include <bgfx/bgfx.h>
|
||||
#include <bx/math.h>
|
||||
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
#include "gfx/vertex.hpp"
|
||||
#include "util/color.hpp"
|
||||
#include "util/vector.hpp"
|
||||
#include "win/window.hpp"
|
||||
|
||||
namespace wsl {
|
||||
|
||||
namespace gfx {
|
||||
|
||||
enum api {
|
||||
automatic,
|
||||
d3d11,
|
||||
d3d12,
|
||||
metal,
|
||||
opengl,
|
||||
opengles,
|
||||
vulkan,
|
||||
};
|
||||
|
||||
class renderer {
|
||||
public:
|
||||
renderer(window* window) : window(window) {}
|
||||
window* window;
|
||||
|
||||
bool init(api graphics_api = api::automatic);
|
||||
void clear(color::solid clear_color);
|
||||
void update();
|
||||
// void draw(bgfx::ProgramHandle program, bgfx::VertexBufferHandle vbo,
|
||||
// bgfx::IndexBufferHandle ibo);
|
||||
void draw();
|
||||
void draw_test_triangle();
|
||||
bgfx::ShaderHandle load_shader(const std::string& path);
|
||||
|
||||
void queue_triangle(vec2f point_1, vec2f point_2, vec2f point_3,
|
||||
color::solid color);
|
||||
|
||||
bgfx::IndexBufferHandle create_index_buffer(const void* indices,
|
||||
std::size_t size);
|
||||
bgfx::VertexBufferHandle create_vertex_buffer(const void* vertices,
|
||||
std::size_t size,
|
||||
bgfx::VertexLayout layout);
|
||||
|
||||
private:
|
||||
bgfx::RendererType::Enum bgfx_renderer_type(api wsl_api);
|
||||
api graphics_api;
|
||||
|
||||
bgfx::VertexBufferHandle vbo;
|
||||
bgfx::IndexBufferHandle ibo;
|
||||
bgfx::ProgramHandle program;
|
||||
|
||||
gfx::vsh::triangle* triangle;
|
||||
/*
|
||||
|
||||
*/
|
||||
unsigned short indices[3] = {0, 1, 2};
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
||||
} // namespace wsl
|
5
src/gfx/shader/mesh/mesh.fsh
Normal file
5
src/gfx/shader/mesh/mesh.fsh
Normal file
@ -0,0 +1,5 @@
|
||||
$input v_color0, v_texcoord0
|
||||
#include <bgfx_shader.sh>
|
||||
void main() {
|
||||
gl_FragColor = v_color0;
|
||||
}
|
9
src/gfx/shader/mesh/mesh.vsh
Normal file
9
src/gfx/shader/mesh/mesh.vsh
Normal file
@ -0,0 +1,9 @@
|
||||
$input a_position, a_color0
|
||||
$output v_color0, v_texcoord0
|
||||
|
||||
#include <bgfx_shader.sh>
|
||||
|
||||
void main() {
|
||||
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0));
|
||||
v_color0 = a_color0;
|
||||
}
|
10
src/gfx/shader/varying.def.sc
Normal file
10
src/gfx/shader/varying.def.sc
Normal file
@ -0,0 +1,10 @@
|
||||
vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
vec4 v_color1 : COLOR1 = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
|
||||
vec3 v_normal : TEXCOORD1 = vec3(0.0, 1.0, 0.0);
|
||||
|
||||
vec3 a_position : POSITION;
|
||||
vec3 a_normal : NORMAL0;
|
||||
vec4 a_color0 : COLOR0;
|
||||
vec4 a_color1 : COLOR1;
|
||||
vec2 a_texcoord0 : TEXCOORD0;
|
9
src/gfx/texture.hpp
Normal file
9
src/gfx/texture.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include <weasel.hpp>
|
||||
|
||||
namespace wsl {
|
||||
class texture {
|
||||
void create_texture_from_file(const std::string& path);
|
||||
private:
|
||||
bgfx::TextureHandle internal_texture;
|
||||
};
|
||||
}
|
49
src/gfx/vertex.hpp
Normal file
49
src/gfx/vertex.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include "util/vector.hpp"
|
||||
|
||||
namespace wsl {
|
||||
|
||||
namespace gfx {
|
||||
|
||||
namespace vsh {
|
||||
|
||||
struct vertex {};
|
||||
|
||||
namespace vertex_types {
|
||||
|
||||
struct shape2d : vertex {
|
||||
vec3f position;
|
||||
vec4f color;
|
||||
};
|
||||
|
||||
} // namespace vertex_types
|
||||
|
||||
template<typename T, int N>
|
||||
struct shape {
|
||||
T* vertices;
|
||||
constexpr std::size_t size() {
|
||||
std::cout << sizeof(T) * N;
|
||||
return sizeof(T) * N;
|
||||
};
|
||||
};
|
||||
|
||||
struct triangle : shape<vertex_types::shape2d, 3> {
|
||||
triangle(vec3f point_1, vec4f color_1, vec3f point_2, vec4f color_2,
|
||||
vec3f point_3, vec4f color_3) {
|
||||
vertices = new vertex_types::shape2d[3]{
|
||||
vertex_types::shape2d{{}, point_1, color_1},
|
||||
vertex_types::shape2d{{}, point_2, color_2},
|
||||
vertex_types::shape2d{{}, point_3, color_3}};
|
||||
}
|
||||
~triangle() { delete vertices; }
|
||||
};
|
||||
|
||||
} // namespace vsh
|
||||
|
||||
} // namespace gfx
|
||||
|
||||
} // namespace wsl
|
9
src/util/color.cpp
Normal file
9
src/util/color.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include "util/color.hpp"
|
||||
|
||||
wsl::color::solid::operator wsl::color::transparent() const {
|
||||
return transparent{red, green, blue, 0xFF};
|
||||
}
|
||||
|
||||
wsl::color::solid::operator unsigned() const {
|
||||
return static_cast<transparent>(*this);
|
||||
}
|
54
src/util/color.hpp
Normal file
54
src/util/color.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/vector.hpp"
|
||||
|
||||
namespace wsl {
|
||||
|
||||
namespace color {
|
||||
|
||||
struct transparent;
|
||||
|
||||
struct solid {
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
|
||||
operator vec3<float>() {
|
||||
return vec3<float>{static_cast<float>(red) / 255.0f,
|
||||
static_cast<float>(green) / 255.0f,
|
||||
static_cast<float>(blue) / 255.0f};
|
||||
};
|
||||
|
||||
operator transparent() const;
|
||||
operator unsigned() const;
|
||||
};
|
||||
|
||||
struct transparent {
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
unsigned char alpha;
|
||||
|
||||
operator vec4<float>() {
|
||||
return vec4<float>{static_cast<float>(red) / 255.0f,
|
||||
static_cast<float>(green) / 255.0f,
|
||||
static_cast<float>(blue) / 255.0f,
|
||||
static_cast<float>(alpha) / 255.0f};
|
||||
};
|
||||
|
||||
operator solid() const { return solid{red, green, blue}; }
|
||||
operator unsigned() const {
|
||||
return ((red << 8 | green) << 8 | blue) << 8 | alpha;
|
||||
}
|
||||
};
|
||||
|
||||
static solid white{0xFF, 0xFF, 0xFF};
|
||||
static solid black{0x00, 0x00, 0x00};
|
||||
|
||||
static solid red{0xFF, 0x00, 0x00};
|
||||
static solid green{0x00, 0xFF, 0x00};
|
||||
static solid blue{0x00, 0x00, 0xFF};
|
||||
|
||||
} // namespace color
|
||||
|
||||
} // namespace wsl
|
47
src/util/n_ary_tree.hpp
Normal file
47
src/util/n_ary_tree.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace wsl {
|
||||
|
||||
template <typename T>
|
||||
class n_ary_tree {
|
||||
public:
|
||||
class node {
|
||||
public:
|
||||
node(node* parent, T value);
|
||||
|
||||
node* parent;
|
||||
T value;
|
||||
|
||||
node& add_child(T value);
|
||||
int children_count();
|
||||
node& child_at(int index);
|
||||
unsigned index_of(node& child);
|
||||
|
||||
private:
|
||||
std::list<node> children;
|
||||
};
|
||||
|
||||
class iterator {
|
||||
public:
|
||||
iterator(n_ary_tree<T>::node* node) : node_ptr(node) {}
|
||||
iterator operator++();
|
||||
node& operator*();
|
||||
node* operator->();
|
||||
bool operator==(const iterator& other);
|
||||
bool operator!=(const iterator& other);
|
||||
|
||||
private:
|
||||
n_ary_tree<T>::node* node_ptr;
|
||||
};
|
||||
n_ary_tree(T root_value);
|
||||
node root;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
};
|
||||
|
||||
} // namespace wsl
|
||||
|
||||
#include "util/n_ary_tree.tpp"
|
99
src/util/n_ary_tree.tpp
Normal file
99
src/util/n_ary_tree.tpp
Normal file
@ -0,0 +1,99 @@
|
||||
#pragma once
|
||||
|
||||
template <typename T>
|
||||
wsl::n_ary_tree<T>::node::node(n_ary_tree<T>::node* parent, T value)
|
||||
: parent(parent), value(value) {}
|
||||
|
||||
template <typename T>
|
||||
typename wsl::n_ary_tree<T>::node& wsl::n_ary_tree<T>::node::add_child(T value) {
|
||||
children.push_back(node(this, value));
|
||||
return children.back();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int wsl::n_ary_tree<T>::node::children_count() {
|
||||
return children.size();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename wsl::n_ary_tree<T>::node& wsl::n_ary_tree<T>::node::child_at(int index) {
|
||||
typename std::list<n_ary_tree<T>::node>::iterator it = children.begin();
|
||||
std::advance(it, index);
|
||||
return *it;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned wsl::n_ary_tree<T>::node::index_of(n_ary_tree<T>::node& child) {
|
||||
int i = 0;
|
||||
for (node& child_i : children) {
|
||||
if (&child == &child_i) return i;
|
||||
i++;
|
||||
}
|
||||
throw std::invalid_argument("child not found");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename wsl::n_ary_tree<T>::iterator
|
||||
wsl::n_ary_tree<T>::iterator::operator++() {
|
||||
if (node_ptr->children_count() > 0) {
|
||||
// Step down the tree
|
||||
node_ptr = &node_ptr->child_at(0);
|
||||
return *this;
|
||||
} else if (node_ptr->parent) {
|
||||
// If can't move right climb up till it can jump to its
|
||||
// next brother node
|
||||
int index = node_ptr->parent->index_of(*node_ptr);
|
||||
while (index + 1 >= node_ptr->parent->children_count()) {
|
||||
node_ptr = node_ptr->parent;
|
||||
if (!node_ptr->parent) {
|
||||
// Reached the end
|
||||
node_ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
index = node_ptr->parent->index_of(*node_ptr);
|
||||
}
|
||||
// Move to the next brother node
|
||||
node_ptr = &node_ptr->parent->child_at(index + 1);
|
||||
return *this;
|
||||
} else {
|
||||
node_ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename wsl::n_ary_tree<T>::node& wsl::n_ary_tree<T>::iterator::operator*() {
|
||||
return *node_ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename wsl::n_ary_tree<T>::node* wsl::n_ary_tree<T>::iterator::operator->() {
|
||||
return node_ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool wsl::n_ary_tree<T>::iterator::operator==(
|
||||
const n_ary_tree<T>::iterator& other) {
|
||||
return node_ptr == other.node_ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool wsl::n_ary_tree<T>::iterator::operator!=(
|
||||
const n_ary_tree<T>::iterator& other) {
|
||||
return node_ptr != other.node_ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
wsl::n_ary_tree<T>::n_ary_tree(T root_value)
|
||||
: root(node(nullptr, root_value)) {}
|
||||
|
||||
|
||||
template <typename T>
|
||||
typename wsl::n_ary_tree<T>::iterator wsl::n_ary_tree<T>::begin() {
|
||||
return &root;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename wsl::n_ary_tree<T>::iterator wsl::n_ary_tree<T>::end() {
|
||||
return nullptr;
|
||||
}
|
62
src/util/vector.hpp
Normal file
62
src/util/vector.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
namespace wsl {
|
||||
|
||||
template <typename T>
|
||||
struct vec3;
|
||||
|
||||
template <typename T>
|
||||
struct vec2 {
|
||||
T x, y;
|
||||
|
||||
template <typename U>
|
||||
operator vec2<U>() {
|
||||
return vec2<U>{static_cast<U>(x), static_cast<U>(y)};
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
operator vec3<U>() {
|
||||
return vec3<U>{static_cast<U>(x), static_cast<U>(y), 0};
|
||||
}
|
||||
};
|
||||
|
||||
typedef vec2<float> vec2f;
|
||||
typedef vec2<int> vec2i;
|
||||
typedef vec2<unsigned> vec2u;
|
||||
|
||||
template <typename T>
|
||||
struct vec3 {
|
||||
T x, y, z;
|
||||
|
||||
template <typename U>
|
||||
operator vec3<U>() {
|
||||
return vec3<U>{static_cast<U>(x), static_cast<U>(y), static_cast<U>(z)};
|
||||
}
|
||||
|
||||
operator vec2<T>() { return vec2<T>{x, y}; }
|
||||
};
|
||||
|
||||
typedef vec3<float> vec3f;
|
||||
typedef vec3<int> vec3i;
|
||||
typedef vec3<unsigned> vec3u;
|
||||
|
||||
template <typename T>
|
||||
struct vec4 {
|
||||
T x, y, z, w;
|
||||
|
||||
template <typename U>
|
||||
operator vec4<U>() {
|
||||
return vec4<U>{static_cast<U>(x), static_cast<U>(y), static_cast<U>(z),
|
||||
static_cast<U>(w)};
|
||||
}
|
||||
|
||||
operator vec3<T>() { return vec3<T>{x, y, z}; }
|
||||
|
||||
operator vec2<T>() { return vec2<T>{x, y}; }
|
||||
};
|
||||
|
||||
typedef vec4<float> vec4f;
|
||||
typedef vec4<int> vec4i;
|
||||
typedef vec4<unsigned> vec4u;
|
||||
|
||||
} // namespace wsl
|
5
src/weasel.hpp
Normal file
5
src/weasel.hpp
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "core/app.hpp"
|
||||
|
||||
#include "win/window.hpp"
|
14
src/win/system_events.cpp
Normal file
14
src/win/system_events.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "win/system_events.hpp"
|
||||
|
||||
wsl::event::system_event::system_event(
|
||||
std::shared_ptr<xwin::EventQueue>& event_queue_ptr)
|
||||
: xwin_event_queue(event_queue_ptr) {}
|
||||
|
||||
wsl::event::quit::quit(std::shared_ptr<xwin::EventQueue>& event_queue_ptr)
|
||||
: system_event(event_queue_ptr) {}
|
||||
|
||||
bool wsl::event::quit::dispatch_condition() {
|
||||
if (std::shared_ptr<xwin::EventQueue> event_queue = xwin_event_queue.lock())
|
||||
return event_queue->front().type == xwin::EventType::Close;
|
||||
return false;
|
||||
}
|
31
src/win/system_events.hpp
Normal file
31
src/win/system_events.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <CrossWindow/CrossWindow.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include "core/event.hpp"
|
||||
|
||||
namespace wsl {
|
||||
|
||||
namespace event {
|
||||
|
||||
class system_event : public event {
|
||||
public:
|
||||
system_event(std::shared_ptr<xwin::EventQueue>& event_queue_ptr);
|
||||
|
||||
protected:
|
||||
std::weak_ptr<xwin::EventQueue> xwin_event_queue;
|
||||
};
|
||||
|
||||
class quit : public system_event {
|
||||
public:
|
||||
quit(std::shared_ptr<xwin::EventQueue>& event_queue_ptr);
|
||||
|
||||
bool dispatch_condition() override;
|
||||
};
|
||||
|
||||
} // namespace event
|
||||
|
||||
} // namespace wsl
|
33
src/win/window.cpp
Normal file
33
src/win/window.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include "win/window.hpp"
|
||||
|
||||
wsl::window::window() { internal_window = std::make_shared<xwin::Window>(); }
|
||||
|
||||
bool wsl::window::init(const char* title, unsigned int width,
|
||||
unsigned int height) {
|
||||
xwin::WindowDesc desc;
|
||||
desc.title = title;
|
||||
desc.width = width;
|
||||
desc.height = height;
|
||||
return internal_window->create(desc, *events.internal_event_queue);
|
||||
}
|
||||
|
||||
void wsl::window::close() { internal_window->close(); }
|
||||
|
||||
wsl::vec2u wsl::window::size() {
|
||||
xwin::UVec2 size = internal_window->getWindowSize();
|
||||
std::cout << size.x << ' ' << size.y << std::endl;
|
||||
std::cout << internal_window->getDesc().width << ' ' << internal_window->getDesc().height << std::endl;
|
||||
return vec2u{size.x, size.y};
|
||||
}
|
||||
|
||||
wsl::window::events::events()
|
||||
: internal_event_queue(std::make_shared<xwin::EventQueue>()),
|
||||
quit(internal_event_queue) {}
|
||||
|
||||
void wsl::window::events::update() {
|
||||
internal_event_queue->update();
|
||||
while (!internal_event_queue->empty()) {
|
||||
quit.update();
|
||||
internal_event_queue->pop();
|
||||
}
|
||||
}
|
37
src/win/window.hpp
Normal file
37
src/win/window.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <CrossWindow/CrossWindow.h>
|
||||
#include <bgfx/bgfx.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "win/system_events.hpp"
|
||||
#include "util/vector.hpp"
|
||||
|
||||
namespace wsl {
|
||||
|
||||
class window {
|
||||
public:
|
||||
window();
|
||||
|
||||
bool init(const char* title, unsigned int width, unsigned int height);
|
||||
void close();
|
||||
vec2u size();
|
||||
|
||||
class events {
|
||||
public:
|
||||
events();
|
||||
|
||||
void update();
|
||||
|
||||
std::shared_ptr<xwin::EventQueue> internal_event_queue;
|
||||
|
||||
event::quit quit;
|
||||
};
|
||||
|
||||
events events;
|
||||
|
||||
std::shared_ptr<xwin::Window> internal_window;
|
||||
};
|
||||
|
||||
} // namespace wsl
|
1
vendor/CrossWindow
vendored
Submodule
1
vendor/CrossWindow
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 7fc3f3fcd1917a6e1da22b7d1c9880466fdcefaa
|
1
vendor/bgfx.cmake
vendored
Submodule
1
vendor/bgfx.cmake
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 9426a2f44f8c4dad6c45a3b32111974feeb4ba58
|
Loading…
Reference in New Issue
Block a user