diff --git a/CMakeLists.txt b/CMakeLists.txt index 3aeedea..f60d446 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,4 +74,6 @@ add_shaders(VulkanEngineShaders ${ShaderSources}) add_dependencies(VulkanEngine VulkanEngineShaders) file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/assets/paving-stones.jpg" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/assets") -file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/assets/player.fbx" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/assets") \ No newline at end of file +file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/assets/copying-stones.jpg" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/assets") +file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/assets/player.fbx" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/assets") +file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/assets/wall.fbx" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/assets") \ No newline at end of file diff --git a/assets/copying-stones.jpg b/assets/copying-stones.jpg new file mode 100644 index 0000000..fd19784 Binary files /dev/null and b/assets/copying-stones.jpg differ diff --git a/assets/player.fbx b/assets/player.fbx index 5576d9e..b14433a 100644 Binary files a/assets/player.fbx and b/assets/player.fbx differ diff --git a/assets/wall.fbx b/assets/wall.fbx new file mode 100644 index 0000000..4717fea Binary files /dev/null and b/assets/wall.fbx differ diff --git a/include/asset/object/material.h b/include/asset/object/material.h new file mode 100644 index 0000000..fc49b11 --- /dev/null +++ b/include/asset/object/material.h @@ -0,0 +1,9 @@ +#pragma once + +#include "vulkan/texture_handle.h" + +namespace veng { +struct Material { + TextureHandle texture; +}; +} // namespace veng diff --git a/include/asset/object/model.h b/include/asset/object/model.h new file mode 100644 index 0000000..206e6b0 --- /dev/null +++ b/include/asset/object/model.h @@ -0,0 +1,27 @@ +#pragma once +#include + +#include "material.h" +#include "vulkan/graphics.h" +#include "vulkan/vertex.h" + +#include + +namespace veng { +struct Model { + Model(std::shared_ptr graphics); + ~Model(); + + std::vector vertices; + veng::BufferHandle vertex_buffer; + std::vector indices; + veng::BufferHandle index_buffer; + + glm::mat4 transform; + + Material material; + +private: + std::weak_ptr graphics_; +}; +} // namespace veng diff --git a/include/glfw/glfw_window.h b/include/glfw/glfw_window.h index 8b9fe41..2bec0ea 100644 --- a/include/glfw/glfw_window.h +++ b/include/glfw/glfw_window.h @@ -1,7 +1,6 @@ #pragma once -struct GLFWmonitor; -struct GLFWwindow; +#include namespace veng { class Window { @@ -14,6 +13,8 @@ class Window { bool ShouldClose() const; GLFWwindow* GetHandle() const; + GLFWkeyfun SetKeyCallback(GLFWkeyfun key_callback); + bool TryMoveToMonitor(std::uint16_t monitor_number); private: diff --git a/include/vulkan/graphics.h b/include/vulkan/graphics.h index 7a41c31..d6856f6 100644 --- a/include/vulkan/graphics.h +++ b/include/vulkan/graphics.h @@ -33,6 +33,7 @@ class Graphics final { void RenderBuffer(BufferHandle handle, std::uint32_t vertex_count); void RenderIndexedBuffer(BufferHandle vertex_buffer, BufferHandle index_buffer, std::uint32_t count); + void RenderModel(struct Model& model); void EndFrame(); BufferHandle CreateVertexBuffer(gsl::span vertices); diff --git a/include/vulkan/model.h b/include/vulkan/model.h deleted file mode 100644 index 038fe4b..0000000 --- a/include/vulkan/model.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include - -#include "vertex.h" - -namespace veng { -struct Model { - std::vector vertices; - std::vector indices; - glm::mat4 transform; -}; -} // namespace veng diff --git a/src/asset/object/model.cpp b/src/asset/object/model.cpp new file mode 100644 index 0000000..7d5be8a --- /dev/null +++ b/src/asset/object/model.cpp @@ -0,0 +1,17 @@ +#include "asset/object/model.h" + +namespace veng { + +Model::Model(std::shared_ptr graphics) { graphics_ = graphics; } + +Model::~Model() { + auto graphics = graphics_.lock(); + + if (!graphics) return; + + graphics->DestroyTexture(material.texture); + graphics->DestroyBuffer(vertex_buffer); + graphics->DestroyBuffer(index_buffer); +} + +} // namespace veng diff --git a/src/glfw/glfw_window.cpp b/src/glfw/glfw_window.cpp index 31d23ef..953224b 100644 --- a/src/glfw/glfw_window.cpp +++ b/src/glfw/glfw_window.cpp @@ -1,7 +1,8 @@ +#include "glfw/glfw_window.h" + #include #include "glfw/glfw_monitor.h" -#include "glfw/glfw_window.h" #include "precomp.h" namespace veng { @@ -32,6 +33,10 @@ bool Window::ShouldClose() const { return glfwWindowShouldClose(window_); } GLFWwindow* Window::GetHandle() const { return window_; } +GLFWkeyfun Window::SetKeyCallback(GLFWkeyfun key_callback) { + return glfwSetKeyCallback(window_, key_callback); +} + bool Window::TryMoveToMonitor(std::uint16_t monitor_number) { gsl::span monitors = veng::GetMonitors(); diff --git a/src/main.cpp b/src/main.cpp index 82865d1..49240ec 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,7 @@ #include #include +#include "asset/object/model.h" #include "assimp/Importer.hpp" #include "assimp/postprocess.h" #include "assimp/scene.h" @@ -18,54 +19,83 @@ std::int32_t main(std::int32_t argc, gsl::zstring* argv) { veng::Window window("Vulkan Engine", {800, 600}); window.TryMoveToMonitor(0); - veng::Graphics graphics(&window); + std::shared_ptr graphics = + std::make_shared(&window); Assimp::Importer assetImporter; const struct aiScene* scene = assetImporter.ReadFile( - "assets/player.fbx", aiProcess_CalcTangentSpace | aiProcess_Triangulate | + "assets/wall.fbx", aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | - aiProcess_SortByPType); + aiProcess_SortByPType | aiProcess_FlipUVs); if (scene == nullptr || !scene->HasMeshes()) { spdlog::error(assetImporter.GetErrorString()); return false; } - std::vector vertices; + veng::Model player(graphics); + aiMesh* mesh = scene->mMeshes[0]; for (std::uint32_t i = 0; i < mesh->mNumVertices; i++) { - vertices.emplace_back( + glm::vec2 uv = {mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y}; + player.vertices.emplace_back( glm::vec3{mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z}, - glm::vec2{mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y}); + uv); } - veng::BufferHandle buffer = graphics.CreateVertexBuffer(vertices); + player.vertex_buffer = graphics->CreateVertexBuffer(player.vertices); - std::vector indices; for (std::uint32_t i = 0; i < mesh->mNumFaces; i++) { aiFace face = mesh->mFaces[i]; for (unsigned int j = 0; j < face.mNumIndices; ++j) { - indices.push_back(face.mIndices[j]); + player.indices.push_back(face.mIndices[j]); } } - veng::BufferHandle index_buffer = graphics.CreateIndexBuffer(indices); + player.index_buffer = graphics->CreateIndexBuffer(player.indices); - glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(45.f), - glm::vec3(0.f, 1.f, 0.f)); + aiString string; + if (scene->mMaterials[scene->mMeshes[0]->mMaterialIndex]->GetTexture( + aiTextureType_DIFFUSE, 0, &string) != AI_SUCCESS) { + std::cout << "No texture" << std::endl; + } - glm::mat4 rotation2 = - glm::rotate(glm::mat4(1.0f), glm::radians(0.f), glm::vec3(0.f, 0.f, 1.f)); + veng::Model wall(graphics); + + wall.vertices = {veng::Vertex{{-1.f, -1.f, 0.f}, {0.f, 1.f}}, + veng::Vertex{{1.f, -1.f, 0.f}, {1.f, 1.f}}, + veng::Vertex{{-1.f, 1.f, 0.f}, {0.f, 0.f}}, + veng::Vertex{{1.f, 1.f, 0.f}, {1.f, 0.f}}}; + wall.vertex_buffer = graphics->CreateVertexBuffer(wall.vertices); + + wall.indices = {0, 3, 2, 0, 1, 3}; + wall.index_buffer = graphics->CreateIndexBuffer(wall.indices); + + player.transform = + glm::rotate(glm::mat4(1.0f), glm::radians(0.f), glm::vec3(0.f, 1.f, 0.f)); + // player.transform = glm::scale(player.transform, + // glm::vec3(50.f, 50.f, 50.f)); + + wall.transform = glm::rotate(glm::mat4(1.0f), glm::radians(180.f), + glm::vec3(0.f, 0.f, 1.f)); + // plane.transform = glm::scale(plane.transform, glm::vec3(100.f, 100.f, + // 100.f)); glm::mat4 view = glm::lookAt(glm::vec3(0.f, 0.f, 10.f), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 1.f, 0.f)); - glm::mat4 projection = - glm::perspective(glm::radians(150.f), 800.f / 600.f, 0.1f, 100.f); - graphics.SetViewProjection(view, projection); + /*glm::mat4 projection = + glm::perspective(glm::radians(150.f), 800.f / 600.f, 0.1f, 100.f);*/ + glm::mat4 projection = glm::ortho(-10.f, 10.f, -10.f, 10.f, -10.f, 10.f); + graphics->SetViewProjection(view, projection); - veng::TextureHandle texture = - graphics.CreateTexture("assets/paving-stones.jpg"); + // player.material.texture = + // graphics->CreateTexture("assets/paving-stones.jpg"); + + auto texture = scene->GetEmbeddedTexture(string.C_Str()); + player.material.texture = graphics->CreateTexture( + gsl::span{(std::uint8_t*)texture->pcData, texture->mWidth}); + wall.material.texture = graphics->CreateTexture("assets/copying-stones.jpg"); double last_time = glfwGetTime(); @@ -77,35 +107,41 @@ std::int32_t main(std::int32_t argc, gsl::zstring* argv) { if (current_window_size != window_size && current_window_size.x != 0 && current_window_size.y != 0) { window_size = current_window_size; - projection = glm::perspective( + auto grater = (current_window_size.x > current_window_size.y) + ? current_window_size.x + : current_window_size.y; + projection = glm::ortho(0.01f * (float)current_window_size.x / 2, + -0.01f * (float)current_window_size.x / 2, + -0.01f * (float)current_window_size.y / 2, + 0.01f * (float)current_window_size.y / 2, + -1 * (float)grater, (float)grater); + /*projection = glm::perspective( glm::radians(90.f), (float)current_window_size.x / (float)current_window_size.y, 0.1f, - 100.f); - graphics.SetViewProjection(view, projection); + 100.f);*/ + graphics->SetViewProjection(view, projection); } - if (graphics.BeginFrame()) { + // std::cout << glfwGetKey(window.GetHandle(), GLFW_KEY_W) << std::endl; + + if (graphics->BeginFrame()) { double current_time = glfwGetTime(); float delta_time = static_cast(current_time - last_time); last_time = current_time; - graphics.SetTexture(texture); - rotation2 = glm::rotate(rotation2, delta_time * glm::radians(-360.f), - glm::vec3(0.f, 0.f, 1.f)); - graphics.SetModelMatrix(rotation2); - graphics.RenderIndexedBuffer(buffer, index_buffer, indices.size()); - rotation = glm::rotate(rotation, delta_time * glm::radians(360.f), - glm::vec3(0.f, 0.f, 1.f)); - graphics.SetModelMatrix(rotation); - graphics.RenderIndexedBuffer(buffer, index_buffer, indices.size()); + player.transform = + glm::rotate(player.transform, delta_time * glm::radians(60.f), + glm::vec3(0.f, 0.f, 1.f)); + graphics->RenderModel(player); - graphics.EndFrame(); + wall.transform = + glm::rotate(wall.transform, delta_time * glm::radians(-60.f), + glm::vec3(0.f, 1.f, 0.f)); + graphics->RenderModel(wall); + + graphics->EndFrame(); } } - graphics.DestroyTexture(texture); - graphics.DestroyBuffer(buffer); - graphics.DestroyBuffer(index_buffer); - return EXIT_SUCCESS; } diff --git a/src/vulkan/buffers.cpp b/src/vulkan/buffers.cpp index 37bd695..a436ae4 100644 --- a/src/vulkan/buffers.cpp +++ b/src/vulkan/buffers.cpp @@ -1,5 +1,6 @@ #include +#include "asset/object/model.h" #include "precomp.h" #include "vulkan/graphics.h" #include "vulkan/uniform_transformations.h" @@ -142,8 +143,8 @@ void Graphics::SetModelMatrix(glm::mat4 model) { void Graphics::SetViewProjection(glm::mat4 view, glm::mat4 projection) { UniformTransformations transformations{view, projection}; for (Frame& frame : frames_) - std::memcpy(frame.uniform_buffer_location, - &transformations, sizeof(UniformTransformations)); + std::memcpy(frame.uniform_buffer_location, &transformations, + sizeof(UniformTransformations)); } void Graphics::RenderBuffer(BufferHandle handle, std::uint32_t vertex_count) { @@ -170,6 +171,12 @@ void Graphics::RenderIndexedBuffer(BufferHandle vertex_buffer, vkCmdDrawIndexed(frames_[current_frame_].command_buffer, count, 1, 0, 0, 0); SetModelMatrix(glm::mat4(1.f)); } +void Graphics::RenderModel(Model& model) { + SetTexture(model.material.texture); + SetModelMatrix(model.transform); + RenderIndexedBuffer(model.vertex_buffer, model.index_buffer, + model.indices.size()); +} VkCommandBuffer Graphics::BeginTransientCommandBuffer() { VkCommandBufferAllocateInfo allocation_info = {};