Can import .hgt files. TODO refactor
This commit is contained in:
parent
136b5cab9c
commit
cba45bdecf
18
imgui.ini
18
imgui.ini
|
@ -4,10 +4,10 @@ Size=400,400
|
|||
Collapsed=0
|
||||
|
||||
[Window][Terrain Controls]
|
||||
Pos=0,19
|
||||
Size=1280,94
|
||||
Pos=929,19
|
||||
Size=351,701
|
||||
Collapsed=0
|
||||
DockId=0x00000001,0
|
||||
DockId=0x00000002,0
|
||||
|
||||
[Window][DockSpaceViewport_11111111]
|
||||
Size=1280,720
|
||||
|
@ -23,13 +23,13 @@ Size=1280,720
|
|||
Collapsed=0
|
||||
|
||||
[Window][Scene Window]
|
||||
Pos=0,115
|
||||
Size=1280,605
|
||||
Pos=0,19
|
||||
Size=927,701
|
||||
Collapsed=0
|
||||
DockId=0x00000002,0
|
||||
DockId=0x00000001,0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x6F42A598 Window=0xE80F322C Pos=0,19 Size=1280,701 Split=Y Selected=0x9F2D9299
|
||||
DockNode ID=0x00000001 Parent=0x6F42A598 SizeRef=1280,94 Selected=0xF69494A7
|
||||
DockNode ID=0x00000002 Parent=0x6F42A598 SizeRef=1280,605 CentralNode=1 Selected=0x9F2D9299
|
||||
DockSpace ID=0x6F42A598 Window=0xE80F322C Pos=0,19 Size=1280,701 Split=X Selected=0x9F2D9299
|
||||
DockNode ID=0x00000001 Parent=0x6F42A598 SizeRef=927,701 CentralNode=1 Selected=0x9F2D9299
|
||||
DockNode ID=0x00000002 Parent=0x6F42A598 SizeRef=351,701 Selected=0xF69494A7
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "fbo.h"
|
||||
|
||||
|
@ -16,6 +18,7 @@ class Scene {
|
|||
void DrawGui(GLFWwindow* window);
|
||||
void Idle();
|
||||
void ReloadShader();
|
||||
std::vector<int16_t> LoadHGT(const std::string& filename, int width, int height);
|
||||
|
||||
int window_width;
|
||||
int window_height;
|
||||
|
@ -42,6 +45,9 @@ class Scene {
|
|||
glm::mat4 projection_matrix_;
|
||||
|
||||
void UpdateCamera();
|
||||
int16_t Scene::SwapEndian(int16_t val);
|
||||
float NormalizeHeight(int16_t value, int16_t minVal, int16_t maxVal);
|
||||
GLuint CreateHeightmapTexture(std::vector<int16_t> data, int width, int height);
|
||||
};
|
||||
|
||||
#endif // SCENE_H_
|
|
@ -1,7 +1,7 @@
|
|||
#version 430
|
||||
precision highp float;
|
||||
|
||||
layout(binding = 0) uniform sampler2D diffuse_tex;
|
||||
layout(binding = 0) uniform sampler2D heightTexture;
|
||||
layout(location = 1) uniform float time;
|
||||
|
||||
layout(std140, binding = 0) uniform SceneUniforms
|
||||
|
@ -26,15 +26,12 @@ layout(std140, binding = 2) uniform MaterialUniforms
|
|||
float shininess; //specular exponent
|
||||
};
|
||||
|
||||
in VertexData
|
||||
{
|
||||
vec2 tex_coord;
|
||||
vec3 pw; //world-space vertex position
|
||||
vec3 nw; //world-space normal vector
|
||||
} inData; //block is named 'inData'
|
||||
|
||||
in vec3 frag_position;
|
||||
|
||||
in VertexData {
|
||||
vec2 tex_coord;
|
||||
} inData;
|
||||
|
||||
out vec4 frag_color; //the output color for this fragment
|
||||
|
||||
void main(void)
|
||||
|
@ -58,6 +55,14 @@ void main(void)
|
|||
// vec4 specular_term = atten*ks*Ls*pow(max(0.0, dot(rw, vw)), shininess);
|
||||
|
||||
// fragcolor = ambient_term + diffuse_term + specular_term;
|
||||
frag_color = vec4(frag_position, 1.0f);
|
||||
|
||||
|
||||
float height = texture(heightTexture, inData.tex_coord).r;
|
||||
|
||||
//frag_color = vec4(inData.tex_coord, 0.0f, 1.0f);
|
||||
|
||||
// if (height > 0.8) frag_color = vec4(vec3(1.0f-height), 1.0f);
|
||||
// else frag_color = vec4(vec3(height), 1.0f);
|
||||
frag_color = vec4(height, height, height, 1.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,19 @@
|
|||
|
||||
layout(vertices = 4) out; // Define the number of control points per patch (e.g., 4 for a quad)
|
||||
|
||||
in VertexData {
|
||||
vec2 tex_coord;
|
||||
} inData[];
|
||||
|
||||
out VertexData {
|
||||
vec2 tex_coord;
|
||||
} outData[];
|
||||
|
||||
void main()
|
||||
{
|
||||
// Pass through control points to the tessellation evaluation shader
|
||||
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
|
||||
outData[gl_InvocationID].tex_coord = inData[gl_InvocationID].tex_coord;
|
||||
|
||||
// Set the tessellation levels (outer and inner)
|
||||
if (gl_InvocationID == 0) {
|
||||
|
|
|
@ -10,8 +10,16 @@ layout(std140, binding = 0) uniform SceneUniforms
|
|||
vec4 eye_w; //world-space eye position
|
||||
};
|
||||
|
||||
in VertexData {
|
||||
vec2 tex_coord;
|
||||
} inData[];
|
||||
|
||||
out vec3 frag_position; // Ensure this matches the input in fragment.glsl
|
||||
|
||||
out VertexData {
|
||||
vec2 tex_coord;
|
||||
} outData;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Interpolate the position using the barycentric coordinates from tessellation
|
||||
|
@ -21,5 +29,9 @@ void main()
|
|||
|
||||
frag_position = pos;
|
||||
|
||||
outData.tex_coord = mix(mix(inData[0].tex_coord, inData[1].tex_coord, gl_TessCoord.x),
|
||||
mix(inData[3].tex_coord, inData[2].tex_coord, gl_TessCoord.x),
|
||||
gl_TessCoord.y);
|
||||
|
||||
gl_Position = PV*M*vec4(pos, 1.0);
|
||||
}
|
||||
|
|
|
@ -11,8 +11,15 @@ layout(location = 0) in vec3 pos_attrib;
|
|||
layout(location = 1) in vec2 tex_coord_attrib;
|
||||
layout(location = 2) in vec3 normal_attrib;
|
||||
|
||||
out VertexData
|
||||
{
|
||||
vec2 tex_coord;
|
||||
} outData;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(pos_attrib, 1.0);
|
||||
|
||||
outData.tex_coord = tex_coord_attrib; //send tex_coord to fragment shader
|
||||
}
|
||||
|
||||
|
||||
|
|
122
source/scene.cpp
122
source/scene.cpp
|
@ -15,6 +15,9 @@
|
|||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
|
||||
#include "scene.h"
|
||||
#include "Uniforms.h"
|
||||
|
@ -32,6 +35,10 @@ const std::string kFragmentShaderPath = "shaders/fragment.glsl";
|
|||
const std::string kQuadVertexPath = "shaders/quad_vertex.glsl";
|
||||
const std::string kQuadFragmentPath = "shaders/quad_fragment.glsl";
|
||||
|
||||
const std::string kHGTPath = "C:/Users/jmchr/Downloads/N02E016.SRTMGL1.hgt/N02E016.hgt";
|
||||
|
||||
GLuint tex_id = -1;
|
||||
|
||||
} // namespace
|
||||
|
||||
Scene::Scene(int width, int height)
|
||||
|
@ -46,7 +53,7 @@ Scene::Scene(int width, int height)
|
|||
aspect_(static_cast<float>(width) / static_cast<float>(height)),
|
||||
near_z_(0.01f),
|
||||
far_z_(100.0f),
|
||||
fov_(glm::pi<float>() / 4.0f)
|
||||
fov_(glm::pi<float>() / 8.0f)
|
||||
{}
|
||||
|
||||
Scene::~Scene() {
|
||||
|
@ -68,6 +75,9 @@ void Scene::Init() {
|
|||
fbo_.Init(window_width, window_height);
|
||||
post_fbo_.Init(window_width, window_height);
|
||||
|
||||
std::vector<int16_t> heightData = LoadHGT(kHGTPath, 3601, 3601);
|
||||
tex_id = CreateHeightmapTexture(heightData, 3601, 3601);
|
||||
|
||||
InitBuffers();
|
||||
ReloadShader();
|
||||
InitQuadBuffers();
|
||||
|
@ -80,21 +90,13 @@ void Scene::Init() {
|
|||
// Currently creates a test triangle and initializes its buffers
|
||||
void Scene::InitBuffers() {
|
||||
GLuint patch_vbo;
|
||||
// Quad vertices in 3D space
|
||||
// float patchVertices[] = {
|
||||
// -0.5f, 0.0f, -0.5f, // Bottom-left
|
||||
// 0.5f, 0.0f, -0.5f, // Bottom-right
|
||||
// 0.5f, 0.0f, 0.5f, // Top-right
|
||||
// -0.5f, 0.0f, 0.5f // Top-left
|
||||
|
||||
// };
|
||||
|
||||
float patchVertices[] = {
|
||||
-0.5f, -0.5f, 0.0f, // Bottom-left
|
||||
0.5f, -0.5f, 0.0f, // Bottom-right
|
||||
0.5f, 0.5f, 0.0f, // Top-right
|
||||
-0.5f, 0.5f, 0.0f // Top-left
|
||||
|
||||
// Positions // Texture Coords
|
||||
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // Bottom-left
|
||||
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // Bottom-right
|
||||
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // Top-right
|
||||
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // Top-left
|
||||
};
|
||||
|
||||
glGenVertexArrays(1, &vao_);
|
||||
|
@ -106,7 +108,11 @@ void Scene::InitBuffers() {
|
|||
|
||||
// Position attribute
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
|
||||
// Texture coordinate attribute
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
@ -163,13 +169,19 @@ void Scene::Display(GLFWwindow* window) {
|
|||
|
||||
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
|
||||
view_matrix_ = glm::lookAt(glm::vec3(0.0f, 2.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
view_matrix_ = glm::lookAt(glm::vec3(1.2f, 1.2f, 1.2f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
Uniforms::SceneData.PV = projection_matrix_ * view_matrix_; // Projection-View matrix
|
||||
Uniforms::BufferSceneData();
|
||||
|
||||
glm::mat4 model_matrix = glm::rotate(angle_, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::scale(glm::vec3(scale_));
|
||||
glUniformMatrix4fv(Uniforms::UniformLocs::M, 1, false, glm::value_ptr(model_matrix));
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, tex_id);
|
||||
|
||||
GLint heightTextureLoc = glGetUniformLocation(shader_program_, "heightTexture");
|
||||
glUniform1i(heightTextureLoc, 0);
|
||||
|
||||
glBindVertexArray(vao_);
|
||||
glPatchParameteri(GL_PATCH_VERTICES, 4);
|
||||
glDrawArrays(GL_PATCHES, 0, 4);
|
||||
|
@ -272,6 +284,84 @@ void Scene::Idle() {
|
|||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void Scene::UpdateCamera() {
|
||||
projection_matrix_ = glm::perspective(fov_, aspect_, near_z_, far_z_);
|
||||
}
|
||||
|
||||
// HGT files are 16bit integers whereas OpenGL prefers floating point values for color data
|
||||
float Scene::NormalizeHeight(int16_t value, int16_t minVal, int16_t maxVal) {
|
||||
return static_cast<float>(value - minVal) / (maxVal - minVal);
|
||||
}
|
||||
|
||||
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::cout << "Min Val: " << minVal << "\n";
|
||||
std::cout << "Max Val: " << maxVal << std::endl;
|
||||
|
||||
std::vector<float> floatData;
|
||||
for (int16_t &d : data) {
|
||||
// Normalize the value between 0 and 1 based on the min/max range
|
||||
d = static_cast<int16_t>(
|
||||
255 * (d - minVal) / (maxVal - minVal)
|
||||
);
|
||||
|
||||
floatData.push_back(static_cast<float>(d / 255.0f));
|
||||
//floatData.push_back((static_cast<float>(d) / 32767.0f + 1.0f) / 2.0f);
|
||||
}
|
||||
|
||||
minVal = *std::min_element(data.begin(), data.end());
|
||||
maxVal = *std::max_element(data.begin(), data.end());
|
||||
|
||||
std::cout << "Min Val: " << minVal << "\n";
|
||||
std::cout << "Max Val: " << maxVal << std::endl;
|
||||
|
||||
float minFloatVal = *std::min_element(floatData.begin(), floatData.end());
|
||||
float maxFloatVal = *std::max_element(floatData.begin(), floatData.end());
|
||||
|
||||
std::cout << "Min Float Val: " << minFloatVal << "\n";
|
||||
std::cout << "Max Float Val: " << maxFloatVal << std::endl;
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue