Skip to content

Commit

Permalink
You can now choose between Low, Medium and High LOD
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathan-Greve committed Dec 22, 2023
1 parent c0966d3 commit c031bb9
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 13 deletions.
12 changes: 11 additions & 1 deletion SourceFiles/MapRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,14 @@ class MapRenderer
TextureManager* GetTextureManager() { return m_texture_manager.get(); }
MeshManager* GetMeshManager() { return m_mesh_manager.get(); }

void SetLODQuality(const LODQuality new_lod_quality) {
m_lod_quality = new_lod_quality;
}

LODQuality GetLODQuality() const {
return m_lod_quality;
}

void Update(const float dt)
{
// Walk
Expand Down Expand Up @@ -468,7 +476,7 @@ class MapRenderer
void Render()
{
m_mesh_manager->Render(m_pixel_shaders, m_blend_state_manager.get(), m_rasterizer_state_manager.get(),
m_stencil_state_manager.get(), m_user_camera->GetPosition3f());
m_stencil_state_manager.get(), m_user_camera->GetPosition3f(), m_lod_quality);
}

void AddBox(float x, float y, float z, float size,
Expand Down Expand Up @@ -528,4 +536,6 @@ class MapRenderer

DirectionalLight m_directionalLight;
bool m_per_frame_cb_changed = true;

LODQuality m_lod_quality = LODQuality::High;
};
62 changes: 54 additions & 8 deletions SourceFiles/MeshInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,27 @@ class MeshInstance
D3D11_BUFFER_DESC ibDesc = {};
ibDesc.Usage = D3D11_USAGE_IMMUTABLE;
ibDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibDesc.ByteWidth = sizeof(uint32_t) * m_mesh.indices.size();
ibDesc.StructureByteStride = sizeof(uint32_t);

// High LOD indices
ibDesc.ByteWidth = sizeof(uint32_t) * m_mesh.indices.size();
D3D11_SUBRESOURCE_DATA ibData = {};
ibData.pSysMem = m_mesh.indices.data();
device->CreateBuffer(&ibDesc, &ibData, &m_indexBuffer);
device->CreateBuffer(&ibDesc, &ibData, &m_indexBuffer_high);

// Medium LOD indices
if (m_mesh.indices1.size() > 0) {
ibDesc.ByteWidth = sizeof(uint32_t) * m_mesh.indices1.size();
ibData.pSysMem = m_mesh.indices1.data();
device->CreateBuffer(&ibDesc, &ibData, &m_indexBuffer_medium);
}

// Low LOD indices
if (m_mesh.indices2.size() > 0) {
ibDesc.ByteWidth = sizeof(uint32_t) * m_mesh.indices2.size();
ibData.pSysMem = m_mesh.indices2.data();
device->CreateBuffer(&ibDesc, &ibData, &m_indexBuffer_low);
}
}

~MeshInstance() { }
Expand Down Expand Up @@ -58,23 +74,50 @@ class MeshInstance

const Mesh& GetMesh() { return m_mesh; }

void Draw(ID3D11DeviceContext* context)
void Draw(ID3D11DeviceContext* context, LODQuality lod_quality)
{
UINT stride = sizeof(GWVertex);
UINT offset = 0;
context->IASetVertexBuffers(0, 1, m_vertexBuffer.GetAddressOf(), &stride, &offset);
context->IASetIndexBuffer(m_indexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);

int num_indices = 0;

switch (lod_quality)
{
case LODQuality::High:
context->IASetIndexBuffer(m_indexBuffer_high.Get(), DXGI_FORMAT_R32_UINT, 0);
num_indices = m_mesh.indices.size();
break;
case LODQuality::Medium:
// Fallthrough to next case if indices are empty
if (m_mesh.indices1.size() > 0) {
context->IASetIndexBuffer(m_indexBuffer_medium.Get(), DXGI_FORMAT_R32_UINT, 0);
num_indices = m_mesh.indices1.size();
break;
}
case LODQuality::Low:
// Fallthrough to next case if indices are empty
if (m_mesh.indices2.size() > 0) {
context->IASetIndexBuffer(m_indexBuffer_low.Get(), DXGI_FORMAT_R32_UINT, 0);
num_indices = m_mesh.indices2.size();
break;
}
default:
context->IASetIndexBuffer(m_indexBuffer_high.Get(), DXGI_FORMAT_R32_UINT, 0);
num_indices = m_mesh.indices.size();
break;
}

for (int slot = 0; slot < 4; ++slot)
{
if (m_textures[slot].size() > 0)
{
context->PSSetShaderResources(slot, m_textures[slot].size(),
m_textures[slot].data()->GetAddressOf());
context->PSSetShaderResources(slot, m_textures[slot].size(),
m_textures[slot].data()->GetAddressOf());
}
}

context->DrawIndexed(m_mesh.indices.size(), 0, 0);
context->DrawIndexed(num_indices, 0, 0);
}

private:
Expand All @@ -83,6 +126,9 @@ class MeshInstance
PerObjectCB m_per_object_data;

Microsoft::WRL::ComPtr<ID3D11Buffer> m_vertexBuffer;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_indexBuffer;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_indexBuffer_high; // High LOD
Microsoft::WRL::ComPtr<ID3D11Buffer> m_indexBuffer_medium; // Medium LOD
Microsoft::WRL::ComPtr<ID3D11Buffer> m_indexBuffer_low; // Low LOD

std::array<std::vector<Microsoft::WRL::ComPtr<ID3D11ShaderResourceView>>, 4> m_textures;
};
4 changes: 2 additions & 2 deletions SourceFiles/MeshManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ class MeshManager

void Render(std::unordered_map<PixelShaderType, std::unique_ptr<PixelShader>>& pixel_shaders,
BlendStateManager* blend_state_manager, RasterizerStateManager* rasterizer_state_manager,
DepthStencilStateManager* depth_stencil_state_manager, XMFLOAT3 camera_position)
DepthStencilStateManager* depth_stencil_state_manager, XMFLOAT3 camera_position, LODQuality lod_quality)
{
static D3D11_PRIMITIVE_TOPOLOGY currentTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
static auto current_ps_shader_type = PixelShaderType::OldModel;
Expand Down Expand Up @@ -301,7 +301,7 @@ class MeshManager
memcpy(mappedResource.pData, &transposedData, sizeof(PerObjectCB));
m_deviceContext->Unmap(m_perObjectCB.Get(), 0);

command.meshInstance->Draw(m_deviceContext);
command.meshInstance->Draw(m_deviceContext, lod_quality);
}
}

Expand Down
8 changes: 7 additions & 1 deletion SourceFiles/draw_right_panel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,17 @@ void draw_right_panel(MapRenderer* map_renderer)
float window_height = 0;
if (ImGui::Begin("Render settings", NULL, window_flags))
{

static float water_level = 0.0f;
static float terrain_tex_pad_x = 0.03f;
static float terrain_tex_pad_y = 0.03f;

int lod_quality = static_cast<uint8_t>(map_renderer->GetLODQuality());
if (ImGui::Combo("LOD Quality", &lod_quality,
"High\0Medium\0Low\0"))
{
map_renderer->SetLODQuality(static_cast<LODQuality>(lod_quality));
}

auto terrain = map_renderer->GetTerrain();
if (terrain)
{
Expand Down
8 changes: 7 additions & 1 deletion SourceFiles/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,10 @@ inline std::optional<std::filesystem::path> save_last_filepath(const std::filesy
}

return std::nullopt;
}
}

enum class LODQuality : uint8_t {
High, // Best quality
Medium, // Medium quality
Low, // Lowset quality
};

0 comments on commit c031bb9

Please sign in to comment.