From 3779e786755bfd5dea8021fa1dd43a87cda2bda5 Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Wed, 27 Oct 2021 21:55:46 +0200 Subject: [PATCH] Render a simple 3D box. --- README.md | 34 +-------------- assets/engine/3d.glsl_fragment | 15 +++++++ assets/engine/3d.glsl_vertex | 13 ++++++ build/android/app/CMakeLists.txt | 9 +--- build/linux/Makefile | 9 +--- src/engine/engine.cc | 14 ++++++ src/engine/engine.h | 7 +++ src/k3dtest/k3dtest.cc | 48 ++++++++++++++++++++ src/k3dtest/k3dtest.h | 32 ++++++++++++++ src/k3dtest/model.cc | 75 ++++++++++++++++++++++++++++++++ src/k3dtest/model.h | 36 +++++++++++++++ 11 files changed, 245 insertions(+), 47 deletions(-) create mode 100644 assets/engine/3d.glsl_fragment create mode 100644 assets/engine/3d.glsl_vertex create mode 100644 src/k3dtest/k3dtest.cc create mode 100644 src/k3dtest/k3dtest.h create mode 100644 src/k3dtest/model.cc create mode 100644 src/k3dtest/model.h diff --git a/README.md b/README.md index 5fea6ac..6ffb82a 100644 --- a/README.md +++ b/README.md @@ -1,33 +1 @@ -A simple, cross-platform 2D game engine with OpenGL and Vulkan renderers. -Supports Linux and Android (lolipop+) platforms. -This is a personal hobby project. I've published a little game on -[Google Play](https://play.google.com/store/apps/details?id=com.woom.game) -based on this engine. Full game code and assets are included in this repository. -#### Building the demo -Linux: -```text -cd build/linux -make -``` -Android: -```text -cd build/android -./gradlew :app:assembleRelease -``` -GN (linux only for now): -```text -gn gen --args='is_debug=false' out/release -ninja -C out/release -``` -#### Third-party libraries: -[glew](https://github.com/nigels-com/glew), -[jsoncpp](https://github.com/open-source-parsers/jsoncpp), -[minimp3](https://github.com/lieff/minimp3), -[oboe](https://github.com/google/oboe), -[stb](https://github.com/nothings/stb), -[texture-compressor](https://github.com/auygun/kaliber/tree/master/src/third_party/texture_compressor), -[minizip](https://github.com/madler/zlib/tree/master/contrib/minizip), -[glslang](https://github.com/KhronosGroup/glslang), -[spirv-reflect](https://github.com/KhronosGroup/SPIRV-Reflect), -[vma](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator), -[vulkan-sdk](https://vulkan.lunarg.com) +3D rendering test branch. Check master branch for more info about the project. diff --git a/assets/engine/3d.glsl_fragment b/assets/engine/3d.glsl_fragment new file mode 100644 index 0000000..f67634f --- /dev/null +++ b/assets/engine/3d.glsl_fragment @@ -0,0 +1,15 @@ +#ifdef GL_ES +precision mediump float; +#endif + +IN(0) vec3 color; + +UNIFORM_BEGIN + UNIFORM_V(mat4 projection) +UNIFORM_END + +FRAG_COLOR_OUT(frag_color) + +void main() { + FRAG_COLOR(frag_color) = vec4(color, 1.0); +} diff --git a/assets/engine/3d.glsl_vertex b/assets/engine/3d.glsl_vertex new file mode 100644 index 0000000..7d1652d --- /dev/null +++ b/assets/engine/3d.glsl_vertex @@ -0,0 +1,13 @@ +IN(0) vec3 in_position; +IN(1) vec3 in_color; + +UNIFORM_BEGIN + UNIFORM_V(mat4 mvp) +UNIFORM_END + +OUT(0) vec3 color; + +void main() { + color = in_color; + gl_Position = PARAM(mvp) * vec4(in_position, 1.0); +} diff --git a/build/android/app/CMakeLists.txt b/build/android/app/CMakeLists.txt index 0008e4b..9b2eda9 100644 --- a/build/android/app/CMakeLists.txt +++ b/build/android/app/CMakeLists.txt @@ -55,13 +55,8 @@ add_library(kaliber SHARED ../../../src/base/task_runner.cc ../../../src/base/thread_pool.cc ../../../src/base/timer.cc - ../../../src/demo/credits.cc - ../../../src/demo/demo.cc - ../../../src/demo/enemy.cc - ../../../src/demo/hud.cc - ../../../src/demo/menu.cc - ../../../src/demo/player.cc - ../../../src/demo/sky_quad.cc + ../../../src/k3dtest/k3dtest.cc + ../../../src/k3dtest/model.cc ../../../src/engine/animatable.cc ../../../src/engine/animator.cc ../../../src/engine/audio/audio_base.cc diff --git a/build/linux/Makefile b/build/linux/Makefile index 92302fd..f67abf7 100644 --- a/build/linux/Makefile +++ b/build/linux/Makefile @@ -186,13 +186,8 @@ $(ENGINE_LIB): $(ENGINE_OBJS) ifneq ($(filter demo,$(APPS)),) DEMO_SRC := \ - $(SRC_ROOT)/demo/credits.cc \ - $(SRC_ROOT)/demo/demo.cc \ - $(SRC_ROOT)/demo/enemy.cc \ - $(SRC_ROOT)/demo/hud.cc \ - $(SRC_ROOT)/demo/menu.cc \ - $(SRC_ROOT)/demo/player.cc \ - $(SRC_ROOT)/demo/sky_quad.cc + $(SRC_ROOT)/k3dtest/k3dtest.cc \ + $(SRC_ROOT)/k3dtest/model.cc DEMO_EXE := $(call app_exe,demo) DEMO_OBJS := $(call objs_from_src, $(DEMO_SRC)) diff --git a/src/engine/engine.cc b/src/engine/engine.cc index 7ecea31..d4a16c0 100644 --- a/src/engine/engine.cc +++ b/src/engine/engine.cc @@ -36,6 +36,8 @@ Engine::Engine(Platform* platform, Renderer* renderer, Audio* audio) pass_through_shader_ = CreateRenderResource(); solid_shader_ = CreateRenderResource(); + box_shader_ = CreateRenderResource(); + stats_ = std::make_unique(); } @@ -62,6 +64,9 @@ bool Engine::Initialize() { projection_.CreateOrthoProjection(-1.0, 1.0, -aspect_ratio, aspect_ratio); } + fov_projection_.CreateFovProjection(45, 4.0f / 3.0f, (float)GetScreenWidth(), + (float)GetScreenHeight(), 4, 2048); + LOG << "image scale factor: " << GetImageScaleFactor(); if (renderer_->SupportsDXT5()) { @@ -493,6 +498,15 @@ bool Engine::CreateRenderResources() { solid_shader_->Create(std::move(source), quad_->vertex_description(), quad_->primitive(), false); + VertexDescripton vd_3d; + ParseVertexDescription("p3f;c3f", vd_3d); + source = std::make_unique(); + if (!source->Load("engine/3d.glsl")) { + LOG << "Could not create 3d shader."; + return false; + } + box_shader_->Create(std::move(source), vd_3d, kPrimitive_Triangles, true); + return true; } diff --git a/src/engine/engine.h b/src/engine/engine.h index a01077e..3d43535 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -108,6 +108,7 @@ class Engine { Geometry* GetQuad() { return quad_.get(); } Shader* GetPassThroughShader() { return pass_through_shader_.get(); } Shader* GetSolidShader() { return solid_shader_.get(); } + Shader* GetBoxShader() { return box_shader_.get(); } const Font* GetSystemFont() { return system_font_.get(); } @@ -125,6 +126,9 @@ class Engine { base::Vector2f GetScreenSize() const { return screen_size_; } const base::Matrix4f& GetProjectionMatrix() const { return projection_; } + const base::Matrix4f& GetFovProjectionMatrix() const { + return fov_projection_; + } int GetDeviceDpi() const; @@ -172,8 +176,11 @@ class Engine { std::unique_ptr pass_through_shader_; std::unique_ptr solid_shader_; + std::unique_ptr box_shader_; + base::Vector2f screen_size_ = {0, 0}; base::Matrix4f projection_; + base::Matrix4f fov_projection_; std::unique_ptr system_font_; diff --git a/src/k3dtest/k3dtest.cc b/src/k3dtest/k3dtest.cc new file mode 100644 index 0000000..8128e55 --- /dev/null +++ b/src/k3dtest/k3dtest.cc @@ -0,0 +1,48 @@ +#include "k3dtest.h" + +#include +#include +#include +#include + +#include "../base/file.h" +#include "../base/interpolation.h" +#include "../base/log.h" +#include "../base/random.h" +#include "../base/timer.h" +#include "../engine/engine.h" +#include "../engine/game_factory.h" +#include "../engine/input_event.h" +#include "../engine/sound.h" + +DECLARE_GAME_BEGIN +DECLARE_GAME(K3dTest) +DECLARE_GAME_END + +using namespace std::string_literals; + +using namespace base; +using namespace eng; + +K3dTest::K3dTest() = default; + +K3dTest::~K3dTest() = default; + + +bool K3dTest::Initialize() { + box_.Create(); + box_.SetVisible(true); + return true; +} + +void K3dTest::Update(float delta_time) { + box_.Update(); +} + +void K3dTest::ContextLost() { +} + +void K3dTest::LostFocus() {} + +void K3dTest::GainedFocus(bool from_interstitial_ad) { +} diff --git a/src/k3dtest/k3dtest.h b/src/k3dtest/k3dtest.h new file mode 100644 index 0000000..e1f554b --- /dev/null +++ b/src/k3dtest/k3dtest.h @@ -0,0 +1,32 @@ +#ifndef K3DTEST_H +#define K3DTEST_H + +#include "../base/closure.h" +#include "../engine/animator.h" +#include "../engine/font.h" +#include "../engine/game.h" +#include "../engine/persistent_data.h" +#include "../engine/solid_quad.h" +#include "../engine/sound_player.h" +#include "model.h" + +class K3dTest : public eng::Game { + public: + K3dTest(); + ~K3dTest() override; + + bool Initialize() override; + + void Update(float delta_time) override; + + void ContextLost() override; + + void LostFocus() override; + + void GainedFocus(bool from_interstitial_ad) override; + + private: + Model box_; +}; + +#endif // K3DTEST_H diff --git a/src/k3dtest/model.cc b/src/k3dtest/model.cc new file mode 100644 index 0000000..f54cb2c --- /dev/null +++ b/src/k3dtest/model.cc @@ -0,0 +1,75 @@ +#include "model.h" + +#include "../base/interpolation.h" +#include "../base/log.h" +#include "../base/random.h" +#include "../engine/engine.h" +#include "../engine/mesh.h" +#include "../engine/renderer/geometry.h" +#include "../engine/renderer/shader.h" + +using namespace base; +using namespace eng; + +Model::Model() : model_(Engine::Get().CreateRenderResource()) {} + +Model::~Model() = default; + +bool Model::Create() { + static const char box_vertex_description[] = "p3f;c3f"; + static const float box_vertices[] = { + // front + -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + // back + -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 1.0f, + 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, + 1.0f}; + static const unsigned short box_indices[] = {// front + 0, 1, 2, 2, 3, 0, + // right + 1, 5, 6, 6, 2, 1, + // back + 7, 6, 5, 5, 4, 7, + // left + 4, 0, 3, 3, 7, 4, + // bottom + 4, 5, 1, 1, 0, 4, + // top + 3, 2, 6, 6, 7, 3}; + + auto box_mesh = std::make_unique(); + box_mesh->Create(kPrimitive_Triangles, box_vertex_description, 8, + box_vertices, kDataType_UShort, 12 * 3, box_indices); + model_->Create(std::move(box_mesh)); + + return true; +} + +void Model::Draw(float frame_frac) { + DCHECK(IsVisible()); + + float tick_time = Engine::Get().time_step() * 0.2; + float ang = ticks_ * tick_time + tick_time * frame_frac; + + Matrix4f model; + model.CreateFromAngles({0, std::fmod(ang, 1.0f), 0}, 1); + model.GetRow(3) = Vector3f(0, 0, 0); + + Matrix4f view, inv_view; + view.CreateLookAt({10, -5, 10}, {0, 0, 0}); + view.InverseOrthogonal(inv_view); + + Matrix4f model_view, mvp; + model.Multiply(inv_view, model_view); + model_view.Multiply(Engine::Get().GetFovProjectionMatrix(), mvp); + + Engine::Get().GetBoxShader()->Activate(); + Engine::Get().GetBoxShader()->SetUniform("mvp", mvp); + Engine::Get().GetBoxShader()->UploadUniforms(); + model_->Draw(); +} + +void Model::Update() { + ++ticks_; +} \ No newline at end of file diff --git a/src/k3dtest/model.h b/src/k3dtest/model.h new file mode 100644 index 0000000..229a47d --- /dev/null +++ b/src/k3dtest/model.h @@ -0,0 +1,36 @@ +#ifndef MODEL_H +#define MODEL_H + +#include "../base/vecmath.h" +#include "../engine/drawable.h" + +#include +#include +#include +#include + +namespace eng { +class Geometry; +} // namespace eng + +class Model : public eng::Drawable { + public: + Model(); + ~Model(); + + bool Create(); + + // Drawable interface. + void Draw(float frame_frac) override; + + void Update(); + + private: + std::unique_ptr model_; + size_t ticks_ = 0; + + Model(const Model&) = delete; + Model& operator=(const Model&) = delete; +}; + +#endif // MODEL_H