Working on custom mesh saving mode

This commit is contained in:
Arnau Alier Torres 2025-04-23 17:58:20 +02:00
parent 76880e25b6
commit 769cc6842f
18 changed files with 669 additions and 547 deletions

View File

@ -7,6 +7,7 @@
#include "Deer/Path.h"
// File to manage Assets
// TODO: Delete Assets and set a custom method of loading
namespace Deer {
template <typename T>

View File

@ -17,6 +17,7 @@
#define DEER_BIN_PATH "bin"
#define DEER_TEMP_PATH "tmp"
#define DEER_NULL_PATH "null"
namespace Deer {
// Namespace to manage memory interactions

View File

@ -61,11 +61,11 @@ namespace Deer {
};
// Namespace to manage scenes in memory
namespace SceneDataStore {
namespace DataStore {
void loadScene(Scene& scene, const Path& name);
void exportScene(const Scene& scene, const Path& name);
void exportRuntimeScene(const Scene& scene);
void importRuntimeScene(Scene& scene);
} // namespace SceneDataStore
} // namespace DataStore
} // namespace Deer

View File

@ -70,14 +70,14 @@ namespace Deer {
};
// Defines the general data of a voxel id stored in the array
// VoxelData::voxelsInfo
// DataStore::voxelsInfo
struct VoxelInfo {
std::string name;
VoxelInfoType type = VoxelInfoType::Air;
};
// Namespace to load and manage voxel data
namespace VoxelData {
namespace DataStore {
// List of the voxels loaded with loadVoxelsData()
extern std::vector<VoxelInfo> voxelsInfo;
@ -118,7 +118,7 @@ namespace Deer {
Ref<Shader>& getSolidVoxelShader();
#endif
} // namespace VoxelData
} // namespace DataStore
// Structure to define what a voxel inside a world must have
struct Voxel {
@ -130,7 +130,7 @@ namespace Deer {
inline bool operator==(const Voxel& b) const { return id == b.id; }
inline bool isVoxelType() const {
return VoxelData::voxelsInfo[id].type == VoxelInfoType::Voxel;
return DataStore::voxelsInfo[id].type == VoxelInfoType::Voxel;
}
};

View File

@ -1,12 +1,148 @@
#pragma once
#include "Deer/Application.h"
#include "DeerRender/KeyCodes.h"
namespace Deer {
class Input {
public:
public:
static bool isKeyPressed(unsigned int key);
static bool isMouseButtonPressed(int button);
static void getMousePos(float& x, float& y);
};
}
} // namespace Deer
// From GLFW
#define DEER_KEY_SPACE 32
#define DEER_KEY_APOSTROPHE 39 /* ' */
#define DEER_KEY_COMMA 44 /* , */
#define DEER_KEY_MINUS 45 /* - */
#define DEER_KEY_PERIOD 46 /* . */
#define DEER_KEY_SLASH 47 /* / */
#define DEER_KEY_0 48
#define DEER_KEY_1 49
#define DEER_KEY_2 50
#define DEER_KEY_3 51
#define DEER_KEY_4 52
#define DEER_KEY_5 53
#define DEER_KEY_6 54
#define DEER_KEY_7 55
#define DEER_KEY_8 56
#define DEER_KEY_9 57
#define DEER_KEY_SEMICOLON 59 /* ; */
#define DEER_KEY_EQUAL 61 /* = */
#define DEER_KEY_A 65
#define DEER_KEY_B 66
#define DEER_KEY_C 67
#define DEER_KEY_D 68
#define DEER_KEY_E 69
#define DEER_KEY_F 70
#define DEER_KEY_G 71
#define DEER_KEY_H 72
#define DEER_KEY_I 73
#define DEER_KEY_J 74
#define DEER_KEY_K 75
#define DEER_KEY_L 76
#define DEER_KEY_M 77
#define DEER_KEY_N 78
#define DEER_KEY_O 79
#define DEER_KEY_P 80
#define DEER_KEY_Q 81
#define DEER_KEY_R 82
#define DEER_KEY_S 83
#define DEER_KEY_T 84
#define DEER_KEY_U 85
#define DEER_KEY_V 86
#define DEER_KEY_W 87
#define DEER_KEY_X 88
#define DEER_KEY_Y 89
#define DEER_KEY_Z 90
#define DEER_KEY_LEFT_BRACKET 91 /* [ */
#define DEER_KEY_BACKSLASH 92 /* \ */
#define DEER_KEY_RIGHT_BRACKET 93 /* ] */
#define DEER_KEY_GRAVE_ACCENT 96 /* ` */
#define DEER_KEY_WORLD_1 161 /* non-US #1 */
#define DEER_KEY_WORLD_2 162 /* non-US #2 */
/* Function keys */
#define DEER_KEY_ESCAPE 256
#define DEER_KEY_ENTER 257
#define DEER_KEY_TAB 258
#define DEER_KEY_BACKSPACE 259
#define DEER_KEY_INSERT 260
#define DEER_KEY_DELETE 261
#define DEER_KEY_RIGHT 262
#define DEER_KEY_LEFT 263
#define DEER_KEY_DOWN 264
#define DEER_KEY_UP 265
#define DEER_KEY_PAGE_UP 266
#define DEER_KEY_PAGE_DOWN 267
#define DEER_KEY_HOME 268
#define DEER_KEY_END 269
#define DEER_KEY_CAPS_LOCK 280
#define DEER_KEY_SCROLL_LOCK 281
#define DEER_KEY_NUM_LOCK 282
#define DEER_KEY_PRINT_SCREEN 283
#define DEER_KEY_PAUSE 284
#define DEER_KEY_F1 290
#define DEER_KEY_F2 291
#define DEER_KEY_F3 292
#define DEER_KEY_F4 293
#define DEER_KEY_F5 294
#define DEER_KEY_F6 295
#define DEER_KEY_F7 296
#define DEER_KEY_F8 297
#define DEER_KEY_F9 298
#define DEER_KEY_F10 299
#define DEER_KEY_F11 300
#define DEER_KEY_F12 301
#define DEER_KEY_F13 302
#define DEER_KEY_F14 303
#define DEER_KEY_F15 304
#define DEER_KEY_F16 305
#define DEER_KEY_F17 306
#define DEER_KEY_F18 307
#define DEER_KEY_F19 308
#define DEER_KEY_F20 309
#define DEER_KEY_F21 310
#define DEER_KEY_F22 311
#define DEER_KEY_F23 312
#define DEER_KEY_F24 313
#define DEER_KEY_F25 314
#define DEER_KEY_KP_0 320
#define DEER_KEY_KP_1 321
#define DEER_KEY_KP_2 322
#define DEER_KEY_KP_3 323
#define DEER_KEY_KP_4 324
#define DEER_KEY_KP_5 325
#define DEER_KEY_KP_6 326
#define DEER_KEY_KP_7 327
#define DEER_KEY_KP_8 328
#define DEER_KEY_KP_9 329
#define DEER_KEY_KP_DECIMAL 330
#define DEER_KEY_KP_DIVIDE 331
#define DEER_KEY_KP_MULTIPLY 332
#define DEER_KEY_KP_SUBTRACT 333
#define DEER_KEY_KP_ADD 334
#define DEER_KEY_KP_ENTER 335
#define DEER_KEY_KP_EQUAL 336
#define DEER_KEY_LEFT_SHIFT 340
#define DEER_KEY_LEFT_CONTROL 341
#define DEER_KEY_LEFT_ALT 342
#define DEER_KEY_LEFT_SUPER 343
#define DEER_KEY_RIGHT_SHIFT 344
#define DEER_KEY_RIGHT_CONTROL 345
#define DEER_KEY_RIGHT_ALT 346
#define DEER_KEY_RIGHT_SUPER 347
#define DEER_KEY_MENU 348
#define DEER_MOUSE_BUTTON_1 0
#define DEER_MOUSE_BUTTON_2 1
#define DEER_MOUSE_BUTTON_3 2
#define DEER_MOUSE_BUTTON_4 3
#define DEER_MOUSE_BUTTON_5 4
#define DEER_MOUSE_BUTTON_6 5
#define DEER_MOUSE_BUTTON_7 6
#define DEER_MOUSE_BUTTON_8 7
#define DEER_MOUSE_BUTTON_LAST DEER_MOUSE_BUTTON_8
#define DEER_MOUSE_BUTTON_LEFT DEER_MOUSE_BUTTON_1
#define DEER_MOUSE_BUTTON_RIGHT DEER_MOUSE_BUTTON_2
#define DEER_MOUSE_BUTTON_MIDDLE DEER_MOUSE_BUTTON_3

View File

@ -1,138 +0,0 @@
#pragma once
// From GLFW
#define DEER_KEY_SPACE 32
#define DEER_KEY_APOSTROPHE 39 /* ' */
#define DEER_KEY_COMMA 44 /* , */
#define DEER_KEY_MINUS 45 /* - */
#define DEER_KEY_PERIOD 46 /* . */
#define DEER_KEY_SLASH 47 /* / */
#define DEER_KEY_0 48
#define DEER_KEY_1 49
#define DEER_KEY_2 50
#define DEER_KEY_3 51
#define DEER_KEY_4 52
#define DEER_KEY_5 53
#define DEER_KEY_6 54
#define DEER_KEY_7 55
#define DEER_KEY_8 56
#define DEER_KEY_9 57
#define DEER_KEY_SEMICOLON 59 /* ; */
#define DEER_KEY_EQUAL 61 /* = */
#define DEER_KEY_A 65
#define DEER_KEY_B 66
#define DEER_KEY_C 67
#define DEER_KEY_D 68
#define DEER_KEY_E 69
#define DEER_KEY_F 70
#define DEER_KEY_G 71
#define DEER_KEY_H 72
#define DEER_KEY_I 73
#define DEER_KEY_J 74
#define DEER_KEY_K 75
#define DEER_KEY_L 76
#define DEER_KEY_M 77
#define DEER_KEY_N 78
#define DEER_KEY_O 79
#define DEER_KEY_P 80
#define DEER_KEY_Q 81
#define DEER_KEY_R 82
#define DEER_KEY_S 83
#define DEER_KEY_T 84
#define DEER_KEY_U 85
#define DEER_KEY_V 86
#define DEER_KEY_W 87
#define DEER_KEY_X 88
#define DEER_KEY_Y 89
#define DEER_KEY_Z 90
#define DEER_KEY_LEFT_BRACKET 91 /* [ */
#define DEER_KEY_BACKSLASH 92 /* \ */
#define DEER_KEY_RIGHT_BRACKET 93 /* ] */
#define DEER_KEY_GRAVE_ACCENT 96 /* ` */
#define DEER_KEY_WORLD_1 161 /* non-US #1 */
#define DEER_KEY_WORLD_2 162 /* non-US #2 */
/* Function keys */
#define DEER_KEY_ESCAPE 256
#define DEER_KEY_ENTER 257
#define DEER_KEY_TAB 258
#define DEER_KEY_BACKSPACE 259
#define DEER_KEY_INSERT 260
#define DEER_KEY_DELETE 261
#define DEER_KEY_RIGHT 262
#define DEER_KEY_LEFT 263
#define DEER_KEY_DOWN 264
#define DEER_KEY_UP 265
#define DEER_KEY_PAGE_UP 266
#define DEER_KEY_PAGE_DOWN 267
#define DEER_KEY_HOME 268
#define DEER_KEY_END 269
#define DEER_KEY_CAPS_LOCK 280
#define DEER_KEY_SCROLL_LOCK 281
#define DEER_KEY_NUM_LOCK 282
#define DEER_KEY_PRINT_SCREEN 283
#define DEER_KEY_PAUSE 284
#define DEER_KEY_F1 290
#define DEER_KEY_F2 291
#define DEER_KEY_F3 292
#define DEER_KEY_F4 293
#define DEER_KEY_F5 294
#define DEER_KEY_F6 295
#define DEER_KEY_F7 296
#define DEER_KEY_F8 297
#define DEER_KEY_F9 298
#define DEER_KEY_F10 299
#define DEER_KEY_F11 300
#define DEER_KEY_F12 301
#define DEER_KEY_F13 302
#define DEER_KEY_F14 303
#define DEER_KEY_F15 304
#define DEER_KEY_F16 305
#define DEER_KEY_F17 306
#define DEER_KEY_F18 307
#define DEER_KEY_F19 308
#define DEER_KEY_F20 309
#define DEER_KEY_F21 310
#define DEER_KEY_F22 311
#define DEER_KEY_F23 312
#define DEER_KEY_F24 313
#define DEER_KEY_F25 314
#define DEER_KEY_KP_0 320
#define DEER_KEY_KP_1 321
#define DEER_KEY_KP_2 322
#define DEER_KEY_KP_3 323
#define DEER_KEY_KP_4 324
#define DEER_KEY_KP_5 325
#define DEER_KEY_KP_6 326
#define DEER_KEY_KP_7 327
#define DEER_KEY_KP_8 328
#define DEER_KEY_KP_9 329
#define DEER_KEY_KP_DECIMAL 330
#define DEER_KEY_KP_DIVIDE 331
#define DEER_KEY_KP_MULTIPLY 332
#define DEER_KEY_KP_SUBTRACT 333
#define DEER_KEY_KP_ADD 334
#define DEER_KEY_KP_ENTER 335
#define DEER_KEY_KP_EQUAL 336
#define DEER_KEY_LEFT_SHIFT 340
#define DEER_KEY_LEFT_CONTROL 341
#define DEER_KEY_LEFT_ALT 342
#define DEER_KEY_LEFT_SUPER 343
#define DEER_KEY_RIGHT_SHIFT 344
#define DEER_KEY_RIGHT_CONTROL 345
#define DEER_KEY_RIGHT_ALT 346
#define DEER_KEY_RIGHT_SUPER 347
#define DEER_KEY_MENU 348
#define DEER_MOUSE_BUTTON_1 0
#define DEER_MOUSE_BUTTON_2 1
#define DEER_MOUSE_BUTTON_3 2
#define DEER_MOUSE_BUTTON_4 3
#define DEER_MOUSE_BUTTON_5 4
#define DEER_MOUSE_BUTTON_6 5
#define DEER_MOUSE_BUTTON_7 6
#define DEER_MOUSE_BUTTON_8 7
#define DEER_MOUSE_BUTTON_LAST DEER_MOUSE_BUTTON_8
#define DEER_MOUSE_BUTTON_LEFT DEER_MOUSE_BUTTON_1
#define DEER_MOUSE_BUTTON_RIGHT DEER_MOUSE_BUTTON_2
#define DEER_MOUSE_BUTTON_MIDDLE DEER_MOUSE_BUTTON_3

View File

@ -0,0 +1,45 @@
#pragma once
#include <cstdint>
#include "Deer/Path.h"
namespace Deer {
// This struct represents the data save in a position vertex, this is
// defined by: integerPart.decimalPart, where each decimal part represents
// 1 / 256. And the integer part is substracted 128
// Example: integerPart = 129; decimalPart = 32;
// Result = (129-128).(32/256) = 1.125f
struct PositionAxis {
uint8_t integerPart = 0;
uint8_t decimalPart = 0;
};
struct VertexPosition {
PositionAxis x;
PositionAxis y;
PositionAxis z;
};
// Vertex normal is represented with a number fromn [-64,64], and then its
// divided by 64 to know the decimal number
struct VertexNormal {
int8_t x;
int8_t y;
int8_t z;
};
struct ModelData {
uint16_t vertexCount = 0;
VertexPosition* vertexPositionsData = nullptr;
VertexNormal* vertexNormalData = nullptr;
uint16_t indexCount = 0;
uint16_t* indexData = nullptr;
};
namespace DataStore {
void saveModel(const ModelData&, const Path& name);
ModelData loadModel(const Path& name);
} // namespace DataStore
} // namespace Deer

View File

@ -9,7 +9,7 @@
namespace Deer {
void SceneDataStore::loadScene(Scene& scene, const Path& name) {
void DataStore::loadScene(Scene& scene, const Path& name) {
Path realName;
realName = Path(DEER_SCENE_PATH) / (name.string() + ".dscn");
@ -26,7 +26,7 @@ namespace Deer {
delete[] data;
}
void SceneDataStore::exportScene(const Scene& scene, const Path& name) {
void DataStore::exportScene(const Scene& scene, const Path& name) {
Path realName;
realName = Path(DEER_SCENE_PATH) / (name.string() + ".dscn");
@ -40,7 +40,7 @@ namespace Deer {
DataStore::saveFile(realName, (uint8_t*)view.data(), view.size());
}
void SceneDataStore::exportRuntimeScene(const Scene& scene) {
void DataStore::exportRuntimeScene(const Scene& scene) {
Path realName;
realName = Path(DEER_TEMP_PATH) / ("temp_scene.dbscn");
@ -53,7 +53,7 @@ namespace Deer {
DataStore::saveFile(realName, (uint8_t*)view.data(), view.size());
}
void SceneDataStore::importRuntimeScene(Scene& scene) {
void DataStore::importRuntimeScene(Scene& scene) {
Path realName;
realName = Path(DEER_TEMP_PATH) / ("temp_scene.dbscn");

View File

@ -2,34 +2,32 @@
#include "Deer/Voxel.h"
#ifdef DEER_RENDER
#include <vector>
#include "DeerRender/LightVoxel.h"
#include "DeerRender/VoxelAspect.h"
#include <vector>
#endif
#include <array>
namespace Deer {
class Chunk {
public:
public:
Chunk() = default;
~Chunk();
inline Voxel readVoxel(ChunkVoxelID id) {
if (m_voxels)
return m_voxels[VOXEL_POSITION(id)];
if (m_voxels) return m_voxels[VOXEL_POSITION(id)];
return emptyVoxel;
}
inline Voxel& modVoxel(ChunkVoxelID id) {
if (!m_voxels)
loadVoxels();
if (!m_voxels) loadVoxels();
return m_voxels[VOXEL_POSITION(id)];
}
inline void fillVoxels(ChunkVoxelID min, ChunkVoxelID max, Voxel info) {
if (!m_voxels)
loadVoxels();
if (!m_voxels) loadVoxels();
ChunkVoxelID voxelID;
for (voxelID.x = min.x; voxelID.x <= max.x; voxelID.x++) {
@ -41,9 +39,9 @@ namespace Deer {
}
}
inline void remplaceVoxels(ChunkVoxelID min, ChunkVoxelID max, Voxel ref, Voxel value) {
if (!m_voxels)
loadVoxels();
inline void remplaceVoxels(ChunkVoxelID min, ChunkVoxelID max,
Voxel ref, Voxel value) {
if (!m_voxels) loadVoxels();
ChunkVoxelID voxelID;
for (voxelID.x = min.x; voxelID.x <= max.x; voxelID.x++) {
@ -51,18 +49,17 @@ namespace Deer {
for (voxelID.z = min.z; voxelID.z <= max.z; voxelID.z++) {
Voxel& currentVoxel = m_voxels[VOXEL_POSITION(voxelID)];
if (currentVoxel.id == ref.id)
currentVoxel = value;
if (currentVoxel.id == ref.id) currentVoxel = value;
}
}
}
}
inline uint8_t calculateLayerVoxelHeight(LayerVoxelID layerVoxelID) {
if (!m_voxels)
return 0;
if (!m_voxels) return 0;
ChunkVoxelID voxelID(layerVoxelID.x, CHUNK_SIZE_Y - 1, layerVoxelID.z);
ChunkVoxelID voxelID(layerVoxelID.x, CHUNK_SIZE_Y - 1,
layerVoxelID.z);
for (int y = CHUNK_SIZE_Y - 1; y >= 0; y--) {
voxelID.y = y;
@ -71,29 +68,28 @@ namespace Deer {
}
return 0;
}
private:
private:
Voxel* m_voxels = nullptr;
void loadVoxels();
#ifdef DEER_RENDER
public:
public:
inline VoxelLight readLight(ChunkVoxelID id) {
if (m_voxels)
return m_lightInfo[VOXEL_POSITION(id)];
if (m_voxels) return m_lightInfo[VOXEL_POSITION(id)];
return VoxelLight();
}
inline VoxelLight& modLight(ChunkVoxelID id) {
if (!m_voxels)
loadVoxels();
if (!m_voxels) loadVoxels();
return m_lightInfo[VOXEL_POSITION(id)];
}
inline void clearVoxelLight(ChunkVoxelID min, ChunkVoxelID max) {
ChunkVoxelID voxelID;
for (voxelID.x = min.x; voxelID.x <= max.x; voxelID.x++){
for (voxelID.y = min.y; voxelID.y <= max.y; voxelID.y++){
for (voxelID.z = min.z; voxelID.z <= max.z; voxelID.z++){
for (voxelID.x = min.x; voxelID.x <= max.x; voxelID.x++) {
for (voxelID.y = min.y; voxelID.y <= max.y; voxelID.y++) {
for (voxelID.z = min.z; voxelID.z <= max.z; voxelID.z++) {
m_lightInfo[VOXEL_POSITION(voxelID)].b_light = 0;
m_lightInfo[VOXEL_POSITION(voxelID)].r_light = 0;
m_lightInfo[VOXEL_POSITION(voxelID)].g_light = 0;
@ -102,23 +98,25 @@ namespace Deer {
}
}
// This function is the same as clear Voxel Light but it also checks if there is a source of light
inline void clearVoxelLightAndSaveSources(ChunkVoxelID min, ChunkVoxelID max, ChunkID chunkID, std::vector<VoxelCordinates>& sources) {
if (!m_voxels)
return;
// This function is the same as clear Voxel Light but it also checks if
// there is a source of light
inline void clearVoxelLightAndSaveSources(
ChunkVoxelID min, ChunkVoxelID max, ChunkID chunkID,
std::vector<VoxelCordinates>& sources) {
if (!m_voxels) return;
ChunkVoxelID voxelID;
for (voxelID.x = min.x; voxelID.x <= max.x; voxelID.x++){
for (voxelID.y = min.y; voxelID.y <= max.y; voxelID.y++){
for (voxelID.z = min.z; voxelID.z <= max.z; voxelID.z++){
for (voxelID.x = min.x; voxelID.x <= max.x; voxelID.x++) {
for (voxelID.y = min.y; voxelID.y <= max.y; voxelID.y++) {
for (voxelID.z = min.z; voxelID.z <= max.z; voxelID.z++) {
Voxel voxel = m_voxels[VOXEL_POSITION(voxelID)];
VoxelAspect& voxelAspect = VoxelData::voxelsAspect[voxel.id];
VoxelAspect& voxelAspect =
DataStore::voxelsAspect[voxel.id];
if (voxelAspect.isLightSource()) {
sources.push_back(VoxelCordinates(
voxelID.x + chunkID.x * CHUNK_SIZE_X,
voxelID.y + chunkID.y * CHUNK_SIZE_Y,
voxelID.z + chunkID.z * CHUNK_SIZE_Z
));
voxelID.x + chunkID.x * CHUNK_SIZE_X,
voxelID.y + chunkID.y * CHUNK_SIZE_Y,
voxelID.z + chunkID.z * CHUNK_SIZE_Z));
}
m_lightInfo[VOXEL_POSITION(voxelID)].b_light = 0;
@ -128,9 +126,9 @@ namespace Deer {
}
}
}
private:
private:
VoxelLight* m_lightInfo = nullptr;
#endif
};
}
} // namespace Deer

View File

@ -10,18 +10,18 @@
#include "cereal/archives/json.hpp"
namespace Deer {
namespace VoxelData {
namespace DataStore {
std::vector<VoxelInfo> voxelsInfo;
std::unordered_map<std::string, uint32_t> blockIDMap;
} // namespace VoxelData
} // namespace DataStore
int32_t VoxelData::getVoxelID(const std::string& name) {
int32_t DataStore::getVoxelID(const std::string& name) {
if (blockIDMap.contains(name)) return blockIDMap[name];
DEER_CORE_WARN("Voxel Info {0} Not Found!", name.c_str());
return -1;
}
void VoxelData::loadVoxelsData() {
void DataStore::loadVoxelsData() {
voxelsInfo.clear();
blockIDMap.clear();
@ -74,7 +74,7 @@ namespace Deer {
}
}
void VoxelData::createExampleVoxelData() {
void DataStore::createExampleVoxelData() {
VoxelInfo block;
std::stringstream data;

View File

@ -0,0 +1,7 @@
#include "DeerRender/Mesh.h"
#include "cereal/archives/json.hpp"
#include "cereal/cereal.hpp"
namespace Deer {
ModelData DataStore::loadModel(const Path& name) {}
} // namespace Deer

View File

@ -1,17 +1,17 @@
#include "DeerRender/GizmoRenderer.h"
#include "DeerRender/Render/Render.h"
#include "Deer/Components.h"
#include "Deer/Voxel.h"
#include "DeerRender/LightVoxel.h"
#include "DeerRender/Render/RenderUtils.h"
#include "DeerRender/SceneCamera.h"
#include "Deer/Components.h"
#include "DeerRender/Render/Texture.h"
#include "DeerRender/Render/Render.h"
#include "DeerRender/Render/RenderCommand.h"
#include "DeerRender/Render/RenderUtils.h"
#include "DeerRender/Render/Texture.h"
#include "DeerRender/SceneCamera.h"
namespace Deer {
void GizmoRenderer::drawLine(glm::vec3 a, glm::vec3 b, glm::vec3 color) {
m_lines.push_back({ a, b, color });
m_lines.push_back({a, b, color});
}
void GizmoRenderer::drawVoxelLine(int _x, int _y, int _z, glm::vec3 color) {
@ -39,18 +39,16 @@ namespace Deer {
drawLine(a, b, color);
}
}
}
void GizmoRenderer::drawVoxelLineFace(int x, int y, int z, uint8_t face, glm::vec3 color) {
void GizmoRenderer::drawVoxelLineFace(int x, int y, int z, uint8_t face,
glm::vec3 color) {
glm::vec3 points[4];
for (int i = 0; i < 4; i++) {
points[i] = {
x + NORMAL_VERTEX_POS(X_AXIS, i, face),
y + NORMAL_VERTEX_POS(Y_AXIS, i, face),
z + NORMAL_VERTEX_POS(Z_AXIS, i, face)
};
points[i] = {x + NORMAL_VERTEX_POS(X_AXIS, i, face),
y + NORMAL_VERTEX_POS(Y_AXIS, i, face),
z + NORMAL_VERTEX_POS(Z_AXIS, i, face)};
}
drawLine(points[0], points[1], color);
@ -59,63 +57,56 @@ namespace Deer {
drawLine(points[1], points[3], color);
}
void GizmoRenderer::drawVoxelFace(int x, int y, int z, uint16_t voxelID, uint8_t faceID, uint8_t priority) {
void GizmoRenderer::drawVoxelFace(int x, int y, int z, uint16_t voxelID,
uint8_t faceID, uint8_t priority) {
glm::vec3 points[4];
VoxelAspect& aspect = VoxelData::voxelsAspect[voxelID];
VoxelAspect& aspect = DataStore::voxelsAspect[voxelID];
GizmoFace face;
face.textureID = aspect.textureFacesIDs[faceID];
face.face = faceID;
for (int i = 0; i < 4; i++) {
face.positions[i] = {
x + NORMAL_VERTEX_POS(X_AXIS, i, faceID),
y + NORMAL_VERTEX_POS(Y_AXIS, i, faceID),
z + NORMAL_VERTEX_POS(Z_AXIS, i, faceID)
};
face.positions[i] = {x + NORMAL_VERTEX_POS(X_AXIS, i, faceID),
y + NORMAL_VERTEX_POS(Y_AXIS, i, faceID),
z + NORMAL_VERTEX_POS(Z_AXIS, i, faceID)};
}
m_faces[priority].push_back(face);
}
void GizmoRenderer::drawVoxelFaceInverted(int x, int y, int z, uint16_t voxelID, uint8_t faceID, uint8_t priority) {
void GizmoRenderer::drawVoxelFaceInverted(int x, int y, int z,
uint16_t voxelID, uint8_t faceID,
uint8_t priority) {
glm::vec3 points[4];
VoxelAspect& aspect = VoxelData::voxelsAspect[voxelID];
VoxelAspect& aspect = DataStore::voxelsAspect[voxelID];
GizmoFace face;
face.textureID = aspect.textureFacesIDs[faceID];
face.face = faceID;
face.positions[0] = {
x + NORMAL_VERTEX_POS(X_AXIS, 0, faceID),
y + NORMAL_VERTEX_POS(Y_AXIS, 0, faceID),
z + NORMAL_VERTEX_POS(Z_AXIS, 0, faceID)
};
face.positions[0] = {x + NORMAL_VERTEX_POS(X_AXIS, 0, faceID),
y + NORMAL_VERTEX_POS(Y_AXIS, 0, faceID),
z + NORMAL_VERTEX_POS(Z_AXIS, 0, faceID)};
face.positions[2] = {
x + NORMAL_VERTEX_POS(X_AXIS, 1, faceID),
y + NORMAL_VERTEX_POS(Y_AXIS, 1, faceID),
z + NORMAL_VERTEX_POS(Z_AXIS, 1, faceID)
};
face.positions[2] = {x + NORMAL_VERTEX_POS(X_AXIS, 1, faceID),
y + NORMAL_VERTEX_POS(Y_AXIS, 1, faceID),
z + NORMAL_VERTEX_POS(Z_AXIS, 1, faceID)};
face.positions[1] = {
x + NORMAL_VERTEX_POS(X_AXIS, 2, faceID),
y + NORMAL_VERTEX_POS(Y_AXIS, 2, faceID),
z + NORMAL_VERTEX_POS(Z_AXIS, 2, faceID)
};
face.positions[1] = {x + NORMAL_VERTEX_POS(X_AXIS, 2, faceID),
y + NORMAL_VERTEX_POS(Y_AXIS, 2, faceID),
z + NORMAL_VERTEX_POS(Z_AXIS, 2, faceID)};
face.positions[3] = {
x + NORMAL_VERTEX_POS(X_AXIS, 3, faceID),
y + NORMAL_VERTEX_POS(Y_AXIS, 3, faceID),
z + NORMAL_VERTEX_POS(Z_AXIS, 3, faceID)
};
face.positions[3] = {x + NORMAL_VERTEX_POS(X_AXIS, 3, faceID),
y + NORMAL_VERTEX_POS(Y_AXIS, 3, faceID),
z + NORMAL_VERTEX_POS(Z_AXIS, 3, faceID)};
m_faces[priority].push_back(face);
}
void GizmoRenderer::render(const SceneCamera& camera) {
RenderCommand::setDepthBuffer(true);
// We make a exact camera but with less far clip to give priority in the depht test
// We make a exact camera but with less far clip to give priority in the
// depht test
CameraComponent camera_lessDistance = camera.camera;
camera_lessDistance.farZ *= 1.1f;
@ -123,32 +114,41 @@ namespace Deer {
glm::mat4 projectionMatrix = camera_lessDistance.getMatrix();
glm::mat4 invertZ = glm::scale(glm::mat4(1.0f), glm::vec3(1, 1, -1));
glm::mat4 cameraProjectionMatrix = projectionMatrix * invertZ * camMatrix;
glm::mat4 cameraProjectionMatrix =
projectionMatrix * invertZ * camMatrix;
VoxelData::getVoxelColorTextureAtlas()->bind(0);
DataStore::getVoxelColorTextureAtlas()->bind(0);
RenderUtils::m_faceShader->bind();
RenderUtils::m_faceShader->uploadUniformMat4("u_viewMatrix", cameraProjectionMatrix);
RenderUtils::m_faceShader->uploadUniformMat4("u_viewMatrix",
cameraProjectionMatrix);
RenderUtils::m_faceShader->uploadUniformInt("u_texture", 0);
RenderUtils::m_faceShader->uploadUniformInt("u_textureSize", VoxelData::getVoxelTextureAtlasSize());
RenderUtils::m_faceShader->uploadUniformInt(
"u_textureSize", DataStore::getVoxelTextureAtlasSize());
for (int i = 0; i < GIZMO_DEPTH; i++) {
for (GizmoFace& face : m_faces[i]) {
RenderUtils::m_faceShader->uploadUniformInt("u_textureID", face.textureID);
RenderUtils::m_faceShader->uploadUniformFloat3("u_posA", face.positions[0]);
RenderUtils::m_faceShader->uploadUniformFloat3("u_posB", face.positions[1]);
RenderUtils::m_faceShader->uploadUniformFloat3("u_posC", face.positions[2]);
RenderUtils::m_faceShader->uploadUniformFloat3("u_posD", face.positions[3]);
RenderUtils::m_faceShader->uploadUniformInt("u_textureID",
face.textureID);
RenderUtils::m_faceShader->uploadUniformFloat3(
"u_posA", face.positions[0]);
RenderUtils::m_faceShader->uploadUniformFloat3(
"u_posB", face.positions[1]);
RenderUtils::m_faceShader->uploadUniformFloat3(
"u_posC", face.positions[2]);
RenderUtils::m_faceShader->uploadUniformFloat3(
"u_posD", face.positions[3]);
Render::submit(RenderUtils::m_faceVertexArray);
}
}
RenderCommand::setDepthBuffer(false);
for (std::array<glm::vec3, 3>&line : m_lines) {
for (std::array<glm::vec3, 3>& line : m_lines) {
RenderUtils::m_lineShader->bind();
RenderUtils::m_lineShader->uploadUniformMat4("u_viewMatrix", cameraProjectionMatrix);
RenderUtils::m_lineShader->uploadUniformMat4(
"u_viewMatrix", cameraProjectionMatrix);
RenderUtils::m_lineShader->uploadUniformFloat3("u_color", line[2]);
RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", line[0]);
@ -160,7 +160,6 @@ namespace Deer {
void GizmoRenderer::refresh() {
m_lines.clear();
for (int i = 0; i < GIZMO_DEPTH; i++)
m_faces[i].clear();
for (int i = 0; i < GIZMO_DEPTH; i++) m_faces[i].clear();
}
}
} // namespace Deer

View File

@ -1,120 +1,129 @@
#include "Deer/Voxel.h"
#include "Deer/Log.h"
#include <sstream>
#include <string>
#include <unordered_map>
#include "Deer/DataStore.h"
#include "Deer/Log.h"
#include "Deer/Voxel.h"
#include "DeerRender/Render/Shader.h"
#include "DeerRender/VoxelAspect.h"
#include "cereal/archives/json.hpp"
#include "DeerRender/Voxels/Serialization/VoxelAspect_Serialization.h"
#include "cereal/archives/json.hpp"
#include <unordered_map>
#include <string>
#include <sstream>
namespace Deer {
namespace DataStore {
std::vector<VoxelAspect> voxelsAspect;
std::unordered_map<std::string, uint16_t> texturesIDs;
Ref<Shader> solidVoxelShader;
} // namespace DataStore
namespace Deer{
namespace VoxelData {
std::vector<VoxelAspect> voxelsAspect;
std::unordered_map<std::string, uint16_t> texturesIDs;
Ref<Shader> solidVoxelShader;
}
void DataStore::loadVoxelsAspect() {
std::vector<Path> voxelsAspectPath =
DataStore::getFiles(DEER_VOXEL_ASPECT_PATH, ".vaspect");
voxelsAspect.clear();
voxelsAspect.resize(voxelsInfo.size());
void VoxelData::loadVoxelsAspect() {
std::vector<Path> voxelsAspectPath = DataStore::getFiles(DEER_VOXEL_ASPECT_PATH, ".vaspect");
voxelsAspect.clear();
voxelsAspect.resize(voxelsInfo.size());
voxelsAspect[0].definition.voxelName = VOXEL_INFO_TYPE_AIR;
voxelsAspect[0].definition.voxelName = VOXEL_INFO_TYPE_AIR;
DEER_CORE_INFO("=== Loading voxel aspect ===");
DEER_CORE_TRACE(" default - air");
for (Path& voxelAspectPath: voxelsAspectPath) {
uint32_t size;
uint8_t* data = DataStore::readFile(voxelAspectPath, &size);
DEER_CORE_INFO("=== Loading voxel aspect ===");
DEER_CORE_TRACE(" default - air");
for (Path& voxelAspectPath : voxelsAspectPath) {
uint32_t size;
uint8_t* data = DataStore::readFile(voxelAspectPath, &size);
std::string dataString((char*)data, size);
std::istringstream inputStream(dataString);
std::string dataString((char*)data, size);
std::istringstream inputStream(dataString);
VoxelAspectDefinition aspectDefinition;
{
cereal::JSONInputArchive archive(inputStream);
archive(cereal::make_nvp("voxelAspect", aspectDefinition));
VoxelAspectDefinition aspectDefinition;
{
cereal::JSONInputArchive archive(inputStream);
archive(cereal::make_nvp("voxelAspect", aspectDefinition));
}
}
if (aspectDefinition.voxelName.empty()) {
DEER_CORE_ERROR("{0} has an empty name",
voxelAspectPath.generic_string().c_str());
continue;
}
if (aspectDefinition.voxelName.empty()) {
DEER_CORE_ERROR("{0} has an empty name", voxelAspectPath.generic_string().c_str());
continue;
}
int16_t voxelID = getVoxelID(aspectDefinition.voxelName);
if (voxelID == -1) {
DEER_CORE_ERROR(
"Voxel aspect {0} references {1} but it does not exist",
voxelAspectPath.generic_string().c_str(),
aspectDefinition.voxelName.c_str());
int16_t voxelID = getVoxelID(aspectDefinition.voxelName);
if (voxelID == -1) {
DEER_CORE_ERROR("Voxel aspect {0} references {1} but it does not exist",
voxelAspectPath.generic_string().c_str(), aspectDefinition.voxelName.c_str());
continue;
}
continue;
}
DEER_CORE_TRACE(" {0} - {1}",
voxelAspectPath.filename().generic_string().c_str(),
aspectDefinition.voxelName.c_str());
voxelsAspect[voxelID].definition = aspectDefinition;
}
DEER_CORE_TRACE(" {0} - {1}",
voxelAspectPath.filename().generic_string().c_str(),
aspectDefinition.voxelName.c_str());
DEER_CORE_INFO("=== Extracting textures ===");
for (VoxelAspect& voxelAspect : voxelsAspect) {
if (voxelsInfo[VoxelData::getVoxelID(voxelAspect.definition.voxelName)].type != VoxelInfoType::Voxel)
continue;
for (int i = 0; i < 6; i++) {
std::string& faceTextureString = voxelAspect.definition.textureFaces[i];
voxelsAspect[voxelID].definition = aspectDefinition;
}
if (faceTextureString.empty()) {
DEER_CORE_WARN("{0} has an empty texture at position {1} this could cause unwanted behaviour!",
voxelAspect.definition.voxelName.c_str(), i);
voxelAspect.textureFacesIDs[i] = 0;
continue;
}
DEER_CORE_INFO("=== Extracting textures ===");
for (VoxelAspect& voxelAspect : voxelsAspect) {
if (voxelsInfo[DataStore::getVoxelID(
voxelAspect.definition.voxelName)]
.type != VoxelInfoType::Voxel)
continue;
if (texturesIDs.contains(faceTextureString))
voxelAspect.textureFacesIDs[i] = texturesIDs[faceTextureString];
else {
uint16_t textureID = texturesIDs.size();
for (int i = 0; i < 6; i++) {
std::string& faceTextureString =
voxelAspect.definition.textureFaces[i];
texturesIDs[faceTextureString] = textureID;
voxelAspect.textureFacesIDs[i] = textureID;
if (faceTextureString.empty()) {
DEER_CORE_WARN(
"{0} has an empty texture at position {1} this could "
"cause unwanted behaviour!",
voxelAspect.definition.voxelName.c_str(), i);
DEER_CORE_TRACE(" texture {0} - id: {1}",
faceTextureString.c_str(), textureID);
}
}
}
}
voxelAspect.textureFacesIDs[i] = 0;
continue;
}
void VoxelData::createExampleVoxelAspect() {
VoxelAspectDefinition voxelAspectDefinition;
if (texturesIDs.contains(faceTextureString))
voxelAspect.textureFacesIDs[i] =
texturesIDs[faceTextureString];
else {
uint16_t textureID = texturesIDs.size();
std::ostringstream outputStream;
{
cereal::JSONOutputArchive archive(outputStream);
archive(cereal::make_nvp("voxelAspect", voxelAspectDefinition));
}
std::string restultString = outputStream.str();
DataStore::saveFile(Path(DEER_VOXEL_PATH) / "vaspect.example", (uint8_t*)restultString.c_str(), restultString.size());
}
texturesIDs[faceTextureString] = textureID;
voxelAspect.textureFacesIDs[i] = textureID;
void VoxelData::loadVoxelsShaders() {
uint32_t size;
uint8_t* data = DataStore::readFile(Path(DEER_VOXEL_SHADER_PATH) / "solid_voxel.glsl", &size);
DEER_CORE_TRACE(" texture {0} - id: {1}",
faceTextureString.c_str(), textureID);
}
}
}
}
solidVoxelShader = Shader::create(data, size);
void DataStore::createExampleVoxelAspect() {
VoxelAspectDefinition voxelAspectDefinition;
delete[] data;
}
std::ostringstream outputStream;
{
cereal::JSONOutputArchive archive(outputStream);
archive(cereal::make_nvp("voxelAspect", voxelAspectDefinition));
}
Ref<Shader>& VoxelData::getSolidVoxelShader() {
return solidVoxelShader;
}
}
std::string restultString = outputStream.str();
DataStore::saveFile(Path(DEER_VOXEL_PATH) / "vaspect.example",
(uint8_t*)restultString.c_str(),
restultString.size());
}
void DataStore::loadVoxelsShaders() {
uint32_t size;
uint8_t* data = DataStore::readFile(
Path(DEER_VOXEL_SHADER_PATH) / "solid_voxel.glsl", &size);
solidVoxelShader = Shader::create(data, size);
delete[] data;
}
Ref<Shader>& DataStore::getSolidVoxelShader() { return solidVoxelShader; }
} // namespace Deer

View File

@ -1,106 +1,123 @@
#include "Deer/Voxel.h"
#include "Deer/Log.h"
#include "DeerRender/VoxelAspect.h"
#include <string>
#include <unordered_map>
#include "Deer/DataStore.h"
#include "Deer/Log.h"
#include "Deer/Voxel.h"
#include "DeerRender/Render/Texture.h"
#include "DeerRender/VoxelAspect.h"
#include "stb_image.h"
#include "stb_image_write.h"
#include "Deer/DataStore.h"
#include "DeerRender/Render/Texture.h"
#include <unordered_map>
#include <string>
namespace Deer {
namespace VoxelData {
extern std::unordered_map<std::string, uint16_t> texturesIDs;
namespace DataStore {
extern std::unordered_map<std::string, uint16_t> texturesIDs;
int squareTextureSize = 0;
uint8_t* voxelColorTextureAtlasData = nullptr;
Ref<Texture2D> voxelColorTextureAtlas = nullptr;
}
int squareTextureSize = 0;
uint8_t* voxelColorTextureAtlasData = nullptr;
Ref<Texture2D> voxelColorTextureAtlas = nullptr;
} // namespace DataStore
void VoxelData::generateTextureAtlas() {
if (voxelColorTextureAtlasData != nullptr) {
delete[] voxelColorTextureAtlasData;
voxelColorTextureAtlasData = nullptr;
}
void DataStore::generateTextureAtlas() {
if (voxelColorTextureAtlasData != nullptr) {
delete[] voxelColorTextureAtlasData;
voxelColorTextureAtlasData = nullptr;
}
squareTextureSize = 1;
int textureCount = texturesIDs.size();
while (squareTextureSize * squareTextureSize < textureCount)
squareTextureSize++;
squareTextureSize = 1;
int textureCount = texturesIDs.size();
while (squareTextureSize * squareTextureSize < textureCount)
squareTextureSize++;
int textureAtlasSize = squareTextureSize * VOXEL_TEXTURE_SIZE_X * squareTextureSize * VOXEL_TEXTURE_SIZE_Y * 4;
voxelColorTextureAtlasData = new uint8_t[textureAtlasSize]{};
int textureAtlasSize = squareTextureSize * VOXEL_TEXTURE_SIZE_X *
squareTextureSize * VOXEL_TEXTURE_SIZE_Y * 4;
voxelColorTextureAtlasData = new uint8_t[textureAtlasSize]{};
stbi_set_flip_vertically_on_load(true);
stbi_flip_vertically_on_write(true);
stbi_set_flip_vertically_on_load(true);
stbi_flip_vertically_on_write(true);
DEER_CORE_INFO("=== Creating Texture Atlas ===");
for (auto& texture : texturesIDs) {
DEER_CORE_INFO("=== Creating Texture Atlas ===");
for (auto& texture : texturesIDs) {
uint32_t size;
uint8_t* fileData = DataStore::readFile(
Path(DEER_VOXEL_TEXTURE_PATH) / (texture.first + ".png"),
&size);
uint32_t size;
uint8_t* fileData = DataStore::readFile(Path(DEER_VOXEL_TEXTURE_PATH) / (texture.first + ".png"), &size);
DEER_CORE_TRACE(" {0}.png - {1}", texture.first.c_str(),
texture.second);
if (fileData == nullptr) {
DEER_CORE_ERROR("{0}.png does not exists",
texture.first.c_str());
continue;
}
DEER_CORE_TRACE(" {0}.png - {1}", texture.first.c_str(), texture.second);
if (fileData == nullptr) {
DEER_CORE_ERROR("{0}.png does not exists",
texture.first.c_str());
continue;
}
int width, height, channels;
uint8_t* textureData = stbi_load_from_memory(fileData, size, &width,
&height, &channels, 4);
int width, height, channels;
uint8_t* textureData = stbi_load_from_memory(fileData, size, &width, &height, &channels, 4);
if (channels < 3) {
DEER_CORE_ERROR(
"{0}.png has {1} channels and it must be bigger than {2}",
texture.first.c_str(), channels, 3);
} else if (width != VOXEL_TEXTURE_SIZE_X) {
DEER_CORE_ERROR("{0}.png has a width of {1} and it must be {2}",
texture.first.c_str(), width,
VOXEL_TEXTURE_SIZE_X);
} else if (height != VOXEL_TEXTURE_SIZE_Y) {
DEER_CORE_ERROR(
"{0}.png has a height of {1} and it must be {2}",
texture.first.c_str(), height, VOXEL_TEXTURE_SIZE_Y);
} else {
int yOffset = (int)(texture.second / squareTextureSize);
int xOffset = texture.second - yOffset * squareTextureSize;
if (channels < 3) {
DEER_CORE_ERROR("{0}.png has {1} channels and it must be bigger than {2}",
texture.first.c_str(), channels, 3);
} else if (width != VOXEL_TEXTURE_SIZE_X) {
DEER_CORE_ERROR("{0}.png has a width of {1} and it must be {2}",
texture.first.c_str(), width, VOXEL_TEXTURE_SIZE_X);
} else if (height != VOXEL_TEXTURE_SIZE_Y) {
DEER_CORE_ERROR("{0}.png has a height of {1} and it must be {2}",
texture.first.c_str(), height, VOXEL_TEXTURE_SIZE_Y);
} else {
int yOffset = (int)(texture.second / squareTextureSize);
int xOffset = texture.second - yOffset * squareTextureSize;
int yOffsetPixels = yOffset * VOXEL_TEXTURE_SIZE_Y;
int xOffsetPixels = xOffset * VOXEL_TEXTURE_SIZE_X;
int yOffsetPixels = yOffset * VOXEL_TEXTURE_SIZE_Y;
int xOffsetPixels = xOffset * VOXEL_TEXTURE_SIZE_X;
for (int y = 0; y < VOXEL_TEXTURE_SIZE_Y; y++) {
for (int x = 0; x < VOXEL_TEXTURE_SIZE_X; x++) {
int inputTextureIndex = (x + y * width) * 4;
int outputTextureIndex =
(x + xOffsetPixels +
(y + yOffsetPixels) * VOXEL_TEXTURE_SIZE_X *
squareTextureSize) *
4;
for (int y = 0; y < VOXEL_TEXTURE_SIZE_Y; y++) {
for (int x = 0; x < VOXEL_TEXTURE_SIZE_X; x++) {
int inputTextureIndex = (x + y * width) * 4;
int outputTextureIndex = (x + xOffsetPixels + (y + yOffsetPixels) * VOXEL_TEXTURE_SIZE_X * squareTextureSize) * 4;
voxelColorTextureAtlasData[outputTextureIndex + 0] =
textureData[inputTextureIndex + 0];
voxelColorTextureAtlasData[outputTextureIndex + 1] =
textureData[inputTextureIndex + 1];
voxelColorTextureAtlasData[outputTextureIndex + 2] =
textureData[inputTextureIndex + 2];
voxelColorTextureAtlasData[outputTextureIndex + 3] =
textureData[inputTextureIndex + 3];
}
}
}
voxelColorTextureAtlasData[outputTextureIndex + 0] = textureData[inputTextureIndex + 0];
voxelColorTextureAtlasData[outputTextureIndex + 1] = textureData[inputTextureIndex + 1];
voxelColorTextureAtlasData[outputTextureIndex + 2] = textureData[inputTextureIndex + 2];
voxelColorTextureAtlasData[outputTextureIndex + 3] = textureData[inputTextureIndex + 3];
}
}
stbi_image_free(textureData);
delete[] fileData;
}
}
voxelColorTextureAtlas =
Texture2D::create(voxelColorTextureAtlasData,
squareTextureSize * VOXEL_TEXTURE_SIZE_X,
squareTextureSize * VOXEL_TEXTURE_SIZE_Y, 4);
stbi_image_free(textureData);
delete[] fileData;
}
// temp
Path savePath =
DataStore::rootPath / DEER_TEMP_PATH / "voxel_texture_atlas.png";
DataStore::createFolder(DataStore::rootPath / DEER_TEMP_PATH);
stbi_write_png(savePath.generic_string().c_str(),
squareTextureSize * VOXEL_TEXTURE_SIZE_X,
squareTextureSize * VOXEL_TEXTURE_SIZE_Y, 4,
voxelColorTextureAtlasData,
squareTextureSize * VOXEL_TEXTURE_SIZE_X * 4);
}
voxelColorTextureAtlas = Texture2D::create(voxelColorTextureAtlasData, squareTextureSize * VOXEL_TEXTURE_SIZE_X, squareTextureSize * VOXEL_TEXTURE_SIZE_Y, 4);
int DataStore::getVoxelTextureAtlasSize() { return squareTextureSize; }
// temp
Path savePath = DataStore::rootPath / DEER_TEMP_PATH / "voxel_texture_atlas.png";
DataStore::createFolder(DataStore::rootPath / DEER_TEMP_PATH);
stbi_write_png(savePath.generic_string().c_str(), squareTextureSize * VOXEL_TEXTURE_SIZE_X, squareTextureSize * VOXEL_TEXTURE_SIZE_Y, 4, voxelColorTextureAtlasData, squareTextureSize * VOXEL_TEXTURE_SIZE_X * 4);
}
int VoxelData::getVoxelTextureAtlasSize() {
return squareTextureSize;
}
Ref<Texture2D>& VoxelData::getVoxelColorTextureAtlas() {
return voxelColorTextureAtlas;
}
}
Ref<Texture2D>& DataStore::getVoxelColorTextureAtlas() {
return voxelColorTextureAtlas;
}
} // namespace Deer

View File

@ -1,22 +1,20 @@
#include "Deer/VoxelWorld.h"
#include "Deer/Voxels/Chunk.h"
#include "Deer/Application.h"
#include "Deer/Memory.h"
#include "Deer/Asset.h"
#include "Deer/Application.h"
#include "Deer/Asset.h"
#include "Deer/Components.h"
#include "Deer/Log.h"
#include "Deer/Memory.h"
#include "Deer/Voxel.h"
#include "Deer/Voxels/Chunk.h"
#include "DeerRender/Render/Render.h"
#include "DeerRender/Render/RenderUtils.h"
#include "DeerRender/Render/Texture.h"
#include "DeerRender/SceneCamera.h"
#include "Deer/Voxel.h"
#include "Deer/Log.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/matrix_inverse.hpp"
#include "DeerRender/Voxels/VoxelWorldRenderData.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_inverse.hpp"
#include "glm/gtc/matrix_transform.hpp"
namespace Deer {
VoxelLight VoxelWorld::readLight(VoxelCordinates coords) {
@ -24,8 +22,7 @@ namespace Deer {
ChunkVoxelID chunkVoxelID;
extractChunkCordinates(coords, chunkID, chunkVoxelID);
if (!m_worldProps.isValid(chunkID))
return lightVoxel;
if (!m_worldProps.isValid(chunkID)) return lightVoxel;
Chunk& chunk = m_chunks[m_worldProps.getWorldChunkID(chunkID)];
return chunk.readLight(chunkVoxelID);
@ -36,8 +33,7 @@ namespace Deer {
ChunkVoxelID chunkVoxelID;
extractChunkCordinates(coords, chunkID, chunkVoxelID);
if (!m_worldProps.isValid(chunkID))
return lightVoxel;
if (!m_worldProps.isValid(chunkID)) return lightVoxel;
m_renderData->chunkQueue.addChunk(chunkID);
@ -51,22 +47,23 @@ namespace Deer {
glm::mat4 invertZ = glm::scale(glm::mat4(1.0f), glm::vec3(1, 1, -1));
// Lets invert the z axis for engine convenience
glm::mat4 cameraProjectionMatrix = projectionMatrix * invertZ * camMatrix;
glm::mat4 cameraProjectionMatrix =
projectionMatrix * invertZ * camMatrix;
VoxelData::getVoxelColorTextureAtlas()->bind(0);
DataStore::getVoxelColorTextureAtlas()->bind(0);
Ref<Shader>& shader = VoxelData::getSolidVoxelShader();
Ref<Shader>& shader = DataStore::getSolidVoxelShader();
shader->bind();
shader->uploadUniformMat4("u_viewMatrix", cameraProjectionMatrix);
shader->uploadUniformMat4("u_worldMatrix", glm::mat4(1.0f));
shader->uploadUniformInt("u_texture", 0);
shader->uploadUniformInt("u_textureSize", VoxelData::getVoxelTextureAtlasSize());
shader->uploadUniformInt("u_textureSize",
DataStore::getVoxelTextureAtlasSize());
for (int x = 0; x < m_worldProps.getChunkCount(); x++) {
ChunkRender& chunkRender = m_renderData->chunksRender[x];
if (!chunkRender.hasData)
continue;
if (!chunkRender.hasData) continue;
ChunkID chunkID = m_worldProps.getChunkID(x);
chunkRender.solidVoxel->bind();
@ -74,8 +71,8 @@ namespace Deer {
shader->uploadUniformInt("u_chunkID_x", chunkID.x);
shader->uploadUniformInt("u_chunkID_y", chunkID.y);
shader->uploadUniformInt("u_chunkID_z", chunkID.z);
Render::submit(chunkRender.solidVoxel);
}
}
}
} // namespace Deer

View File

@ -1,22 +1,19 @@
#include "Deer/VoxelWorld.h"
#include "Deer/Voxels/Chunk.h"
#include "Deer/Application.h"
#include "Deer/Asset.h"
#include "Deer/Components.h"
#include "Deer/VoxelWorld.h"
#include "Deer/Voxels/Chunk.h"
#include "DeerRender/Render/Render.h"
#include "DeerRender/Render/RenderUtils.h"
#include "DeerRender/Render/Texture.h"
#include "DeerRender/Voxels/VoxelWorldRenderData.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/matrix_inverse.hpp"
#include "glm/gtc/matrix_transform.hpp"
namespace Deer {
void VoxelWorld::bakeNextChunk() {
if (!m_renderData->chunkQueue.hasChunk())
return;
if (!m_renderData->chunkQueue.hasChunk()) return;
// Pull the next chunk to render
ChunkID nextChunk = m_renderData->chunkQueue.pullChunk();
@ -35,27 +32,49 @@ namespace Deer {
// Pass the data to the GPU
Ref<VertexArray> va = VertexArray::create();
va->bind();
Ref<VertexBuffer> vb = VertexBuffer::create(m_renderData->vertexData.data(), m_renderData->vertexData.size() * sizeof(SolidVoxelVertexData));
Ref<IndexBuffer> ib = IndexBuffer::create(m_renderData->indices.data(), m_renderData->indices.size() * sizeof(uint32_t), IndexDataType::Unsigned_Int);
Ref<VertexBuffer> vb = VertexBuffer::create(
m_renderData->vertexData.data(),
m_renderData->vertexData.size() * sizeof(SolidVoxelVertexData));
Ref<IndexBuffer> ib =
IndexBuffer::create(m_renderData->indices.data(),
m_renderData->indices.size() * sizeof(uint32_t),
IndexDataType::Unsigned_Int);
BufferLayout layout({
{ "a_textureID", DataType::Unsigned_Short2, ShaderDataType::Integer, offsetof(SolidVoxelVertexData, textureID) },
{ "a_ambient_occlusion", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint, offsetof(SolidVoxelVertexData, ambient_occlusion) },
BufferLayout layout(
{{"a_textureID", DataType::Unsigned_Short2, ShaderDataType::Integer,
offsetof(SolidVoxelVertexData, textureID)},
{"a_ambient_occlusion", DataType::Unsigned_Byte,
ShaderDataType::FloatingPoint,
offsetof(SolidVoxelVertexData, ambient_occlusion)},
{ "a_xPos", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint, offsetof(SolidVoxelVertexData, xPos) },
{ "a_yPos", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint, offsetof(SolidVoxelVertexData, yPos) },
{ "a_zPos", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint, offsetof(SolidVoxelVertexData, zPos) },
{"a_xPos", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint,
offsetof(SolidVoxelVertexData, xPos)},
{"a_yPos", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint,
offsetof(SolidVoxelVertexData, yPos)},
{"a_zPos", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint,
offsetof(SolidVoxelVertexData, zPos)},
{ "a_a_light", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint, offsetof(SolidVoxelVertexData, a_light) },
{ "a_r_light", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint, offsetof(SolidVoxelVertexData, r_light) },
{ "a_g_light", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint, offsetof(SolidVoxelVertexData, g_light) },
{ "a_b_light", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint, offsetof(SolidVoxelVertexData, b_light) },
{"a_a_light", DataType::Unsigned_Byte,
ShaderDataType::FloatingPoint,
offsetof(SolidVoxelVertexData, a_light)},
{"a_r_light", DataType::Unsigned_Byte,
ShaderDataType::FloatingPoint,
offsetof(SolidVoxelVertexData, r_light)},
{"a_g_light", DataType::Unsigned_Byte,
ShaderDataType::FloatingPoint,
offsetof(SolidVoxelVertexData, g_light)},
{"a_b_light", DataType::Unsigned_Byte,
ShaderDataType::FloatingPoint,
offsetof(SolidVoxelVertexData, b_light)},
{ "a_normal", DataType::Unsigned_Byte, ShaderDataType::Integer, offsetof(SolidVoxelVertexData, normal)},
{"a_normal", DataType::Unsigned_Byte, ShaderDataType::Integer,
offsetof(SolidVoxelVertexData, normal)},
{ "a_u", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint, offsetof(SolidVoxelVertexData, u) },
{ "a_v", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint, offsetof(SolidVoxelVertexData, v) }
}, sizeof(SolidVoxelVertexData));
{"a_u", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint,
offsetof(SolidVoxelVertexData, u)},
{"a_v", DataType::Unsigned_Byte, ShaderDataType::FloatingPoint,
offsetof(SolidVoxelVertexData, v)}},
sizeof(SolidVoxelVertexData));
vb->setLayout(layout);
va->addVertexBuffer(vb);
@ -72,36 +91,40 @@ namespace Deer {
Chunk& workingChunk = m_chunks[m_worldProps.getWorldChunkID(chunkID)];
Voxel voxel = workingChunk.readVoxel(chunkVoxelID);
if (!voxel.isVoxelType())
return;
if (!voxel.isVoxelType()) return;
for (int i = 0; i < 6; i++) {
// front means the front voxel of the face
VoxelCordinates frontID(
NORMAL_DIR(X_AXIS, i) + chunkVoxelID.x + CHUNK_SIZE_X * chunkID.x,
NORMAL_DIR(Y_AXIS, i) + chunkVoxelID.y + CHUNK_SIZE_Y * chunkID.y,
NORMAL_DIR(Z_AXIS, i) + chunkVoxelID.z + CHUNK_SIZE_Z * chunkID.z
);
VoxelCordinates frontID(NORMAL_DIR(X_AXIS, i) + chunkVoxelID.x +
CHUNK_SIZE_X * chunkID.x,
NORMAL_DIR(Y_AXIS, i) + chunkVoxelID.y +
CHUNK_SIZE_Y * chunkID.y,
NORMAL_DIR(Z_AXIS, i) + chunkVoxelID.z +
CHUNK_SIZE_Z * chunkID.z);
Voxel frontVoxel = readVoxel(frontID);
// If the face is inside 2 Voxels we will not render it
if (frontVoxel.isVoxelType())
continue;
if (frontVoxel.isVoxelType()) continue;
VoxelLight frontVoxelLight = readLight(frontID);
// front2ID means the front voxel in 2 voxels apart
VoxelCordinates front2ID(
NORMAL_DIR(X_AXIS, i) * 2 + chunkVoxelID.x + CHUNK_SIZE_X * chunkID.x,
NORMAL_DIR(Y_AXIS, i) * 2 + chunkVoxelID.y + CHUNK_SIZE_Y * chunkID.y,
NORMAL_DIR(Z_AXIS, i) * 2 + chunkVoxelID.z + CHUNK_SIZE_Z * chunkID.z
);
NORMAL_DIR(X_AXIS, i) * 2 + chunkVoxelID.x +
CHUNK_SIZE_X * chunkID.x,
NORMAL_DIR(Y_AXIS, i) * 2 + chunkVoxelID.y +
CHUNK_SIZE_Y * chunkID.y,
NORMAL_DIR(Z_AXIS, i) * 2 + chunkVoxelID.z +
CHUNK_SIZE_Z * chunkID.z);
Voxel front2Voxel = readVoxel(frontID);
VoxelLight front2VoxelLight = readLight(frontID);
// Face Shadow means that face is not in the direction of the light
bool isFaceShadow = frontVoxelLight.ambient_light != 255 && (frontVoxel.isVoxelType() || frontVoxelLight.ambient_light > front2VoxelLight.ambient_light);
bool isFaceShadow = frontVoxelLight.ambient_light != 255 &&
(frontVoxel.isVoxelType() ||
frontVoxelLight.ambient_light >
front2VoxelLight.ambient_light);
// Save the vertex id for later
int vertexID = m_renderData->vertexData.size();
@ -110,9 +133,11 @@ namespace Deer {
// For every vertex
for (int v = 0; v < 4; v++) {
// This var takes the count of the voxels that where added in voxel_light
// This var takes the count of the voxels that where added in
// voxel_light
int sample_count = 1;
// Count the blocks to calculate the ambient occlusion, min value 0 max value 2
// Count the blocks to calculate the ambient occlusion, min
// value 0 max value 2
voxel_count[v] = 0;
// col 0 -> ambient oclusion
@ -120,22 +145,21 @@ namespace Deer {
// col 2 -> green light
// col 3 -> blue light
int voxel_light[4];
voxel_light[0] = frontVoxelLight.ambient_light;
voxel_light[1] = frontVoxelLight.r_light;
voxel_light[2] = frontVoxelLight.g_light;
voxel_light[3] = frontVoxelLight.b_light;
//Checks if there is air on the blocks of the side
// Checks if there is air on the blocks of the side
bool airEdge[2];
// Calculate ambient occlusion and light difusion
for (int a = 0; a < 2; a++) {
VoxelCordinates checkChordsID(
frontID.x + AMBIENT_OCCLUSION_VERTEX(X_AXIS, a, v, i),
frontID.y + AMBIENT_OCCLUSION_VERTEX(Y_AXIS, a, v, i),
frontID.z + AMBIENT_OCCLUSION_VERTEX(Z_AXIS, a, v, i)
);
frontID.x + AMBIENT_OCCLUSION_VERTEX(X_AXIS, a, v, i),
frontID.y + AMBIENT_OCCLUSION_VERTEX(Y_AXIS, a, v, i),
frontID.z + AMBIENT_OCCLUSION_VERTEX(Z_AXIS, a, v, i));
Voxel checkChordsVoxel = readVoxel(checkChordsID);
VoxelLight checkChordsVoxelLight = readLight(checkChordsID);
@ -156,10 +180,12 @@ namespace Deer {
if (airEdge[0] || airEdge[1]) {
VoxelCordinates checkChordsID(
frontID.x + AMBIENT_OCCLUSION_VERTEX(X_AXIS, 0, v, i) + AMBIENT_OCCLUSION_VERTEX(X_AXIS, 1, v, i),
frontID.y + AMBIENT_OCCLUSION_VERTEX(Y_AXIS, 0, v, i) + AMBIENT_OCCLUSION_VERTEX(Y_AXIS, 1, v, i),
frontID.z + AMBIENT_OCCLUSION_VERTEX(Z_AXIS, 0, v, i) + AMBIENT_OCCLUSION_VERTEX(Z_AXIS, 1, v, i)
);
frontID.x + AMBIENT_OCCLUSION_VERTEX(X_AXIS, 0, v, i) +
AMBIENT_OCCLUSION_VERTEX(X_AXIS, 1, v, i),
frontID.y + AMBIENT_OCCLUSION_VERTEX(Y_AXIS, 0, v, i) +
AMBIENT_OCCLUSION_VERTEX(Y_AXIS, 1, v, i),
frontID.z + AMBIENT_OCCLUSION_VERTEX(Z_AXIS, 0, v, i) +
AMBIENT_OCCLUSION_VERTEX(Z_AXIS, 1, v, i));
Voxel checkChordsVoxel = readVoxel(checkChordsID);
VoxelLight checkChordsVoxelLight = readLight(checkChordsID);
@ -178,17 +204,22 @@ namespace Deer {
for (int xi = 0; xi < 4; xi++) {
voxel_light[xi] = (voxel_light[xi]) / sample_count;
voxel_light[xi] = (voxel_light[xi] > 255)? 255 : voxel_light[xi];
voxel_light[xi] =
(voxel_light[xi] > 255) ? 255 : voxel_light[xi];
}
SolidVoxelVertexData vertex_data;
vertex_data.textureID = VoxelData::voxelsAspect[voxel.id].getTextureID(i);
vertex_data.textureID =
DataStore::voxelsAspect[voxel.id].getTextureID(i);
vertex_data.ambient_occlusion = voxel_count[v];
vertex_data.xPos = chunkVoxelID.x + NORMAL_VERTEX_POS(X_AXIS, v, i);
vertex_data.yPos = chunkVoxelID.y + NORMAL_VERTEX_POS(Y_AXIS, v, i);
vertex_data.zPos = chunkVoxelID.z + NORMAL_VERTEX_POS(Z_AXIS, v, i);
vertex_data.xPos =
chunkVoxelID.x + NORMAL_VERTEX_POS(X_AXIS, v, i);
vertex_data.yPos =
chunkVoxelID.y + NORMAL_VERTEX_POS(Y_AXIS, v, i);
vertex_data.zPos =
chunkVoxelID.z + NORMAL_VERTEX_POS(Z_AXIS, v, i);
vertex_data.a_light = voxel_light[0];
vertex_data.r_light = voxel_light[1];
vertex_data.g_light = voxel_light[2];
@ -202,7 +233,8 @@ namespace Deer {
m_renderData->vertexData.push_back(vertex_data);
}
if (voxel_count[0] + voxel_count[3] > voxel_count[1] + voxel_count[2]) {
if (voxel_count[0] + voxel_count[3] >
voxel_count[1] + voxel_count[2]) {
m_renderData->indices.push_back(vertexID);
m_renderData->indices.push_back(vertexID + 2);
m_renderData->indices.push_back(vertexID + 1);
@ -222,4 +254,4 @@ namespace Deer {
}
}
}
} // namespace Deer

View File

@ -120,7 +120,7 @@ namespace Deer {
VoxelLight& voxelLight = modLight(cordinates);
Voxel voxel = readVoxel(cordinates);
VoxelAspect& voxelAspect = VoxelData::voxelsAspect[voxel.id];
VoxelAspect& voxelAspect = DataStore::voxelsAspect[voxel.id];
voxelLight.r_light = voxelAspect.definition.colorEmission.r_value;
voxelLight.g_light = voxelAspect.definition.colorEmission.g_value;
voxelLight.b_light = voxelAspect.definition.colorEmission.b_value;

View File

@ -1,14 +1,22 @@
#include "DeerRender/ImGui/ImGuiLayer.h"
#include "Plattform/OpenGL/imgui_impl_opengl3.h"
#include "Deer/Application.h"
#include "DeerRender/Events/Event.h"
#include "Deer/Log.h"
#include "DeerRender/KeyCodes.h"
#include "backends/imgui_impl_glfw.h"
#include "DeerRender/Events/Event.h"
#include "DeerRender/Input.h"
// THIS ORDER
#include "Plattform/OpenGL/imgui_impl_opengl3.h"
// THIS ORDER
#include "glad/glad.h"
// THIS ORDER
#include "GLFW/glfw3.h"
#include "ImGuizmo.h"
// THIS ORDER
#include "imgui.h"
// THIS ORDER
#include "backends/imgui_impl_glfw.h"
// THIS ORDER
#include "ImGuizmo.h"
namespace Deer {
void ImGuiLayer::onAttach() {
@ -22,12 +30,12 @@ namespace Deer {
ImGui_ImplOpenGL3_Init("#version 410");
Application::s_application->m_window->initImGUI();
io.DisplaySize = ImVec2(Application::s_application->m_window->getWitdth(), Application::s_application->m_window->getHeight());
io.DisplaySize =
ImVec2(Application::s_application->m_window->getWitdth(),
Application::s_application->m_window->getHeight());
}
void ImGuiLayer::onDetach() {
}
void ImGuiLayer::onDetach() {}
void ImGuiLayer::begin() {
ImGui_ImplOpenGL3_NewFrame();
@ -35,9 +43,7 @@ namespace Deer {
ImGuizmo::BeginFrame();
}
void ImGuiLayer::end()
{
void ImGuiLayer::end() {
ImGui::EndFrame();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
@ -46,13 +52,20 @@ namespace Deer {
void ImGuiLayer::onEvent(Event& e) {
EventDispatcher dispacher(e);
//dispacher.dispatch<MouseButtonPressedEvent>(std::bind(&ImGuiLayer::onMouseButtonPressedEvent, this, std::placeholders::_1));
//dispacher.dispatch<MouseButtonReleasedEvent>(std::bind(&ImGuiLayer::onMouseButtonReleasedEvent, this, std::placeholders::_1));
//dispacher.dispatch<MouseMovedEvent>(std::bind(&ImGuiLayer::onMouseMovedEvent, this, std::placeholders::_1));
//dispacher.dispatch<MouseScrolledEvent>(std::bind(&ImGuiLayer::onMouseScrollEvent, this, std::placeholders::_1));
//dispacher.dispatch<KeyPressedEvent>(std::bind(&ImGuiLayer::onKeyPressedEvent, this, std::placeholders::_1));
//dispacher.dispatch<KeyTypedEvent>(std::bind(&ImGuiLayer::onKeyTypedEvent, this, std::placeholders::_1));
dispacher.dispatch<WindowResizeEvent>(std::bind(&ImGuiLayer::onWindowResizeEvent, this, std::placeholders::_1));
// dispacher.dispatch<MouseButtonPressedEvent>(std::bind(&ImGuiLayer::onMouseButtonPressedEvent,
// this, std::placeholders::_1));
// dispacher.dispatch<MouseButtonReleasedEvent>(std::bind(&ImGuiLayer::onMouseButtonReleasedEvent,
// this, std::placeholders::_1));
// dispacher.dispatch<MouseMovedEvent>(std::bind(&ImGuiLayer::onMouseMovedEvent,
// this, std::placeholders::_1));
// dispacher.dispatch<MouseScrolledEvent>(std::bind(&ImGuiLayer::onMouseScrollEvent,
// this, std::placeholders::_1));
// dispacher.dispatch<KeyPressedEvent>(std::bind(&ImGuiLayer::onKeyPressedEvent,
// this, std::placeholders::_1));
// dispacher.dispatch<KeyTypedEvent>(std::bind(&ImGuiLayer::onKeyTypedEvent,
// this, std::placeholders::_1));
dispacher.dispatch<WindowResizeEvent>(std::bind(
&ImGuiLayer::onWindowResizeEvent, this, std::placeholders::_1));
}
bool ImGuiLayer::onMouseButtonPressedEvent(MouseButtonPressedEvent& e) {
@ -84,12 +97,17 @@ namespace Deer {
bool ImGuiLayer::onKeyPressedEvent(KeyPressedEvent& e) {
ImGuiIO& io = ImGui::GetIO();
io.KeysDown[e.getKeyCode()] = true;
io.KeysDown[ImGuiKey::ImGuiKey_Backspace] = e.getKeyCode() == DEER_KEY_BACKSPACE;
io.KeysDown[ImGuiKey::ImGuiKey_Backspace] =
e.getKeyCode() == DEER_KEY_BACKSPACE;
io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL];
io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT];
io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT];
io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER];
io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] ||
io.KeysDown[GLFW_KEY_RIGHT_CONTROL];
io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] ||
io.KeysDown[GLFW_KEY_RIGHT_SHIFT];
io.KeyAlt =
io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT];
io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] ||
io.KeysDown[GLFW_KEY_RIGHT_SUPER];
return false;
}
@ -119,4 +137,4 @@ namespace Deer {
return false;
}
}
} // namespace Deer