2024-08-10 19:12:21 -04:00
|
|
|
#include <GL/glew.h>
|
|
|
|
#include <GLFW/glfw3.h>
|
|
|
|
|
2024-08-12 21:40:28 -04:00
|
|
|
#define GLM_ENABLE_EXPERIMENTAL
|
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
|
|
#include <glm/gtx/transform.hpp>
|
|
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
|
|
|
2024-08-11 21:20:17 -04:00
|
|
|
#include <imgui.h>
|
|
|
|
#include <imgui_impl_glfw.h>
|
|
|
|
#include <imgui_impl_opengl3.h>
|
|
|
|
|
2024-08-10 19:12:21 -04:00
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
2024-08-15 00:56:29 -04:00
|
|
|
#include <vector>
|
|
|
|
#include <cstdint>
|
|
|
|
#include <algorithm>
|
2024-08-10 19:12:21 -04:00
|
|
|
|
2024-08-12 17:20:14 -04:00
|
|
|
#include "scene.h"
|
2024-08-12 21:40:28 -04:00
|
|
|
#include "Uniforms.h"
|
|
|
|
#include "InitShader.h" //Functions for loading shaders from text files
|
|
|
|
#include "DebugCallback.h"
|
2024-08-12 21:55:08 -04:00
|
|
|
#include "PlatformUtils.h"
|
2024-08-12 21:40:28 -04:00
|
|
|
|
2024-08-13 16:25:56 -04:00
|
|
|
namespace {
|
2024-08-12 21:40:28 -04:00
|
|
|
|
2024-08-13 16:25:56 -04:00
|
|
|
const std::string kVertexShaderPath = "shaders/vertex.glsl";
|
2024-08-14 18:04:06 -04:00
|
|
|
const std::string kTessellationCtrlPath = "shaders/tessellation_ctrl.glsl";
|
|
|
|
const std::string kTessellationEvalPath = "shaders/tessellation_eval.glsl";
|
2024-08-13 16:25:56 -04:00
|
|
|
const std::string kFragmentShaderPath = "shaders/fragment.glsl";
|
2024-08-12 21:40:28 -04:00
|
|
|
|
2024-08-14 02:16:53 -04:00
|
|
|
const std::string kQuadVertexPath = "shaders/quad_vertex.glsl";
|
|
|
|
const std::string kQuadFragmentPath = "shaders/quad_fragment.glsl";
|
|
|
|
|
2024-08-15 01:09:37 -04:00
|
|
|
const std::string kHGTPath = "hgt/N02E016.hgt";
|
2024-08-15 00:56:29 -04:00
|
|
|
|
|
|
|
GLuint tex_id = -1;
|
|
|
|
|
2024-08-17 19:40:42 -04:00
|
|
|
float tessellationFactor = 32.0f;
|
2024-08-17 19:05:05 -04:00
|
|
|
|
2024-08-17 12:25:42 -04:00
|
|
|
std::vector<Vertex> vertices;
|
|
|
|
std::vector<GLuint> indices;
|
|
|
|
|
2024-08-13 16:25:56 -04:00
|
|
|
} // namespace
|
2024-08-12 21:40:28 -04:00
|
|
|
|
2024-08-13 17:58:49 -04:00
|
|
|
Scene::Scene(int width, int height)
|
|
|
|
: window_width(width),
|
|
|
|
window_height(height),
|
2024-08-14 02:16:53 -04:00
|
|
|
shader_program_(-1),
|
|
|
|
quad_shader_program_(-1),
|
2024-08-13 17:58:49 -04:00
|
|
|
vao_(-1),
|
2024-08-14 02:16:53 -04:00
|
|
|
quad_vao_(-1),
|
2024-08-14 19:14:43 -04:00
|
|
|
angle_(-glm::pi<float>() / 2.0f),
|
2024-08-13 17:58:49 -04:00
|
|
|
scale_(1.0f),
|
2024-08-14 02:16:53 -04:00
|
|
|
aspect_(static_cast<float>(width) / static_cast<float>(height)),
|
2024-08-17 19:10:41 -04:00
|
|
|
near_z_(0.1f),
|
|
|
|
far_z_(10.0f),
|
2024-08-16 00:15:26 -04:00
|
|
|
fov_(glm::pi<float>() / 6.0f)
|
2024-08-13 17:58:49 -04:00
|
|
|
{}
|
2024-08-12 21:40:28 -04:00
|
|
|
|
2024-08-13 16:25:56 -04:00
|
|
|
Scene::~Scene() {
|
|
|
|
glDeleteProgram(shader_program_);
|
|
|
|
glDeleteVertexArrays(1, &vao_);
|
2024-08-13 17:47:16 -04:00
|
|
|
|
|
|
|
fbo_.~FBO();
|
2024-08-14 02:16:53 -04:00
|
|
|
post_fbo_.~FBO();
|
2024-08-13 16:25:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::Init() {
|
|
|
|
glewInit();
|
|
|
|
|
2024-08-14 18:04:06 -04:00
|
|
|
// GL_DEPTH_TEST causes artifacts in meshes made up of multiple triangles
|
|
|
|
// disabling for now
|
2024-08-17 19:10:41 -04:00
|
|
|
glEnable(GL_DEPTH_TEST);
|
2024-08-17 12:25:42 -04:00
|
|
|
glEnable(GL_CULL_FACE);
|
2024-08-13 16:25:56 -04:00
|
|
|
|
2024-08-13 17:47:16 -04:00
|
|
|
fbo_.Init(window_width, window_height);
|
2024-08-14 02:16:53 -04:00
|
|
|
post_fbo_.Init(window_width, window_height);
|
2024-08-13 17:47:16 -04:00
|
|
|
|
2024-08-15 00:56:29 -04:00
|
|
|
std::vector<int16_t> heightData = LoadHGT(kHGTPath, 3601, 3601);
|
|
|
|
tex_id = CreateHeightmapTexture(heightData, 3601, 3601);
|
|
|
|
|
2024-08-13 16:25:56 -04:00
|
|
|
InitBuffers();
|
|
|
|
ReloadShader();
|
2024-08-14 02:16:53 -04:00
|
|
|
InitQuadBuffers();
|
|
|
|
quad_shader_program_ = InitShader(kQuadVertexPath.c_str(), kQuadFragmentPath.c_str());
|
2024-08-13 16:25:56 -04:00
|
|
|
|
|
|
|
UpdateCamera();
|
|
|
|
Uniforms::Init();
|
|
|
|
}
|
|
|
|
|
2024-08-17 12:25:42 -04:00
|
|
|
void Scene::GenerateGrid(int divisions, std::vector<Vertex>& verts, std::vector<GLuint>& inds) {
|
|
|
|
float step = 1.0f / static_cast<float>(divisions);
|
|
|
|
float halfSize = 0.5f;
|
|
|
|
|
|
|
|
// Create vertices for patches
|
|
|
|
for (int i = 0; i <= divisions; i++) {
|
|
|
|
for (int j = 0; j <= divisions; j++) {
|
|
|
|
float x = -halfSize + j * step;
|
|
|
|
float y = -halfSize + i * step;
|
|
|
|
|
|
|
|
Vertex vertex;
|
|
|
|
vertex.position = glm::vec3(x, y, 0.0f);
|
|
|
|
vertex.texCoord = glm::vec2(static_cast<float>(j) / divisions, static_cast<float>(i) / divisions);
|
|
|
|
|
|
|
|
verts.push_back(vertex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create indices for patches
|
|
|
|
for (int i = 0; i < divisions; i++) {
|
|
|
|
for (int j = 0; j < divisions; j++) {
|
|
|
|
int bottomLeft = i * (divisions + 1) + j;
|
|
|
|
int bottomRight = bottomLeft + 1;
|
|
|
|
int topLeft = bottomLeft + (divisions + 1);
|
|
|
|
int topRight = topLeft + 1;
|
|
|
|
|
|
|
|
inds.push_back(topLeft);
|
|
|
|
inds.push_back(topRight);
|
|
|
|
inds.push_back(bottomRight);
|
|
|
|
inds.push_back(bottomLeft);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-13 17:47:16 -04:00
|
|
|
// Currently creates a test triangle and initializes its buffers
|
2024-08-13 16:25:56 -04:00
|
|
|
void Scene::InitBuffers() {
|
2024-08-17 19:10:41 -04:00
|
|
|
int divisions = 1 + (tessellationFactor / 64); // Number of divisions along one axis of the grid
|
2024-08-17 12:25:42 -04:00
|
|
|
GenerateGrid(divisions, vertices, indices);
|
2024-08-13 16:25:56 -04:00
|
|
|
|
2024-08-17 12:25:42 -04:00
|
|
|
// Create and bind VAO, VBO, and EBO, and pass the data to OpenGL
|
|
|
|
GLuint vao, vbo, ebo;
|
2024-08-13 16:25:56 -04:00
|
|
|
glGenVertexArrays(1, &vao_);
|
2024-08-17 12:25:42 -04:00
|
|
|
glGenBuffers(1, &vbo);
|
|
|
|
glGenBuffers(1, &ebo);
|
|
|
|
|
2024-08-13 16:25:56 -04:00
|
|
|
glBindVertexArray(vao_);
|
2024-08-14 18:04:06 -04:00
|
|
|
|
2024-08-17 12:25:42 -04:00
|
|
|
// Bind and fill the vertex buffer
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW);
|
|
|
|
|
|
|
|
// Bind and fill the element buffer
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
|
|
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW);
|
2024-08-14 18:04:06 -04:00
|
|
|
|
2024-08-17 12:25:42 -04:00
|
|
|
// Define vertex position attribute
|
|
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
|
2024-08-13 16:25:56 -04:00
|
|
|
glEnableVertexAttribArray(0);
|
2024-08-15 00:56:29 -04:00
|
|
|
|
2024-08-17 12:25:42 -04:00
|
|
|
// Define texture coordinate attribute
|
|
|
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texCoord));
|
2024-08-15 00:56:29 -04:00
|
|
|
glEnableVertexAttribArray(1);
|
2024-08-14 18:04:06 -04:00
|
|
|
|
2024-08-17 12:25:42 -04:00
|
|
|
// Unbind VAO
|
2024-08-14 18:04:06 -04:00
|
|
|
glBindVertexArray(0);
|
2024-08-13 16:25:56 -04:00
|
|
|
}
|
|
|
|
|
2024-08-14 02:16:53 -04:00
|
|
|
void Scene::InitQuadBuffers() {
|
|
|
|
GLuint quad_vbo;
|
|
|
|
// Full-screen quad vertices (position and texture coordinates)
|
|
|
|
float quadVertices[] = {
|
|
|
|
// positions // texCoords
|
|
|
|
-1.0f, 1.0f, 0.0f, 1.0f, // Top-left
|
|
|
|
-1.0f, -1.0f, 0.0f, 0.0f, // Bottom-left
|
|
|
|
1.0f, 1.0f, 1.0f, 1.0f, // Top-right
|
|
|
|
1.0f, -1.0f, 1.0f, 0.0f // Bottom-right
|
|
|
|
};
|
|
|
|
|
|
|
|
glGenVertexArrays(1, &quad_vao_);
|
|
|
|
glGenBuffers(1, &quad_vbo);
|
|
|
|
glBindVertexArray(quad_vao_);
|
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, quad_vbo);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
|
|
|
|
|
|
|
|
glEnableVertexAttribArray(0);
|
|
|
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
|
|
|
|
|
|
|
|
glEnableVertexAttribArray(1);
|
|
|
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
|
|
|
|
|
|
|
|
glBindVertexArray(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-08-13 17:47:16 -04:00
|
|
|
// Allows for runtime shader updates
|
2024-08-13 16:25:56 -04:00
|
|
|
void Scene::ReloadShader() {
|
2024-08-14 18:04:06 -04:00
|
|
|
GLuint new_shader = InitShader(kVertexShaderPath.c_str(), kTessellationCtrlPath.c_str(), kTessellationEvalPath.c_str(), kFragmentShaderPath.c_str());
|
2024-08-13 16:25:56 -04:00
|
|
|
if (new_shader == -1) {
|
|
|
|
DEBUG_BREAK();
|
|
|
|
glClearColor(1.0f, 0.0f, 1.0f, 0.0f);
|
|
|
|
} else {
|
|
|
|
glClearColor(0.35f, 0.35f, 0.35f, 0.0f);
|
|
|
|
if (shader_program_ != -1) {
|
|
|
|
glDeleteProgram(shader_program_);
|
|
|
|
}
|
|
|
|
shader_program_ = new_shader;
|
2024-08-12 21:40:28 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::Display(GLFWwindow* window) {
|
2024-08-17 19:10:41 -04:00
|
|
|
fbo_.Bind();
|
2024-08-13 16:25:56 -04:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
2024-08-12 21:40:28 -04:00
|
|
|
|
2024-08-14 02:16:53 -04:00
|
|
|
glUseProgram(shader_program_);
|
|
|
|
|
2024-08-14 19:14:43 -04:00
|
|
|
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
2024-08-14 18:04:06 -04:00
|
|
|
|
2024-08-17 19:10:41 -04:00
|
|
|
view_matrix_ = glm::lookAt(glm::vec3(0.0f, 1.4f, -1.4f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
2024-08-13 16:25:56 -04:00
|
|
|
Uniforms::SceneData.PV = projection_matrix_ * view_matrix_; // Projection-View matrix
|
2024-08-12 21:40:28 -04:00
|
|
|
Uniforms::BufferSceneData();
|
|
|
|
|
2024-08-14 19:14:43 -04:00
|
|
|
glm::mat4 model_matrix = glm::rotate(angle_, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::scale(glm::vec3(scale_));
|
2024-08-13 16:25:56 -04:00
|
|
|
glUniformMatrix4fv(Uniforms::UniformLocs::M, 1, false, glm::value_ptr(model_matrix));
|
2024-08-12 21:40:28 -04:00
|
|
|
|
2024-08-15 00:56:29 -04:00
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex_id);
|
|
|
|
|
|
|
|
GLint heightTextureLoc = glGetUniformLocation(shader_program_, "heightTexture");
|
|
|
|
glUniform1i(heightTextureLoc, 0);
|
|
|
|
|
2024-08-17 19:05:05 -04:00
|
|
|
GLint tessFactorLoc = glGetUniformLocation(shader_program_, "tessellationFactor");
|
|
|
|
glUniform1f(tessFactorLoc, tessellationFactor);
|
|
|
|
|
2024-08-13 16:25:56 -04:00
|
|
|
glBindVertexArray(vao_);
|
2024-08-14 18:04:06 -04:00
|
|
|
glPatchParameteri(GL_PATCH_VERTICES, 4);
|
2024-08-17 12:25:42 -04:00
|
|
|
glDrawElements(GL_PATCHES, indices.size(), GL_UNSIGNED_INT, 0);
|
2024-08-14 18:04:06 -04:00
|
|
|
|
2024-08-14 19:14:43 -04:00
|
|
|
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
2024-08-12 21:40:28 -04:00
|
|
|
|
2024-08-13 17:47:16 -04:00
|
|
|
fbo_.Unbind();
|
|
|
|
|
2024-08-14 02:16:53 -04:00
|
|
|
post_fbo_.Bind();
|
2024-08-17 19:10:41 -04:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
2024-08-14 02:16:53 -04:00
|
|
|
|
|
|
|
glUseProgram(quad_shader_program_);
|
|
|
|
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
2024-08-17 19:40:42 -04:00
|
|
|
glBindTexture(GL_TEXTURE_2D, fbo_.GetAlbedoGbuffer());
|
2024-08-17 19:08:11 -04:00
|
|
|
glActiveTexture(GL_TEXTURE1);
|
2024-08-17 19:40:42 -04:00
|
|
|
glBindTexture(GL_TEXTURE_2D, fbo_.GetPositionGbuffer());
|
|
|
|
glActiveTexture(GL_TEXTURE2);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, fbo_.GetNormalGbuffer());
|
2024-08-14 02:16:53 -04:00
|
|
|
|
2024-08-17 19:40:42 -04:00
|
|
|
GLint colorTextureLoc = glGetUniformLocation(quad_shader_program_, "albedoGbuffer");
|
|
|
|
glUniform1i(colorTextureLoc, 0);
|
|
|
|
GLint positionTextureLoc = glGetUniformLocation(quad_shader_program_, "positionGbuffer");
|
2024-08-17 19:08:11 -04:00
|
|
|
glUniform1i(positionTextureLoc, 1);
|
2024-08-17 19:40:42 -04:00
|
|
|
GLint normalTextureLoc = glGetUniformLocation(quad_shader_program_, "normalGbuffer");
|
|
|
|
glUniform1i(normalTextureLoc, 2);
|
2024-08-14 02:16:53 -04:00
|
|
|
|
|
|
|
// Render the full-screen quad
|
|
|
|
glBindVertexArray(quad_vao_);
|
|
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
|
|
|
|
|
|
post_fbo_.Unbind();
|
|
|
|
|
2024-08-13 16:25:56 -04:00
|
|
|
DrawGui(window);
|
2024-08-12 21:40:28 -04:00
|
|
|
glfwSwapBuffers(window);
|
|
|
|
}
|
2024-08-10 19:12:21 -04:00
|
|
|
|
2024-08-13 16:25:56 -04:00
|
|
|
void Scene::DrawGui(GLFWwindow* window) {
|
2024-08-11 21:20:17 -04:00
|
|
|
// Begin ImGui frame
|
|
|
|
ImGui_ImplOpenGL3_NewFrame();
|
|
|
|
ImGui_ImplGlfw_NewFrame();
|
|
|
|
|
|
|
|
// Enable docking
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
|
|
|
|
|
|
|
ImGui::NewFrame();
|
|
|
|
|
|
|
|
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode;
|
|
|
|
|
|
|
|
// Add menu bar
|
|
|
|
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
|
|
|
|
|
|
|
// Style windows
|
|
|
|
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
|
|
|
ImGui::SetNextWindowPos(viewport->WorkPos);
|
|
|
|
ImGui::SetNextWindowSize(viewport->WorkSize);
|
|
|
|
ImGui::SetNextWindowViewport(viewport->ID);
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
|
|
|
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
|
|
|
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
|
|
|
window_flags |= ImGuiWindowFlags_NoBackground;
|
|
|
|
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
|
|
|
ImGui::Begin("TerraVisor", nullptr, window_flags);
|
|
|
|
ImGui::PopStyleVar(3);
|
|
|
|
|
|
|
|
// Submit the DockSpace
|
2024-08-13 16:25:56 -04:00
|
|
|
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) {
|
2024-08-11 21:20:17 -04:00
|
|
|
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
|
|
|
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
|
|
|
}
|
|
|
|
|
2024-08-13 16:25:56 -04:00
|
|
|
if (ImGui::BeginMenuBar()) {
|
|
|
|
if (ImGui::BeginMenu("Options")) {
|
2024-08-11 21:20:17 -04:00
|
|
|
ImGui::Text("Nothing Here Yet, Check Back Later!");
|
|
|
|
|
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::EndMenuBar();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::End();
|
|
|
|
|
2024-08-14 02:16:53 -04:00
|
|
|
// Draw Gui
|
2024-08-11 21:20:17 -04:00
|
|
|
ImGui::Begin("Terrain Controls");
|
2024-08-13 16:25:56 -04:00
|
|
|
if (ImGui::Button("Quit")) {
|
2024-08-11 21:20:17 -04:00
|
|
|
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
2024-08-17 19:05:05 -04:00
|
|
|
|
|
|
|
ImGui::SliderFloat("Tessellation Level", &tessellationFactor, 1.0f, 64.0f);
|
2024-08-11 21:20:17 -04:00
|
|
|
ImGui::End();
|
|
|
|
|
2024-08-14 02:16:53 -04:00
|
|
|
// Draw FBO to ImGui window
|
|
|
|
ImGui::Begin("Scene Window");
|
|
|
|
ImVec2 windowSize = ImGui::GetContentRegionAvail();
|
2024-08-17 19:40:42 -04:00
|
|
|
ImGui::Image((void*)(intptr_t)post_fbo_.GetAlbedoGbuffer(), windowSize, ImVec2(0, 1), ImVec2(1, 0));
|
2024-08-14 02:16:53 -04:00
|
|
|
ImGui::End();
|
|
|
|
|
2024-08-11 21:20:17 -04:00
|
|
|
ImGui::Render();
|
|
|
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
2024-08-10 19:12:21 -04:00
|
|
|
}
|
|
|
|
|
2024-08-12 21:40:28 -04:00
|
|
|
void Scene::Idle() {
|
2024-08-13 16:25:56 -04:00
|
|
|
|
2024-08-10 19:12:21 -04:00
|
|
|
}
|
|
|
|
|
2024-08-15 00:56:29 -04:00
|
|
|
int16_t Scene::SwapEndian(int16_t val) {
|
|
|
|
return (val << 8) | ((val >> 8) & 0xFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<int16_t> Scene::LoadHGT(const std::string& filename, int width, int height) {
|
|
|
|
std::ifstream file(filename, std::ios::binary);
|
|
|
|
std::vector<int16_t> elevationData;
|
|
|
|
|
|
|
|
if (file) {
|
|
|
|
for (int i = 0; i < width * height; ++i) {
|
|
|
|
int16_t value;
|
|
|
|
file.read(reinterpret_cast<char*>(&value), sizeof(int16_t));
|
|
|
|
|
|
|
|
// Handle endianness
|
|
|
|
value = SwapEndian(value);
|
|
|
|
|
|
|
|
if (value == -32768) {
|
|
|
|
value = -32767; // Clamp no-data values
|
|
|
|
}
|
|
|
|
|
|
|
|
elevationData.push_back(value);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
std::cerr << "Failed to open HGT file!" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return elevationData;
|
|
|
|
}
|
|
|
|
|
2024-08-13 16:25:56 -04:00
|
|
|
void Scene::UpdateCamera() {
|
|
|
|
projection_matrix_ = glm::perspective(fov_, aspect_, near_z_, far_z_);
|
2024-08-15 00:56:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
GLuint Scene::CreateHeightmapTexture(std::vector<int16_t> data, int width, int height) {
|
|
|
|
int16_t minVal = *std::min_element(data.begin(), data.end());
|
|
|
|
int16_t maxVal = *std::max_element(data.begin(), data.end());
|
|
|
|
|
|
|
|
std::vector<float> floatData;
|
|
|
|
for (int16_t &d : data) {
|
|
|
|
// Normalize the value between 0 and 1 based on the min/max range
|
2024-08-15 01:09:37 -04:00
|
|
|
d = static_cast<int16_t>(255 * (d - minVal) / (maxVal - minVal));
|
2024-08-15 00:56:29 -04:00
|
|
|
|
|
|
|
floatData.push_back(static_cast<float>(d / 255.0f));
|
|
|
|
}
|
|
|
|
|
|
|
|
GLuint textureID;
|
|
|
|
glGenTextures(1, &textureID);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, textureID);
|
|
|
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, floatData.data());
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
return textureID;
|
2024-08-13 17:47:16 -04:00
|
|
|
}
|