diff --git a/source/renderer/TexturedLineRData.cpp b/source/renderer/TexturedLineRData.cpp index 143840b29f..a4b683c785 100644 --- a/source/renderer/TexturedLineRData.cpp +++ b/source/renderer/TexturedLineRData.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -71,16 +71,8 @@ void CTexturedLineRData::Render(const SOverlayTexturedLine& line, const CShaderP void CTexturedLineRData::Update(const SOverlayTexturedLine& line) { - if (m_VB) - { - g_VBMan.Release(m_VB); - m_VB = NULL; - } - if (m_VBIndices) - { - g_VBMan.Release(m_VBIndices); - m_VBIndices = NULL; - } + m_VBIndices.Reset(); + m_VB.Reset(); if (!line.m_SimContext) { @@ -313,17 +305,17 @@ void CTexturedLineRData::Update(const SOverlayTexturedLine& line) for (const SVertex& vertex : vertices) m_BoundingBox += vertex.m_Position; - m_VB = g_VBMan.Allocate(sizeof(SVertex), vertices.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER); + m_VB = g_VBMan.AllocateChunk(sizeof(SVertex), vertices.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER); if (m_VB) // allocation might fail (e.g. due to too many vertices) { - m_VB->m_Owner->UpdateChunkVertices(m_VB, &vertices[0]); // copy data into VBO + m_VB->m_Owner->UpdateChunkVertices(m_VB.Get(), &vertices[0]); // copy data into VBO for (size_t k = 0; k < indices.size(); ++k) indices[k] += static_cast(m_VB->m_Index); - m_VBIndices = g_VBMan.Allocate(sizeof(u16), indices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER); + m_VBIndices = g_VBMan.AllocateChunk(sizeof(u16), indices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER); if (m_VBIndices) - m_VBIndices->m_Owner->UpdateChunkVertices(m_VBIndices, &indices[0]); + m_VBIndices->m_Owner->UpdateChunkVertices(m_VBIndices.Get(), &indices[0]); } } diff --git a/source/renderer/TexturedLineRData.h b/source/renderer/TexturedLineRData.h index aed2803429..e8afcee1e7 100644 --- a/source/renderer/TexturedLineRData.h +++ b/source/renderer/TexturedLineRData.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -47,15 +47,8 @@ class CTexturedLineRData : public CRenderData public: - CTexturedLineRData() : m_VB(NULL), m_VBIndices(NULL) { } - - ~CTexturedLineRData() - { - if (m_VB) - g_VBMan.Release(m_VB); - if (m_VBIndices) - g_VBMan.Release(m_VBIndices); - } + CTexturedLineRData() = default; + ~CTexturedLineRData() = default; void Update(const SOverlayTexturedLine& line); void Render(const SOverlayTexturedLine& line, const CShaderProgramPtr& shader); @@ -69,7 +62,7 @@ protected: SVertex(CVector3D pos, float u, float v) : m_Position(pos) { m_UVs[0] = u; m_UVs[1] = v; } CVector3D m_Position; GLfloat m_UVs[2]; - float _padding[3]; // get a pow2 struct size + float padding[3]; // get a pow2 struct size }; cassert(sizeof(SVertex) == 32); @@ -93,8 +86,8 @@ protected: return (v1.m_Position + v2.m_Position) * 0.5; } - CVertexBuffer::VBChunk* m_VB; - CVertexBuffer::VBChunk* m_VBIndices; + CVertexBufferManager::Handle m_VB; + CVertexBufferManager::Handle m_VBIndices; CBoundingBoxAligned m_BoundingBox; }; diff --git a/source/renderer/VertexArray.cpp b/source/renderer/VertexArray.cpp index 20061ffc88..1ba91a3880 100644 --- a/source/renderer/VertexArray.cpp +++ b/source/renderer/VertexArray.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -36,12 +36,10 @@ VertexArray::VertexArray(GLenum usage, GLenum target) m_Target = target; m_NumVertices = 0; - m_VB = 0; m_BackingStore = 0; m_Stride = 0; } - VertexArray::~VertexArray() { Free(); @@ -53,14 +51,9 @@ void VertexArray::Free() rtl_FreeAligned(m_BackingStore); m_BackingStore = 0; - if (m_VB) - { - g_VBMan.Release(m_VB); - m_VB = 0; - } + m_VB.Reset(); } - // Set the number of vertices stored in the array void VertexArray::SetNumVertices(size_t num) { @@ -71,7 +64,6 @@ void VertexArray::SetNumVertices(size_t num) m_NumVertices = num; } - // Add vertex attributes like Position, Normal, UV void VertexArray::AddAttribute(Attribute* attr) { @@ -87,7 +79,6 @@ void VertexArray::AddAttribute(Attribute* attr) Free(); } - // Template specialization for GetIterator(). // We can put this into the source file because only a fixed set of types // is supported for type safety. @@ -276,7 +267,7 @@ void VertexArray::Layout() void VertexArray::PrepareForRendering() { - m_VB->m_Owner->PrepareForRendering(m_VB); + m_VB->m_Owner->PrepareForRendering(m_VB.Get()); } // (Re-)Upload the attributes. @@ -286,7 +277,7 @@ void VertexArray::Upload() ENSURE(m_BackingStore); if (!m_VB) - m_VB = g_VBMan.Allocate(m_Stride, m_NumVertices, m_Usage, m_Target, m_BackingStore); + m_VB = g_VBMan.AllocateChunk(m_Stride, m_NumVertices, m_Usage, m_Target, m_BackingStore); if (!m_VB) { @@ -294,7 +285,7 @@ void VertexArray::Upload() return; } - m_VB->m_Owner->UpdateChunkVertices(m_VB, m_BackingStore); + m_VB->m_Owner->UpdateChunkVertices(m_VB.Get(), m_BackingStore); } diff --git a/source/renderer/VertexArray.h b/source/renderer/VertexArray.h index 9111e21934..11b8ecf4a0 100644 --- a/source/renderer/VertexArray.h +++ b/source/renderer/VertexArray.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2012 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -18,7 +18,9 @@ #ifndef INCLUDED_VERTEXARRAY #define INCLUDED_VERTEXARRAY -#include "renderer/VertexBuffer.h" +#include "renderer/VertexBufferManager.h" + +#include // Iterator template @@ -200,7 +202,7 @@ private: size_t m_NumVertices; std::vector m_Attributes; - CVertexBuffer::VBChunk* m_VB; + CVertexBufferManager::Handle m_VB; size_t m_Stride; char* m_BackingStore; // 16-byte aligned, to allow fast SSE access }; diff --git a/source/renderer/VertexBufferManager.cpp b/source/renderer/VertexBufferManager.cpp index ee5d564a3f..abc0c3a2c3 100644 --- a/source/renderer/VertexBufferManager.cpp +++ b/source/renderer/VertexBufferManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -15,10 +15,6 @@ * along with 0 A.D. If not, see . */ -/* - * Allocate and destroy CVertexBuffers - */ - #include "precompiled.h" #include "VertexBufferManager.h" @@ -73,23 +69,12 @@ void CVertexBufferManager::Shutdown() m_Buffers[group].clear(); } -CVertexBuffer::VBChunk* CVertexBufferManager::Allocate(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target, void* backingStore) -{ - return AllocateImpl(vertexSize, numVertices, usage, target, backingStore, Group::DEFAULT); -} - +/** + * AllocateChunk: try to allocate a buffer of given number of vertices (each of + * given size), with the given type, and using the given texture - return null + * if no free chunks available + */ CVertexBufferManager::Handle CVertexBufferManager::AllocateChunk(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target, void* backingStore, Group group) -{ - CVertexBuffer::VBChunk* chunk = AllocateImpl(vertexSize, numVertices, usage, target, backingStore, group); - if (!chunk) - return Handle(); - return Handle(chunk); -} - -// Allocate: try to allocate a buffer of given number of vertices (each of -// given size), with the given type, and using the given texture - return null -// if no free chunks available -CVertexBuffer::VBChunk* CVertexBufferManager::AllocateImpl(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target, void* backingStore, Group group) { CVertexBuffer::VBChunk* result = nullptr; @@ -122,7 +107,7 @@ CVertexBuffer::VBChunk* CVertexBufferManager::AllocateImpl(size_t vertexSize, si { result = buffer->Allocate(vertexSize, numVertices, usage, target, backingStore); if (result) - return result; + return Handle(result); } // got this far; need to allocate a new buffer @@ -136,9 +121,10 @@ CVertexBuffer::VBChunk* CVertexBufferManager::AllocateImpl(size_t vertexSize, si if (!result) { LOGERROR("Failed to create VBOs (%zu*%zu)", vertexSize, numVertices); + return Handle(); } - return result; + return Handle(result); } void CVertexBufferManager::Release(CVertexBuffer::VBChunk* chunk) diff --git a/source/renderer/VertexBufferManager.h b/source/renderer/VertexBufferManager.h index d112b9b3e7..ae7af67c7e 100644 --- a/source/renderer/VertexBufferManager.h +++ b/source/renderer/VertexBufferManager.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -86,17 +86,13 @@ public: * @param backingStore if usage is STATIC, this is NULL; else for DYNAMIC/STREAM, * this must be a copy of the vertex data that remains valid for the * lifetime of the VBChunk - * @return chunk, or NULL if no free chunks available + * @return chunk, or empty handle if no free chunks available */ - CVertexBuffer::VBChunk* Allocate(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target, void* backingStore = nullptr); + Handle AllocateChunk(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target, void* backingStore = nullptr, Group group = Group::DEFAULT); /// Returns the given @p chunk to its owning buffer void Release(CVertexBuffer::VBChunk* chunk); - // Same as the Allocate function but returns Handle. Should be used instead - // of the Allocate. - Handle AllocateChunk(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target, void* backingStore = nullptr, Group group = Group::DEFAULT); - size_t GetBytesReserved() const; size_t GetBytesAllocated() const; @@ -104,7 +100,6 @@ public: void Shutdown(); private: - CVertexBuffer::VBChunk* AllocateImpl(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target, void* backingStore = nullptr, Group group = Group::DEFAULT); /// List of all known vertex buffers std::vector> m_Buffers[static_cast(Group::COUNT)]; diff --git a/source/renderer/WaterManager.cpp b/source/renderer/WaterManager.cpp index e95a171ab5..f174a5f2c1 100644 --- a/source/renderer/WaterManager.cpp +++ b/source/renderer/WaterManager.cpp @@ -40,6 +40,7 @@ #include "simulation2/components/ICmpWaterManager.h" #include "simulation2/components/ICmpRangeManager.h" +#include struct CoastalPoint { @@ -66,7 +67,7 @@ cassert(sizeof(SWavesVertex) == 64); struct WaveObject { - CVertexBuffer::VBChunk* m_VBvertices; + CVertexBufferManager::Handle m_VBVertices; CBoundingBoxAligned m_AABB; size_t m_Width; float m_TimeDiff; @@ -93,12 +94,6 @@ WaterManager::WaterManager() m_Murkiness = 0.45f; m_RepeatPeriod = 16.0f; - m_DistanceHeightmap = NULL; - m_BlurredNormalMap = NULL; - m_WindStrength = NULL; - - m_ShoreWaves_VBIndices = NULL; - m_WaterEffects = true; m_WaterFancyEffects = false; m_WaterRealDepth = false; @@ -122,19 +117,11 @@ WaterManager::~WaterManager() // Cleanup if the caller messed up UnloadWaterTextures(); - for (WaveObject* const& obj : m_ShoreWaves) - { - if (obj->m_VBvertices) - g_VBMan.Release(obj->m_VBvertices); - delete obj; - } + m_ShoreWaves.clear(); + m_ShoreWavesVBIndices.Reset(); - if (m_ShoreWaves_VBIndices) - g_VBMan.Release(m_ShoreWaves_VBIndices); - - delete[] m_DistanceHeightmap; - delete[] m_BlurredNormalMap; - delete[] m_WindStrength; + m_DistanceHeightmap.reset(); + m_WindStrength.reset(); if (!g_Renderer.GetCapabilities().m_PrettyWater) return; @@ -405,10 +392,10 @@ void WaterManager::RecomputeDistanceHeightmap() // we want to look ahead some distance, but not too much (less efficient and not interesting). This is our lookahead. const size_t maxLevel = 5; - if (m_DistanceHeightmap == NULL) + if (!m_DistanceHeightmap) { - m_DistanceHeightmap = new float[SideSize*SideSize]; - std::fill(m_DistanceHeightmap, m_DistanceHeightmap + SideSize*SideSize, (float)maxLevel); + m_DistanceHeightmap = std::make_unique(SideSize * SideSize); + std::fill(m_DistanceHeightmap.get(), m_DistanceHeightmap.get() + SideSize * SideSize, static_cast(maxLevel)); } // Create a manhattan-distance heightmap. @@ -416,8 +403,8 @@ void WaterManager::RecomputeDistanceHeightmap() u16* heightmap = terrain->GetHeightMap(); - ComputeDirection(m_DistanceHeightmap, heightmap, m_WaterHeight, SideSize, maxLevel); - ComputeDirection(m_DistanceHeightmap, heightmap, m_WaterHeight, SideSize, maxLevel); + ComputeDirection(m_DistanceHeightmap.get(), heightmap, m_WaterHeight, SideSize, maxLevel); + ComputeDirection(m_DistanceHeightmap.get(), heightmap, m_WaterHeight, SideSize, maxLevel); } // This requires m_DistanceHeightmap to be defined properly. @@ -432,19 +419,8 @@ void WaterManager::CreateWaveMeshes() if (!terrain || !terrain->GetHeightMap()) return; - for (WaveObject* const& obj : m_ShoreWaves) - { - if (obj->m_VBvertices) - g_VBMan.Release(obj->m_VBvertices); - delete obj; - } m_ShoreWaves.clear(); - - if (m_ShoreWaves_VBIndices) - { - g_VBMan.Release(m_ShoreWaves_VBIndices); - m_ShoreWaves_VBIndices = NULL; - } + m_ShoreWavesVBIndices.Reset(); if (m_Waviness < 5.0f && m_WaterType != L"ocean") return; @@ -587,11 +563,15 @@ void WaterManager::CreateWaveMeshes() } } // Generic indexes, max-length - m_ShoreWaves_VBIndices = g_VBMan.Allocate(sizeof(GLushort), water_indices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER); - m_ShoreWaves_VBIndices->m_Owner->UpdateChunkVertices(m_ShoreWaves_VBIndices, &water_indices[0]); + m_ShoreWavesVBIndices = g_VBMan.AllocateChunk( + sizeof(GLushort), water_indices.size(), + GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER, + nullptr, CVertexBufferManager::Group::WATER); + m_ShoreWavesVBIndices->m_Owner->UpdateChunkVertices(m_ShoreWavesVBIndices.Get(), &water_indices[0]); float diff = (rand() % 50) / 5.0f; + std::vector vertices, reversed; for (size_t i = 0; i < CoastalPointsChains.size(); ++i) { for (size_t j = 0; j < CoastalPointsChains[i].size()-waveSizes; ++j) @@ -679,9 +659,9 @@ void WaterManager::CreateWaveMeshes() } // we passed the checks, we can create a wave of size "width". - WaveObject* shoreWave = new WaveObject; - std::vector vertices; - vertices.reserve(9*width); + std::unique_ptr shoreWave = std::make_unique(); + vertices.clear(); + vertices.reserve(9 * width); shoreWave->m_Width = width; shoreWave->m_TimeDiff = diff; @@ -793,21 +773,24 @@ void WaterManager::CreateWaveMeshes() if (sign == 1) { // Let's do some fancy reversing. - std::vector reversed; + reversed.clear(); reversed.reserve(vertices.size()); - for (int a = width-1; a >= 0; --a) + for (int a = width - 1; a >= 0; --a) { for (size_t t = 0; t < 9; ++t) - reversed.push_back(vertices[a*9+t]); + reversed.push_back(vertices[a * 9 + t]); } - vertices = reversed; + std::swap(vertices, reversed); } j += width/2-1; - shoreWave->m_VBvertices = g_VBMan.Allocate(sizeof(SWavesVertex), vertices.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER); - shoreWave->m_VBvertices->m_Owner->UpdateChunkVertices(shoreWave->m_VBvertices, &vertices[0]); + shoreWave->m_VBVertices = g_VBMan.AllocateChunk( + sizeof(SWavesVertex), vertices.size(), + GL_STATIC_DRAW, GL_ARRAY_BUFFER, + nullptr, CVertexBufferManager::Group::WATER); + shoreWave->m_VBVertices->m_Owner->UpdateChunkVertices(shoreWave->m_VBVertices.Get(), &vertices[0]); - m_ShoreWaves.push_back(shoreWave); + m_ShoreWaves.emplace_back(std::move(shoreWave)); } } } @@ -850,7 +833,7 @@ void WaterManager::RenderWaves(const CFrustum& frustrum) if (!frustrum.IsBoxVisible(m_ShoreWaves[a]->m_AABB)) continue; - CVertexBuffer::VBChunk* VBchunk = m_ShoreWaves[a]->m_VBvertices; + CVertexBuffer::VBChunk* VBchunk = m_ShoreWaves[a]->m_VBVertices.Get(); SWavesVertex* base = (SWavesVertex*)VBchunk->m_Owner->Bind(); // setup data pointers @@ -868,9 +851,9 @@ void WaterManager::RenderWaves(const CFrustum& frustrum) shader->Uniform(str_translation, m_ShoreWaves[a]->m_TimeDiff); shader->Uniform(str_width, (int)m_ShoreWaves[a]->m_Width); - u8* indexBase = m_ShoreWaves_VBIndices->m_Owner->Bind(); + u8* indexBase = m_ShoreWavesVBIndices->m_Owner->Bind(); glDrawElements(GL_TRIANGLES, (GLsizei) (m_ShoreWaves[a]->m_Width-1)*(7*6), - GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(m_ShoreWaves_VBIndices->m_Index)); + GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(m_ShoreWavesVBIndices->m_Index)); shader->Uniform(str_translation, m_ShoreWaves[a]->m_TimeDiff + 6.0f); @@ -905,8 +888,8 @@ void WaterManager::RecomputeWindStrength() if (m_MapSize <= 0) return; - if (m_WindStrength == nullptr) - m_WindStrength = new float[m_MapSize*m_MapSize]; + if (!m_WindStrength) + m_WindStrength = std::make_unique(m_MapSize * m_MapSize); CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); if (!terrain || !terrain->GetHeightMap()) @@ -1027,9 +1010,8 @@ void WaterManager::SetMapSize(size_t size) m_updatej0 = 0; m_updatej1 = size; - SAFE_ARRAY_DELETE(m_DistanceHeightmap); - SAFE_ARRAY_DELETE(m_BlurredNormalMap); - SAFE_ARRAY_DELETE(m_WindStrength); + m_DistanceHeightmap.reset(); + m_WindStrength.reset(); } //////////////////////////////////////////////////////////////////////// diff --git a/source/renderer/WaterManager.h b/source/renderer/WaterManager.h index 37d0daff49..52831b047d 100644 --- a/source/renderer/WaterManager.h +++ b/source/renderer/WaterManager.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -24,12 +24,14 @@ #include "graphics/Color.h" #include "graphics/Texture.h" -#include "lib/ogl.h" #include "maths/Matrix3D.h" #include "maths/Vector2D.h" #include "renderer/backend/gl/Texture.h" #include "renderer/VertexBufferManager.h" +#include +#include + class CFrustum; struct WaveObject; @@ -45,14 +47,16 @@ public: CTexturePtr m_WaterTexture[60]; CTexturePtr m_NormalMap[60]; - float* m_WindStrength; // How strong the waves are at point X. % of waviness. - float* m_DistanceHeightmap; // How far from the shore a point is. Manhattan - CVector3D* m_BlurredNormalMap; // Cache a slightly blurred map of the normals of the terrain. + // How strong the waves are at point X. % of waviness. + std::unique_ptr m_WindStrength; + // How far from the shore a point is. Manhattan. + std::unique_ptr m_DistanceHeightmap; // Waves vertex buffers - std::vector< WaveObject* > m_ShoreWaves; // TODO: once we get C++11, remove pointer + // TODO: measure storing value instead of pointer. + std::vector> m_ShoreWaves; // Waves indices buffer. Only one since All Wave Objects have the same. - CVertexBuffer::VBChunk* m_ShoreWaves_VBIndices; + CVertexBufferManager::Handle m_ShoreWavesVBIndices; size_t m_MapSize; ssize_t m_TexSize;