forked from 0ad/0ad
Moves all GL draw commands to CDeviceCommandContext.
Differential Revision: https://code.wildfiregames.com/D4518 This was SVN commit r26525.
This commit is contained in:
parent
7c3aed5f36
commit
3a4bbd11fd
@ -60,7 +60,7 @@ inline void DrawTextureImpl(
|
||||
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, uvs.data());
|
||||
shader->AssertPointersBound();
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 2);
|
||||
deviceCommandContext->Draw(0, vertices.size() / 2);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
@ -253,7 +253,8 @@ void CCanvas2D::DrawLine(const std::vector<CVector2D>& points, const float width
|
||||
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, uvs.data());
|
||||
shader->AssertPointersBound();
|
||||
|
||||
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, indices.data());
|
||||
m->DeviceCommandContext->SetIndexBufferData(indices.data());
|
||||
m->DeviceCommandContext->DrawIndexed(0, indices.size(), 0);
|
||||
}
|
||||
|
||||
void CCanvas2D::DrawRect(const CRect& rect, const CColor& color)
|
||||
|
@ -184,7 +184,7 @@ void CLOSTexture::InterpolateLOS(Renderer::Backend::GL::CDeviceCommandContext* d
|
||||
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex);
|
||||
shader->VertexPointer(2, GL_FLOAT, 0, quadVerts);
|
||||
shader->AssertPointersBound();
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
deviceCommandContext->Draw(0, 6);
|
||||
|
||||
g_Renderer.SetViewport(oldVp);
|
||||
|
||||
|
@ -68,7 +68,9 @@ unsigned int ScaleColor(unsigned int color, float x)
|
||||
return (0xff000000 | b | g << 8 | r << 16);
|
||||
}
|
||||
|
||||
void DrawTexture(const CShaderProgramPtr& shader)
|
||||
void DrawTexture(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
|
||||
const CShaderProgramPtr& shader)
|
||||
{
|
||||
const float quadUVs[] =
|
||||
{
|
||||
@ -95,7 +97,7 @@ void DrawTexture(const CShaderProgramPtr& shader)
|
||||
shader->VertexPointer(3, GL_FLOAT, 0, quadVertices);
|
||||
shader->AssertPointersBound();
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
deviceCommandContext->Draw(0, 6);
|
||||
}
|
||||
|
||||
struct MinimapUnitVertex
|
||||
@ -387,7 +389,7 @@ void CMiniMapTexture::RenderFinalTexture(
|
||||
shader->Uniform(str_textureTransform, terrainTransform);
|
||||
|
||||
if (m_TerrainTexture)
|
||||
DrawTexture(shader);
|
||||
DrawTexture(deviceCommandContext, shader);
|
||||
|
||||
pipelineStateDesc.blendState.enabled = true;
|
||||
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
||||
@ -409,7 +411,7 @@ void CMiniMapTexture::RenderFinalTexture(
|
||||
shader->Uniform(str_transform, baseTransform);
|
||||
shader->Uniform(str_textureTransform, territoryTexture.GetMinimapTextureMatrix());
|
||||
|
||||
DrawTexture(shader);
|
||||
DrawTexture(deviceCommandContext, shader);
|
||||
|
||||
pipelineStateDesc.blendState.enabled = false;
|
||||
pipelineStateDesc.blendState.colorWriteMask =
|
||||
@ -420,7 +422,7 @@ void CMiniMapTexture::RenderFinalTexture(
|
||||
shader->Uniform(str_transform, baseTransform);
|
||||
shader->Uniform(str_textureTransform, losTexture.GetMinimapTextureMatrix());
|
||||
|
||||
DrawTexture(shader);
|
||||
DrawTexture(deviceCommandContext, shader);
|
||||
|
||||
tech->EndPass();
|
||||
|
||||
@ -528,7 +530,7 @@ void CMiniMapTexture::RenderFinalTexture(
|
||||
scissorRect.width = scissorRect.height = FINAL_TEXTURE_SIZE - 2;
|
||||
deviceCommandContext->SetScissors(1, &scissorRect);
|
||||
|
||||
u8* indexBase = m_IndexArray.Bind(deviceCommandContext);
|
||||
m_IndexArray.UploadIfNeeded(deviceCommandContext);
|
||||
u8* base = m_VertexArray.Bind(deviceCommandContext);
|
||||
const GLsizei stride = (GLsizei)m_VertexArray.GetStride();
|
||||
|
||||
@ -536,7 +538,8 @@ void CMiniMapTexture::RenderFinalTexture(
|
||||
shader->ColorPointer(4, GL_UNSIGNED_BYTE, stride, base + m_AttributeColor.offset);
|
||||
shader->AssertPointersBound();
|
||||
|
||||
glDrawElements(GL_TRIANGLES, m_EntitiesDrawn * 6, GL_UNSIGNED_SHORT, indexBase);
|
||||
deviceCommandContext->SetIndexBuffer(m_IndexArray.GetBuffer());
|
||||
deviceCommandContext->DrawIndexed(m_IndexArray.GetOffset(), m_EntitiesDrawn * 6, 0);
|
||||
|
||||
g_Renderer.GetStats().m_DrawCalls++;
|
||||
CVertexBuffer::Unbind(deviceCommandContext);
|
||||
|
@ -200,12 +200,10 @@ void CParticleEmitter::RenderArray(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
|
||||
const CShaderProgramPtr& shader)
|
||||
{
|
||||
// Some drivers apparently don't like count=0 in glDrawArrays here,
|
||||
// so skip all drawing in that case
|
||||
if (m_Particles.empty())
|
||||
return;
|
||||
|
||||
u8* indexBase = m_IndexArray.Bind(deviceCommandContext);
|
||||
m_IndexArray.UploadIfNeeded(deviceCommandContext);
|
||||
u8* base = m_VertexArray.Bind(deviceCommandContext);
|
||||
|
||||
GLsizei stride = (GLsizei)m_VertexArray.GetStride();
|
||||
@ -220,7 +218,9 @@ void CParticleEmitter::RenderArray(
|
||||
shader->ColorPointer(4, GL_UNSIGNED_BYTE, stride, base + m_AttributeColor.offset);
|
||||
|
||||
shader->AssertPointersBound();
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)(m_Particles.size() * 6), GL_UNSIGNED_SHORT, indexBase);
|
||||
|
||||
deviceCommandContext->SetIndexBuffer(m_IndexArray.GetBuffer());
|
||||
deviceCommandContext->DrawIndexed(m_IndexArray.GetOffset(), m_Particles.size() * 6, 0);
|
||||
|
||||
g_Renderer.GetStats().m_DrawCalls++;
|
||||
g_Renderer.GetStats().m_Particles += m_Particles.size();
|
||||
|
@ -182,7 +182,7 @@ public:
|
||||
|
||||
/**
|
||||
* Checks that all the required vertex attributes have been set.
|
||||
* Call this before calling glDrawArrays/glDrawElements etc to avoid potential crashes.
|
||||
* Call this before calling Draw/DrawIndexed etc to avoid potential crashes.
|
||||
*/
|
||||
void AssertPointersBound();
|
||||
|
||||
|
@ -263,13 +263,14 @@ void CTextRenderer::Render(
|
||||
|
||||
size_t idx = 0;
|
||||
|
||||
auto flush = [&idx, &vertexes, &indexes, &shader]() -> void {
|
||||
auto flush = [deviceCommandContext, &idx, &vertexes, &indexes, &shader]() -> void {
|
||||
if (idx == 0)
|
||||
return;
|
||||
shader->VertexPointer(2, GL_SHORT, sizeof(t2f_v2i), &vertexes[0].x);
|
||||
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, sizeof(t2f_v2i), &vertexes[0].u);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, idx * 6, GL_UNSIGNED_SHORT, &indexes[0]);
|
||||
deviceCommandContext->SetIndexBufferData(indexes.data());
|
||||
deviceCommandContext->DrawIndexed(0, idx * 6, 0);
|
||||
idx = 0;
|
||||
};
|
||||
|
||||
|
@ -95,7 +95,9 @@ void CropPointsByCircle(const std::array<CVector3D, 4>& points, const CVector3D&
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTexture(CShaderProgramPtr shader, float angle, float x, float y, float x2, float y2, float mapScale)
|
||||
void DrawTexture(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
|
||||
const CShaderProgramPtr& shader, float angle, float x, float y, float x2, float y2, float mapScale)
|
||||
{
|
||||
// Rotate the texture coordinates (0,0)-(coordMax,coordMax) around their center point (m,m)
|
||||
// Scale square maps to fit in circular minimap area
|
||||
@ -126,7 +128,7 @@ void DrawTexture(CShaderProgramPtr shader, float angle, float x, float y, float
|
||||
shader->VertexPointer(3, GL_FLOAT, 0, quadVerts);
|
||||
shader->AssertPointersBound();
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
deviceCommandContext->Draw(0, 6);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
@ -422,7 +424,9 @@ void CMiniMap::Draw(CCanvas2D& canvas)
|
||||
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
||||
Renderer::Backend::BlendOp::ADD;
|
||||
tech->BeginPass();
|
||||
g_Renderer.GetDeviceCommandContext()->SetGraphicsPipelineState(pipelineStateDesc);
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext =
|
||||
g_Renderer.GetDeviceCommandContext();
|
||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
||||
shader = tech->GetShader();
|
||||
|
||||
shader->BindTexture(str_baseTex, miniMapTexture.GetTexture());
|
||||
@ -435,7 +439,7 @@ void CMiniMap::Draw(CCanvas2D& canvas)
|
||||
const float x = m_CachedActualSize.left, y = m_CachedActualSize.bottom;
|
||||
const float x2 = m_CachedActualSize.right, y2 = m_CachedActualSize.top;
|
||||
const float angle = GetAngle();
|
||||
DrawTexture(shader, angle, x, y, x2, y2, m_MapScale);
|
||||
DrawTexture(deviceCommandContext, shader, angle, x, y, x2, y2, m_MapScale);
|
||||
|
||||
tech->EndPass();
|
||||
}
|
||||
|
@ -86,7 +86,10 @@ void CDebugRenderer::DrawLine(
|
||||
CShaderTechniquePtr debugLineTech =
|
||||
g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
|
||||
debugLineTech->BeginPass();
|
||||
SetGraphicsPipelineStateFromTechAndColor(g_Renderer.GetDeviceCommandContext(), debugLineTech, color, depthTestEnabled);
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext =
|
||||
g_Renderer.GetDeviceCommandContext();
|
||||
SetGraphicsPipelineStateFromTechAndColor(
|
||||
deviceCommandContext, debugLineTech, color, depthTestEnabled);
|
||||
|
||||
const CCamera& viewCamera = g_Renderer.GetSceneRenderer().GetViewCamera();
|
||||
|
||||
@ -125,7 +128,7 @@ void CDebugRenderer::DrawLine(
|
||||
|
||||
debugLineShader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
|
||||
debugLineShader->AssertPointersBound();
|
||||
glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 3);
|
||||
deviceCommandContext->Draw(0, vertices.size() / 3);
|
||||
|
||||
debugLineTech->EndPass();
|
||||
#endif
|
||||
@ -140,7 +143,10 @@ void CDebugRenderer::DrawCircle(const CVector3D& origin, const float radius, con
|
||||
CShaderTechniquePtr debugCircleTech =
|
||||
g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
|
||||
debugCircleTech->BeginPass();
|
||||
SetGraphicsPipelineStateFromTechAndColor(g_Renderer.GetDeviceCommandContext(), debugCircleTech, color);
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext =
|
||||
g_Renderer.GetDeviceCommandContext();
|
||||
SetGraphicsPipelineStateFromTechAndColor(
|
||||
deviceCommandContext, debugCircleTech, color);
|
||||
|
||||
const CCamera& camera = g_Renderer.GetSceneRenderer().GetViewCamera();
|
||||
|
||||
@ -173,7 +179,7 @@ void CDebugRenderer::DrawCircle(const CVector3D& origin, const float radius, con
|
||||
|
||||
debugCircleShader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
|
||||
debugCircleShader->AssertPointersBound();
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, vertices.size() / 3);
|
||||
deviceCommandContext->Draw(0, vertices.size() / 3);
|
||||
|
||||
debugCircleTech->EndPass();
|
||||
#endif
|
||||
@ -199,7 +205,10 @@ void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, const CColor& colo
|
||||
CShaderTechniquePtr overlayTech =
|
||||
g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
|
||||
overlayTech->BeginPass();
|
||||
SetGraphicsPipelineStateFromTechAndColor(g_Renderer.GetDeviceCommandContext(), overlayTech, color, true, wireframe);
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext =
|
||||
g_Renderer.GetDeviceCommandContext();
|
||||
SetGraphicsPipelineStateFromTechAndColor(
|
||||
deviceCommandContext, overlayTech, color, true, wireframe);
|
||||
|
||||
CShaderProgramPtr overlayShader = overlayTech->GetShader();
|
||||
overlayShader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
|
||||
@ -246,7 +255,7 @@ void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, const CColor& colo
|
||||
|
||||
overlayShader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
|
||||
overlayShader->AssertPointersBound();
|
||||
glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 3);
|
||||
deviceCommandContext->Draw(0, vertices.size() / 3);
|
||||
|
||||
vertices.clear();
|
||||
|
||||
@ -264,7 +273,7 @@ void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, const CColor& colo
|
||||
|
||||
overlayShader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
|
||||
overlayShader->AssertPointersBound();
|
||||
glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 3);
|
||||
deviceCommandContext->Draw(0, vertices.size() / 3);
|
||||
#undef ADD
|
||||
|
||||
overlayTech->EndPass();
|
||||
@ -286,8 +295,10 @@ void CDebugRenderer::DrawBoundingBox(
|
||||
{
|
||||
CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
|
||||
shaderTech->BeginPass();
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext =
|
||||
g_Renderer.GetDeviceCommandContext();
|
||||
SetGraphicsPipelineStateFromTechAndColor(
|
||||
g_Renderer.GetDeviceCommandContext(), shaderTech, color, true, wireframe);
|
||||
deviceCommandContext, shaderTech, color, true, wireframe);
|
||||
|
||||
const CShaderProgramPtr& shader = shaderTech->GetShader();
|
||||
shader->Uniform(str_color, color);
|
||||
@ -317,7 +328,7 @@ void CDebugRenderer::DrawBoundingBox(
|
||||
shader->VertexPointer(3, GL_FLOAT, 3 * sizeof(float), data.data());
|
||||
|
||||
shader->AssertPointersBound();
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6*6);
|
||||
deviceCommandContext->Draw(0, 6*6);
|
||||
|
||||
shaderTech->EndPass();
|
||||
}
|
||||
@ -326,8 +337,10 @@ void CDebugRenderer::DrawBrush(const CBrush& brush, const CColor& color, bool wi
|
||||
{
|
||||
CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
|
||||
shaderTech->BeginPass();
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext =
|
||||
g_Renderer.GetDeviceCommandContext();
|
||||
SetGraphicsPipelineStateFromTechAndColor(
|
||||
g_Renderer.GetDeviceCommandContext(), shaderTech, color, true, wireframe);
|
||||
deviceCommandContext, shaderTech, color, true, wireframe);
|
||||
|
||||
const CShaderProgramPtr& shader = shaderTech->GetShader();
|
||||
shader->Uniform(str_color, color);
|
||||
@ -361,7 +374,7 @@ void CDebugRenderer::DrawBrush(const CBrush& brush, const CColor& color, bool wi
|
||||
shader->VertexPointer(3, GL_FLOAT, 3 * sizeof(float), data.data());
|
||||
|
||||
shader->AssertPointersBound();
|
||||
glDrawArrays(GL_TRIANGLES, 0, data.size() / 5);
|
||||
deviceCommandContext->Draw(0, data.size() / 5);
|
||||
|
||||
shaderTech->EndPass();
|
||||
}
|
||||
|
@ -211,11 +211,11 @@ void CDecalRData::RenderDecals(
|
||||
if (lastIB != batch.indices->m_Owner)
|
||||
{
|
||||
lastIB = batch.indices->m_Owner;
|
||||
batch.indices->m_Owner->Bind(deviceCommandContext);
|
||||
batch.indices->m_Owner->UploadIfNeeded(deviceCommandContext);
|
||||
deviceCommandContext->SetIndexBuffer(batch.indices->m_Owner->GetBuffer());
|
||||
}
|
||||
|
||||
u8* indexBase = nullptr;
|
||||
glDrawElements(GL_TRIANGLES, batch.indices->m_Count, GL_UNSIGNED_SHORT, indexBase + sizeof(u16) * (batch.indices->m_Index));
|
||||
deviceCommandContext->DrawIndexed(batch.indices->m_Index, batch.indices->m_Count, 0);
|
||||
|
||||
// bump stats
|
||||
g_Renderer.m_Stats.m_DrawCalls++;
|
||||
|
@ -221,7 +221,8 @@ void ShaderModelVertexRenderer::RenderModel(
|
||||
u8* base = shadermodel->m_Array.Bind(deviceCommandContext);
|
||||
GLsizei stride = (GLsizei)shadermodel->m_Array.GetStride();
|
||||
|
||||
u8* indexBase = m->shadermodeldef->m_IndexArray.Bind(deviceCommandContext);
|
||||
m->shadermodeldef->m_IndexArray.UploadIfNeeded(deviceCommandContext);
|
||||
deviceCommandContext->SetIndexBuffer(m->shadermodeldef->m_IndexArray.GetBuffer());
|
||||
|
||||
if (streamflags & STREAM_POS)
|
||||
shader->VertexPointer(3, GL_FLOAT, stride, base + shadermodel->m_Position.offset);
|
||||
@ -231,19 +232,14 @@ void ShaderModelVertexRenderer::RenderModel(
|
||||
|
||||
shader->AssertPointersBound();
|
||||
|
||||
// render the lot
|
||||
size_t numFaces = mdldef->GetNumFaces();
|
||||
// Render the lot.
|
||||
const size_t numberOfFaces = mdldef->GetNumFaces();
|
||||
|
||||
// Draw with DrawRangeElements where available, since it might be more efficient
|
||||
#if CONFIG2_GLES
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)numFaces*3, GL_UNSIGNED_SHORT, indexBase);
|
||||
#else
|
||||
glDrawRangeElementsEXT(GL_TRIANGLES, 0, (GLuint)mdldef->GetNumVertices()-1,
|
||||
(GLsizei)numFaces*3, GL_UNSIGNED_SHORT, indexBase);
|
||||
#endif
|
||||
deviceCommandContext->DrawIndexedInRange(
|
||||
m->shadermodeldef->m_IndexArray.GetOffset(), numberOfFaces * 3, 0, mdldef->GetNumVertices() - 1);
|
||||
|
||||
// bump stats
|
||||
// Bump stats.
|
||||
g_Renderer.m_Stats.m_DrawCalls++;
|
||||
g_Renderer.m_Stats.m_ModelTris += numFaces;
|
||||
g_Renderer.m_Stats.m_ModelTris += numberOfFaces;
|
||||
}
|
||||
|
||||
|
@ -327,7 +327,8 @@ void InstancingModelRenderer::PrepareModelDef(
|
||||
u8* base = m->imodeldef->m_Array.Bind(deviceCommandContext);
|
||||
GLsizei stride = (GLsizei)m->imodeldef->m_Array.GetStride();
|
||||
|
||||
m->imodeldefIndexBase = m->imodeldef->m_IndexArray.Bind(deviceCommandContext);
|
||||
m->imodeldef->m_IndexArray.UploadIfNeeded(deviceCommandContext);
|
||||
deviceCommandContext->SetIndexBuffer(m->imodeldef->m_IndexArray.GetBuffer());
|
||||
|
||||
if (streamflags & STREAM_POS)
|
||||
shader->VertexPointer(3, GL_FLOAT, stride, base + m->imodeldef->m_Position.offset);
|
||||
@ -361,7 +362,7 @@ void InstancingModelRenderer::PrepareModelDef(
|
||||
|
||||
// Render one model
|
||||
void InstancingModelRenderer::RenderModel(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* UNUSED(deviceCommandContext),
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
|
||||
const CShaderProgramPtr& shader, int UNUSED(streamflags), CModel* model, CModelRData* UNUSED(data))
|
||||
{
|
||||
const CModelDefPtr& mdldef = model->GetModelDef();
|
||||
@ -377,19 +378,14 @@ void InstancingModelRenderer::RenderModel(
|
||||
shader->Uniform(str_skinBlendMatrices, mdldef->GetNumBones() + 1, model->GetAnimatedBoneMatrices());
|
||||
}
|
||||
|
||||
// render the lot
|
||||
size_t numFaces = mdldef->GetNumFaces();
|
||||
// Render the lot.
|
||||
const size_t numberOfFaces = mdldef->GetNumFaces();
|
||||
|
||||
// Draw with DrawRangeElements where available, since it might be more efficient
|
||||
#if CONFIG2_GLES
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)numFaces*3, GL_UNSIGNED_SHORT, m->imodeldefIndexBase);
|
||||
#else
|
||||
glDrawRangeElementsEXT(GL_TRIANGLES, 0, (GLuint)m->imodeldef->m_Array.GetNumberOfVertices()-1,
|
||||
(GLsizei)numFaces*3, GL_UNSIGNED_SHORT, m->imodeldefIndexBase);
|
||||
#endif
|
||||
deviceCommandContext->DrawIndexedInRange(
|
||||
m->imodeldef->m_IndexArray.GetOffset(), numberOfFaces * 3, 0, m->imodeldef->m_Array.GetNumberOfVertices() - 1);
|
||||
|
||||
// bump stats
|
||||
// Bump stats.
|
||||
g_Renderer.m_Stats.m_DrawCalls++;
|
||||
g_Renderer.m_Stats.m_ModelTris += numFaces;
|
||||
g_Renderer.m_Stats.m_ModelTris += numberOfFaces;
|
||||
|
||||
}
|
||||
|
@ -548,11 +548,12 @@ void OverlayRenderer::RenderQuadOverlays(
|
||||
shader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
|
||||
|
||||
// Base offsets (in bytes) of the two backing stores relative to their owner VBO
|
||||
u8* indexBase = m->quadIndices.Bind(deviceCommandContext);
|
||||
m->quadIndices.UploadIfNeeded(deviceCommandContext);
|
||||
u8* vertexBase = m->quadVertices.Bind(deviceCommandContext);
|
||||
GLsizei indexStride = m->quadIndices.GetStride();
|
||||
GLsizei vertexStride = m->quadVertices.GetStride();
|
||||
|
||||
deviceCommandContext->SetIndexBuffer(m->quadIndices.GetBuffer());
|
||||
|
||||
for (OverlayRendererInternals::QuadBatchMap::iterator it = m->quadBatchMap.begin(); it != m->quadBatchMap.end(); ++it)
|
||||
{
|
||||
QuadBatchData& batchRenderData = it->second;
|
||||
@ -584,7 +585,7 @@ void OverlayRenderer::RenderQuadOverlays(
|
||||
shader->ColorPointer(m->quadAttributeColor.elems, m->quadAttributeColor.type, vertexStride, vertexBase + m->quadAttributeColor.offset);
|
||||
|
||||
shader->AssertPointersBound();
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)(batchNumQuads * 6), GL_UNSIGNED_SHORT, indexBase + indexStride * batchRenderData.m_IndicesBase);
|
||||
deviceCommandContext->DrawIndexed(m->quadIndices.GetOffset() + batchRenderData.m_IndicesBase, batchNumQuads * 6, 0);
|
||||
|
||||
g_Renderer.GetStats().m_DrawCalls++;
|
||||
g_Renderer.GetStats().m_OverlayTris += batchNumQuads*2;
|
||||
@ -668,7 +669,7 @@ void OverlayRenderer::RenderForegroundOverlays(
|
||||
|
||||
shader->VertexPointer(3, GL_FLOAT, sizeof(CVector3D), &position[0].X);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
deviceCommandContext->Draw(0, 6);
|
||||
|
||||
g_Renderer.GetStats().m_DrawCalls++;
|
||||
g_Renderer.GetStats().m_OverlayTris += 2;
|
||||
@ -788,7 +789,8 @@ void OverlayRenderer::RenderSphereOverlays(
|
||||
|
||||
shader->Uniform(str_color, sphere->m_Color);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, m->sphereIndexes.size(), GL_UNSIGNED_SHORT, &m->sphereIndexes[0]);
|
||||
deviceCommandContext->SetIndexBufferData(m->sphereIndexes.data());
|
||||
deviceCommandContext->DrawIndexed(0, m->sphereIndexes.size(), 0);
|
||||
|
||||
g_Renderer.GetStats().m_DrawCalls++;
|
||||
g_Renderer.GetStats().m_OverlayTris = m->sphereIndexes.size()/3;
|
||||
|
@ -669,8 +669,6 @@ void CPatchRData::Update(CSimulation2* simulation)
|
||||
}
|
||||
}
|
||||
|
||||
// Types used for glMultiDrawElements batching:
|
||||
|
||||
// To minimise the cost of memory allocations, everything used for computing
|
||||
// batches uses a arena allocator. (All allocations are short-lived so we can
|
||||
// just throw away the whole arena at the end of each frame.)
|
||||
@ -702,7 +700,7 @@ typename M::mapped_type& PooledPairGet(M& m, const typename M::key_type& k, Aren
|
||||
}
|
||||
|
||||
// Each multidraw batch has a list of index counts, and a list of pointers-to-first-indexes
|
||||
using BatchElements = std::pair<std::vector<GLint, ProxyAllocator<GLint, Arena>>, std::vector<void*, ProxyAllocator<void*, Arena>>>;
|
||||
using BatchElements = std::pair<std::vector<GLint, ProxyAllocator<GLint, Arena>>, std::vector<u32, ProxyAllocator<u32, Arena>>>;
|
||||
|
||||
// Group batches by index buffer
|
||||
using IndexBufferBatches = PooledBatchMap<CVertexBuffer*, BatchElements>;
|
||||
@ -760,8 +758,7 @@ void CPatchRData::RenderBases(
|
||||
|
||||
batch.first.push_back(splat.m_IndexCount);
|
||||
|
||||
u8* indexBase = nullptr;
|
||||
batch.second.push_back(indexBase + sizeof(u16)*(patch->m_VBBaseIndices->m_Index + splat.m_IndexStart));
|
||||
batch.second.push_back(patch->m_VBBaseIndices->m_Index + splat.m_IndexStart);
|
||||
}
|
||||
}
|
||||
|
||||
@ -814,15 +811,13 @@ void CPatchRData::RenderBases(
|
||||
|
||||
for (IndexBufferBatches::iterator it = itv->second.begin(); it != itv->second.end(); ++it)
|
||||
{
|
||||
it->first->Bind(deviceCommandContext);
|
||||
it->first->UploadIfNeeded(deviceCommandContext);
|
||||
deviceCommandContext->SetIndexBuffer(it->first->GetBuffer());
|
||||
|
||||
BatchElements& batch = it->second;
|
||||
|
||||
// Don't use glMultiDrawElements here since it doesn't have a significant
|
||||
// performance impact and it suffers from various driver bugs (e.g. it breaks
|
||||
// in Mesa 7.10 swrast with index VBOs)
|
||||
for (size_t i = 0; i < batch.first.size(); ++i)
|
||||
glDrawElements(GL_TRIANGLES, batch.first[i], GL_UNSIGNED_SHORT, batch.second[i]);
|
||||
deviceCommandContext->DrawIndexed(batch.second[i], batch.first[i], 0);
|
||||
|
||||
g_Renderer.m_Stats.m_DrawCalls++;
|
||||
g_Renderer.m_Stats.m_TerrainTris += std::accumulate(batch.first.begin(), batch.first.end(), 0) / 3;
|
||||
@ -928,8 +923,7 @@ void CPatchRData::RenderBlends(
|
||||
BatchElements& batch = PooledPairGet(PooledMapGet(batches.back().m_Batches, vertices->m_Owner, arena), indices->m_Owner, arena);
|
||||
batch.first.push_back(splats.back().m_IndexCount);
|
||||
|
||||
u8* indexBase = nullptr;
|
||||
batch.second.push_back(indexBase + sizeof(u16)*(indices->m_Index + splats.back().m_IndexStart));
|
||||
batch.second.push_back(indices->m_Index + splats.back().m_IndexStart);
|
||||
|
||||
splats.pop_back();
|
||||
}
|
||||
@ -1045,12 +1039,13 @@ void CPatchRData::RenderBlends(
|
||||
|
||||
for (IndexBufferBatches::iterator it = itv->second.begin(); it != itv->second.end(); ++it)
|
||||
{
|
||||
it->first->Bind(deviceCommandContext);
|
||||
it->first->UploadIfNeeded(deviceCommandContext);
|
||||
deviceCommandContext->SetIndexBuffer(it->first->GetBuffer());
|
||||
|
||||
BatchElements& batch = it->second;
|
||||
|
||||
for (size_t i = 0; i < batch.first.size(); ++i)
|
||||
glDrawElements(GL_TRIANGLES, batch.first[i], GL_UNSIGNED_SHORT, batch.second[i]);
|
||||
deviceCommandContext->DrawIndexed(batch.second[i], batch.first[i], 0);
|
||||
|
||||
g_Renderer.m_Stats.m_DrawCalls++;
|
||||
g_Renderer.m_Stats.m_BlendSplats++;
|
||||
@ -1072,13 +1067,13 @@ void CPatchRData::RenderStreams(
|
||||
PROFILE3("render terrain streams");
|
||||
|
||||
// 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<u32>>;
|
||||
|
||||
// Group batches by index buffer
|
||||
using StreamIndexBufferBatches = std::map<CVertexBuffer*, StreamBatchElements> ;
|
||||
using StreamIndexBufferBatches = std::map<CVertexBuffer*, StreamBatchElements>;
|
||||
|
||||
// Group batches by vertex buffer
|
||||
using StreamVertexBufferBatches = std::map<CVertexBuffer*, StreamIndexBufferBatches> ;
|
||||
using StreamVertexBufferBatches = std::map<CVertexBuffer*, StreamIndexBufferBatches>;
|
||||
|
||||
StreamVertexBufferBatches batches;
|
||||
|
||||
@ -1091,8 +1086,7 @@ void CPatchRData::RenderStreams(
|
||||
|
||||
batch.first.push_back(patch->m_VBBaseIndices->m_Count);
|
||||
|
||||
u8* indexBase = nullptr;
|
||||
batch.second.push_back(indexBase + sizeof(u16)*(patch->m_VBBaseIndices->m_Index));
|
||||
batch.second.push_back(patch->m_VBBaseIndices->m_Index);
|
||||
}
|
||||
|
||||
PROFILE_END("compute batches");
|
||||
@ -1115,12 +1109,13 @@ void CPatchRData::RenderStreams(
|
||||
|
||||
for (const std::pair<CVertexBuffer* const, StreamBatchElements>& batchIndexBuffer : streamBatch.second)
|
||||
{
|
||||
batchIndexBuffer.first->Bind(deviceCommandContext);
|
||||
batchIndexBuffer.first->UploadIfNeeded(deviceCommandContext);
|
||||
deviceCommandContext->SetIndexBuffer(batchIndexBuffer.first->GetBuffer());
|
||||
|
||||
const StreamBatchElements& batch = batchIndexBuffer.second;
|
||||
|
||||
for (size_t i = 0; i < batch.first.size(); ++i)
|
||||
glDrawElements(GL_TRIANGLES, batch.first[i], GL_UNSIGNED_SHORT, batch.second[i]);
|
||||
deviceCommandContext->DrawIndexed(batch.second[i], batch.first[i], 0);
|
||||
|
||||
g_Renderer.m_Stats.m_DrawCalls++;
|
||||
g_Renderer.m_Stats.m_TerrainTris += std::accumulate(batch.first.begin(), batch.first.end(), 0) / 3;
|
||||
@ -1187,7 +1182,7 @@ void CPatchRData::RenderSides(
|
||||
|
||||
shader->AssertPointersBound();
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, patch->m_VBSides->m_Index, (GLsizei)patch->m_VBSides->m_Count);
|
||||
deviceCommandContext->Draw(patch->m_VBSides->m_Index, (GLsizei)patch->m_VBSides->m_Count);
|
||||
|
||||
// bump stats
|
||||
g_Renderer.m_Stats.m_DrawCalls++;
|
||||
@ -1433,6 +1428,8 @@ void CPatchRData::RenderWaterSurface(
|
||||
if (!m_VBWater)
|
||||
return;
|
||||
|
||||
m_VBWaterIndices->m_Owner->UploadIfNeeded(deviceCommandContext);
|
||||
|
||||
SWaterVertex* base = reinterpret_cast<SWaterVertex*>(m_VBWater->m_Owner->Bind(deviceCommandContext));
|
||||
|
||||
// Setup data pointers.
|
||||
@ -1443,10 +1440,8 @@ void CPatchRData::RenderWaterSurface(
|
||||
|
||||
shader->AssertPointersBound();
|
||||
|
||||
u8* indexBase = m_VBWaterIndices->m_Owner->Bind(deviceCommandContext);
|
||||
glDrawElements(
|
||||
GL_TRIANGLES, static_cast<GLsizei>(m_VBWaterIndices->m_Count),
|
||||
GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(m_VBWaterIndices->m_Index));
|
||||
deviceCommandContext->SetIndexBuffer(m_VBWaterIndices->m_Owner->GetBuffer());
|
||||
deviceCommandContext->DrawIndexed(m_VBWaterIndices->m_Index, m_VBWaterIndices->m_Count, 0);
|
||||
|
||||
g_Renderer.m_Stats.m_DrawCalls++;
|
||||
g_Renderer.m_Stats.m_WaterTris += m_VBWaterIndices->m_Count / 3;
|
||||
@ -1463,6 +1458,8 @@ void CPatchRData::RenderWaterShore(
|
||||
if (!m_VBWaterShore)
|
||||
return;
|
||||
|
||||
m_VBWaterIndicesShore->m_Owner->UploadIfNeeded(deviceCommandContext);
|
||||
|
||||
SWaterVertex* base = reinterpret_cast<SWaterVertex*>(m_VBWaterShore->m_Owner->Bind(deviceCommandContext));
|
||||
|
||||
const GLsizei stride = sizeof(SWaterVertex);
|
||||
@ -1471,9 +1468,8 @@ void CPatchRData::RenderWaterShore(
|
||||
|
||||
shader->AssertPointersBound();
|
||||
|
||||
u8* indexBase = m_VBWaterIndicesShore->m_Owner->Bind(deviceCommandContext);
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(m_VBWaterIndicesShore->m_Count),
|
||||
GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(m_VBWaterIndicesShore->m_Index));
|
||||
deviceCommandContext->SetIndexBuffer(m_VBWaterIndicesShore->m_Owner->GetBuffer());
|
||||
deviceCommandContext->DrawIndexed(m_VBWaterIndicesShore->m_Index, m_VBWaterIndicesShore->m_Count, 0);
|
||||
|
||||
g_Renderer.m_Stats.m_DrawCalls++;
|
||||
g_Renderer.m_Stats.m_WaterTris += m_VBWaterIndicesShore->m_Count / 3;
|
||||
|
@ -231,7 +231,7 @@ void CPostprocManager::ApplyBlurDownscale2x(
|
||||
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex);
|
||||
shader->VertexPointer(2, GL_FLOAT, 0, quadVerts);
|
||||
shader->AssertPointersBound();
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
deviceCommandContext->Draw(0, 6);
|
||||
|
||||
g_Renderer.SetViewport(oldVp);
|
||||
|
||||
@ -287,7 +287,7 @@ void CPostprocManager::ApplyBlurGauss(
|
||||
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex);
|
||||
shader->VertexPointer(2, GL_FLOAT, 0, quadVerts);
|
||||
shader->AssertPointersBound();
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
deviceCommandContext->Draw(0, 6);
|
||||
|
||||
g_Renderer.SetViewport(oldVp);
|
||||
|
||||
@ -312,7 +312,7 @@ void CPostprocManager::ApplyBlurGauss(
|
||||
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex);
|
||||
shader->VertexPointer(2, GL_FLOAT, 0, quadVerts);
|
||||
shader->AssertPointersBound();
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
deviceCommandContext->Draw(0, 6);
|
||||
|
||||
g_Renderer.SetViewport(oldVp);
|
||||
|
||||
@ -432,7 +432,7 @@ void CPostprocManager::ApplyEffect(
|
||||
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex);
|
||||
shader->VertexPointer(2, GL_FLOAT, 0, quadVerts);
|
||||
shader->AssertPointersBound();
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
deviceCommandContext->Draw(0, 6);
|
||||
|
||||
shaderTech->EndPass(pass);
|
||||
|
||||
|
@ -750,7 +750,7 @@ void ShadowMap::RenderDebugTexture(
|
||||
texShader->VertexPointer(2, GL_FLOAT, 0, boxVerts);
|
||||
texShader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, boxUV);
|
||||
texShader->AssertPointersBound();
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
deviceCommandContext->Draw(0, 6);
|
||||
|
||||
texTech->EndPass();
|
||||
|
||||
|
@ -494,7 +494,7 @@ void SilhouetteRenderer::RenderDebugOverlays(
|
||||
r.x0, r.y1,
|
||||
};
|
||||
shader->VertexPointer(2, GL_SHORT, 0, verts);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
deviceCommandContext->Draw(0, 6);
|
||||
}
|
||||
|
||||
shaderTech->EndPass();
|
||||
|
@ -248,7 +248,7 @@ void SkyManager::RenderSky(
|
||||
GL_TEXTURE0, 3, GL_FLOAT, stride, base + m_AttributeUV.offset);
|
||||
shader->AssertPointersBound();
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, m_VertexArray.GetNumberOfVertices());
|
||||
deviceCommandContext->Draw(0, m_VertexArray.GetNumberOfVertices());
|
||||
|
||||
skytech->EndPass();
|
||||
#endif
|
||||
|
@ -232,7 +232,7 @@ void TerrainOverlay::RenderTile(
|
||||
overlayShader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
|
||||
overlayShader->AssertPointersBound();
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 3);
|
||||
deviceCommandContext->Draw(0, vertices.size() / 3);
|
||||
|
||||
overlayTech->EndPass();
|
||||
#endif
|
||||
@ -300,7 +300,7 @@ void TerrainOverlay::RenderTileOutline(
|
||||
overlayShader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
|
||||
overlayShader->AssertPointersBound();
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 3);
|
||||
deviceCommandContext->Draw(0, vertices.size() / 3);
|
||||
|
||||
overlayTech->EndPass();
|
||||
#endif
|
||||
|
@ -212,7 +212,7 @@ void TerrainRenderer::RenderTerrainOverlayTexture(
|
||||
debugOverlayShader->TexCoordPointer(GL_TEXTURE0, 3, GL_FLOAT, stride, waterPos);
|
||||
debugOverlayShader->AssertPointersBound();
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
deviceCommandContext->Draw(0, 6);
|
||||
}
|
||||
|
||||
debugOverlayTech->EndPass();
|
||||
|
@ -48,6 +48,9 @@ void CTexturedLineRData::Render(
|
||||
|
||||
line.m_TextureBase->UploadBackendTextureIfNeeded(deviceCommandContext);
|
||||
line.m_TextureMask->UploadBackendTextureIfNeeded(deviceCommandContext);
|
||||
|
||||
m_VBIndices->m_Owner->UploadIfNeeded(deviceCommandContext);
|
||||
|
||||
shader->BindTexture(str_baseTex, line.m_TextureBase->GetBackendTexture());
|
||||
shader->BindTexture(str_maskTex, line.m_TextureMask->GetBackendTexture());
|
||||
shader->Uniform(str_objectColor, line.m_Color);
|
||||
@ -65,10 +68,10 @@ void CTexturedLineRData::Render(
|
||||
if (streamFlags & STREAM_UV1)
|
||||
shader->TexCoordPointer(GL_TEXTURE1, 2, GL_FLOAT, stride, &vertexBase->m_UVs[0]);
|
||||
|
||||
u8* indexBase = m_VBIndices->m_Owner->Bind(deviceCommandContext);
|
||||
|
||||
shader->AssertPointersBound();
|
||||
glDrawElements(GL_TRIANGLES, m_VBIndices->m_Count, GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*m_VBIndices->m_Index);
|
||||
|
||||
deviceCommandContext->SetIndexBuffer(m_VBIndices->m_Owner->GetBuffer());
|
||||
deviceCommandContext->DrawIndexed(m_VBIndices->m_Index, m_VBIndices->m_Count, 0);
|
||||
|
||||
g_Renderer.GetStats().m_DrawCalls++;
|
||||
g_Renderer.GetStats().m_OverlayTris += m_VBIndices->m_Count/3;
|
||||
|
@ -291,13 +291,20 @@ u8* VertexArray::Bind(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
|
||||
{
|
||||
if (!m_VB)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
u8* base = m_VB->m_Owner->Bind(deviceCommandContext);
|
||||
base += m_VB->m_Index*m_Stride;
|
||||
UploadIfNeeded(deviceCommandContext);
|
||||
m_VB->m_Owner->Bind(deviceCommandContext);
|
||||
u8* base = nullptr;
|
||||
base += m_VB->m_Index * m_Stride;
|
||||
return base;
|
||||
}
|
||||
|
||||
void VertexArray::UploadIfNeeded(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
|
||||
{
|
||||
m_VB->m_Owner->UploadIfNeeded(deviceCommandContext);
|
||||
}
|
||||
|
||||
// Free the backing store to save some memory
|
||||
void VertexArray::FreeBackingStore()
|
||||
|
@ -179,17 +179,22 @@ public:
|
||||
// All vertex data is lost when a vertex array is re-layouted.
|
||||
void Layout();
|
||||
// (Re-)Upload the attributes of the vertex array from the backing store to
|
||||
// the underlying VBO object.
|
||||
// the underlying buffer.
|
||||
void Upload();
|
||||
// Make this vertex array's data available for the next series of calls to Bind
|
||||
void PrepareForRendering();
|
||||
// Bind this array, returns the base address for calls to glVertexPointer etc.
|
||||
u8* Bind(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
|
||||
void UploadIfNeeded(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
|
||||
|
||||
// If you know for certain that you'll never have to change the data again,
|
||||
// call this to free some memory.
|
||||
void FreeBackingStore();
|
||||
|
||||
Renderer::Backend::GL::CBuffer* GetBuffer() { return m_VB ? m_VB->m_Owner->GetBuffer() : nullptr; }
|
||||
|
||||
uint32_t GetOffset() const { return m_VB ? m_VB->m_Index : 0; }
|
||||
|
||||
private:
|
||||
void Free();
|
||||
|
||||
@ -212,9 +217,7 @@ private:
|
||||
|
||||
/**
|
||||
* A VertexArray that is specialised to handle 16-bit array indices.
|
||||
* Call Bind() and pass the return value to the indices parameter of
|
||||
* glDrawElements/glDrawRangeElements/glMultiDrawElements.
|
||||
* Use CVertexBuffer::Unbind() to unbind the array when done.
|
||||
* Call UploadIfNeeded() before use in Draw/DrawIndexed.
|
||||
*/
|
||||
class VertexIndexArray : public VertexArray
|
||||
{
|
||||
|
@ -59,6 +59,10 @@ CVertexBuffer::CVertexBuffer(
|
||||
// address at most 64K of them with 16-bit indices
|
||||
size = std::min(size, vertexSize * 65536);
|
||||
}
|
||||
else if (type == Renderer::Backend::GL::CBuffer::Type::INDEX)
|
||||
{
|
||||
ENSURE(vertexSize == sizeof(u16));
|
||||
}
|
||||
|
||||
// store max/free vertex counts
|
||||
m_MaxVertices = m_FreeVertices = size / vertexSize;
|
||||
@ -222,19 +226,13 @@ void CVertexBuffer::UpdateChunkVertices(VBChunk* chunk, void* data)
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Bind: bind to this buffer; return pointer to address required as parameter
|
||||
// to glVertexPointer ( + etc) calls
|
||||
u8* CVertexBuffer::Bind(
|
||||
void CVertexBuffer::UploadIfNeeded(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
|
||||
{
|
||||
if (UseStreaming(m_Buffer->IsDynamic()))
|
||||
{
|
||||
if (!m_HasNeededChunks)
|
||||
{
|
||||
deviceCommandContext->BindBuffer(m_Buffer->GetType(), m_Buffer.get());
|
||||
return nullptr;
|
||||
}
|
||||
return;
|
||||
|
||||
// If any chunks are out of sync with the current VBO, and are
|
||||
// needed for rendering this frame, we'll need to re-upload the VBO
|
||||
@ -290,8 +288,15 @@ u8* CVertexBuffer::Bind(
|
||||
|
||||
m_HasNeededChunks = false;
|
||||
}
|
||||
deviceCommandContext->BindBuffer(m_Buffer->GetType(), m_Buffer.get());
|
||||
}
|
||||
|
||||
// Bind: bind to this buffer; return pointer to address required as parameter
|
||||
// to glVertexPointer ( + etc) calls
|
||||
u8* CVertexBuffer::Bind(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
|
||||
{
|
||||
UploadIfNeeded(deviceCommandContext);
|
||||
deviceCommandContext->BindBuffer(m_Buffer->GetType(), m_Buffer.get());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -102,6 +102,8 @@ public:
|
||||
/// to glVertexPointer ( + etc) calls
|
||||
u8* Bind(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
|
||||
|
||||
void UploadIfNeeded(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
|
||||
|
||||
/// Unbind any currently-bound buffer, so glVertexPointer etc calls will not attempt to use it
|
||||
static void Unbind(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
|
||||
@ -135,6 +137,8 @@ public:
|
||||
*/
|
||||
static bool UseStreaming(const bool dynamic);
|
||||
|
||||
Renderer::Backend::GL::CBuffer* GetBuffer() { return m_Buffer.get(); }
|
||||
|
||||
private:
|
||||
friend class CVertexBufferManager; // allow allocate only via CVertexBufferManager
|
||||
|
||||
|
@ -812,9 +812,9 @@ void WaterManager::RenderWaves(
|
||||
shader->Uniform(str_translation, m_ShoreWaves[a]->m_TimeDiff);
|
||||
shader->Uniform(str_width, (int)m_ShoreWaves[a]->m_Width);
|
||||
|
||||
u8* indexBase = m_ShoreWavesVBIndices->m_Owner->Bind(deviceCommandContext);
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei) (m_ShoreWaves[a]->m_Width-1)*(7*6),
|
||||
GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(m_ShoreWavesVBIndices->m_Index));
|
||||
m_ShoreWavesVBIndices->m_Owner->UploadIfNeeded(deviceCommandContext);
|
||||
deviceCommandContext->SetIndexBuffer(m_ShoreWavesVBIndices->m_Owner->GetBuffer());
|
||||
deviceCommandContext->DrawIndexed(m_ShoreWavesVBIndices->m_Index, (m_ShoreWaves[a]->m_Width - 1) * (7 * 6), 0);
|
||||
|
||||
shader->Uniform(str_translation, m_ShoreWaves[a]->m_TimeDiff + 6.0f);
|
||||
|
||||
|
@ -379,7 +379,13 @@ void CDeviceCommandContext::BindTexture(const uint32_t unit, const GLenum target
|
||||
|
||||
void CDeviceCommandContext::BindBuffer(const CBuffer::Type type, CBuffer* buffer)
|
||||
{
|
||||
ENSURE(!buffer || type == buffer->GetType());
|
||||
ENSURE(!buffer || buffer->GetType() == type);
|
||||
if (type == CBuffer::Type::INDEX)
|
||||
{
|
||||
if (!buffer)
|
||||
m_IndexBuffer = nullptr;
|
||||
m_IndexBufferData = nullptr;
|
||||
}
|
||||
glBindBufferARB(BufferTypeToGLTarget(type), buffer ? buffer->GetHandle() : 0);
|
||||
}
|
||||
|
||||
@ -387,7 +393,12 @@ void CDeviceCommandContext::Flush()
|
||||
{
|
||||
ResetStates();
|
||||
|
||||
m_IndexBuffer = nullptr;
|
||||
m_IndexBufferData = nullptr;
|
||||
|
||||
BindTexture(0, GL_TEXTURE_2D, 0);
|
||||
BindBuffer(CBuffer::Type::INDEX, nullptr);
|
||||
BindBuffer(CBuffer::Type::VERTEX, nullptr);
|
||||
|
||||
ENSURE(m_ScopedLabelDepth == 0);
|
||||
}
|
||||
@ -711,6 +722,70 @@ void CDeviceCommandContext::SetViewports(const uint32_t viewportCount, const Rec
|
||||
glViewport(viewports[0].x, viewports[0].y, viewports[0].width, viewports[0].height);
|
||||
}
|
||||
|
||||
void CDeviceCommandContext::SetIndexBuffer(CBuffer* buffer)
|
||||
{
|
||||
ENSURE(buffer->GetType() == CBuffer::Type::INDEX);
|
||||
m_IndexBuffer = buffer;
|
||||
m_IndexBufferData = nullptr;
|
||||
BindBuffer(CBuffer::Type::INDEX, m_IndexBuffer);
|
||||
}
|
||||
|
||||
void CDeviceCommandContext::SetIndexBufferData(const void* data)
|
||||
{
|
||||
if (m_IndexBuffer)
|
||||
{
|
||||
BindBuffer(CBuffer::Type::INDEX, nullptr);
|
||||
m_IndexBuffer = nullptr;
|
||||
}
|
||||
m_IndexBufferData = data;
|
||||
}
|
||||
|
||||
void CDeviceCommandContext::Draw(
|
||||
const uint32_t firstVertex, const uint32_t vertexCount)
|
||||
{
|
||||
// Some drivers apparently don't like count = 0 in glDrawArrays here, so skip
|
||||
// all drawing in that case.
|
||||
if (vertexCount == 0)
|
||||
return;
|
||||
glDrawArrays(GL_TRIANGLES, firstVertex, vertexCount);
|
||||
}
|
||||
|
||||
void CDeviceCommandContext::DrawIndexed(
|
||||
const uint32_t firstIndex, const uint32_t indexCount, const int32_t vertexOffset)
|
||||
{
|
||||
if (indexCount == 0)
|
||||
return;
|
||||
ENSURE(m_IndexBuffer || m_IndexBufferData);
|
||||
ENSURE(vertexOffset == 0);
|
||||
if (m_IndexBuffer)
|
||||
{
|
||||
ENSURE(sizeof(uint16_t) * (firstIndex + indexCount) <= m_IndexBuffer->GetSize());
|
||||
}
|
||||
// Don't use glMultiDrawElements here since it doesn't have a significant
|
||||
// performance impact and it suffers from various driver bugs (e.g. it breaks
|
||||
// in Mesa 7.10 swrast with index VBOs).
|
||||
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT,
|
||||
static_cast<const void*>((static_cast<const uint8_t*>(m_IndexBufferData) + sizeof(uint16_t) * firstIndex)));
|
||||
}
|
||||
|
||||
void CDeviceCommandContext::DrawIndexedInRange(
|
||||
const uint32_t firstIndex, const uint32_t indexCount,
|
||||
const uint32_t start, const uint32_t end)
|
||||
{
|
||||
if (indexCount == 0)
|
||||
return;
|
||||
ENSURE(m_IndexBuffer || m_IndexBufferData);
|
||||
const void* indices =
|
||||
static_cast<const void*>((static_cast<const uint8_t*>(m_IndexBufferData) + sizeof(uint16_t) * firstIndex));
|
||||
// Draw with DrawRangeElements where available, since it might be more
|
||||
// efficient for slow hardware.
|
||||
#if CONFIG2_GLES
|
||||
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, indices);
|
||||
#else
|
||||
glDrawRangeElementsEXT(GL_TRIANGLES, start, end, indexCount, GL_UNSIGNED_SHORT, indices);
|
||||
#endif
|
||||
}
|
||||
|
||||
CDeviceCommandContext::ScopedBind::ScopedBind(
|
||||
CDeviceCommandContext* deviceCommandContext,
|
||||
const GLenum target, const GLuint handle)
|
||||
|
@ -85,6 +85,17 @@ public:
|
||||
void SetScissors(const uint32_t scissorCount, const Rect* scissors);
|
||||
void SetViewports(const uint32_t viewportCount, const Rect* viewports);
|
||||
|
||||
void SetIndexBuffer(CBuffer* buffer);
|
||||
void SetIndexBufferData(const void* data);
|
||||
|
||||
void Draw(const uint32_t firstVertex, const uint32_t vertexCount);
|
||||
void DrawIndexed(
|
||||
const uint32_t firstIndex, const uint32_t indexCount, const int32_t vertexOffset);
|
||||
// TODO: should be removed when performance impact is minimal on slow hardware.
|
||||
void DrawIndexedInRange(
|
||||
const uint32_t firstIndex, const uint32_t indexCount,
|
||||
const uint32_t start, const uint32_t end);
|
||||
|
||||
void BeginScopedLabel(const char* name);
|
||||
void EndScopedLabel();
|
||||
|
||||
@ -116,6 +127,9 @@ private:
|
||||
|
||||
uint32_t m_ScopedLabelDepth = 0;
|
||||
|
||||
CBuffer* m_IndexBuffer = nullptr;
|
||||
const void* m_IndexBufferData = nullptr;
|
||||
|
||||
uint32_t m_ActiveTextureUnit = 0;
|
||||
using BindUnit = std::pair<GLenum, GLuint>;
|
||||
std::array<BindUnit, 16> m_BoundTextures;
|
||||
|
Loading…
Reference in New Issue
Block a user