diff --git a/.gitignore b/.gitignore index 96dcbc1..a4fb4fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ -thirdparty/*/ build/ .cache/ diff --git a/.gitmodules b/.gitmodules index 0364b4e..640170b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "thirdparty/bgfx.cmake"] path = thirdparty/bgfx.cmake url = https://github.com/bkaradzic/bgfx.cmake -[submodule "thirdparty/imgui.cmake"] - path = thirdparty/imgui.cmake - url = https://github.com/tamaskenez/imgui-cmake [submodule "thirdparty/glfw.cmake"] path = thirdparty/glfw.cmake url = https://github.com/glfw/glfw @@ -13,3 +10,6 @@ [submodule "thirdparty/glm.cmake"] path = thirdparty/glm.cmake url = https://github.com/icaven/glm +[submodule "thirdparty/imgui.cmake"] + path = thirdparty/imgui.cmake + url = https://github.com/tamaskenez/imgui-cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 3dd6ba6..eb22780 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,3 +75,9 @@ foreach(TEXTURE_SOURCE ${TEXTURE_SOURCE_FILES}) ) endforeach() +# build models into /build/models +add_custom_target("models" ALL + COMMAND /bin/bash -c "cp -rf ${PROJECT_SOURCE_DIR}/models/ ${CMAKE_CURRENT_BINARY_DIR}/" +) +# file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/models") +# file(COPY "${PROJECT_SOURCE_DIR}/models/" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/models/") diff --git a/assets/models/cube.obj b/assets/models/cube.obj deleted file mode 100644 index 653c3bf..0000000 Binary files a/assets/models/cube.obj and /dev/null differ diff --git a/include/common.hpp b/include/common.hpp index 73e887e..452a790 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -5,6 +5,8 @@ #include #include +#define GLFW_DEBUG + #define DEFAULT_WIDTH 1280 #define DEFAULT_HEIGHT 720 diff --git a/include/engine.hpp b/include/engine.hpp index 9a008a1..017509c 100644 --- a/include/engine.hpp +++ b/include/engine.hpp @@ -16,17 +16,24 @@ class Engine { public: Engine(void); int Init(void); - void Start(void); int Update(void); void Shutdown(void); static void GlfwErrorCallback(int error, const char *s); void Instantiate(EngineObject* obj); - unsigned int GetInput(void); GLFWwindow* main_window; int main_view; + int keyboard_slots[GLFW_KEY_LAST]; + int cursor_slots[GLFW_MOUSE_BUTTON_LAST+1]; + int cursor_xpos; + int cursor_ypos; + + static void keyboard_callback(GLFWwindow *window, int key, int scancode, int action, int mods); + static void cursor_callback(GLFWwindow *window, double x, double y); + static void cursor_button_callback(GLFWwindow *window, int button, int action, int mods); + private: int width; int height; @@ -36,9 +43,8 @@ class Engine { bgfx::UniformHandle u_position; bgfx::UniformHandle u_rotation; bgfx::UniformHandle u_scale; - bgfx::UniformHandle u_texture_color; - std::vector objs; + std::vector objs; }; #endif diff --git a/include/engine/object.hpp b/include/engine/object.hpp index 7b1a44a..2678c79 100644 --- a/include/engine/object.hpp +++ b/include/engine/object.hpp @@ -1,21 +1,27 @@ #ifndef OBJECT_HPP #define OBJECT_HPP -#include "bgfx/bgfx.h" -#include +#include #include +#include +#include +#include class EngineObject { public: - EngineObject(void); - EngineObject(std::string texture); + EngineObject(); - EngineQuad quad_data; + int load_node(aiScene *scene, aiNode *node); + int load_model(std::string filename); glm::vec4 position; glm::vec4 rotation; glm::vec4 scale; + std::vector vertices; + std::vector indices; + + bgfx::VertexLayout layout; bgfx::TextureHandle texture; bgfx::VertexBufferHandle vbh; bgfx::IndexBufferHandle ibh; diff --git a/models/cube.obj b/models/cube.obj new file mode 100644 index 0000000..1deafb7 --- /dev/null +++ b/models/cube.obj @@ -0,0 +1,25 @@ +# Blender 4.3.2 +# www.blender.org +o Cube +v 1.000000 1.000000 -1.000000 +v 1.000000 -1.000000 -1.000000 +v 1.000000 1.000000 1.000000 +v 1.000000 -1.000000 1.000000 +v -1.000000 1.000000 -1.000000 +v -1.000000 -1.000000 -1.000000 +v -1.000000 1.000000 1.000000 +v -1.000000 -1.000000 1.000000 +s 0 +g off +f 5 3 1 +f 3 8 4 +f 7 6 8 +f 2 8 6 +f 1 4 2 +f 5 2 6 +f 5 7 3 +f 3 7 8 +f 7 5 6 +f 2 4 8 +f 1 3 4 +f 5 1 2 diff --git a/shaders/fs_basic.sc b/shaders/fs_basic.sc index aa01fd5..8d45ebd 100644 --- a/shaders/fs_basic.sc +++ b/shaders/fs_basic.sc @@ -1,14 +1,8 @@ -$input v_texcoord0 - -uniform sampler2D u_texture_color; +$input f_position #include #include void main() { - vec4 color = texture2D(u_texture_color, v_texcoord0); - if (color.r == 0 && color.g == 0 && color.b == 0) { - return; - } - gl_FragColor = color; + gl_FragColor = vec4(f_position.xyz, 1.0f); } diff --git a/shaders/varying.def.sc b/shaders/varying.def.sc index 3defac1..70b364f 100644 --- a/shaders/varying.def.sc +++ b/shaders/varying.def.sc @@ -1,5 +1,3 @@ -vec2 a_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0); vec3 a_position : POSITION; -vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0); - +vec3 f_position : POSITION; diff --git a/shaders/vs_basic.sc b/shaders/vs_basic.sc index eaf2d8a..5e19da2 100644 --- a/shaders/vs_basic.sc +++ b/shaders/vs_basic.sc @@ -1,17 +1,34 @@ -$input a_position, a_texcoord0 -$output v_texcoord0 +$input a_position +$output f_position uniform vec4 u_position; uniform vec4 u_rotation; uniform vec4 u_scale; #include +#include void main() { - vec4 scale = mul(u_scale, vec4(a_position, 1.0f)); + // rotation + mat3 x_rot = mat3(1, 0, 0, + 0, cos(u_rotation.x), -sin(u_rotation.x), + 0, sin(u_rotation.x), cos(u_rotation.x)); + mat3 y_rot = mat3(cos(u_rotation.y), 0, sin(u_rotation.y), + 0, 1, 0, + -sin(u_rotation.y), 0, cos(u_rotation.y)); + mat3 z_rot = mat3(cos(u_rotation.z), -sin(u_rotation.z), 0, + sin(u_rotation.z), cos(u_rotation.z), 0, + 0, 0, 1); + + vec3 r_position = a_position; + r_position = mul(r_position, x_rot); + r_position = mul(r_position, y_rot); + r_position = mul(r_position, z_rot); + + vec4 scale = mul(u_scale, vec4(r_position, 1.0f)); vec4 view = mul(u_view, scale); vec4 pos = view + u_position; gl_Position = mul(u_proj, pos); - v_texcoord0 = a_texcoord0; + f_position = r_position; } diff --git a/src/engine.cpp b/src/engine.cpp index 3f98c2f..1d0510a 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1,10 +1,11 @@ +#include #include "bgfx/defines.h" #include "engine/object.hpp" #include #include #include -#include #include +#include #include #include #include @@ -21,23 +22,51 @@ Engine::Engine(void) { this->title = "EO"; this->main_view = 0; + + memset(this->keyboard_slots, 0, sizeof(this->keyboard_slots)); + memset(this->cursor_slots, 0, sizeof(this->cursor_slots)); +} + +void Engine::keyboard_callback(GLFWwindow *window, int key, int scancode, int action, int mods) { + Engine *engine = (Engine *) glfwGetWindowUserPointer(window); + engine->keyboard_slots[key] = action; +} + +void Engine::cursor_callback(GLFWwindow *window, double x, double y) { + Engine *engine = (Engine *) glfwGetWindowUserPointer(window); + engine->cursor_xpos = x; + engine->cursor_ypos = y; +} + +void Engine::cursor_button_callback(GLFWwindow *window, int button, int action, int mods) { + Engine *engine = (Engine *) glfwGetWindowUserPointer(window); + engine->cursor_slots[button] = action; } int Engine::Init(void) { - int ret = 0; - glfwSetErrorCallback(Engine::GlfwErrorCallback); - ret = glfwInit(); + int ret = glfwInit(); if (ret < 0) { ERROR("failed initializing glfw"); return -1; } + glfwSetErrorCallback(Engine::GlfwErrorCallback); + this->main_window = glfwCreateWindow(this->width, this->height, this->title.c_str(), NULL, NULL); if (!this->main_window) { ERROR("failed creating window"); return -1; } + glfwSetWindowUserPointer(this->main_window, this); + glfwSetKeyCallback(this->main_window, Engine::keyboard_callback); + glfwSetCursorPosCallback(this->main_window, Engine::cursor_callback); + glfwSetMouseButtonCallback(this->main_window, Engine::cursor_button_callback); + +#ifndef GLFW_DEBUG + glfwSetInputMode(this->main_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); +#endif + bgfx::Init init; init.platformData.ndt = glfwGetX11Display(); init.platformData.nwh = (void*) (uintptr_t) glfwGetX11Window(this->main_window); @@ -51,6 +80,10 @@ int Engine::Init(void) { return -1; } +#ifndef BGFX_DEBUG + bgfx::setDebug(BGFX_DEBUG_NONE); +#endif + bgfx::setViewClear(this->main_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x478effff, @@ -64,25 +97,14 @@ int Engine::Init(void) { float view[16]; bx::mtxLookAt(view, eye, at); - float ortho[16]; - bx::mtxOrtho(ortho, - (float) -this->width/(CAMERA_WIDTH*2), - (float) this->width/(CAMERA_WIDTH*2), - (float) -this->height/(CAMERA_WIDTH*2), - (float) this->height/(CAMERA_WIDTH*2), - CAMERA_NEAR, - CAMERA_FAR, - 0.0f, - bgfx::getCaps()->homogeneousDepth - ); + float proj[16]; + bx::mtxProj(proj, 60.0f, float(this->width)/float(this->height), 0.1f, 100.0f, bgfx::getCaps()->homogeneousDepth); - bgfx::setViewTransform(this->main_view, view, ortho); + bgfx::setViewTransform(this->main_view, view, proj); } bgfx::setViewRect(this->main_view, 0, 0, this->width, this->height); - this->u_texture_color = bgfx::createUniform("u_texture_color", bgfx::UniformType::Sampler); - this->u_position = bgfx::createUniform("u_position", bgfx::UniformType::Vec4); this->u_rotation = bgfx::createUniform("u_rotation", bgfx::UniformType::Vec4); this->u_scale = bgfx::createUniform("u_scale", bgfx::UniformType::Vec4); @@ -91,9 +113,6 @@ int Engine::Init(void) { return 0; } -void Engine::Start(void) { -} - int Engine::Update(void) { std::int32_t new_width; std::int32_t new_height; @@ -107,14 +126,15 @@ int Engine::Update(void) { bgfx::touch(this->main_view); + for (int i = 0; i < this->objs.size(); i++) { - bgfx::setState( - BGFX_STATE_WRITE_R | - BGFX_STATE_WRITE_G | - BGFX_STATE_WRITE_B | - BGFX_STATE_WRITE_A | - BGFX_STATE_BLEND_ALPHA - ); + bgfx::setState(BGFX_STATE_WRITE_R | + BGFX_STATE_WRITE_G | + BGFX_STATE_WRITE_B | + BGFX_STATE_WRITE_A | + BGFX_STATE_BLEND_ALPHA | + BGFX_STATE_DEPTH_TEST_LESS | + BGFX_STATE_CULL_CCW ); EngineObject* obj = this->objs[i]; @@ -125,8 +145,6 @@ int Engine::Update(void) { bgfx::setUniform(this->u_rotation, &obj->rotation); bgfx::setUniform(this->u_scale, &obj->scale); - bgfx::setTexture(0, this->u_texture_color, obj->texture); - bgfx::submit(this->main_view, this->program); } @@ -145,7 +163,6 @@ void Engine::Shutdown(void) { bgfx::destroy(this->u_position); bgfx::destroy(this->u_rotation); bgfx::destroy(this->u_scale); - bgfx::destroy(this->u_texture_color); bgfx::destroy(this->program); @@ -160,21 +177,3 @@ void Engine::GlfwErrorCallback(int error, const char *s) { void Engine::Instantiate(EngineObject* obj) { this->objs.push_back(obj); } - -unsigned int Engine::GetInput(void) { - unsigned int ret = 0; - - int keys[] = { - GLFW_KEY_A, - GLFW_KEY_D, - GLFW_KEY_W, - GLFW_KEY_S, - }; - - for (int i = sizeof(keys)/sizeof(int); i >= 0; i--) { - int state = glfwGetKey(this->main_window, keys[i]); - ret = (ret << 1) + (state == GLFW_PRESS ? 1 : 0); - } - - return ret; -} diff --git a/src/engine/object.cpp b/src/engine/object.cpp index 616f72e..aab4cec 100644 --- a/src/engine/object.cpp +++ b/src/engine/object.cpp @@ -1,35 +1,90 @@ +#include "assimp/mesh.h" +#include "assimp/vector3.h" #include "common.hpp" +#include "glm/fwd.hpp" #include #include +#include +#include +#include -EngineObject::EngineObject(void) : quad_data() { - this->position = glm::vec4(0.0f); +EngineObject::EngineObject() { + this->position = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f); this->rotation = glm::vec4(0.0f); this->scale = glm::vec4(1.0f); - - this->vbh = bgfx::createVertexBuffer(bgfx::makeRef( - this->quad_data.vertices.data(), - this->quad_data.vertices.size()*sizeof(VertexData)), - this->quad_data.layout); - this->ibh = bgfx::createIndexBuffer(bgfx::makeRef( - this->quad_data.indices.data(), - this->quad_data.indices.size()*sizeof(uint16_t)) - ); + this->layout.begin() + .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) + .end(); } -EngineObject::EngineObject(std::string texture) : quad_data() { - this->position = glm::vec4(0.0f); - this->rotation = glm::vec4(0.0f); - this->scale = glm::vec4(1.0f); +int EngineObject::load_node(aiScene *scene, aiNode *node) { + if (node == nullptr) { + return -1; + } + + if (scene == nullptr) { + return -1; + } + + for (unsigned int i = 0; i < scene->mNumMeshes; ++i) { + aiMesh *mesh = scene->mMeshes[i]; + for (unsigned int j = 0; j < mesh->mNumVertices; ++j) { + this->vertices.push_back(mesh->mVertices[j].x); + this->vertices.push_back(mesh->mVertices[j].y); + this->vertices.push_back(mesh->mVertices[j].z); + } + + for (unsigned int j = 0; j < mesh->mNumFaces; ++j) { + aiFace *face = &(mesh->mFaces[j]); + this->indices.insert(this->indices.end(), &face->mIndices[0], &face->mIndices[face->mNumIndices]); + } + } + + for (int i = 0; i < node->mNumChildren; ++i) { + this->load_node(scene, node->mChildren[i]); + } + + return 0; +} + +struct vertex { + float x; + float y; + float z; +}; + +int EngineObject::load_model(std::string filename) { + Assimp::Importer importer; + aiScene *scene = (aiScene *) importer.ReadFile(filename, aiProcess_Triangulate | aiProcess_FlipUVs); + if (scene == nullptr || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) { + std::cout << "--error: failed loading model from file-system" << std::endl; + return -1; + } + + aiNode *root = scene->mRootNode; + if (root == NULL) { + std::cout << "--error: no model inside the loaded scene" << std::endl; + return -1; + } + + + int ret = this->load_node(scene, root); + if (ret < 0) { + std::cout << "-error: failed loading node tree" << std::endl; + return -1; + } + + std::cout << "--log: successfully loaded model (" << filename << ")" << std::endl; this->vbh = bgfx::createVertexBuffer(bgfx::makeRef( - this->quad_data.vertices.data(), - this->quad_data.vertices.size()*sizeof(VertexData)), - this->quad_data.layout); + this->vertices.data(), + this->vertices.size()*sizeof(float)), + this->layout); + this->ibh = bgfx::createIndexBuffer(bgfx::makeRef( - this->quad_data.indices.data(), - this->quad_data.indices.size()*sizeof(uint16_t)) + this->indices.data(), + this->indices.size()*sizeof(uint16_t)) ); - this->texture = load_texture(texture); + return 0; } diff --git a/src/eo.cpp b/src/eo.cpp index c296582..a550893 100644 --- a/src/eo.cpp +++ b/src/eo.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #define GET_MS \ std::chrono::duration_cast( \ @@ -15,21 +14,17 @@ int main(int argc, char *argv[]) { Engine engine; int ret = engine.Init(); + std::cout << "ret " << ret << std::endl; if (ret < 0) { ERROR("failed initializing engine"); return EXIT_FAILURE; } - Animation idle_animation(&engine, "textures/idle.dds", 32, 32, 4, 0.2f); - Animation run_animation(&engine, "textures/run.dds", 32, 32, 8, 0.2f); - Animation* active_animation; + EngineObject obj; + obj.load_model("models/cube.obj"); + obj.position.z = -30.0f; - EngineObject* character = new EngineObject("textures/knight.dds"); - character->scale.x = 2.5f; - character->scale.y = 2.5f; - engine.Instantiate(character); - - engine.Start(); + engine.Instantiate(&obj); std::chrono::milliseconds ms = GET_MS; int delta_time = 0; @@ -37,19 +32,18 @@ int main(int argc, char *argv[]) { while (!glfwWindowShouldClose(engine.main_window)) { glfwPollEvents(); - unsigned int input = engine.GetInput(); - active_animation = input > 0 ? &run_animation : &idle_animation; - active_animation->Cycle(time, character); + obj.rotation.y += 0.01f; + obj.rotation.z -= 0.01f; + obj.rotation.z += 0.02f; std::chrono::milliseconds tmp = GET_MS; delta_time = tmp.count() - ms.count(); time += delta_time; ms = tmp; + engine.Update(); } engine.Shutdown(); - delete(character); - return EXIT_SUCCESS; } diff --git a/thirdparty/assimp.cmake b/thirdparty/assimp.cmake new file mode 160000 index 0000000..2aac984 --- /dev/null +++ b/thirdparty/assimp.cmake @@ -0,0 +1 @@ +Subproject commit 2aac984fa3e2459fcca18d5b8f88e648170ee694 diff --git a/thirdparty/bgfx.cmake b/thirdparty/bgfx.cmake new file mode 160000 index 0000000..06144dc --- /dev/null +++ b/thirdparty/bgfx.cmake @@ -0,0 +1 @@ +Subproject commit 06144dcb9b8924c096966432d7702e3d66f7721a diff --git a/thirdparty/glfw.cmake b/thirdparty/glfw.cmake new file mode 160000 index 0000000..e7ea71b --- /dev/null +++ b/thirdparty/glfw.cmake @@ -0,0 +1 @@ +Subproject commit e7ea71be039836da3a98cea55ae5569cb5eb885c diff --git a/thirdparty/glm.cmake b/thirdparty/glm.cmake new file mode 160000 index 0000000..dca3802 --- /dev/null +++ b/thirdparty/glm.cmake @@ -0,0 +1 @@ +Subproject commit dca38025fba63bb9284023e6de55f756b9e37cec diff --git a/thirdparty/imgui.cmake b/thirdparty/imgui.cmake new file mode 160000 index 0000000..21a8fa1 --- /dev/null +++ b/thirdparty/imgui.cmake @@ -0,0 +1 @@ +Subproject commit 21a8fa1d0f46f100c142dace636bae85699e5aeb diff --git a/tools/shaderc b/tools/shaderc index 0c1551e..e69f992 100755 Binary files a/tools/shaderc and b/tools/shaderc differ diff --git a/tools/texturec b/tools/texturec index 54cba0a..013bd1c 100755 Binary files a/tools/texturec and b/tools/texturec differ