1
0
forked from 0ad/0ad

Uses CVertexBufferManager handle instead of raw VBChunk pointer management.

Tested By: Stan
Differential Revision: https://code.wildfiregames.com/D4430
This was SVN commit r26196.
This commit is contained in:
Vladislav Belov 2022-01-10 16:51:43 +00:00
parent 795fb070af
commit 0cda752ec3
8 changed files with 84 additions and 139 deletions

View File

@ -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<u16>(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]);
}
}

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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 <vector>
// Iterator
template<typename T>
@ -200,7 +202,7 @@ private:
size_t m_NumVertices;
std::vector<Attribute*> 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
};

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/*
* 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)

View File

@ -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<std::unique_ptr<CVertexBuffer>> m_Buffers[static_cast<std::size_t>(Group::COUNT)];

View File

@ -40,6 +40,7 @@
#include "simulation2/components/ICmpWaterManager.h"
#include "simulation2/components/ICmpRangeManager.h"
#include <algorithm>
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<float[]>(SideSize * SideSize);
std::fill(m_DistanceHeightmap.get(), m_DistanceHeightmap.get() + SideSize * SideSize, static_cast<float>(maxLevel));
}
// Create a manhattan-distance heightmap.
@ -416,8 +403,8 @@ void WaterManager::RecomputeDistanceHeightmap()
u16* heightmap = terrain->GetHeightMap();
ComputeDirection<false>(m_DistanceHeightmap, heightmap, m_WaterHeight, SideSize, maxLevel);
ComputeDirection<true>(m_DistanceHeightmap, heightmap, m_WaterHeight, SideSize, maxLevel);
ComputeDirection<false>(m_DistanceHeightmap.get(), heightmap, m_WaterHeight, SideSize, maxLevel);
ComputeDirection<true>(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<SWavesVertex> 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<SWavesVertex> vertices;
vertices.reserve(9*width);
std::unique_ptr<WaveObject> shoreWave = std::make_unique<WaveObject>();
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<SWavesVertex> 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<float[]>(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();
}
////////////////////////////////////////////////////////////////////////

View File

@ -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 <memory>
#include <vector>
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<float[]> m_WindStrength;
// How far from the shore a point is. Manhattan.
std::unique_ptr<float[]> 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<std::unique_ptr<WaveObject>> 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;