Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/renderer/PatchRData.cpp
Show First 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | CPatchRData::CPatchRData(CPatch* patch, CSimulation2* simulation) : | ||||
Build(); | Build(); | ||||
} | } | ||||
/////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////// | ||||
// CPatchRData destructor | // CPatchRData destructor | ||||
CPatchRData::~CPatchRData() | CPatchRData::~CPatchRData() | ||||
{ | { | ||||
// release vertex buffer chunks | // release vertex buffer chunks | ||||
if (m_VBSides) g_VBMan.Release(m_VBSides); | m_VBSides.Reset(); | ||||
if (m_VBBase) g_VBMan.Release(m_VBBase); | m_VBBase.Reset(); | ||||
if (m_VBBaseIndices) g_VBMan.Release(m_VBBaseIndices); | m_VBBaseIndices.Reset(); | ||||
if (m_VBBlends) g_VBMan.Release(m_VBBlends); | m_VBBlends.Reset(); | ||||
if (m_VBBlendIndices) g_VBMan.Release(m_VBBlendIndices); | m_VBBlendIndices.Reset(); | ||||
if (m_VBWater) g_VBMan.Release(m_VBWater); | m_VBWater.Reset(); | ||||
if (m_VBWaterIndices) g_VBMan.Release(m_VBWaterIndices); | m_VBWaterIndices.Reset(); | ||||
if (m_VBWaterShore) g_VBMan.Release(m_VBWaterShore); | m_VBWaterShore.Reset(); | ||||
if (m_VBWaterIndicesShore) g_VBMan.Release(m_VBWaterIndicesShore); | m_VBWaterIndicesShore.Reset(); | ||||
} | } | ||||
/** | /** | ||||
* Represents a blend for a single tile, texture and shape. | * Represents a blend for a single tile, texture and shape. | ||||
*/ | */ | ||||
struct STileBlend | struct STileBlend | ||||
{ | { | ||||
CTerrainTextureEntry* m_Texture; | CTerrainTextureEntry* m_Texture; | ||||
▲ Show 20 Lines • Show All 187 Lines • ▼ Show 20 Lines | for (size_t t = 0; t < blendLayers[k].m_Tiles.size(); ++t) | ||||
SBlendLayer::Tile& tile = blendLayers[k].m_Tiles[t]; | SBlendLayer::Tile& tile = blendLayers[k].m_Tiles[t]; | ||||
AddBlend(blendVertices, blendIndices, tile.i, tile.j, tile.shape, splat.m_Texture); | AddBlend(blendVertices, blendIndices, tile.i, tile.j, tile.shape, splat.m_Texture); | ||||
} | } | ||||
splat.m_IndexCount = blendIndices.size() - splat.m_IndexStart; | splat.m_IndexCount = blendIndices.size() - splat.m_IndexStart; | ||||
} | } | ||||
// Release existing vertex buffer chunks | // Release existing vertex buffer chunks | ||||
if (m_VBBlends) | m_VBBlends.Reset(); | ||||
{ | m_VBBlendIndices.Reset(); | ||||
g_VBMan.Release(m_VBBlends); | |||||
m_VBBlends = 0; | |||||
} | |||||
if (m_VBBlendIndices) | |||||
{ | |||||
g_VBMan.Release(m_VBBlendIndices); | |||||
m_VBBlendIndices = 0; | |||||
} | |||||
if (blendVertices.size()) | if (blendVertices.size()) | ||||
{ | { | ||||
// Construct vertex buffer | // Construct vertex buffer | ||||
m_VBBlends = g_VBMan.Allocate(sizeof(SBlendVertex), blendVertices.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER); | m_VBBlends = g_VBMan.AllocateChunk(sizeof(SBlendVertex), blendVertices.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER, nullptr, CVertexBufferManager::Group::TERRAIN); | ||||
m_VBBlends->m_Owner->UpdateChunkVertices(m_VBBlends, &blendVertices[0]); | m_VBBlends->m_Owner->UpdateChunkVertices(m_VBBlends.Get(), &blendVertices[0]); | ||||
// Update the indices to include the base offset of the vertex data | // Update the indices to include the base offset of the vertex data | ||||
for (size_t k = 0; k < blendIndices.size(); ++k) | for (size_t k = 0; k < blendIndices.size(); ++k) | ||||
blendIndices[k] += static_cast<u16>(m_VBBlends->m_Index); | blendIndices[k] += static_cast<u16>(m_VBBlends->m_Index); | ||||
m_VBBlendIndices = g_VBMan.Allocate(sizeof(u16), blendIndices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER); | m_VBBlendIndices = g_VBMan.AllocateChunk(sizeof(u16), blendIndices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER, nullptr, CVertexBufferManager::Group::TERRAIN); | ||||
m_VBBlendIndices->m_Owner->UpdateChunkVertices(m_VBBlendIndices, &blendIndices[0]); | m_VBBlendIndices->m_Owner->UpdateChunkVertices(m_VBBlendIndices.Get(), &blendIndices[0]); | ||||
} | } | ||||
} | } | ||||
void CPatchRData::AddBlend(std::vector<SBlendVertex>& blendVertices, std::vector<u16>& blendIndices, | void CPatchRData::AddBlend(std::vector<SBlendVertex>& blendVertices, std::vector<u16>& blendIndices, | ||||
u16 i, u16 j, u8 shape, CTerrainTextureEntry* texture) | u16 i, u16 j, u8 shape, CTerrainTextureEntry* texture) | ||||
{ | { | ||||
CTerrain* terrain = m_Patch->m_Parent; | CTerrain* terrain = m_Patch->m_Parent; | ||||
▲ Show 20 Lines • Show All 178 Lines • ▼ Show 20 Lines | for (ssize_t j = 0; j < PATCH_SIZE; j++) | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
splat.m_IndexCount=indices.size()-splat.m_IndexStart; | splat.m_IndexCount=indices.size()-splat.m_IndexStart; | ||||
} | } | ||||
// Release existing vertex buffer chunk | // Release existing vertex buffer chunk | ||||
if (m_VBBaseIndices) | m_VBBaseIndices.Reset(); | ||||
{ | |||||
g_VBMan.Release(m_VBBaseIndices); | |||||
m_VBBaseIndices = 0; | |||||
} | |||||
ENSURE(indices.size()); | ENSURE(indices.size()); | ||||
// Construct vertex buffer | // Construct vertex buffer | ||||
m_VBBaseIndices = g_VBMan.Allocate(sizeof(u16), indices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER); | m_VBBaseIndices = g_VBMan.AllocateChunk(sizeof(u16), indices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER, nullptr, CVertexBufferManager::Group::TERRAIN); | ||||
m_VBBaseIndices->m_Owner->UpdateChunkVertices(m_VBBaseIndices, &indices[0]); | m_VBBaseIndices->m_Owner->UpdateChunkVertices(m_VBBaseIndices.Get(), &indices[0]); | ||||
} | } | ||||
void CPatchRData::BuildVertices() | void CPatchRData::BuildVertices() | ||||
{ | { | ||||
PROFILE3("build vertices"); | PROFILE3("build vertices"); | ||||
// create both vertices and lighting colors | // create both vertices and lighting colors | ||||
Show All 25 Lines | for (ssize_t i = 0; i < vsize; ++i) | ||||
CVector3D normal; | CVector3D normal; | ||||
terrain->CalcNormal(ix, iz, normal); | terrain->CalcNormal(ix, iz, normal); | ||||
vertices[v].m_Normal = normal; | vertices[v].m_Normal = normal; | ||||
} | } | ||||
} | } | ||||
// upload to vertex buffer | // upload to vertex buffer | ||||
if (!m_VBBase) | if (!m_VBBase) | ||||
m_VBBase = g_VBMan.Allocate(sizeof(SBaseVertex), vsize * vsize, GL_STATIC_DRAW, GL_ARRAY_BUFFER); | m_VBBase = g_VBMan.AllocateChunk(sizeof(SBaseVertex), vsize * vsize, GL_STATIC_DRAW, GL_ARRAY_BUFFER, nullptr, CVertexBufferManager::Group::TERRAIN); | ||||
m_VBBase->m_Owner->UpdateChunkVertices(m_VBBase, &vertices[0]); | m_VBBase->m_Owner->UpdateChunkVertices(m_VBBase.Get(), &vertices[0]); | ||||
} | } | ||||
void CPatchRData::BuildSide(std::vector<SSideVertex>& vertices, CPatchSideFlags side) | void CPatchRData::BuildSide(std::vector<SSideVertex>& vertices, CPatchSideFlags side) | ||||
{ | { | ||||
ssize_t vsize = PATCH_SIZE + 1; | ssize_t vsize = PATCH_SIZE + 1; | ||||
CTerrain* terrain = m_Patch->m_Parent; | CTerrain* terrain = m_Patch->m_Parent; | ||||
CmpPtr<ICmpWaterManager> cmpWaterManager(*m_Simulation, SYSTEM_ENTITY); | CmpPtr<ICmpWaterManager> cmpWaterManager(*m_Simulation, SYSTEM_ENTITY); | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | void CPatchRData::BuildSides() | ||||
if (sideFlags & CPATCH_SIDE_POSZ) | if (sideFlags & CPATCH_SIDE_POSZ) | ||||
BuildSide(sideVertices, CPATCH_SIDE_POSZ); | BuildSide(sideVertices, CPATCH_SIDE_POSZ); | ||||
if (sideVertices.empty()) | if (sideVertices.empty()) | ||||
return; | return; | ||||
if (!m_VBSides) | if (!m_VBSides) | ||||
m_VBSides = g_VBMan.Allocate(sizeof(SSideVertex), sideVertices.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER); | m_VBSides = g_VBMan.AllocateChunk(sizeof(SSideVertex), sideVertices.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER, nullptr, CVertexBufferManager::Group::DEFAULT); | ||||
m_VBSides->m_Owner->UpdateChunkVertices(m_VBSides, &sideVertices[0]); | m_VBSides->m_Owner->UpdateChunkVertices(m_VBSides.Get(), &sideVertices[0]); | ||||
} | } | ||||
void CPatchRData::Build() | void CPatchRData::Build() | ||||
{ | { | ||||
BuildVertices(); | BuildVertices(); | ||||
BuildSides(); | BuildSides(); | ||||
BuildIndices(); | BuildIndices(); | ||||
BuildBlends(); | BuildBlends(); | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
using TextureBatches = PooledBatchMap<CTerrainTextureEntry*, VertexBufferBatches>; | using TextureBatches = PooledBatchMap<CTerrainTextureEntry*, VertexBufferBatches>; | ||||
// Group batches by shaders. | // Group batches by shaders. | ||||
using ShaderTechniqueBatches = PooledBatchMap<CShaderTechniquePtr, TextureBatches>; | using ShaderTechniqueBatches = PooledBatchMap<CShaderTechniquePtr, TextureBatches>; | ||||
void CPatchRData::RenderBases( | void CPatchRData::RenderBases( | ||||
const std::vector<CPatchRData*>& patches, const CShaderDefines& context, ShadowMap* shadow) | const std::vector<CPatchRData*>& patches, const CShaderDefines& context, ShadowMap* shadow) | ||||
{ | { | ||||
PROFILE3("render terrain bases"); | |||||
Arena arena; | Arena arena; | ||||
ShaderTechniqueBatches batches(ShaderTechniqueBatches::key_compare(), (ShaderTechniqueBatches::allocator_type(arena))); | ShaderTechniqueBatches batches(ShaderTechniqueBatches::key_compare(), (ShaderTechniqueBatches::allocator_type(arena))); | ||||
PROFILE_START("compute batches"); | PROFILE_START("compute batches"); | ||||
// Collect all the patches' base splats into their appropriate batches | // Collect all the patches' base splats into their appropriate batches | ||||
for (size_t i = 0; i < patches.size(); ++i) | for (size_t i = 0; i < patches.size(); ++i) | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | struct SBlendStackItem | ||||
CVertexBuffer::VBChunk* vertices; | CVertexBuffer::VBChunk* vertices; | ||||
CVertexBuffer::VBChunk* indices; | CVertexBuffer::VBChunk* indices; | ||||
SplatStack splats; | SplatStack splats; | ||||
}; | }; | ||||
void CPatchRData::RenderBlends( | void CPatchRData::RenderBlends( | ||||
const std::vector<CPatchRData*>& patches, const CShaderDefines& context, ShadowMap* shadow) | const std::vector<CPatchRData*>& patches, const CShaderDefines& context, ShadowMap* shadow) | ||||
{ | { | ||||
PROFILE3("render terrain blends"); | |||||
Arena arena; | Arena arena; | ||||
using BatchesStack = std::vector<SBlendBatch, ProxyAllocator<SBlendBatch, Arena>>; | using BatchesStack = std::vector<SBlendBatch, ProxyAllocator<SBlendBatch, Arena>>; | ||||
BatchesStack batches((BatchesStack::allocator_type(arena))); | BatchesStack batches((BatchesStack::allocator_type(arena))); | ||||
CShaderDefines contextBlend = context; | CShaderDefines contextBlend = context; | ||||
contextBlend.Add(str_BLEND, str_1); | contextBlend.Add(str_BLEND, str_1); | ||||
Show All 9 Lines | void CPatchRData::RenderBlends( | ||||
// Extract all the blend splats from each patch | // Extract all the blend splats from each patch | ||||
for (size_t i = 0; i < patches.size(); ++i) | for (size_t i = 0; i < patches.size(); ++i) | ||||
{ | { | ||||
CPatchRData* patch = patches[i]; | CPatchRData* patch = patches[i]; | ||||
if (!patch->m_BlendSplats.empty()) | if (!patch->m_BlendSplats.empty()) | ||||
{ | { | ||||
blendStacks.push_back(SBlendStackItem(patch->m_VBBlends, patch->m_VBBlendIndices, patch->m_BlendSplats, arena)); | blendStacks.push_back(SBlendStackItem(patch->m_VBBlends.Get(), patch->m_VBBlendIndices.Get(), patch->m_BlendSplats, arena)); | ||||
// Reverse the splats so the first to be rendered is at the back of the list | // Reverse the splats so the first to be rendered is at the back of the list | ||||
std::reverse(blendStacks.back().splats.begin(), blendStacks.back().splats.end()); | std::reverse(blendStacks.back().splats.begin(), blendStacks.back().splats.end()); | ||||
} | } | ||||
} | } | ||||
// Rearrange the collection of splats to be grouped by texture, preserving | // Rearrange the collection of splats to be grouped by texture, preserving | ||||
// order of splats within each patch: | // order of splats within each patch: | ||||
// (This is exactly the same algorithm used in CPatchRData::BuildBlends, | // (This is exactly the same algorithm used in CPatchRData::BuildBlends, | ||||
▲ Show 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | void CPatchRData::RenderBlends( | ||||
glDisable(GL_BLEND); | glDisable(GL_BLEND); | ||||
CVertexBuffer::Unbind(); | CVertexBuffer::Unbind(); | ||||
} | } | ||||
void CPatchRData::RenderStreams(const std::vector<CPatchRData*>& patches, const CShaderProgramPtr& shader, int streamflags) | void CPatchRData::RenderStreams(const std::vector<CPatchRData*>& patches, const CShaderProgramPtr& shader, int streamflags) | ||||
{ | { | ||||
PROFILE3("render terrain streams"); | |||||
// Each batch has a list of index counts, and a list of pointers-to-first-indexes | // Each batch has a list of index counts, and a list of pointers-to-first-indexes | ||||
using StreamBatchElements = std::pair<std::vector<GLint>, std::vector<void*> > ; | using StreamBatchElements = std::pair<std::vector<GLint>, std::vector<void*> > ; | ||||
// Group batches by index buffer | // Group batches by index buffer | ||||
using StreamIndexBufferBatches = std::map<CVertexBuffer*, StreamBatchElements> ; | using StreamIndexBufferBatches = std::map<CVertexBuffer*, StreamBatchElements> ; | ||||
// Group batches by vertex buffer | // Group batches by vertex buffer | ||||
using StreamVertexBufferBatches = std::map<CVertexBuffer*, StreamIndexBufferBatches> ; | using StreamVertexBufferBatches = std::map<CVertexBuffer*, StreamIndexBufferBatches> ; | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | |||||
#if CONFIG2_GLES | #if CONFIG2_GLES | ||||
#warning TODO: implement CPatchRData::RenderOutlines for GLES | #warning TODO: implement CPatchRData::RenderOutlines for GLES | ||||
#else | #else | ||||
glVertexPointer(3, GL_FLOAT, sizeof(CVector3D), &line[0]); | glVertexPointer(3, GL_FLOAT, sizeof(CVector3D), &line[0]); | ||||
glDrawArrays(GL_LINE_STRIP, 0, line.size()); | glDrawArrays(GL_LINE_STRIP, 0, line.size()); | ||||
#endif | #endif | ||||
} | } | ||||
void CPatchRData::RenderSides(CShaderProgramPtr& shader) | void CPatchRData::RenderSides(const std::vector<CPatchRData*>& patches, const CShaderProgramPtr& shader) | ||||
{ | { | ||||
ENSURE(m_UpdateFlags==0); | |||||
if (!m_VBSides) | |||||
return; | |||||
glDisable(GL_CULL_FACE); | glDisable(GL_CULL_FACE); | ||||
SSideVertex *base = (SSideVertex *)m_VBSides->m_Owner->Bind(); | CVertexBuffer* lastVB = nullptr; | ||||
for (CPatchRData* patch : patches) | |||||
{ | |||||
ENSURE(patch->m_UpdateFlags == 0); | |||||
if (!patch->m_VBSides) | |||||
continue; | |||||
if (lastVB != patch->m_VBSides->m_Owner) | |||||
{ | |||||
lastVB = patch->m_VBSides->m_Owner; | |||||
SSideVertex *base = (SSideVertex*)patch->m_VBSides->m_Owner->Bind(); | |||||
// setup data pointers | // setup data pointers | ||||
GLsizei stride = sizeof(SSideVertex); | GLsizei stride = sizeof(SSideVertex); | ||||
shader->VertexPointer(3, GL_FLOAT, stride, &base->m_Position); | shader->VertexPointer(3, GL_FLOAT, stride, &base->m_Position); | ||||
} | |||||
shader->AssertPointersBound(); | shader->AssertPointersBound(); | ||||
if (!g_Renderer.m_SkipSubmit) | if (!g_Renderer.m_SkipSubmit) | ||||
glDrawArrays(GL_TRIANGLE_STRIP, m_VBSides->m_Index, (GLsizei)m_VBSides->m_Count); | glDrawArrays(GL_TRIANGLE_STRIP, patch->m_VBSides->m_Index, (GLsizei)patch->m_VBSides->m_Count); | ||||
// bump stats | // bump stats | ||||
g_Renderer.m_Stats.m_DrawCalls++; | g_Renderer.m_Stats.m_DrawCalls++; | ||||
g_Renderer.m_Stats.m_TerrainTris += m_VBSides->m_Count - 2; | g_Renderer.m_Stats.m_TerrainTris += patch->m_VBSides->m_Count - 2; | ||||
} | |||||
CVertexBuffer::Unbind(); | CVertexBuffer::Unbind(); | ||||
glEnable(GL_CULL_FACE); | glEnable(GL_CULL_FACE); | ||||
} | } | ||||
void CPatchRData::RenderPriorities(CTextRenderer& textRenderer) | void CPatchRData::RenderPriorities(CTextRenderer& textRenderer) | ||||
{ | { | ||||
Show All 29 Lines | |||||
// Build vertex buffer for water vertices over our patch | // Build vertex buffer for water vertices over our patch | ||||
void CPatchRData::BuildWater() | void CPatchRData::BuildWater() | ||||
{ | { | ||||
PROFILE3("build water"); | PROFILE3("build water"); | ||||
// Number of vertices in each direction in each patch | // Number of vertices in each direction in each patch | ||||
ENSURE(PATCH_SIZE % water_cell_size == 0); | ENSURE(PATCH_SIZE % water_cell_size == 0); | ||||
if (m_VBWater) | m_VBWater.Reset(); | ||||
{ | m_VBWaterIndices.Reset(); | ||||
g_VBMan.Release(m_VBWater); | m_VBWaterShore.Reset(); | ||||
m_VBWater = nullptr; | m_VBWaterIndicesShore.Reset(); | ||||
} | |||||
if (m_VBWaterIndices) | |||||
{ | |||||
g_VBMan.Release(m_VBWaterIndices); | |||||
m_VBWaterIndices = nullptr; | |||||
} | |||||
if (m_VBWaterShore) | |||||
{ | |||||
g_VBMan.Release(m_VBWaterShore); | |||||
m_VBWaterShore = nullptr; | |||||
} | |||||
if (m_VBWaterIndicesShore) | |||||
{ | |||||
g_VBMan.Release(m_VBWaterIndicesShore); | |||||
m_VBWaterIndicesShore = nullptr; | |||||
} | |||||
m_WaterBounds.SetEmpty(); | m_WaterBounds.SetEmpty(); | ||||
// We need to use this to access the water manager or we may not have the | // We need to use this to access the water manager or we may not have the | ||||
// actual values but some compiled-in defaults | // actual values but some compiled-in defaults | ||||
CmpPtr<ICmpWaterManager> cmpWaterManager(*m_Simulation, SYSTEM_ENTITY); | CmpPtr<ICmpWaterManager> cmpWaterManager(*m_Simulation, SYSTEM_ENTITY); | ||||
if (!cmpWaterManager) | if (!cmpWaterManager) | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | for (ssize_t x = 0; x < PATCH_SIZE; x += water_cell_size) | ||||
water_indices_shore.push_back(water_shore_index_map[z + moves[1][1]][x + moves[1][0]]); | water_indices_shore.push_back(water_shore_index_map[z + moves[1][1]][x + moves[1][0]]); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// No vertex buffers if no data generated | // No vertex buffers if no data generated | ||||
if (!water_indices.empty()) | if (!water_indices.empty()) | ||||
{ | { | ||||
m_VBWater = g_VBMan.Allocate(sizeof(SWaterVertex), water_vertex_data.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER); | m_VBWater = g_VBMan.AllocateChunk(sizeof(SWaterVertex), water_vertex_data.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER, nullptr, CVertexBufferManager::Group::WATER); | ||||
m_VBWater->m_Owner->UpdateChunkVertices(m_VBWater, &water_vertex_data[0]); | m_VBWater->m_Owner->UpdateChunkVertices(m_VBWater.Get(), &water_vertex_data[0]); | ||||
m_VBWaterIndices = g_VBMan.Allocate(sizeof(GLushort), water_indices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER); | m_VBWaterIndices = g_VBMan.AllocateChunk(sizeof(GLushort), water_indices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER, nullptr, CVertexBufferManager::Group::WATER); | ||||
m_VBWaterIndices->m_Owner->UpdateChunkVertices(m_VBWaterIndices, &water_indices[0]); | m_VBWaterIndices->m_Owner->UpdateChunkVertices(m_VBWaterIndices.Get(), &water_indices[0]); | ||||
} | } | ||||
if (!water_indices_shore.empty()) | if (!water_indices_shore.empty()) | ||||
{ | { | ||||
m_VBWaterShore = g_VBMan.Allocate(sizeof(SWaterVertex), water_vertex_data_shore.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER); | m_VBWaterShore = g_VBMan.AllocateChunk(sizeof(SWaterVertex), water_vertex_data_shore.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER, nullptr, CVertexBufferManager::Group::WATER); | ||||
m_VBWaterShore->m_Owner->UpdateChunkVertices(m_VBWaterShore, &water_vertex_data_shore[0]); | m_VBWaterShore->m_Owner->UpdateChunkVertices(m_VBWaterShore.Get(), &water_vertex_data_shore[0]); | ||||
// Construct indices buffer | // Construct indices buffer | ||||
m_VBWaterIndicesShore = g_VBMan.Allocate(sizeof(GLushort), water_indices_shore.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER); | m_VBWaterIndicesShore = g_VBMan.AllocateChunk(sizeof(GLushort), water_indices_shore.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER, nullptr, CVertexBufferManager::Group::WATER); | ||||
m_VBWaterIndicesShore->m_Owner->UpdateChunkVertices(m_VBWaterIndicesShore, &water_indices_shore[0]); | m_VBWaterIndicesShore->m_Owner->UpdateChunkVertices(m_VBWaterIndicesShore.Get(), &water_indices_shore[0]); | ||||
} | } | ||||
} | } | ||||
void CPatchRData::RenderWater(CShaderProgramPtr& shader, bool onlyShore, bool fixedPipeline) | void CPatchRData::RenderWater(CShaderProgramPtr& shader, bool onlyShore, bool fixedPipeline) | ||||
{ | { | ||||
ASSERT(m_UpdateFlags==0); | ASSERT(m_UpdateFlags==0); | ||||
if (g_Renderer.m_SkipSubmit || (!m_VBWater && !m_VBWaterShore)) | if (g_Renderer.m_SkipSubmit || (!m_VBWater && !m_VBWaterShore)) | ||||
return; | return; | ||||
#if !CONFIG2_GLES | #if !CONFIG2_GLES | ||||
if (g_Renderer.GetWaterRenderMode() == WIREFRAME) | if (g_Renderer.GetWaterRenderMode() == WIREFRAME) | ||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||||
#endif | #endif | ||||
if (m_VBWater != 0x0 && !onlyShore) | if (m_VBWater && !onlyShore) | ||||
{ | { | ||||
SWaterVertex *base=(SWaterVertex *)m_VBWater->m_Owner->Bind(); | SWaterVertex *base=(SWaterVertex *)m_VBWater->m_Owner->Bind(); | ||||
// setup data pointers | // setup data pointers | ||||
GLsizei stride = sizeof(SWaterVertex); | GLsizei stride = sizeof(SWaterVertex); | ||||
shader->VertexPointer(3, GL_FLOAT, stride, &base[m_VBWater->m_Index].m_Position); | shader->VertexPointer(3, GL_FLOAT, stride, &base[m_VBWater->m_Index].m_Position); | ||||
if (!fixedPipeline) | if (!fixedPipeline) | ||||
shader->VertexAttribPointer(str_a_waterInfo, 2, GL_FLOAT, false, stride, &base[m_VBWater->m_Index].m_WaterData); | shader->VertexAttribPointer(str_a_waterInfo, 2, GL_FLOAT, false, stride, &base[m_VBWater->m_Index].m_WaterData); | ||||
shader->AssertPointersBound(); | shader->AssertPointersBound(); | ||||
u8* indexBase = m_VBWaterIndices->m_Owner->Bind(); | u8* indexBase = m_VBWaterIndices->m_Owner->Bind(); | ||||
glDrawElements(GL_TRIANGLES, (GLsizei) m_VBWaterIndices->m_Count, | glDrawElements(GL_TRIANGLES, (GLsizei) m_VBWaterIndices->m_Count, | ||||
GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(m_VBWaterIndices->m_Index)); | GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(m_VBWaterIndices->m_Index)); | ||||
g_Renderer.m_Stats.m_DrawCalls++; | g_Renderer.m_Stats.m_DrawCalls++; | ||||
g_Renderer.m_Stats.m_WaterTris += m_VBWaterIndices->m_Count / 3; | g_Renderer.m_Stats.m_WaterTris += m_VBWaterIndices->m_Count / 3; | ||||
} | } | ||||
if (m_VBWaterShore != 0x0 && | if (m_VBWaterShore && | ||||
g_Renderer.GetWaterManager()->m_WaterEffects && | g_Renderer.GetWaterManager()->m_WaterEffects && | ||||
g_Renderer.GetWaterManager()->m_WaterFancyEffects) | g_Renderer.GetWaterManager()->m_WaterFancyEffects) | ||||
{ | { | ||||
SWaterVertex *base=(SWaterVertex *)m_VBWaterShore->m_Owner->Bind(); | SWaterVertex *base=(SWaterVertex *)m_VBWaterShore->m_Owner->Bind(); | ||||
GLsizei stride = sizeof(SWaterVertex); | GLsizei stride = sizeof(SWaterVertex); | ||||
shader->VertexPointer(3, GL_FLOAT, stride, &base[m_VBWaterShore->m_Index].m_Position); | shader->VertexPointer(3, GL_FLOAT, stride, &base[m_VBWaterShore->m_Index].m_Position); | ||||
if (!fixedPipeline) | if (!fixedPipeline) | ||||
Show All 19 Lines |
Wildfire Games · Phabricator