2020-07-06 19:18:29 +00:00
|
|
|
/**
|
|
|
|
* \file main.cpp
|
|
|
|
* \brief Univerxel game
|
|
|
|
* \author Maelys Bois
|
|
|
|
* \version 0.0.1
|
|
|
|
*
|
|
|
|
* Univerxel main program.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <iostream>
|
|
|
|
#include <chrono>
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
#include "render/window.hpp"
|
|
|
|
#include "render/UI.hpp"
|
|
|
|
#include "control/InputMap.hpp"
|
|
|
|
#include "control/Camera.hpp"
|
|
|
|
|
2020-07-10 17:49:16 +00:00
|
|
|
#include "render/Renderer.hpp"
|
2020-07-25 14:29:05 +00:00
|
|
|
#include "render/pass/ColorProgram.hpp"
|
2020-07-25 16:45:03 +00:00
|
|
|
#include "render/buffer/Colored.hpp"
|
|
|
|
#include "world/Universe.hpp"
|
2020-07-06 19:18:29 +00:00
|
|
|
|
2020-07-25 16:45:03 +00:00
|
|
|
#include "state.h"
|
2020-07-06 19:18:29 +00:00
|
|
|
|
2020-07-18 12:54:07 +00:00
|
|
|
#include <Remotery.h>
|
|
|
|
|
2020-07-06 19:18:29 +00:00
|
|
|
/// Entry point
|
|
|
|
int main(int, char *[]){
|
|
|
|
options options;
|
|
|
|
state state;
|
|
|
|
reports reports;
|
|
|
|
|
|
|
|
GLFWwindow *window = createWindow(options.samples);
|
|
|
|
if(window == NULL)
|
|
|
|
return 1;
|
|
|
|
|
2020-07-12 13:46:51 +00:00
|
|
|
glClearColor(options.renderer.clear_color.x, options.renderer.clear_color.y, options.renderer.clear_color.z, options.renderer.clear_color.w);
|
2020-07-06 19:18:29 +00:00
|
|
|
glfwSwapInterval(options.target_fps < MIN_FPS);
|
|
|
|
|
|
|
|
InputMap inputs(window);
|
2020-07-10 19:37:49 +00:00
|
|
|
Camera camera(window, inputs, options.camera);
|
2020-07-06 19:18:29 +00:00
|
|
|
|
2020-07-10 17:49:16 +00:00
|
|
|
Renderer *renderer = new Renderer(options.renderer);
|
2020-07-25 14:29:05 +00:00
|
|
|
renderer->LightInvDir = glm::vec3(-0.5f, 2, -2);
|
2020-07-06 19:18:29 +00:00
|
|
|
UI::setup(window);
|
|
|
|
|
2020-07-25 16:45:03 +00:00
|
|
|
GLuint aimTexture = pass::Program::loadTexture("ui/Aim", false);
|
2020-07-06 19:18:29 +00:00
|
|
|
|
2020-07-25 16:45:03 +00:00
|
|
|
pass::ColorProgram *lookProgram = new pass::ColorProgram();
|
|
|
|
buffer::Colored lookBuffer(GL_LINES, 24, {
|
2020-07-25 14:29:05 +00:00
|
|
|
glm::vec3(0, 0, 0), glm::vec3(0, 0, 1),
|
|
|
|
glm::vec3(0, 0, 1), glm::vec3(0, 1, 1),
|
|
|
|
glm::vec3(0, 1, 1), glm::vec3(0, 1, 0),
|
|
|
|
glm::vec3(0, 1, 0), glm::vec3(0, 0, 0),
|
|
|
|
glm::vec3(1, 0, 0), glm::vec3(1, 0, 1),
|
|
|
|
glm::vec3(1, 0, 1), glm::vec3(1, 1, 1),
|
|
|
|
glm::vec3(1, 1, 1), glm::vec3(1, 1, 0),
|
|
|
|
glm::vec3(1, 1, 0), glm::vec3(1, 0, 0),
|
|
|
|
glm::vec3(0, 0, 0), glm::vec3(1, 0, 0),
|
|
|
|
glm::vec3(0, 0, 1), glm::vec3(1, 0, 1),
|
|
|
|
glm::vec3(0, 1, 1), glm::vec3(1, 1, 1),
|
|
|
|
glm::vec3(0, 1, 0), glm::vec3(1, 1, 0),
|
|
|
|
}, {
|
|
|
|
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
|
|
|
|
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
|
|
|
|
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
|
|
|
|
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
|
|
|
|
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
|
|
|
|
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
|
|
|
|
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
|
|
|
|
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
|
|
|
|
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
|
|
|
|
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
|
|
|
|
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
|
|
|
|
glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1),
|
|
|
|
});
|
2020-07-10 17:49:16 +00:00
|
|
|
|
2020-07-18 12:54:07 +00:00
|
|
|
Remotery *rmt;
|
|
|
|
rmt_CreateGlobalInstance(&rmt);
|
|
|
|
rmt_BindOpenGL();
|
|
|
|
#if RMT_ENABLED
|
|
|
|
std::cout << "Profiling !" << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2020-07-25 16:45:03 +00:00
|
|
|
world::Universe world = world::Universe(options.world);
|
2020-07-22 20:55:13 +00:00
|
|
|
world.setContouring(contouring::load(options.contouring_idx, options.contouring_data));
|
|
|
|
state.contouring = world.getContouring();
|
|
|
|
|
2020-07-06 19:18:29 +00:00
|
|
|
do {
|
|
|
|
const double startTime = glfwGetTime();
|
|
|
|
{ // Update
|
2020-07-18 12:54:07 +00:00
|
|
|
rmt_ScopedCPUSample(Update, 0);
|
2020-07-06 19:18:29 +00:00
|
|
|
const double partTime = glfwGetTime();
|
|
|
|
inputs.toggle(state.capture_mouse, Input::Mouse);
|
|
|
|
inputs.toggle(options.show_debug_menu, Input::Debug);
|
|
|
|
|
|
|
|
camera.update(state.capture_mouse, !UI::isFocus());
|
2020-07-10 17:49:16 +00:00
|
|
|
renderer->lookFrom(camera);
|
|
|
|
|
2020-07-10 19:37:49 +00:00
|
|
|
state.position = camera.getPosition();
|
2020-07-25 14:29:05 +00:00
|
|
|
state.look_at = world.raycast(camera.getRay() / options.voxel_size);
|
|
|
|
if (state.capture_mouse && state.look_at.has_value()) {
|
2020-07-06 19:18:29 +00:00
|
|
|
if (inputs.isPressing(Mouse::Left))
|
2020-07-25 16:45:03 +00:00
|
|
|
world.setCube(state.look_at.value().first, world::Voxel{0, 0}, options.tool.radius);
|
2020-07-06 19:18:29 +00:00
|
|
|
else if (inputs.isPressing(Mouse::Right))
|
2020-07-25 16:45:03 +00:00
|
|
|
world.setCube(state.look_at.value().first, world::Voxel{UCHAR_MAX, options.tool.material}, options.tool.radius);
|
2020-07-25 14:29:05 +00:00
|
|
|
}
|
2020-07-10 19:37:49 +00:00
|
|
|
world.update(state.position / options.voxel_size, reports.world);
|
2020-07-06 19:18:29 +00:00
|
|
|
inputs.saveKeys();
|
|
|
|
reports.main.update.push((glfwGetTime() - partTime) * 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2020-07-18 12:54:07 +00:00
|
|
|
rmt_ScopedCPUSample(UI, 0);
|
2020-07-06 19:18:29 +00:00
|
|
|
const auto actions = UI::draw(options, state, reports, aimTexture);
|
|
|
|
if (actions && UI::Actions::FPS) {
|
|
|
|
glfwSwapInterval(options.target_fps < MIN_FPS);
|
|
|
|
}
|
|
|
|
if (actions && UI::Actions::FullScreen) {
|
|
|
|
// MAYBE: real fullscreen
|
|
|
|
if(options.fullscreen) {
|
|
|
|
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
|
|
|
|
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
|
|
|
|
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
|
|
|
|
} else {
|
|
|
|
glfwSetWindowMonitor(window, NULL, 0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT, GLFW_DONT_CARE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(actions && UI::Actions::ClearColor) {
|
2020-07-12 13:46:51 +00:00
|
|
|
renderer->FogColor = glm::vec3(options.renderer.clear_color.x, options.renderer.clear_color.y, options.renderer.clear_color.z);
|
|
|
|
glClearColor(options.renderer.clear_color.x, options.renderer.clear_color.y, options.renderer.clear_color.z, options.renderer.clear_color.w);
|
2020-07-06 19:18:29 +00:00
|
|
|
}
|
2020-07-10 17:49:16 +00:00
|
|
|
if(actions && UI::Actions::RendererSharders) {
|
|
|
|
renderer->reloadShaders(options.renderer.main);
|
|
|
|
}
|
|
|
|
if(actions && UI::Actions::RendererTextures) {
|
|
|
|
renderer->reloadTextures(options.renderer.textures, options.renderer.mipMapLOD);
|
|
|
|
}
|
|
|
|
if(actions && UI::Actions::World) {
|
|
|
|
world.setOptions(options.world);
|
|
|
|
}
|
2020-07-10 19:37:49 +00:00
|
|
|
if(actions && UI::Actions::Camera) {
|
|
|
|
camera.setOptions(options.camera);
|
|
|
|
}
|
2020-07-18 15:42:45 +00:00
|
|
|
if(actions && UI::Actions::ChangeContouring) {
|
|
|
|
state.contouring = NULL;
|
2020-07-22 20:55:13 +00:00
|
|
|
world.setContouring(contouring::load(options.contouring_idx, options.contouring_data));
|
|
|
|
state.contouring = world.getContouring();
|
2020-07-18 15:42:45 +00:00
|
|
|
}
|
2020-07-13 16:45:08 +00:00
|
|
|
renderer->SkyEnable = options.renderer.skybox;
|
2020-07-06 19:18:29 +00:00
|
|
|
}
|
|
|
|
{ // Rendering
|
2020-07-18 12:54:07 +00:00
|
|
|
rmt_ScopedCPUSample(Render, 0);
|
2020-07-06 19:18:29 +00:00
|
|
|
const double partTime = glfwGetTime();
|
2020-07-10 17:49:16 +00:00
|
|
|
auto pass = renderer->getPass();
|
|
|
|
pass.start();
|
2020-07-06 19:18:29 +00:00
|
|
|
|
2020-07-25 16:45:03 +00:00
|
|
|
std::vector<std::pair<glm::mat4, buffer::Abstract *const>> models;
|
|
|
|
std::optional<geometry::Frustum> frustum;
|
2020-07-10 19:37:49 +00:00
|
|
|
if(options.culling) {
|
2020-07-24 19:42:47 +00:00
|
|
|
frustum = {camera.getFrustum()};
|
2020-07-10 19:37:49 +00:00
|
|
|
}
|
2020-07-24 19:42:47 +00:00
|
|
|
world.getContouring()->getModels(models, frustum, options.voxel_size);
|
2020-07-06 19:18:29 +00:00
|
|
|
reports.main.models_count = 0;
|
2020-07-10 17:49:16 +00:00
|
|
|
reports.main.tris_count = 0;
|
2020-07-18 12:54:07 +00:00
|
|
|
rmt_ScopedOpenGLSample(Render);
|
2020-07-10 17:49:16 +00:00
|
|
|
for (auto [model, buffer] : models) {
|
|
|
|
reports.main.models_count++;
|
|
|
|
reports.main.tris_count += buffer->draw(pass.setup(model));
|
|
|
|
}
|
2020-07-25 14:29:05 +00:00
|
|
|
if(state.look_at.has_value()) {
|
|
|
|
lookProgram->useIt();
|
|
|
|
lookProgram->start(renderer);
|
|
|
|
const auto model = glm::scale(glm::translate(glm::scale(glm::mat4(1), glm::vec3(options.voxel_size)), glm::vec3(state.look_at.value().first) - glm::vec3(.5 + options.tool.radius)), glm::vec3(1 + options.tool.radius * 2));
|
|
|
|
lookBuffer.draw(lookProgram->setup(renderer, model));
|
|
|
|
}
|
2020-07-13 16:45:08 +00:00
|
|
|
renderer->postProcess();
|
2020-07-06 19:18:29 +00:00
|
|
|
|
|
|
|
UI::render();
|
|
|
|
reports.main.render.push((glfwGetTime() - partTime) * 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Swap buffers
|
2020-07-18 12:54:07 +00:00
|
|
|
rmt_ScopedCPUSample(Swap, 0);
|
|
|
|
rmt_ScopedOpenGLSample(Swap);
|
2020-07-06 19:18:29 +00:00
|
|
|
const double partTime = glfwGetTime();
|
|
|
|
glfwSwapBuffers(window);
|
|
|
|
glfwPollEvents();
|
|
|
|
reports.main.swap.push((glfwGetTime() - partTime) * 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Wait target fps
|
|
|
|
const double partTime = glfwGetTime();
|
|
|
|
if(options.target_fps >= MIN_FPS && options.target_fps <= MAX_FPS) {
|
|
|
|
while (glfwGetTime() < startTime + 1.0 / options.target_fps) {
|
|
|
|
std::this_thread::sleep_for(std::chrono::microseconds(100));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
reports.main.wait.push((glfwGetTime() - partTime) * 1000);
|
|
|
|
}
|
|
|
|
reports.main.fps.push(1.0 / (glfwGetTime() - startTime));
|
|
|
|
} // Check if the ESC key was pressed or the window was closed
|
|
|
|
while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
|
|
|
|
glfwWindowShouldClose(window) == 0);
|
|
|
|
|
|
|
|
UI::unload();
|
2020-07-10 17:49:16 +00:00
|
|
|
delete renderer;
|
2020-07-06 19:18:29 +00:00
|
|
|
|
2020-07-18 12:54:07 +00:00
|
|
|
rmt_UnbindOpenGL();
|
|
|
|
rmt_DestroyGlobalInstance(rmt);
|
|
|
|
|
2020-07-06 19:18:29 +00:00
|
|
|
// Close OpenGL window and terminate GLFW
|
|
|
|
glfwTerminate();
|
|
|
|
|
2020-07-22 20:55:13 +00:00
|
|
|
contouring::save(options.contouring_idx, state.contouring, options.contouring_data);
|
2020-07-12 13:46:51 +00:00
|
|
|
options.save();
|
|
|
|
|
2020-07-06 19:18:29 +00:00
|
|
|
return 0;
|
|
|
|
}
|