mirror of
https://gitea.windcorp.ru/Wind-Corporation/Progressia.git
synced 2025-08-28 10:36:50 +03:00
Initial commit
This commit is contained in:
178
main/game.cpp
Normal file
178
main/game.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
#include "game.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define GLM_FORCE_RADIANS
|
||||
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||
#include <glm/gtx/euler_angles.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#include "rendering.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace main {
|
||||
|
||||
std::unique_ptr<Primitive> cube1, cube2;
|
||||
std::unique_ptr<Texture> texture1, texture2;
|
||||
std::unique_ptr<View> perspective;
|
||||
std::unique_ptr<Light> light;
|
||||
|
||||
GraphicsInterface *gint;
|
||||
|
||||
void addRect(glm::vec3 origin, glm::vec3 width, glm::vec3 height,
|
||||
glm::vec4 color, std::vector<Vertex> &vertices,
|
||||
std::vector<Vertex::Index> &indices) {
|
||||
|
||||
Vertex::Index offset = vertices.size();
|
||||
|
||||
vertices.push_back({origin, color, {}, {0, 0}});
|
||||
vertices.push_back({origin + width, color, {}, {0, 1}});
|
||||
vertices.push_back({origin + width + height, color, {}, {1, 1}});
|
||||
vertices.push_back({origin + height, color, {}, {1, 0}});
|
||||
|
||||
indices.push_back(offset + 0);
|
||||
indices.push_back(offset + 1);
|
||||
indices.push_back(offset + 2);
|
||||
|
||||
indices.push_back(offset + 0);
|
||||
indices.push_back(offset + 2);
|
||||
indices.push_back(offset + 3);
|
||||
}
|
||||
|
||||
void addBox(glm::vec3 origin, glm::vec3 length, glm::vec3 height,
|
||||
glm::vec3 depth, std::array<glm::vec4, 6> colors,
|
||||
std::vector<Vertex> &vertices,
|
||||
std::vector<Vertex::Index> &indices) {
|
||||
addRect(origin, height, length, colors[0], vertices, indices);
|
||||
addRect(origin, length, depth, colors[1], vertices, indices);
|
||||
addRect(origin, depth, height, colors[2], vertices, indices);
|
||||
addRect(origin + height, depth, length, colors[3], vertices, indices);
|
||||
addRect(origin + length, height, depth, colors[4], vertices, indices);
|
||||
addRect(origin + depth, length, height, colors[5], vertices, indices);
|
||||
}
|
||||
|
||||
void initialize(GraphicsInterface &gintp) {
|
||||
|
||||
std::cout << "game init begin" << std::endl;
|
||||
gint = &gintp;
|
||||
|
||||
texture1.reset(
|
||||
gint->newTexture(progressia::main::loadImage(u"../assets/texture.png")));
|
||||
texture2.reset(
|
||||
gint->newTexture(progressia::main::loadImage(u"../assets/texture2.png")));
|
||||
|
||||
// Cube 1
|
||||
{
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<Vertex::Index> indices;
|
||||
auto white = glm::vec4(1, 1, 1, 1);
|
||||
|
||||
addBox({-0.5, -0.5, -0.5}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1},
|
||||
{white, white, white, white, white, white}, vertices, indices);
|
||||
|
||||
for (std::size_t i = 0; i < indices.size(); i += 3) {
|
||||
Vertex &a = vertices[indices[i + 0]];
|
||||
Vertex &b = vertices[indices[i + 1]];
|
||||
Vertex &c = vertices[indices[i + 2]];
|
||||
|
||||
glm::vec3 x = b.position - a.position;
|
||||
glm::vec3 y = c.position - a.position;
|
||||
|
||||
glm::vec3 normal = glm::normalize(glm::cross(x, y));
|
||||
|
||||
a.normal = normal;
|
||||
b.normal = normal;
|
||||
c.normal = normal;
|
||||
}
|
||||
|
||||
cube1.reset(gint->newPrimitive(vertices, indices, &*texture1));
|
||||
}
|
||||
|
||||
// Cube 2
|
||||
{
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<Vertex::Index> indices;
|
||||
auto white = glm::vec4(1, 1, 1, 1);
|
||||
|
||||
addBox({-0.5, -2.5, -0.5}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1},
|
||||
{white, white, white, white, white, white}, vertices, indices);
|
||||
|
||||
for (std::size_t i = 0; i < indices.size(); i += 3) {
|
||||
Vertex &a = vertices[indices[i + 0]];
|
||||
Vertex &b = vertices[indices[i + 1]];
|
||||
Vertex &c = vertices[indices[i + 2]];
|
||||
|
||||
glm::vec3 x = b.position - a.position;
|
||||
glm::vec3 y = c.position - a.position;
|
||||
|
||||
glm::vec3 normal = glm::normalize(glm::cross(x, y));
|
||||
|
||||
a.normal = normal;
|
||||
b.normal = normal;
|
||||
c.normal = normal;
|
||||
}
|
||||
|
||||
cube2.reset(gint->newPrimitive(vertices, indices, &*texture2));
|
||||
}
|
||||
|
||||
perspective.reset(gint->newView());
|
||||
light.reset(gint->newLight());
|
||||
|
||||
std::cout << "game init complete" << std::endl;
|
||||
}
|
||||
|
||||
void renderTick() {
|
||||
|
||||
{
|
||||
float fov = 70.0f;
|
||||
|
||||
auto extent = gint->getViewport();
|
||||
auto proj = glm::perspective(glm::radians(fov),
|
||||
extent.x / (float)extent.y, 0.1f, 10.0f);
|
||||
proj[1][1] *= -1;
|
||||
|
||||
auto view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f),
|
||||
glm::vec3(0.0f, 0.0f, 0.0f),
|
||||
glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
|
||||
perspective->configure(proj, view);
|
||||
}
|
||||
|
||||
perspective->use();
|
||||
|
||||
float contrast = glm::sin(gint->tmp_getTime() / 3) * 0.18f + 0.18f;
|
||||
glm::vec3 color0(0.60f, 0.60f, 0.70f);
|
||||
glm::vec3 color1(1.10f, 1.05f, 0.70f);
|
||||
|
||||
float m = glm::sin(gint->tmp_getTime() / 3) * 0.5 + 0.5;
|
||||
glm::vec3 color = m * color1 + (1 - m) * color0;
|
||||
|
||||
light->configure(color, glm::vec3(1.0f, -2.0f, 1.0f), contrast, 0.1f);
|
||||
light->use();
|
||||
|
||||
auto model = glm::eulerAngleYXZ(0.0f, 0.0f, gint->tmp_getTime() * 0.1f);
|
||||
|
||||
gint->setModelTransform(model);
|
||||
cube1->draw();
|
||||
cube2->draw();
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
std::cout << "game shutdown begin" << std::endl;
|
||||
|
||||
cube1.reset();
|
||||
cube2.reset();
|
||||
texture1.reset();
|
||||
texture2.reset();
|
||||
|
||||
light.reset();
|
||||
perspective.reset();
|
||||
|
||||
std::cout << "game shutdown complete" << std::endl;
|
||||
}
|
||||
|
||||
} // namespace main
|
||||
} // namespace progressia
|
13
main/game.h
Normal file
13
main/game.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "rendering.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace main {
|
||||
|
||||
void initialize(GraphicsInterface &);
|
||||
void renderTick();
|
||||
void shutdown();
|
||||
|
||||
} // namespace main
|
||||
} // namespace progressia
|
44
main/meta.h
Normal file
44
main/meta.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace progressia {
|
||||
namespace main {
|
||||
namespace meta {
|
||||
|
||||
constexpr const char *NAME = "Progressia";
|
||||
|
||||
#ifndef _MAJOR
|
||||
#warning Version number (_MAJOR _MINOR _PATCH _BUILD) not set, using 0.0.0+1
|
||||
#define _MAJOR 0
|
||||
#define _MINOR 0
|
||||
#define _PATCH 0
|
||||
#define _BUILD 1
|
||||
#endif
|
||||
|
||||
using VersionUnit = uint8_t;
|
||||
using VersionInt = uint32_t;
|
||||
|
||||
constexpr struct {
|
||||
|
||||
VersionUnit major, minor, patch, build;
|
||||
|
||||
VersionInt number;
|
||||
|
||||
bool isRelease;
|
||||
|
||||
} VERSION{_MAJOR,
|
||||
_MINOR,
|
||||
_PATCH,
|
||||
_BUILD,
|
||||
|
||||
(static_cast<VersionInt>(_MAJOR) << 24) |
|
||||
(static_cast<VersionInt>(_MINOR) << 16) |
|
||||
(static_cast<VersionInt>(_PATCH) << 8) |
|
||||
(static_cast<VersionInt>(_BUILD) << 0),
|
||||
|
||||
_BUILD == 0};
|
||||
|
||||
} // namespace meta
|
||||
} // namespace main
|
||||
} // namespace progressia
|
8
main/rendering.h
Normal file
8
main/rendering.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "rendering/graphics_interface.h"
|
||||
#include "rendering/image.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace main {} // namespace main
|
||||
} // namespace progressia
|
123
main/rendering/graphics_interface.h
Normal file
123
main/rendering/graphics_interface.h
Normal file
@@ -0,0 +1,123 @@
|
||||
#pragma once
|
||||
|
||||
#include "boost/core/noncopyable.hpp"
|
||||
#include <vector>
|
||||
|
||||
#define GLM_FORCE_RADIANS
|
||||
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#include "image.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace main {
|
||||
|
||||
struct Vertex {
|
||||
|
||||
using Index = uint16_t;
|
||||
|
||||
glm::vec3 position;
|
||||
glm::vec4 color;
|
||||
glm::vec3 normal;
|
||||
glm::vec2 texCoord;
|
||||
};
|
||||
|
||||
class Texture : private boost::noncopyable {
|
||||
public:
|
||||
using Backend = void *;
|
||||
|
||||
private:
|
||||
Backend backend;
|
||||
|
||||
friend class Primitive;
|
||||
|
||||
public:
|
||||
Texture(Backend);
|
||||
~Texture();
|
||||
};
|
||||
|
||||
class Primitive : private boost::noncopyable {
|
||||
public:
|
||||
using Backend = void *;
|
||||
|
||||
private:
|
||||
Backend backend;
|
||||
|
||||
friend class GraphicsInterface;
|
||||
|
||||
public:
|
||||
Primitive(Backend);
|
||||
~Primitive();
|
||||
|
||||
void draw();
|
||||
|
||||
const Texture *getTexture() const;
|
||||
};
|
||||
|
||||
class View : private boost::noncopyable {
|
||||
public:
|
||||
using Backend = void *;
|
||||
|
||||
private:
|
||||
Backend backend;
|
||||
|
||||
public:
|
||||
View(Backend);
|
||||
~View();
|
||||
|
||||
void configure(const glm::mat4 &proj, const glm::mat4 &view);
|
||||
void use();
|
||||
};
|
||||
|
||||
class Light : private boost::noncopyable {
|
||||
public:
|
||||
using Backend = void *;
|
||||
|
||||
private:
|
||||
Backend backend;
|
||||
|
||||
public:
|
||||
Light(Backend);
|
||||
~Light();
|
||||
|
||||
void configure(const glm::vec3 &color, const glm::vec3 &from,
|
||||
float contrast, float softness);
|
||||
void use();
|
||||
};
|
||||
|
||||
class GraphicsInterface : private boost::noncopyable {
|
||||
public:
|
||||
using Backend = void *;
|
||||
|
||||
private:
|
||||
Backend backend;
|
||||
|
||||
public:
|
||||
GraphicsInterface(Backend);
|
||||
~GraphicsInterface();
|
||||
|
||||
Texture *newTexture(const Image &);
|
||||
|
||||
Primitive *newPrimitive(const std::vector<Vertex> &,
|
||||
const std::vector<Vertex::Index> &,
|
||||
Texture *texture);
|
||||
|
||||
glm::vec2 getViewport() const;
|
||||
|
||||
void setModelTransform(const glm::mat4 &);
|
||||
|
||||
View *newView();
|
||||
Light *newLight();
|
||||
|
||||
void flush();
|
||||
void startNextLayer();
|
||||
|
||||
float tmp_getTime();
|
||||
uint64_t getLastStartedFrame();
|
||||
};
|
||||
|
||||
} // namespace main
|
||||
} // namespace progressia
|
64
main/rendering/image.cpp
Normal file
64
main/rendering/image.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "image.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "stb/stb_image.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace main {
|
||||
|
||||
std::size_t Image::getSize() const { return data.size(); }
|
||||
|
||||
const Image::Byte *Image::getData() const { return data.data(); }
|
||||
|
||||
Image::Byte *Image::getData() { return data.data(); }
|
||||
|
||||
Image loadImage(const std::filesystem::path &path) {
|
||||
|
||||
std::ifstream file(path, std::ios::ate | std::ios::binary);
|
||||
|
||||
if (!file.is_open()) {
|
||||
std::cout << "Could not read a PNG image from file " << path
|
||||
<< std::endl;
|
||||
// REPORT_ERROR
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::size_t fileSize = static_cast<std::size_t>(file.tellg());
|
||||
std::vector<Image::Byte> png(fileSize);
|
||||
|
||||
file.seekg(0);
|
||||
file.read(reinterpret_cast<char *>(png.data()), fileSize);
|
||||
|
||||
file.close();
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int channelsInFile;
|
||||
|
||||
Image::Byte *stbAllocatedData =
|
||||
stbi_load_from_memory(png.data(), png.size(), &width, &height,
|
||||
&channelsInFile, STBI_rgb_alpha);
|
||||
|
||||
if (stbAllocatedData == NULL) {
|
||||
std::cout << "Could not load a PNG image from file " << path
|
||||
<< std::endl;
|
||||
// REPORT_ERROR
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::vector<Image::Byte> data(width * height * STBI_rgb_alpha);
|
||||
memcpy(data.data(), stbAllocatedData, data.size());
|
||||
|
||||
stbi_image_free(stbAllocatedData);
|
||||
|
||||
return {static_cast<std::size_t>(width), static_cast<std::size_t>(height),
|
||||
data};
|
||||
}
|
||||
|
||||
} // namespace main
|
||||
} // namespace progressia
|
25
main/rendering/image.h
Normal file
25
main/rendering/image.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
|
||||
namespace progressia {
|
||||
namespace main {
|
||||
|
||||
class Image {
|
||||
public:
|
||||
using Byte = unsigned char;
|
||||
|
||||
std::size_t width;
|
||||
std::size_t height;
|
||||
std::vector<Byte> data;
|
||||
|
||||
std::size_t getSize() const;
|
||||
const Byte *getData() const;
|
||||
Byte *getData();
|
||||
};
|
||||
|
||||
Image loadImage(const std::filesystem::path &);
|
||||
|
||||
} // namespace main
|
||||
} // namespace progressia
|
4
main/stb_image.c
Normal file
4
main/stb_image.c
Normal file
@@ -0,0 +1,4 @@
|
||||
#define STBI_ONLY_PNG
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb/stb_image.h>
|
30
main/util.h
Normal file
30
main/util.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
#define FOR_PACK(PACK_TYPE, PACK_NAME, VAR, CODE) \
|
||||
{ \
|
||||
[[maybe_unused]] int dummy[] { \
|
||||
( \
|
||||
[&](PACK_TYPE VAR) { \
|
||||
CODE; \
|
||||
return 0; \
|
||||
} \
|
||||
)(PACK_NAME)... \
|
||||
}; \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
// clang-format off
|
||||
#define FOR_PACK_S(PACK_TYPE, VAR_TYPE, CODE) \
|
||||
{ \
|
||||
[[maybe_unused]] int dummy[] { \
|
||||
( \
|
||||
[&]() { \
|
||||
using VAR_TYPE = PACK_TYPE; \
|
||||
CODE; \
|
||||
return 0; \
|
||||
} \
|
||||
)()... \
|
||||
}; \
|
||||
}
|
||||
// clang-format on
|
Reference in New Issue
Block a user