Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
gue-ni committed Oct 14, 2023
1 parent cfda14a commit be7602e
Show file tree
Hide file tree
Showing 7 changed files with 305 additions and 284 deletions.
1 change: 1 addition & 0 deletions OpenGL_Flightsim/OpenGL_Flightsim.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ xcopy /y /i /s $(ProjectDir)..\lib\glew-2.2.0\bin\Release\x64\*.dll $(OutDir)</C
<ClCompile Include="src\gfx\util.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\gfx\gfx.cpp" />
<ClCompile Include="src\terrain.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="shaders\basic.frag" />
Expand Down
3 changes: 3 additions & 0 deletions OpenGL_Flightsim/OpenGL_Flightsim.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@
<ClCompile Include="src\gfx\billboard.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\terrain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="shaders\basic.frag" />
Expand Down
2 changes: 1 addition & 1 deletion OpenGL_Flightsim/src/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ void App::init()
#if 1
#endif
#if 1
m_clipmap = new Clipmap();
m_clipmap = new GeometryClipmap();
m_clipmap->visible = true;
m_scene->add(m_clipmap);
#endif
Expand Down
2 changes: 1 addition & 1 deletion OpenGL_Flightsim/src/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class App
// physics
Airplane* m_flightmodel;
phi::RigidBody* m_terrain;
Clipmap* m_clipmap;
GeometryClipmap* m_clipmap;

void init_airplane();
void init_flightmodel();
Expand Down
4 changes: 2 additions & 2 deletions OpenGL_Flightsim/src/collider.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ struct Sphere : public Collider {
};

