mirror of https://github.com/auygun/kaliber.git
Render a simple 3D box.
This commit is contained in:
parent
1e57355593
commit
3779e78675
34
README.md
34
README.md
|
@ -1,33 +1 @@
|
||||||
A simple, cross-platform 2D game engine with OpenGL and Vulkan renderers.
|
3D rendering test branch. Check master branch for more info about the project.
|
||||||
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)
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -55,13 +55,8 @@ add_library(kaliber SHARED
|
||||||
../../../src/base/task_runner.cc
|
../../../src/base/task_runner.cc
|
||||||
../../../src/base/thread_pool.cc
|
../../../src/base/thread_pool.cc
|
||||||
../../../src/base/timer.cc
|
../../../src/base/timer.cc
|
||||||
../../../src/demo/credits.cc
|
../../../src/k3dtest/k3dtest.cc
|
||||||
../../../src/demo/demo.cc
|
../../../src/k3dtest/model.cc
|
||||||
../../../src/demo/enemy.cc
|
|
||||||
../../../src/demo/hud.cc
|
|
||||||
../../../src/demo/menu.cc
|
|
||||||
../../../src/demo/player.cc
|
|
||||||
../../../src/demo/sky_quad.cc
|
|
||||||
../../../src/engine/animatable.cc
|
../../../src/engine/animatable.cc
|
||||||
../../../src/engine/animator.cc
|
../../../src/engine/animator.cc
|
||||||
../../../src/engine/audio/audio_base.cc
|
../../../src/engine/audio/audio_base.cc
|
||||||
|
|
|
@ -186,13 +186,8 @@ $(ENGINE_LIB): $(ENGINE_OBJS)
|
||||||
ifneq ($(filter demo,$(APPS)),)
|
ifneq ($(filter demo,$(APPS)),)
|
||||||
|
|
||||||
DEMO_SRC := \
|
DEMO_SRC := \
|
||||||
$(SRC_ROOT)/demo/credits.cc \
|
$(SRC_ROOT)/k3dtest/k3dtest.cc \
|
||||||
$(SRC_ROOT)/demo/demo.cc \
|
$(SRC_ROOT)/k3dtest/model.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
|
|
||||||
|
|
||||||
DEMO_EXE := $(call app_exe,demo)
|
DEMO_EXE := $(call app_exe,demo)
|
||||||
DEMO_OBJS := $(call objs_from_src, $(DEMO_SRC))
|
DEMO_OBJS := $(call objs_from_src, $(DEMO_SRC))
|
||||||
|
|
|
@ -36,6 +36,8 @@ Engine::Engine(Platform* platform, Renderer* renderer, Audio* audio)
|
||||||
pass_through_shader_ = CreateRenderResource<Shader>();
|
pass_through_shader_ = CreateRenderResource<Shader>();
|
||||||
solid_shader_ = CreateRenderResource<Shader>();
|
solid_shader_ = CreateRenderResource<Shader>();
|
||||||
|
|
||||||
|
box_shader_ = CreateRenderResource<Shader>();
|
||||||
|
|
||||||
stats_ = std::make_unique<ImageQuad>();
|
stats_ = std::make_unique<ImageQuad>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +64,9 @@ bool Engine::Initialize() {
|
||||||
projection_.CreateOrthoProjection(-1.0, 1.0, -aspect_ratio, aspect_ratio);
|
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();
|
LOG << "image scale factor: " << GetImageScaleFactor();
|
||||||
|
|
||||||
if (renderer_->SupportsDXT5()) {
|
if (renderer_->SupportsDXT5()) {
|
||||||
|
@ -493,6 +498,15 @@ bool Engine::CreateRenderResources() {
|
||||||
solid_shader_->Create(std::move(source), quad_->vertex_description(),
|
solid_shader_->Create(std::move(source), quad_->vertex_description(),
|
||||||
quad_->primitive(), false);
|
quad_->primitive(), false);
|
||||||
|
|
||||||
|
VertexDescripton vd_3d;
|
||||||
|
ParseVertexDescription("p3f;c3f", vd_3d);
|
||||||
|
source = std::make_unique<ShaderSource>();
|
||||||
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,7 @@ class Engine {
|
||||||
Geometry* GetQuad() { return quad_.get(); }
|
Geometry* GetQuad() { return quad_.get(); }
|
||||||
Shader* GetPassThroughShader() { return pass_through_shader_.get(); }
|
Shader* GetPassThroughShader() { return pass_through_shader_.get(); }
|
||||||
Shader* GetSolidShader() { return solid_shader_.get(); }
|
Shader* GetSolidShader() { return solid_shader_.get(); }
|
||||||
|
Shader* GetBoxShader() { return box_shader_.get(); }
|
||||||
|
|
||||||
const Font* GetSystemFont() { return system_font_.get(); }
|
const Font* GetSystemFont() { return system_font_.get(); }
|
||||||
|
|
||||||
|
@ -125,6 +126,9 @@ class Engine {
|
||||||
base::Vector2f GetScreenSize() const { return screen_size_; }
|
base::Vector2f GetScreenSize() const { return screen_size_; }
|
||||||
|
|
||||||
const base::Matrix4f& GetProjectionMatrix() const { return projection_; }
|
const base::Matrix4f& GetProjectionMatrix() const { return projection_; }
|
||||||
|
const base::Matrix4f& GetFovProjectionMatrix() const {
|
||||||
|
return fov_projection_;
|
||||||
|
}
|
||||||
|
|
||||||
int GetDeviceDpi() const;
|
int GetDeviceDpi() const;
|
||||||
|
|
||||||
|
@ -172,8 +176,11 @@ class Engine {
|
||||||
std::unique_ptr<Shader> pass_through_shader_;
|
std::unique_ptr<Shader> pass_through_shader_;
|
||||||
std::unique_ptr<Shader> solid_shader_;
|
std::unique_ptr<Shader> solid_shader_;
|
||||||
|
|
||||||
|
std::unique_ptr<Shader> box_shader_;
|
||||||
|
|
||||||
base::Vector2f screen_size_ = {0, 0};
|
base::Vector2f screen_size_ = {0, 0};
|
||||||
base::Matrix4f projection_;
|
base::Matrix4f projection_;
|
||||||
|
base::Matrix4f fov_projection_;
|
||||||
|
|
||||||
std::unique_ptr<Font> system_font_;
|
std::unique_ptr<Font> system_font_;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include "k3dtest.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <atomic>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#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) {
|
||||||
|
}
|
|
@ -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
|
|
@ -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<Geometry>()) {}
|
||||||
|
|
||||||
|
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<Mesh>();
|
||||||
|
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_;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef MODEL_H
|
||||||
|
#define MODEL_H
|
||||||
|
|
||||||
|
#include "../base/vecmath.h"
|
||||||
|
#include "../engine/drawable.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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<eng::Geometry> model_;
|
||||||
|
size_t ticks_ = 0;
|
||||||
|
|
||||||
|
Model(const Model&) = delete;
|
||||||
|
Model& operator=(const Model&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MODEL_H
|
Loading…
Reference in New Issue