Frustum & Fog
This commit is contained in:
parent
77d10611ae
commit
91e8c1a619
3
TODO.md
3
TODO.md
|
@ -13,6 +13,7 @@
|
|||
- [x] Render triangle
|
||||
- [x] Avoid texture noise
|
||||
- [x] MipMap LOD
|
||||
- [x] Fog
|
||||
- [ ] SRGB
|
||||
- [ ] Skybox
|
||||
- [ ] Better cheap planar
|
||||
|
@ -24,5 +25,5 @@
|
|||
- [ ] Dual MC
|
||||
- [ ] Collision
|
||||
- [ ] Render with glBufferSubData
|
||||
- [ ] Frustum Culling
|
||||
- [x] Frustum Culling
|
||||
- [ ] Occlusion Culling
|
|
@ -8,6 +8,7 @@ uniform sampler2DArray NormalAtlas;
|
|||
uniform sampler2DArray HOSAtlas;
|
||||
|
||||
uniform mat4 View;
|
||||
uniform vec3 FogColor;
|
||||
|
||||
in VertexData {
|
||||
vec3 Position_worldspace;
|
||||
|
@ -18,6 +19,9 @@ in VertexData {
|
|||
vec3 EyeDirection_cameraspace;
|
||||
vec3 LightDirection_cameraspace;
|
||||
#endif
|
||||
#ifdef FOG
|
||||
float Depth;
|
||||
#endif
|
||||
} vs;
|
||||
|
||||
vec3 expand(vec3 v) {
|
||||
|
@ -140,4 +144,8 @@ void main() {
|
|||
#else
|
||||
color = tex;
|
||||
#endif
|
||||
#if FOG
|
||||
float ratio = exp(vs.Depth * 0.69)-1;
|
||||
color = mix(color, FogColor, clamp(ratio, 0, 1));
|
||||
#endif
|
||||
}
|
|
@ -13,6 +13,9 @@ out VertexData {
|
|||
vec3 EyeDirection_cameraspace;
|
||||
vec3 LightDirection_cameraspace;
|
||||
#endif
|
||||
#ifdef FOG
|
||||
float Depth;
|
||||
#endif
|
||||
} vs;
|
||||
|
||||
uniform mat4 MVP;
|
||||
|
@ -20,10 +23,15 @@ uniform mat4 Model;
|
|||
uniform mat4 View;
|
||||
|
||||
uniform vec3 LightInvDirection_worldspace;
|
||||
uniform float FogDepth;
|
||||
|
||||
void main(){
|
||||
gl_Position = MVP * vec4(Position_modelspace, 1);
|
||||
vs.Position_worldspace = Position_modelspace;
|
||||
vs.Position_worldspace = (Model * vec4(Position_modelspace,1)).xyz;
|
||||
|
||||
#ifdef FOG
|
||||
vs.Depth = length((View * vec4(vs.Position_worldspace,1)).xyz) / FogDepth;
|
||||
#endif
|
||||
|
||||
vs.Material = float(Material_model);
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include "../render/window.hpp"
|
||||
|
||||
Camera::Camera(GLFWwindow *window, const InputMap& inputs): window(window), inputs(inputs) {
|
||||
Camera::Camera(GLFWwindow *window, const InputMap& inputs, const Camera::options& opt): window(window), inputs(inputs), o(opt) {
|
||||
updateProjection();
|
||||
}
|
||||
Camera::~Camera() { }
|
||||
|
||||
void Camera::updateProjection() {
|
||||
ProjectionMatrix = glm::perspective(FoV, RATIO, Near, Far);
|
||||
ProjectionMatrix = glm::perspective(o.fov, RATIO, o.near, o.far);
|
||||
}
|
||||
|
||||
void Camera::update(bool captureMouse, bool captureKeys) {
|
||||
|
@ -29,8 +29,8 @@ void Camera::update(bool captureMouse, bool captureKeys) {
|
|||
glfwGetCursorPos(window, &xPos, &yPos);
|
||||
|
||||
// Compute new orientation
|
||||
HorizontalAngle += Sensibility * 0.0001f * float(viewportX / 2 - xPos);
|
||||
VerticalAngle += Sensibility * 0.0001f * float(viewportY / 2 - yPos);
|
||||
HorizontalAngle += o.sensibility * 0.0001f * float(viewportX / 2 - xPos);
|
||||
VerticalAngle += o.sensibility * 0.0001f * float(viewportY / 2 - yPos);
|
||||
} else {
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
capturingMouse = true;
|
||||
|
@ -57,27 +57,27 @@ void Camera::update(bool captureMouse, bool captureKeys) {
|
|||
if(captureKeys) {
|
||||
// Move forward
|
||||
if (inputs.isDown(Input::Forward)) {
|
||||
Position += direction * deltaTime * Speed;
|
||||
Position += direction * deltaTime * o.speed;
|
||||
}
|
||||
// Move backward
|
||||
if (inputs.isDown(Input::Backward)) {
|
||||
Position -= direction * deltaTime * Speed;
|
||||
Position -= direction * deltaTime * o.speed;
|
||||
}
|
||||
// Strafe right
|
||||
if (inputs.isDown(Input::Right)) {
|
||||
Position += right * deltaTime * Speed;
|
||||
Position += right * deltaTime * o.speed;
|
||||
}
|
||||
// Strafe left
|
||||
if (inputs.isDown(Input::Left)) {
|
||||
Position -= right * deltaTime * Speed;
|
||||
Position -= right * deltaTime * o.speed;
|
||||
}
|
||||
// Move up
|
||||
if (inputs.isDown(Input::Up)) {
|
||||
Position += up * deltaTime * Speed;
|
||||
Position += up * deltaTime * o.speed;
|
||||
}
|
||||
// Move down
|
||||
if (inputs.isDown(Input::Down)) {
|
||||
Position -= up * deltaTime * Speed;
|
||||
Position -= up * deltaTime * o.speed;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,11 +5,21 @@
|
|||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "../data/glm.hpp"
|
||||
#include "../data/geometry/Frustum.hpp"
|
||||
|
||||
/// Moving perspective camera
|
||||
class Camera {
|
||||
public:
|
||||
Camera(GLFWwindow*, const InputMap&);
|
||||
struct options {
|
||||
float fov = glm::radians(70.f);
|
||||
float near = 0.1;
|
||||
float far = 64;
|
||||
|
||||
float speed = 5.0f;
|
||||
int sensibility = 50;
|
||||
};
|
||||
|
||||
Camera(GLFWwindow*, const InputMap&, const options&);
|
||||
Camera(Camera &&) = default;
|
||||
Camera(const Camera &) = default;
|
||||
Camera &operator=(Camera &&) = default;
|
||||
|
@ -17,20 +27,18 @@ public:
|
|||
~Camera();
|
||||
|
||||
void update(bool captureMouse, bool captureKeys);
|
||||
void updateProjection();
|
||||
void setOptions(const options &options) {
|
||||
o = options;
|
||||
updateProjection();
|
||||
}
|
||||
|
||||
glm::vec3 getDirection() const { return glm::vec3(cos(VerticalAngle) * sin(HorizontalAngle), sin(VerticalAngle), cos(VerticalAngle) * cos(HorizontalAngle)); }
|
||||
inline Frustum getFrustum() const { return Frustum(ViewMatrix, ProjectionMatrix); }
|
||||
|
||||
glm::mat4 getViewMatrix() const { return ViewMatrix; }
|
||||
glm::mat4 getProjectionMatrix() const { return ProjectionMatrix; }
|
||||
camera_pos getPosition() const { return Position; }
|
||||
|
||||
float FoV = glm::radians(70.f);
|
||||
float Near = 0.1;
|
||||
float Far = 64;
|
||||
|
||||
float Speed = 5.0f;
|
||||
int Sensibility = 50;
|
||||
float getDepth() const { return o.far; }
|
||||
|
||||
private:
|
||||
GLFWwindow *window;
|
||||
|
@ -38,6 +46,7 @@ private:
|
|||
|
||||
glm::mat4 ViewMatrix;
|
||||
glm::mat4 ProjectionMatrix;
|
||||
void updateProjection();
|
||||
|
||||
camera_pos Position = glm::vec3(0, 0, 5);
|
||||
|
||||
|
@ -45,4 +54,5 @@ private:
|
|||
float VerticalAngle = 0.0f;
|
||||
|
||||
bool capturingMouse = false;
|
||||
options o;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <iostream>
|
||||
|
||||
/// Axis Aligned Floating Box
|
||||
struct Box {
|
||||
enum class ContainmentType {
|
||||
Disjoint = false, Intersects, Contains
|
||||
};
|
||||
|
||||
Box(glm::vec3 min, glm::vec3 max): Min(min), Max(max) {
|
||||
assert(("Min > Max", max.x >= min.x && max.y >= min.y && max.z >= min.z));
|
||||
}
|
||||
inline static Box fromCenter(glm::vec3 center, float radius) { return Box(center - radius, center + radius); }
|
||||
inline static Box fromMin(glm::vec3 min, glm::vec3 size) { return Box(min, min + size); }
|
||||
|
||||
glm::vec3 Min;
|
||||
glm::vec3 Max;
|
||||
|
||||
ContainmentType contains(const Box& box) const {
|
||||
//test if all corner is in the same side of a face by just checking min and max
|
||||
if (box.Max.x < Min.x
|
||||
|| box.Min.x > Max.x
|
||||
|| box.Max.y < Min.y
|
||||
|| box.Min.y > Max.y
|
||||
|| box.Max.z < Min.z
|
||||
|| box.Min.z > Max.z)
|
||||
return ContainmentType::Disjoint;
|
||||
|
||||
|
||||
if (box.Min.x >= Min.x
|
||||
&& box.Max.x <= Max.x
|
||||
&& box.Min.y >= Min.y
|
||||
&& box.Max.y <= Max.y
|
||||
&& box.Min.z >= Min.z
|
||||
&& box.Max.z <= Max.z)
|
||||
return ContainmentType::Contains;
|
||||
|
||||
return ContainmentType::Intersects;
|
||||
}
|
||||
};
|
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#include "Box.hpp"
|
||||
|
||||
/// Bounding frustum
|
||||
struct Frustum {
|
||||
glm::vec4 planes[6];
|
||||
|
||||
enum FrustumSide
|
||||
{
|
||||
RIGHT = 0, // The RIGHT side of the frustum
|
||||
LEFT = 1, // The LEFT side of the frustum
|
||||
BOTTOM = 2, // The BOTTOM side of the frustum
|
||||
TOP = 3, // The TOP side of the frustum
|
||||
BACK = 4, // The BACK side of the frustum
|
||||
FRONT = 5 // The FRONT side of the frustum
|
||||
};
|
||||
|
||||
void normalize(glm::vec4 &plane) {
|
||||
plane /= (float)sqrt(plane.x * plane.x + plane.y * plane.y + plane.z * plane.z);
|
||||
}
|
||||
|
||||
Frustum(const glm::mat4& view_matrix, const glm::mat4& proj_matrix) {
|
||||
const float *proj = &proj_matrix[0][0];
|
||||
const float *modl = &view_matrix[0][0];
|
||||
float clip[16]; //clipping planes
|
||||
|
||||
clip[0] = modl[0] * proj[0] + modl[1] * proj[4] + modl[2] * proj[8] + modl[3] * proj[12];
|
||||
clip[1] = modl[0] * proj[1] + modl[1] * proj[5] + modl[2] * proj[9] + modl[3] * proj[13];
|
||||
clip[2] = modl[0] * proj[2] + modl[1] * proj[6] + modl[2] * proj[10] + modl[3] * proj[14];
|
||||
clip[3] = modl[0] * proj[3] + modl[1] * proj[7] + modl[2] * proj[11] + modl[3] * proj[15];
|
||||
|
||||
clip[4] = modl[4] * proj[0] + modl[5] * proj[4] + modl[6] * proj[8] + modl[7] * proj[12];
|
||||
clip[5] = modl[4] * proj[1] + modl[5] * proj[5] + modl[6] * proj[9] + modl[7] * proj[13];
|
||||
clip[6] = modl[4] * proj[2] + modl[5] * proj[6] + modl[6] * proj[10] + modl[7] * proj[14];
|
||||
clip[7] = modl[4] * proj[3] + modl[5] * proj[7] + modl[6] * proj[11] + modl[7] * proj[15];
|
||||
|
||||
clip[8] = modl[8] * proj[0] + modl[9] * proj[4] + modl[10] * proj[8] + modl[11] * proj[12];
|
||||
clip[9] = modl[8] * proj[1] + modl[9] * proj[5] + modl[10] * proj[9] + modl[11] * proj[13];
|
||||
clip[10] = modl[8] * proj[2] + modl[9] * proj[6] + modl[10] * proj[10] + modl[11] * proj[14];
|
||||
clip[11] = modl[8] * proj[3] + modl[9] * proj[7] + modl[10] * proj[11] + modl[11] * proj[15];
|
||||
|
||||
clip[12] = modl[12] * proj[0] + modl[13] * proj[4] + modl[14] * proj[8] + modl[15] * proj[12];
|
||||
clip[13] = modl[12] * proj[1] + modl[13] * proj[5] + modl[14] * proj[9] + modl[15] * proj[13];
|
||||
clip[14] = modl[12] * proj[2] + modl[13] * proj[6] + modl[14] * proj[10] + modl[15] * proj[14];
|
||||
clip[15] = modl[12] * proj[3] + modl[13] * proj[7] + modl[14] * proj[11] + modl[15] * proj[15];
|
||||
|
||||
planes[RIGHT] = glm::vec4(clip[3] - clip[0], clip[7] - clip[4], clip[11] - clip[8], clip[15] - clip[12]);
|
||||
normalize(planes[RIGHT]);
|
||||
|
||||
planes[LEFT] = glm::vec4(clip[3] + clip[0], clip[7] + clip[4], clip[11] + clip[8], clip[15] + clip[12]);
|
||||
normalize(planes[LEFT]);
|
||||
|
||||
planes[BOTTOM] = glm::vec4(clip[3] + clip[1], clip[7] + clip[5], clip[11] + clip[9], clip[15] + clip[13]);
|
||||
normalize(planes[BOTTOM]);
|
||||
|
||||
planes[TOP] = glm::vec4(clip[3] - clip[1], clip[7] - clip[5], clip[11] - clip[9], clip[15] - clip[13]);
|
||||
normalize(planes[TOP]);
|
||||
|
||||
planes[BACK] = glm::vec4(clip[3] - clip[2], clip[7] - clip[6], clip[11] - clip[10], clip[15] - clip[14]);
|
||||
normalize(planes[BACK]);
|
||||
|
||||
planes[FRONT] = glm::vec4(clip[3] + clip[2], clip[7] + clip[6], clip[11] + clip[10], clip[15] + clip[14]);
|
||||
normalize(planes[FRONT]);
|
||||
}
|
||||
|
||||
/// Check if box is contained
|
||||
inline bool contains(const Box &box) const {
|
||||
bool inside = true;
|
||||
//test all 6 frustum planes
|
||||
for (int i = 0; i<6; i++) {
|
||||
//pick closest point to plane and check if it behind the plane
|
||||
//if yes - object outside frustum
|
||||
float d = std::max(box.Min.x * planes[i].x, box.Max.x * planes[i].x)
|
||||
+ std::max(box.Min.y * planes[i].y, box.Max.y * planes[i].y)
|
||||
+ std::max(box.Min.z * planes[i].z, box.Max.z * planes[i].z)
|
||||
+ planes[i].w;
|
||||
inside &= d > 0;
|
||||
//return false; //with flag works faster
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
};
|
|
@ -10,6 +10,7 @@
|
|||
#include "circular_buffer.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../world/World.hpp"
|
||||
#include "../control/Camera.hpp"
|
||||
|
||||
/// Savable game options
|
||||
struct options {
|
||||
|
@ -25,12 +26,13 @@ struct options {
|
|||
|
||||
bool show_debug_world = false;
|
||||
World::options world;
|
||||
float voxelSize = 1;
|
||||
float voxel_size = 1;
|
||||
|
||||
bool show_debug_contouring = false;
|
||||
int contouring_idx = 0;
|
||||
|
||||
bool show_debug_controls = false;
|
||||
Camera::options camera;
|
||||
|
||||
bool show_overlay = true;
|
||||
int overlay_corner = 0;
|
||||
|
@ -42,7 +44,8 @@ struct options {
|
|||
/// Live state
|
||||
struct state {
|
||||
bool capture_mouse = true;
|
||||
//std::optional<std::pair<voxel_pos, Voxel>> look_at = {};
|
||||
camera_pos position;
|
||||
std::optional<std::pair<voxel_pos, Voxel>> look_at = {};
|
||||
|
||||
char console_buffer[256];
|
||||
};
|
||||
|
|
16
src/main.cpp
16
src/main.cpp
|
@ -37,14 +37,13 @@ int main(int, char *[]){
|
|||
glfwSwapInterval(options.target_fps < MIN_FPS);
|
||||
|
||||
InputMap inputs(window);
|
||||
Camera camera(window, inputs);
|
||||
Camera camera(window, inputs, options.camera);
|
||||
|
||||
Renderer *renderer = new Renderer(options.renderer);
|
||||
UI::setup(window);
|
||||
|
||||
GLuint aimTexture = Program::loadTexture("ui/Aim", false);
|
||||
|
||||
const auto model = glm::scale(glm::mat4(1), glm::vec3(2));
|
||||
renderer->LightInvDir = glm::vec3(-0.5f, 2, -2);
|
||||
|
||||
World world = World(options.world);
|
||||
|
@ -59,6 +58,7 @@ int main(int, char *[]){
|
|||
camera.update(state.capture_mouse, !UI::isFocus());
|
||||
renderer->lookFrom(camera);
|
||||
|
||||
state.position = camera.getPosition();
|
||||
/*look_at = world.raycast(camera.getViewRay() / scale);
|
||||
if (capture_mouse && look_at.has_value()) {
|
||||
if (inputs.isPressing(Mouse::Left))
|
||||
|
@ -66,7 +66,7 @@ int main(int, char *[]){
|
|||
else if (inputs.isPressing(Mouse::Right))
|
||||
world.setCube(look_at.value().first, 2, Voxel{2, 1});
|
||||
}*/
|
||||
world.update(camera.getPosition() / options.voxelSize, reports.world);
|
||||
world.update(state.position / options.voxel_size, reports.world);
|
||||
inputs.saveKeys();
|
||||
reports.main.update.push((glfwGetTime() - partTime) * 1000);
|
||||
}
|
||||
|
@ -95,9 +95,13 @@ int main(int, char *[]){
|
|||
if(actions && UI::Actions::RendererTextures) {
|
||||
renderer->reloadTextures(options.renderer.textures, options.renderer.mipMapLOD);
|
||||
}
|
||||
renderer->FogColor = glm::vec3(options.clear_color.x, options.clear_color.y, options.clear_color.z);
|
||||
if(actions && UI::Actions::World) {
|
||||
world.setOptions(options.world);
|
||||
}
|
||||
if(actions && UI::Actions::Camera) {
|
||||
camera.setOptions(options.camera);
|
||||
}
|
||||
}
|
||||
{ // Rendering
|
||||
const double partTime = glfwGetTime();
|
||||
|
@ -105,7 +109,11 @@ int main(int, char *[]){
|
|||
pass.start();
|
||||
|
||||
std::vector<std::pair<glm::mat4, Buffer *>> models;
|
||||
world.getModels(models, options.voxelSize);
|
||||
if(options.culling) {
|
||||
world.getModels(models, options.voxel_size, camera.getFrustum());
|
||||
} else {
|
||||
world.getModels(models, options.voxel_size);
|
||||
}
|
||||
reports.main.models_count = 0;
|
||||
reports.main.tris_count = 0;
|
||||
for (auto [model, buffer] : models) {
|
||||
|
|
|
@ -49,4 +49,5 @@ void Renderer::loadTextures(const std::string& texturePath, float mipMapLOD) {
|
|||
void Renderer::lookFrom(const Camera& camera) {
|
||||
ProjectionMatrix = camera.getProjectionMatrix();
|
||||
ViewMatrix = camera.getViewMatrix();
|
||||
FogDepth = camera.getDepth();
|
||||
}
|
|
@ -23,6 +23,8 @@ public:
|
|||
~Renderer();
|
||||
|
||||
glm::vec3 LightInvDir = glm::vec3(0.5f, 2, 2);
|
||||
glm::vec3 FogColor;
|
||||
GLfloat FogDepth;
|
||||
|
||||
glm::mat4 getProjectionMatrix() const {
|
||||
return ProjectionMatrix;
|
||||
|
|
|
@ -68,6 +68,8 @@ UI::Actions UI::draw(options &options, state &state, const reports &reports, GLu
|
|||
changeRenderer |= ImGui::Checkbox("PBR", &options.renderer.main.pbr);
|
||||
ImGui::SameLine();
|
||||
changeRenderer |= ImGui::Checkbox("Triplanar", &options.renderer.main.triplanar);
|
||||
ImGui::SameLine();
|
||||
changeRenderer |= ImGui::Checkbox("Fog", &options.renderer.main.fog);
|
||||
if (changeRenderer) {
|
||||
actions = actions | Actions::RendererSharders;
|
||||
}
|
||||
|
@ -91,7 +93,13 @@ UI::Actions UI::draw(options &options, state &state, const reports &reports, GLu
|
|||
if (ImGui::SliderInt("Load distance", &options.world.loadDistance, 1, options.world.keepDistance) |
|
||||
ImGui::SliderInt("Keep distance", &options.world.keepDistance, options.world.loadDistance + 1, 21)) {
|
||||
actions = actions | Actions::World;
|
||||
const auto far = std::clamp(options.camera.far, (options.world.loadDistance - 1.5f) * CHUNK_LENGTH * options.voxel_size, (options.world.keepDistance + .5f) * CHUNK_LENGTH * options.voxel_size);
|
||||
if(far != options.camera.far) {
|
||||
options.camera.far = far;
|
||||
actions = actions | Actions::Camera;
|
||||
}
|
||||
}
|
||||
ImGui::SliderFloat("Voxel size", &options.voxel_size, .1, 2);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
@ -106,29 +114,29 @@ UI::Actions UI::draw(options &options, state &state, const reports &reports, GLu
|
|||
ImGui::End();
|
||||
}*/
|
||||
|
||||
/*if (options.show_debug_controls) {
|
||||
if (options.show_debug_controls) {
|
||||
ImGui::Begin("Debug: Controls", &options.show_debug_controls, ImGuiWindowFlags_AlwaysAutoResize);
|
||||
ImGui::Text("Position: (%.3f, %.3f, %.3f)", camera.getPosition().x, camera.getPosition().y, camera.getPosition().z);
|
||||
if (look_at.has_value()) {
|
||||
ImGui::Text("Look at: (%d, %d, %d) (%d, %.1f)", look_at.value().first.x, look_at.value().first.y, look_at.value().first.z, look_at.value().second.Material, look_at.value().second.Density); // TODO: printf array
|
||||
ImGui::Text("(%.3f, %.3f, %.3f)", look_at.value().first.x * scale, look_at.value().first.y * scale, look_at.value().first.z * scale); // TODO: printf array
|
||||
ImGui::Text("Position: (%.3f, %.3f, %.3f)", state.position.x, state.position.y, state.position.z);
|
||||
if (state.look_at.has_value()) {
|
||||
ImGui::Text("Look at: (%lld, %lld, %lld) (%d, %.1f)", state.look_at.value().first.x, state.look_at.value().first.y, state.look_at.value().first.z, state.look_at.value().second.Material, state.look_at.value().second.Density / UCHAR_MAX);
|
||||
ImGui::Text("(%.3f, %.3f, %.3f)", state.look_at.value().first.x * options.voxel_size, state.look_at.value().first.y * options.voxel_size, state.look_at.value().first.z * options.voxel_size);
|
||||
} else {
|
||||
ImGui::Text("Look at: none");
|
||||
}
|
||||
ImGui::Separator();
|
||||
{
|
||||
bool changePerspective = false;
|
||||
changePerspective |= ImGui::SliderAngle("FoV", &camera.FoV, 30, 110);
|
||||
changePerspective |= ImGui::SliderFloat("Near", &camera.Near, 0.01, 10);
|
||||
changePerspective |= ImGui::SliderFloat("Far", &camera.Far, (world.getContouring()->getViewDistance() - 1.5) * CHUNK_LENGTH * scale, (world.getContouring()->getViewDistance() + .5) * CHUNK_LENGTH * scale);
|
||||
changePerspective |= ImGui::SliderAngle("FoV", &options.camera.fov, 30, 110);
|
||||
changePerspective |= ImGui::SliderFloat("Near", &options.camera.near, 0.01, 10);
|
||||
changePerspective |= ImGui::SliderFloat("Far", &options.camera.far, (options.world.loadDistance - 1.5) * CHUNK_LENGTH * options.voxel_size, (options.world.keepDistance + .5) * CHUNK_LENGTH * options.voxel_size);
|
||||
changePerspective |= ImGui::SliderFloat("Move speed", &options.camera.speed, 0.1, 50);
|
||||
changePerspective |= ImGui::SliderInt("Sensibility", &options.camera.sensibility, 1, 100, "%d%%");
|
||||
if(changePerspective) {
|
||||
camera.updateProjection();
|
||||
actions = actions | Actions::Camera;
|
||||
}
|
||||
}
|
||||
ImGui::SliderFloat("Move speed", &camera.Speed, 0.1, 50);
|
||||
ImGui::SliderInt("Sensibility", &camera.Sensibility, 1, 100, "%d%%");
|
||||
ImGui::End();
|
||||
}*/
|
||||
}
|
||||
|
||||
/*if (show_console) {
|
||||
ImGui::SetNextWindowPos(ImVec2(UI_MARGIN, 500), ImGuiCond_FirstUseEver);
|
||||
|
@ -189,7 +197,7 @@ UI::Actions UI::draw(options &options, state &state, const reports &reports, GLu
|
|||
ImGui::End();
|
||||
}
|
||||
ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x / 2, io.DisplaySize.y / 2), ImGuiCond_Always, ImVec2(.5f, .5f));
|
||||
ImGui::Begin("Aim", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoBackground);
|
||||
ImGui::Begin("Aim", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoInputs);
|
||||
ImGui::Image((void *)(intptr_t)aim, ImVec2(32, 32));
|
||||
ImGui::Render();
|
||||
return actions;
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace UI {
|
|||
RendererSharders = 1 << 3,
|
||||
RendererTextures = 1 << 4,
|
||||
World = 1 << 5,
|
||||
Camera = 1 << 6,
|
||||
};
|
||||
inline Actions operator|(Actions a, Actions b) {
|
||||
return static_cast<Actions>(static_cast<int>(a) | static_cast<int>(b));
|
||||
|
|
|
@ -9,6 +9,8 @@ MainProgram::MainProgram(const MainProgram::options& opts): Program() {
|
|||
flags.push_back("PBR");
|
||||
if(opts.triplanar)
|
||||
flags.push_back("TRIPLANAR");
|
||||
if (opts.fog)
|
||||
flags.push_back("FOG");
|
||||
|
||||
std::vector<Shader*> shaders;
|
||||
shaders.push_back(loadShader(GL_VERTEX_SHADER, flags));
|
||||
|
@ -24,6 +26,9 @@ MainProgram::MainProgram(const MainProgram::options& opts): Program() {
|
|||
HOSID = glGetUniformLocation(ProgramID, "HOSAtlas");
|
||||
|
||||
LightInvDirID = glGetUniformLocation(ProgramID, "LightInvDirection_worldspace");
|
||||
|
||||
FogDepthID = glGetUniformLocation(ProgramID, "FogDepth");
|
||||
FogColorID = glGetUniformLocation(ProgramID, "FogColor");
|
||||
}
|
||||
|
||||
MainProgram::~MainProgram() { }
|
||||
|
@ -36,6 +41,7 @@ void MainProgram::start(Renderer *renderer) {
|
|||
bindNormal(renderer->getNormalAtlas());
|
||||
bindHOS(renderer->getHOSAtlas());
|
||||
setLightInvDir(&renderer->LightInvDir[0]);
|
||||
setFog(&renderer->FogColor[0], renderer->FogDepth);
|
||||
}
|
||||
Buffer::params MainProgram::setup(Renderer *renderer, glm::mat4 modelMatrix) {
|
||||
setModel(&modelMatrix[0][0]);
|
||||
|
@ -73,4 +79,8 @@ void MainProgram::bindHOS(GLuint textureID) {
|
|||
|
||||
void MainProgram::setLightInvDir(const GLfloat *pos) {
|
||||
glUniform3fv(LightInvDirID, 1, pos);
|
||||
}
|
||||
void MainProgram::setFog(const GLfloat *color, const GLfloat depth) {
|
||||
glUniform3fv(FogColorID, 1, color);
|
||||
glUniform1f(FogDepthID, depth);
|
||||
}
|
|
@ -9,7 +9,7 @@ public:
|
|||
bool pbr = true;
|
||||
bool triplanar = false;
|
||||
//TODO: bool blend = false;
|
||||
//TODO: bool fog = true;
|
||||
bool fog = true;
|
||||
};
|
||||
|
||||
MainProgram(const options &opts);
|
||||
|
@ -28,6 +28,7 @@ public:
|
|||
void bindHOS(const GLuint textureID);
|
||||
|
||||
void setLightInvDir(const GLfloat *pos);
|
||||
void setFog(const GLfloat *color, GLfloat depth);
|
||||
|
||||
private:
|
||||
GLuint MVPMatrixID;
|
||||
|
@ -39,4 +40,6 @@ private:
|
|||
GLuint HOSID;
|
||||
|
||||
GLuint LightInvDirID;
|
||||
GLuint FogDepthID;
|
||||
GLuint FogColorID;
|
||||
};
|
||||
|
|
|
@ -64,7 +64,7 @@ void World::update(const camera_pos& pos, World::report& rep) {
|
|||
|
||||
rep.chunk_load.push(loadQueue.size());
|
||||
// Load chunks
|
||||
for (size_t i = 0; i < 2 && !loadQueue.empty(); i++) {
|
||||
for (size_t i = 0; i < 8 && !loadQueue.empty(); i++) {
|
||||
const auto pos = loadQueue.pop();
|
||||
const auto chunk = std::make_shared<Chunk>(pos, generator);
|
||||
chunks.insert({pos, chunk});
|
||||
|
@ -83,3 +83,10 @@ void World::getModels(std::vector<std::pair<glm::mat4, Buffer*>> &out, float sca
|
|||
out.push_back({glm::translate(scaling, glm::vec3(pos) * glm::vec3(CHUNK_LENGTH)), chunk->buffer});
|
||||
}
|
||||
}
|
||||
void World::getModels(std::vector<std::pair<glm::mat4, Buffer*>> &out, float scale, const Frustum& frustum) const {
|
||||
const auto scaling = glm::scale(glm::mat4(1), glm::vec3(scale));
|
||||
for(const auto [pos, chunk]: chunks) {
|
||||
if(chunk->buffer != NULL && frustum.contains(Box::fromMin(scale * glm::vec3(pos) * glm::vec3(CHUNK_LENGTH), scale * glm::vec3(CHUNK_LENGTH))))
|
||||
out.push_back({glm::translate(scaling, glm::vec3(pos) * glm::vec3(CHUNK_LENGTH)), chunk->buffer});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <memory>
|
||||
#include "../data/unique_queue.hpp"
|
||||
#include "../data/circular_buffer.hpp"
|
||||
#include "../data/geometry/Frustum.hpp"
|
||||
#include "Chunk.hpp"
|
||||
#define REPORT_BUFFER_SIZE 128
|
||||
|
||||
|
@ -32,6 +33,7 @@ public:
|
|||
return {it->second};
|
||||
}
|
||||
void getModels(std::vector<std::pair<glm::mat4, Buffer*>> &models, float scale) const;
|
||||
void getModels(std::vector<std::pair<glm::mat4, Buffer*>> &models, float scale, const Frustum& frustum) const;
|
||||
|
||||
private:
|
||||
chunk_pos last_pos = chunk_pos(INT_MAX);
|
||||
|
|
Loading…
Reference in New Issue