struct Heightmap : public Collider {
const Clipmap* terrain = nullptr;
const GeometryClipmap* terrain = nullptr;

Heightmap(Clipmap* terrain_) : terrain(terrain_) {}
Heightmap(GeometryClipmap* terrain_) : terrain(terrain_) {}

bool test(const phi::Transform* tf, const Collider* other, const phi::Transform* other_tf,
phi::Collision* info) const override;
Expand Down
264 changes: 264 additions & 0 deletions OpenGL_Flightsim/src/terrain.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
#include "terrain.h"

TextureCLipmap::TextureCLipmap() {}

Seam::Seam(int columns, float size)
{
int rows = 1;
index_count = columns;

std::vector<glm::vec3> vertices;

int x;
for (x = 0; x < columns; x++) {
vertices.push_back({x * size, 0.0f, 0 * size});
vertices.push_back({x * size + size / 2.0f, size, 0 * size});
vertices.push_back({x * size + size, 0.0f, 0 * size});
}

vao.bind();
vbo.buffer(&vertices[0], vertices.size() * sizeof(vertices[0]));

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

vao.unbind();
}

void Seam::bind() { vao.bind(); }

void Seam::unbind() { vao.unbind(); }

void Seam::draw()
{
bind();
glDrawArrays(GL_TRIANGLES, 0, 3 * index_count);
unbind();
}

Block::Block(int width, int height, float segment_size)
{
std::vector<glm::vec3> vertices;
std::vector<unsigned int> indices;

for (int y = 0; y <= width; y++) {
for (int x = 0; x <= height; x++) {
vertices.push_back({x * segment_size, 0.0f, y * segment_size});
}
}

for (int r = 0; r < width; r++) {
for (int c = 0; c < height + 1; c++) {
auto i0 = (r + 0) * (height + 1) + c;
indices.push_back(i0);

auto i1 = (r + 1) * (height + 1) + c;
indices.push_back(i1);
}
indices.push_back(primitive_restart); // restart primitive
}

index_count = indices.size();

assert(indices.size() > 0 && vertices.size() > 0);

vao.bind();

vbo.buffer(&vertices[0], vertices.size() * sizeof(vertices[0]));
ebo.buffer(&indices[0], indices.size() * sizeof(indices[0]));

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

vao.unbind();
}

void Block::bind() { vao.bind(); }

void Block::unbind() { vao.unbind(); }

void Block::draw()
{
bind();
glDrawElements(GL_TRIANGLE_STRIP, index_count, GL_UNSIGNED_INT, 0);
unbind();
}

GeometryClipmap::GeometryClipmap(int levels_, int segments_)
: segment_size(2.0f),
levels(levels_),
segments(segments_),
terrain_size(MAX_TILE_SIZE / ZOOM_FACTOR),
shader("shaders/terrain"),
heightmap_image(PATH + "height.png"),
heightmap(heightmap_image, params),
normalmap(PATH + "normal.png", params),
terrain(PATH + "texture.png", params),
terrain_0(),
tile(segments, segments, segment_size),
col_fixup(2, segments, segment_size),
row_fixup(segments, 2, segment_size),
horizontal(2 * segments + 2, 1, segment_size),
vertical(1, 2 * segments + 2, segment_size),
center(2 * segments + 2, 2 * segments + 2, segment_size),
seam(2 * segments + 2, segment_size * 2)
{
std::cout << "terrain_size = " << terrain_size << " m" << std::endl;

auto fog = gfx::rgb(0x5e5e6e);
auto color = glm::vec4(fog, 1.0f);

auto p = pixel_from_height(2561.0f);

terrain.bind();
terrain.set_parameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
terrain.set_parameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
terrain.set_parameter(GL_TEXTURE_BORDER_COLOR, glm::value_ptr(color));

heightmap.bind();
heightmap.set_parameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
heightmap.set_parameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
heightmap.set_parameter(GL_TEXTURE_BORDER_COLOR, glm::value_ptr(glm::vec4(pixel_from_height(0.0f), 1.0f)));
}

void GeometryClipmap::draw_self(gfx::RenderContext& context)
{
if (context.shadow_pass) {
return;
}
auto camera_pos = context.camera->get_world_position();
float height = camera_pos.y;
auto camera_pos_xy = glm::vec2(camera_pos.x, camera_pos.z);

// TODO: select proper texture LOD
glm::vec2 origin = camera_pos_xy - glm::vec2(terrain_size / 2);

shader.bind();
shader.set_uniform("u_Heightmap", 2);
shader.set_uniform("u_Normalmap", 3);
shader.set_uniform("u_Texture_01", 4);
shader.set_uniform("u_FogColor", context.fog_color);
shader.set_uniform("u_View", context.camera->get_view_matrix());
shader.set_uniform("u_CameraPos", context.camera->get_world_position());
shader.set_uniform("u_Projection", context.camera->get_projection_matrix());
shader.set_uniform("u_TerrainSize", terrain_size);
shader.set_uniform("u_Shadowmap", 5);
shader.set_uniform("u_LightSpaceMatrix", context.light_space_matrix);

glEnable(GL_CULL_FACE);
glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(primitive_restart);

int min_level = 1; // depends on camera height

for (int level = min_level; level <= levels; level++) {
const int rows = 5, columns = 5;
float scale = std::pow(2.0f, level);
float next_scale = std::pow(2.0f, level + 2);
float scaled_segment_size = segment_size * scale;
float tile_size = segments * scaled_segment_size;
glm::vec2 snapped = glm::floor(camera_pos_xy / next_scale) * next_scale;
auto base = calc_base(level, camera_pos_xy);

shader.set_uniform("u_Scale", scale);
shader.set_uniform("u_SegmentSize", scaled_segment_size);
shader.set_uniform("u_Level", static_cast<float>(level) / levels);

#if 1
// don't render lots of detail if we are very high up
if (tile_size * 5 < height * 2.5) {
min_level = level + 1;
continue;
}
#endif

heightmap.bind(2);
normalmap.bind(3);
terrain.bind(4);
context.depth_map->bind(5);

#if 1
if (level == min_level) {
shader.set_uniform("u_Model", transform_matrix(base + glm::vec2(tile_size, tile_size), scale));
center.draw();
} else { // not at base level
auto prev_base = calc_base(level - 1, camera_pos_xy);
auto diff = glm::abs(base - prev_base);

auto l_offset = glm::vec2(tile_size, tile_size);
if (diff.x == tile_size) {
l_offset.x += (2 * segments + 1) * scaled_segment_size;
}
shader.set_uniform("u_Model", transform_matrix(base + l_offset, scale));
horizontal.draw();

auto v_offset = glm::vec2(tile_size, tile_size);
if (diff.y == tile_size) {
v_offset.y += (2 * segments + 1) * scaled_segment_size;
}

shader.set_uniform("u_Model", transform_matrix(base + v_offset, scale));
vertical.draw();
}
#endif
#if 1
glm::vec2 offset(0.0f);
for (int row = 0; row < rows; row++) {
offset.y = 0;
for (int column = 0; column < columns; column++) {
if (row == 0 || row == rows - 1 || column == 0 || column == columns - 1) {
auto tile_pos = base + offset;
shader.set_uniform("u_Model", transform_matrix(tile_pos, scale));

if ((column != 2) && (row != 2)) {
if (column == 0 && row == 0) // east
{
shader.set_uniform("u_Model", transform_matrix(tile_pos, scale));
seam.draw();
} else if (column == columns - 1 && row == rows - 1) // west
{
shader.set_uniform("u_Model", transform_matrix(tile_pos + glm::vec2(tile_size), scale, 180.0f));
seam.draw();
} else if (column == columns - 1 && row == 0) // south
{
shader.set_uniform("u_Model", transform_matrix(tile_pos + glm::vec2(0, tile_size), scale, 90.0f));
seam.draw();
} else if (column == 0 && row == rows - 1) // north
{
shader.set_uniform("u_Model", transform_matrix(tile_pos + glm::vec2(tile_size, 0), scale, -90.0f));
seam.draw();
}

shader.set_uniform("u_Model", transform_matrix(tile_pos, scale));
tile.draw();
} else if (column == 2) {
col_fixup.draw();
} else if (row == 2) {
row_fixup.draw();
}
}

if (column == 2) {
offset.y += 2 * scaled_segment_size;
} else {
offset.y += tile_size;
}
}

if (row == 2) {
offset.x += 2 * scaled_segment_size;
} else {
offset.x += tile_size;
}
}
#endif

heightmap.unbind();
normalmap.unbind();
terrain.unbind();
}

glDisable(GL_CULL_FACE);

shader.unbind();
}
Loading

0 comments on commit be7602e

Please sign in to comment.