Moves vertex attribute binding to CDeviceCommandContext.

Tested By: Langbart, Stan
Differential Revision: https://code.wildfiregames.com/D4610
This was SVN commit r26815.
This commit is contained in:
Vladislav Belov 2022-04-23 20:11:14 +00:00
parent ddb8b08508
commit aba7a170d9
37 changed files with 857 additions and 551 deletions

View File

@ -56,10 +56,16 @@ inline void DrawTextureImpl(
shader->Uniform(str_colorAdd, add);
shader->Uniform(str_colorMul, multiply);
shader->Uniform(str_grayscaleFactor, grayscaleFactor);
shader->VertexPointer(
Renderer::Backend::Format::R32G32_SFLOAT, 0, vertices.data());
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, 0, uvs.data());
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
deviceCommandContext->SetVertexBufferData(0, vertices.data());
deviceCommandContext->SetVertexBufferData(1, uvs.data());
deviceCommandContext->Draw(0, vertices.size() / 2);
}
@ -250,10 +256,16 @@ void CCanvas2D::DrawLine(const std::vector<CVector2D>& points, const float width
shader->Uniform(str_colorAdd, CColor(0.0f, 0.0f, 0.0f, 0.0f));
shader->Uniform(str_colorMul, color);
shader->Uniform(str_grayscaleFactor, 0.0f);
shader->VertexPointer(
Renderer::Backend::Format::R32G32_SFLOAT, 0, vertices.data());
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, 0, uvs.data());
m->DeviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
m->DeviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
m->DeviceCommandContext->SetVertexBufferData(0, vertices.data());
m->DeviceCommandContext->SetVertexBufferData(1, uvs.data());
m->DeviceCommandContext->SetIndexBufferData(indices.data());
m->DeviceCommandContext->DrawIndexed(0, indices.size(), 0);

View File

@ -181,8 +181,17 @@ void CLOSTexture::InterpolateLOS(Renderer::Backend::GL::CDeviceCommandContext* d
1.0f, 0.0f,
1.0f, 1.0f
};
shader->TexCoordPointer(GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, 0, quadTex);
shader->VertexPointer(Renderer::Backend::Format::R32G32_SFLOAT, 0, quadVerts);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
deviceCommandContext->SetVertexBufferData(0, quadVerts);
deviceCommandContext->SetVertexBufferData(1, quadTex);
deviceCommandContext->Draw(0, 6);
g_Renderer.SetViewport(oldVp);

View File

@ -71,8 +71,7 @@ unsigned int ScaleColor(unsigned int color, float x)
}
void DrawTexture(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader)
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
{
const float quadUVs[] =
{
@ -95,10 +94,15 @@ void DrawTexture(
-1.0f, -1.0f, 0.0f
};
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, 0, quadUVs);
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, quadVertices);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
deviceCommandContext->SetVertexBufferData(0, quadVertices);
deviceCommandContext->SetVertexBufferData(1, quadUVs);
deviceCommandContext->Draw(0, 6);
}
@ -390,7 +394,7 @@ void CMiniMapTexture::RenderFinalTexture(
shader->Uniform(str_textureTransform, terrainTransform);
if (m_TerrainTexture)
DrawTexture(deviceCommandContext, shader);
DrawTexture(deviceCommandContext);
deviceCommandContext->EndPass();
pipelineStateDesc.blendState.enabled = true;
@ -414,7 +418,7 @@ void CMiniMapTexture::RenderFinalTexture(
shader->Uniform(str_transform, baseTransform);
shader->Uniform(str_textureTransform, territoryTexture.GetMinimapTextureMatrix());
DrawTexture(deviceCommandContext, shader);
DrawTexture(deviceCommandContext);
deviceCommandContext->EndPass();
pipelineStateDesc.blendState.enabled = false;
@ -427,7 +431,7 @@ void CMiniMapTexture::RenderFinalTexture(
shader->Uniform(str_transform, baseTransform);
shader->Uniform(str_textureTransform, losTexture.GetMinimapTextureMatrix());
DrawTexture(deviceCommandContext, shader);
DrawTexture(deviceCommandContext);
deviceCommandContext->EndPass();
@ -565,20 +569,25 @@ void CMiniMapTexture::RenderFinalTexture(
scissorRect.width = scissorRect.height = FINAL_TEXTURE_SIZE - 2;
deviceCommandContext->SetScissors(1, &scissorRect);
m_VertexArray.UploadIfNeeded(deviceCommandContext);
m_IndexArray.UploadIfNeeded(deviceCommandContext);
u8* base = m_VertexArray.Bind(deviceCommandContext);
const GLsizei stride = (GLsizei)m_VertexArray.GetStride();
shader->VertexPointer(
m_AttributePos.format, stride, base + m_AttributePos.offset);
shader->ColorPointer(
m_AttributeColor.format, stride, base + m_AttributeColor.offset);
const uint32_t stride = m_VertexArray.GetStride();
const uint32_t firstVertexOffset = m_VertexArray.GetOffset() * stride;
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
m_AttributePos.format, firstVertexOffset + m_AttributePos.offset, stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::COLOR,
m_AttributeColor.format, firstVertexOffset + m_AttributeColor.offset, stride, 0);
deviceCommandContext->SetVertexBuffer(0, m_VertexArray.GetBuffer());
deviceCommandContext->SetIndexBuffer(m_IndexArray.GetBuffer());
deviceCommandContext->DrawIndexed(m_IndexArray.GetOffset(), m_EntitiesDrawn * 6, 0);
g_Renderer.GetStats().m_DrawCalls++;
CVertexBuffer::Unbind(deviceCommandContext);
deviceCommandContext->SetScissors(0, nullptr);
}

View File

@ -194,30 +194,33 @@ void CParticleEmitter::Bind(
void CParticleEmitter::RenderArray(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader)
Renderer::Backend::GL::CShaderProgram* UNUSED(shader))
{
if (m_Particles.empty())
return;
m_VertexArray.UploadIfNeeded(deviceCommandContext);
m_IndexArray.UploadIfNeeded(deviceCommandContext);
u8* base = m_VertexArray.Bind(deviceCommandContext);
GLsizei stride = (GLsizei)m_VertexArray.GetStride();
const uint32_t stride = m_VertexArray.GetStride();
const uint32_t firstVertexOffset = m_VertexArray.GetStride() * stride;
shader->VertexPointer(
m_AttributePos.format, stride, base + m_AttributePos.offset);
// Pass the sin/cos axis components as texcoords for no particular reason
// other than that they fit. (Maybe this should be glVertexAttrib* instead?)
shader->TexCoordPointer(
GL_TEXTURE0, m_AttributeUV.format, stride, base + m_AttributeUV.offset);
shader->TexCoordPointer(
GL_TEXTURE1, m_AttributeAxis.format, stride, base + m_AttributeAxis.offset);
shader->ColorPointer(
m_AttributeColor.format, stride, base + m_AttributeColor.offset);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
m_AttributePos.format, firstVertexOffset + m_AttributePos.offset, stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::COLOR,
m_AttributeColor.format, firstVertexOffset + m_AttributeColor.offset, stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
m_AttributeUV.format, firstVertexOffset + m_AttributeUV.offset, stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
m_AttributeAxis.format, firstVertexOffset + m_AttributeAxis.offset, stride, 0);
deviceCommandContext->SetVertexBuffer(0, m_VertexArray.GetBuffer());
deviceCommandContext->SetIndexBuffer(m_IndexArray.GetBuffer());
deviceCommandContext->DrawIndexed(m_IndexArray.GetOffset(), m_Particles.size() * 6, 0);
g_Renderer.GetStats().m_DrawCalls++;

View File

@ -44,6 +44,8 @@ public:
Renderer::Backend::GL::CShaderProgram* GetBackendShaderProgram() { return m_BackendShaderProgram.get(); }
// TODO: add reloadable handles.
protected:
CShaderProgram(const CStr& name, const CShaderDefines& defines);

View File

@ -263,15 +263,23 @@ void CTextRenderer::Render(
size_t idx = 0;
auto flush = [deviceCommandContext, &idx, &vertexes, &indexes, &shader]() -> void {
auto flush = [deviceCommandContext, &idx, &vertexes, &indexes]() -> void
{
if (idx == 0)
return;
shader->VertexPointer(
Renderer::Backend::Format::R16G16_SINT, sizeof(t2f_v2i), &vertexes[0].x);
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, sizeof(t2f_v2i), &vertexes[0].u);
const uint32_t stride = sizeof(t2f_v2i);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R16G16_SINT, offsetof(t2f_v2i, x), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT, offsetof(t2f_v2i, u), stride, 0);
deviceCommandContext->SetVertexBufferData(0, vertexes.data());
deviceCommandContext->SetIndexBufferData(indexes.data());
deviceCommandContext->DrawIndexed(0, idx * 6, 0);
idx = 0;
};

View File

@ -97,7 +97,7 @@ void CropPointsByCircle(const std::array<CVector3D, 4>& points, const CVector3D&
void DrawTexture(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader, float angle, float x, float y, float x2, float y2, float mapScale)
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
@ -105,7 +105,8 @@ void DrawTexture(
const float c = cos(angle) * mapScale;
const float m = 0.5f;
float quadTex[] = {
float quadTex[] =
{
m*(-c + s + 1.f), m*(-c + -s + 1.f),
m*(c + s + 1.f), m*(-c + s + 1.f),
m*(c + -s + 1.f), m*(c + s + 1.f),
@ -114,7 +115,8 @@ void DrawTexture(
m*(-c + -s + 1.f), m*(c + -s + 1.f),
m*(-c + s + 1.f), m*(-c + -s + 1.f)
};
float quadVerts[] = {
float quadVerts[] =
{
x, y, 0.0f,
x2, y, 0.0f,
x2, y2, 0.0f,
@ -124,10 +126,15 @@ void DrawTexture(
x, y, 0.0f
};
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, 0, quadTex);
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, quadVerts);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
deviceCommandContext->SetVertexBufferData(0, quadVerts);
deviceCommandContext->SetVertexBufferData(1, quadTex);
deviceCommandContext->Draw(0, 6);
}
@ -440,7 +447,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(deviceCommandContext, shader, angle, x, y, x2, y2, m_MapScale);
DrawTexture(deviceCommandContext, angle, x, y, x2, y2, m_MapScale);
deviceCommandContext->EndPass();
}

View File

@ -291,8 +291,7 @@ class CProfiler2GPUARB
public:
};
CProfiler2GPU::CProfiler2GPU(CProfiler2& profiler) :
m_Profiler(profiler)
CProfiler2GPU::CProfiler2GPU(CProfiler2& UNUSED(profiler))
{
}

View File

@ -42,7 +42,9 @@ public:
void RegionLeave(const char* id);
private:
#if !CONFIG2_GLES
CProfiler2& m_Profiler;
#endif
std::unique_ptr<CProfiler2GPUARB> m_ProfilerARB;
};

View File

@ -126,8 +126,11 @@ void CDebugRenderer::DrawLine(
#undef ADD
debugLineShader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, vertices.data());
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexBufferData(0, vertices.data());
deviceCommandContext->Draw(0, vertices.size() / 3);
deviceCommandContext->EndPass();
@ -177,8 +180,11 @@ void CDebugRenderer::DrawCircle(const CVector3D& origin, const float radius, con
#undef ADD
debugCircleShader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, vertices.data());
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexBufferData(0, vertices.data());
deviceCommandContext->Draw(0, vertices.size() / 3);
deviceCommandContext->EndPass();
@ -253,8 +259,11 @@ void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, const CColor& colo
ADD(intermediatePoints[3]);
}
overlayShader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, vertices.data());
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexBufferData(0, vertices.data());
deviceCommandContext->Draw(0, vertices.size() / 3);
vertices.clear();
@ -271,8 +280,11 @@ void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, const CColor& colo
ADD(farPoints[nextI]);
}
overlayShader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, vertices.data());
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexBufferData(0, vertices.data());
deviceCommandContext->Draw(0, vertices.size() / 3);
#undef ADD
@ -325,10 +337,12 @@ void CDebugRenderer::DrawBoundingBox(
#undef ADD_FACE
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, 3 * sizeof(float), data.data());
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexBufferData(0, data.data());
deviceCommandContext->Draw(0, 6*6);
deviceCommandContext->Draw(0, 6 * 6);
deviceCommandContext->EndPass();
}
@ -371,8 +385,10 @@ void CDebugRenderer::DrawBrush(const CBrush& brush, const CColor& color, bool wi
#undef ADD_VERT
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, 3 * sizeof(float), data.data());
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexBufferData(0, data.data());
deviceCommandContext->Draw(0, data.size() / 5);

View File

@ -215,15 +215,25 @@ void CDecalRData::RenderDecals(
if (lastVB != batch.vertices->m_Owner)
{
lastVB = batch.vertices->m_Owner;
const GLsizei stride = sizeof(SDecalVertex);
SDecalVertex* base = (SDecalVertex*)batch.vertices->m_Owner->Bind(deviceCommandContext);
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base->m_Position[0]);
shader->NormalPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base->m_Normal[0]);
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, stride, &base->m_UV[0]);
batch.vertices->m_Owner->UploadIfNeeded(deviceCommandContext);
const uint32_t stride = sizeof(SDecalVertex);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
offsetof(SDecalVertex, m_Position), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::NORMAL,
Renderer::Backend::Format::R32G32B32_SFLOAT,
offsetof(SDecalVertex, m_Normal), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT,
offsetof(SDecalVertex, m_UV), stride, 0);
deviceCommandContext->SetVertexBuffer(0, batch.vertices->m_Owner->GetBuffer());
}
if (lastIB != batch.indices->m_Owner)
@ -243,8 +253,6 @@ void CDecalRData::RenderDecals(
deviceCommandContext->EndPass();
}
}
CVertexBuffer::Unbind(deviceCommandContext);
}
void CDecalRData::BuildVertexData()

View File

@ -174,75 +174,71 @@ void ShaderModelVertexRenderer::UpdateModelData(CModel* model, CModelRData* data
// Setup one rendering pass
void ShaderModelVertexRenderer::BeginPass(int streamflags)
void ShaderModelVertexRenderer::BeginPass()
{
ENSURE(streamflags == (streamflags & (STREAM_POS | STREAM_UV0 | STREAM_UV1 | STREAM_NORMAL)));
}
// Cleanup one rendering pass
void ShaderModelVertexRenderer::EndPass(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, int UNUSED(streamflags))
Renderer::Backend::GL::CDeviceCommandContext* UNUSED(deviceCommandContext))
{
CVertexBuffer::Unbind(deviceCommandContext);
}
// Prepare UV coordinates for this modeldef
void ShaderModelVertexRenderer::PrepareModelDef(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader, int streamflags, const CModelDef& def)
Renderer::Backend::GL::CShaderProgram* UNUSED(shader), const CModelDef& def)
{
m->shadermodeldef = (ShaderModelDef*)def.GetRenderData(m);
ENSURE(m->shadermodeldef);
u8* base = m->shadermodeldef->m_Array.Bind(deviceCommandContext);
GLsizei stride = (GLsizei)m->shadermodeldef->m_Array.GetStride();
m->shadermodeldef->m_Array.UploadIfNeeded(deviceCommandContext);
if (streamflags & STREAM_UV0)
const uint32_t stride = m->shadermodeldef->m_Array.GetStride();
const uint32_t firstVertexOffset = m->shadermodeldef->m_Array.GetOffset() * stride;
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
m->shadermodeldef->m_UVs[0].format,
firstVertexOffset + m->shadermodeldef->m_UVs[0].offset, stride, 0);
if (def.GetNumUVsPerVertex() >= 2)
{
shader->TexCoordPointer(
GL_TEXTURE0, m->shadermodeldef->m_UVs[0].format, stride,
base + m->shadermodeldef->m_UVs[0].offset);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
m->shadermodeldef->m_UVs[1].format,
firstVertexOffset + m->shadermodeldef->m_UVs[1].offset, stride, 0);
}
if ((streamflags & STREAM_UV1) && def.GetNumUVsPerVertex() >= 2)
{
shader->TexCoordPointer(
GL_TEXTURE1, m->shadermodeldef->m_UVs[1].format, stride,
base + m->shadermodeldef->m_UVs[1].offset);
}
deviceCommandContext->SetVertexBuffer(0, m->shadermodeldef->m_Array.GetBuffer());
}
// Render one model
void ShaderModelVertexRenderer::RenderModel(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader, int streamflags, CModel* model, CModelRData* data)
Renderer::Backend::GL::CShaderProgram* UNUSED(shader), CModel* model, CModelRData* data)
{
const CModelDefPtr& mdldef = model->GetModelDef();
ShaderModel* shadermodel = static_cast<ShaderModel*>(data);
u8* base = shadermodel->m_Array.Bind(deviceCommandContext);
GLsizei stride = (GLsizei)shadermodel->m_Array.GetStride();
shadermodel->m_Array.UploadIfNeeded(deviceCommandContext);
m->shadermodeldef->m_IndexArray.UploadIfNeeded(deviceCommandContext);
const uint32_t stride = shadermodel->m_Array.GetStride();
const uint32_t firstVertexOffset = shadermodel->m_Array.GetOffset() * stride;
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
firstVertexOffset + shadermodel->m_Position.offset, stride, 1);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::NORMAL,
Renderer::Backend::Format::R32G32B32_SFLOAT,
firstVertexOffset + shadermodel->m_Normal.offset, stride, 1);
deviceCommandContext->SetVertexBuffer(1, shadermodel->m_Array.GetBuffer());
deviceCommandContext->SetIndexBuffer(m->shadermodeldef->m_IndexArray.GetBuffer());
if (streamflags & STREAM_POS)
{
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride,
base + shadermodel->m_Position.offset);
}
if (streamflags & STREAM_NORMAL)
{
shader->NormalPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride,
base + shadermodel->m_Normal.offset);
}
// Render the lot.
const size_t numberOfFaces = mdldef->GetNumFaces();

View File

@ -39,15 +39,15 @@ public:
CModelRData* CreateModelData(const void* key, CModel* model) override;
void UpdateModelData(CModel* model, CModelRData* data, int updateflags) override;
void BeginPass(int streamflags) override;
void BeginPass() override;
void EndPass(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, int streamflags) override;
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext) override;
void PrepareModelDef(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader, int streamflags, const CModelDef& def) override;
Renderer::Backend::GL::CShaderProgram* shader, const CModelDef& def) override;
void RenderModel(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader, int streamflags, CModel* model, CModelRData* data) override;
Renderer::Backend::GL::CShaderProgram* shader, CModel* model, CModelRData* data) override;
protected:
struct ShaderModelRendererInternals;

View File

@ -295,86 +295,81 @@ void InstancingModelRenderer::UpdateModelData(CModel* UNUSED(model), CModelRData
// Setup one rendering pass.
void InstancingModelRenderer::BeginPass(int streamflags)
void InstancingModelRenderer::BeginPass()
{
ENSURE(streamflags == (streamflags & (STREAM_POS|STREAM_NORMAL|STREAM_UV0|STREAM_UV1|STREAM_UV2|STREAM_UV3|STREAM_UV4)));
}
// Cleanup rendering pass.
void InstancingModelRenderer::EndPass(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
int UNUSED(streamflags))
Renderer::Backend::GL::CDeviceCommandContext* UNUSED(deviceCommandContext))
{
CVertexBuffer::Unbind(deviceCommandContext);
}
// Prepare UV coordinates for this modeldef
void InstancingModelRenderer::PrepareModelDef(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader, int streamflags, const CModelDef& def)
Renderer::Backend::GL::CShaderProgram* UNUSED(shader), const CModelDef& def)
{
m->imodeldef = (IModelDef*)def.GetRenderData(m);
ENSURE(m->imodeldef);
u8* base = m->imodeldef->m_Array.Bind(deviceCommandContext);
GLsizei stride = (GLsizei)m->imodeldef->m_Array.GetStride();
m->imodeldef->m_Array.UploadIfNeeded(deviceCommandContext);
m->imodeldef->m_IndexArray.UploadIfNeeded(deviceCommandContext);
deviceCommandContext->SetIndexBuffer(m->imodeldef->m_IndexArray.GetBuffer());
if (streamflags & STREAM_POS)
const uint32_t stride = m->imodeldef->m_Array.GetStride();
const uint32_t firstVertexOffset = m->imodeldef->m_Array.GetOffset() * stride;
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
m->imodeldef->m_Position.format,
firstVertexOffset + m->imodeldef->m_Position.offset, stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::NORMAL,
m->imodeldef->m_Normal.format,
firstVertexOffset + m->imodeldef->m_Normal.offset, stride, 0);
constexpr size_t MAX_UV = 2;
for (size_t uv = 0; uv < std::min(MAX_UV, def.GetNumUVsPerVertex()); ++uv)
{
shader->VertexPointer(
m->imodeldef->m_Position.format, stride,
base + m->imodeldef->m_Position.offset);
const Renderer::Backend::VertexAttributeStream stream =
static_cast<Renderer::Backend::VertexAttributeStream>(
static_cast<int>(Renderer::Backend::VertexAttributeStream::UV0) + uv);
deviceCommandContext->SetVertexAttributeFormat(
stream, m->imodeldef->m_UVs[uv].format,
firstVertexOffset + m->imodeldef->m_UVs[uv].offset, stride, 0);
}
if (streamflags & STREAM_NORMAL)
// GPU skinning requires extra attributes to compute positions/normals.
if (m->gpuSkinning)
{
shader->NormalPointer(
m->imodeldef->m_Normal.format, stride,
base + m->imodeldef->m_Normal.offset);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV2,
m->imodeldef->m_BlendJoints.format,
firstVertexOffset + m->imodeldef->m_BlendJoints.offset, stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV3,
m->imodeldef->m_BlendWeights.format,
firstVertexOffset + m->imodeldef->m_BlendWeights.offset, stride, 0);
}
if (m->calculateTangents)
{
shader->VertexAttribPointer(
str_a_tangent, m->imodeldef->m_Tangent.format,
GL_FALSE, stride, base + m->imodeldef->m_Tangent.offset);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV4,
m->imodeldef->m_Tangent.format,
firstVertexOffset + m->imodeldef->m_Tangent.offset, stride, 0);
}
for (size_t uv = 0; uv < 2; ++uv)
if (streamflags & (STREAM_UV0 << uv))
{
if (def.GetNumUVsPerVertex() >= uv + 1)
{
shader->TexCoordPointer(
GL_TEXTURE0 + uv, m->imodeldef->m_UVs[uv].format, stride,
base + m->imodeldef->m_UVs[uv].offset);
}
else
ONCE(LOGERROR("Model '%s' has no UV%d set.", def.GetName().string8().c_str(), uv));
}
// GPU skinning requires extra attributes to compute positions/normals
if (m->gpuSkinning)
{
shader->VertexAttribPointer(
str_a_skinJoints, m->imodeldef->m_BlendJoints.format, GL_FALSE,
stride, base + m->imodeldef->m_BlendJoints.offset);
shader->VertexAttribPointer(
str_a_skinWeights, m->imodeldef->m_BlendWeights.format, GL_TRUE,
stride, base + m->imodeldef->m_BlendWeights.offset);
}
deviceCommandContext->SetVertexBuffer(0, m->imodeldef->m_Array.GetBuffer());
}
// Render one model
void InstancingModelRenderer::RenderModel(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader, int UNUSED(streamflags), CModel* model, CModelRData* UNUSED(data))
Renderer::Backend::GL::CShaderProgram* shader, CModel* model, CModelRData* UNUSED(data))
{
const CModelDefPtr& mdldef = model->GetModelDef();
@ -398,5 +393,4 @@ void InstancingModelRenderer::RenderModel(
// Bump stats.
g_Renderer.m_Stats.m_DrawCalls++;
g_Renderer.m_Stats.m_ModelTris += numberOfFaces;
}

View File

@ -42,15 +42,14 @@ public:
CModelRData* CreateModelData(const void* key, CModel* model);
void UpdateModelData(CModel* model, CModelRData* data, int updateflags);
void BeginPass(int streamflags);
void BeginPass();
void EndPass(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
int streamflags);
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
void PrepareModelDef(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader, int streamflags, const CModelDef& def);
Renderer::Backend::GL::CShaderProgram* shader, const CModelDef& def);
void RenderModel(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader, int streamflags, CModel* model, CModelRData* data);
Renderer::Backend::GL::CShaderProgram* shader, CModel* model, CModelRData* data);
protected:
InstancingModelRendererInternals* m;

View File

@ -608,7 +608,6 @@ void ShaderModelRenderer::Render(
deviceCommandContext->BeginPass();
Renderer::Backend::GL::CShaderProgram* shader = currentTech->GetShader(pass);
int streamflags = shader->GetStreamFlags();
modifier->BeginPass(shader);
@ -617,7 +616,7 @@ void ShaderModelRenderer::Render(
bool boundWaterTexture = false;
bool boundSkyCube = false;
m->vertexRenderer->BeginPass(streamflags);
m->vertexRenderer->BeginPass();
// When the shader technique changes, textures need to be
// rebound, so ensure there are no remnants from the last pass.
@ -685,7 +684,7 @@ void ShaderModelRenderer::Render(
if (newModeldef != currentModeldef)
{
currentModeldef = newModeldef;
m->vertexRenderer->PrepareModelDef(deviceCommandContext, shader, streamflags, *currentModeldef);
m->vertexRenderer->PrepareModelDef(deviceCommandContext, shader, *currentModeldef);
}
// Bind all uniforms when any change
@ -741,11 +740,11 @@ void ShaderModelRenderer::Render(
CModelRData* rdata = static_cast<CModelRData*>(model->GetRenderData());
ENSURE(rdata->GetKey() == m->vertexRenderer.get());
m->vertexRenderer->RenderModel(deviceCommandContext, shader, streamflags, model, rdata);
m->vertexRenderer->RenderModel(deviceCommandContext, shader, model, rdata);
}
}
m->vertexRenderer->EndPass(deviceCommandContext, streamflags);
m->vertexRenderer->EndPass(deviceCommandContext);
deviceCommandContext->EndPass();
}

View File

@ -88,22 +88,20 @@ public:
/**
* BeginPass: Setup global OpenGL state for this ModelVertexRenderer.
* BeginPass: Setup backend state for this ModelVertexRenderer.
*
* ModelVertexRenderer implementations should prepare "heavy" OpenGL
* ModelVertexRenderer implementations should prepare "heavy"
* state such as vertex shader state to prepare for rendering models
* and delivering vertex data to the fragment stage as described by
* streamflags.
* shader.
*
* ModelRenderer implementations must call this function before any
* calls to other rendering related functions.
*
* Recursive calls to BeginPass are not allowed, and every BeginPass
* is matched by a corresponding call to EndPass.
*
* @param streamflags Vertex streams required by the fragment stage.
*/
virtual void BeginPass(int streamflags) = 0;
virtual void BeginPass() = 0;
/**
@ -111,12 +109,8 @@ public:
*
* ModelRenderer implementations must call this function after
* rendering related functions for one pass have been called.
*
* @param streamflags Vertex streams required by the fragment stage.
* This equals the streamflags parameter passed on the last call to
* BeginPass.
*/
virtual void EndPass(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, int streamflags) = 0;
virtual void EndPass(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext) = 0;
/**
@ -128,14 +122,11 @@ public:
* When a ModelRenderer switches back and forth between CModelDefs,
* it must call PrepareModelDef for every switch.
*
* @param streamflags Vertex streams required by the fragment stage.
* This equals the streamflags parameter passed on the last call to
* BeginPass.
* @param def The model definition.
*/
virtual void PrepareModelDef(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader, int streamflags, const CModelDef& def) = 0;
Renderer::Backend::GL::CShaderProgram* shader, const CModelDef& def) = 0;
/**
@ -147,9 +138,6 @@ public:
* preconditions : The most recent call to PrepareModelDef since
* BeginPass has been for model->GetModelDef().
*
* @param streamflags Vertex streams required by the fragment stage.
* This equals the streamflags parameter passed on the last call to
* BeginPass.
* @param model The model that should be rendered.
* @param data Private data for the model as returned by CreateModelData.
*
@ -159,7 +147,7 @@ public:
*/
virtual void RenderModel(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader, int streamflags, CModel* model, CModelRData* data) = 0;
Renderer::Backend::GL::CShaderProgram* shader, CModel* model, CModelRData* data) = 0;
};

View File

@ -482,8 +482,6 @@ void OverlayRenderer::RenderTexturedOverlayLines(Renderer::Backend::GL::CDeviceC
// TODO: the shaders should probably be responsible for unbinding their textures
deviceCommandContext->BindTexture(1, GL_TEXTURE_2D, 0);
deviceCommandContext->BindTexture(0, GL_TEXTURE_2D, 0);
CVertexBuffer::Unbind(deviceCommandContext);
}
void OverlayRenderer::RenderTexturedOverlayLines(
@ -542,19 +540,16 @@ 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
m->quadIndices.UploadIfNeeded(deviceCommandContext);
u8* vertexBase = m->quadVertices.Bind(deviceCommandContext);
GLsizei vertexStride = m->quadVertices.GetStride();
deviceCommandContext->SetIndexBuffer(m->quadIndices.GetBuffer());
const uint32_t vertexStride = m->quadVertices.GetStride();
const uint32_t firstVertexOffset = m->quadVertices.GetOffset() * vertexStride;
for (OverlayRendererInternals::QuadBatchMap::iterator it = m->quadBatchMap.begin(); it != m->quadBatchMap.end(); ++it)
{
QuadBatchData& batchRenderData = it->second;
const size_t batchNumQuads = batchRenderData.m_NumRenderQuads;
// Careful; some drivers don't like drawing calls with 0 stuff to draw.
if (batchNumQuads == 0)
continue;
@ -565,19 +560,23 @@ void OverlayRenderer::RenderQuadOverlays(
shader->BindTexture(str_baseTex, maskPair.m_Texture->GetBackendTexture());
shader->BindTexture(str_maskTex, maskPair.m_TextureMask->GetBackendTexture());
int streamflags = shader->GetStreamFlags();
// TODO: move setting format out of the loop, we might want move the offset
// to the index offset when it's supported.
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
m->quadAttributePos.format, firstVertexOffset + m->quadAttributePos.offset, vertexStride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::COLOR,
m->quadAttributeColor.format, firstVertexOffset + m->quadAttributeColor.offset, vertexStride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
m->quadAttributeUV.format, firstVertexOffset + m->quadAttributeUV.offset, vertexStride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
m->quadAttributeUV.format, firstVertexOffset + m->quadAttributeUV.offset, vertexStride, 0);
if (streamflags & STREAM_POS)
shader->VertexPointer(m->quadAttributePos.format, vertexStride, vertexBase + m->quadAttributePos.offset);
if (streamflags & STREAM_UV0)
shader->TexCoordPointer(GL_TEXTURE0, m->quadAttributeUV.format, vertexStride, vertexBase + m->quadAttributeUV.offset);
if (streamflags & STREAM_UV1)
shader->TexCoordPointer(GL_TEXTURE1, m->quadAttributeUV.format, vertexStride, vertexBase + m->quadAttributeUV.offset);
if (streamflags & STREAM_COLOR)
shader->ColorPointer(m->quadAttributeColor.format, vertexStride, vertexBase + m->quadAttributeColor.offset);
deviceCommandContext->SetVertexBuffer(0, m->quadVertices.GetBuffer());
deviceCommandContext->SetIndexBuffer(m->quadIndices.GetBuffer());
deviceCommandContext->DrawIndexed(m->quadIndices.GetOffset() + batchRenderData.m_IndicesBase, batchNumQuads * 6, 0);
@ -590,8 +589,6 @@ void OverlayRenderer::RenderQuadOverlays(
// TODO: the shader should probably be responsible for unbinding its textures
deviceCommandContext->BindTexture(1, GL_TEXTURE_2D, 0);
deviceCommandContext->BindTexture(0, GL_TEXTURE_2D, 0);
CVertexBuffer::Unbind(deviceCommandContext);
}
void OverlayRenderer::RenderForegroundOverlays(
@ -638,8 +635,14 @@ void OverlayRenderer::RenderForegroundOverlays(
{0.0f, 0.0f},
};
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, sizeof(CVector2D), &uvs[0]);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
deviceCommandContext->SetVertexBufferData(1, &uvs[0]);
for (size_t i = 0; i < m->sprites.size(); ++i)
{
@ -662,8 +665,7 @@ void OverlayRenderer::RenderForegroundOverlays(
sprite->m_Position + right*sprite->m_X0 + up*sprite->m_Y1
};
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, sizeof(CVector3D), &position[0].X);
deviceCommandContext->SetVertexBufferData(0, &position[0].X);
deviceCommandContext->Draw(0, 6);
@ -767,10 +769,16 @@ void OverlayRenderer::RenderSphereOverlays(
shader = tech->GetShader();
shader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
m->GenerateSphere();
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, &m->sphereVertexes[0]);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexBufferData(0, m->sphereVertexes.data());
deviceCommandContext->SetIndexBufferData(m->sphereIndexes.data());
for (size_t i = 0; i < m->spheres.size(); ++i)
{
@ -781,12 +789,10 @@ void OverlayRenderer::RenderSphereOverlays(
transform.Scale(sphere->m_Radius, sphere->m_Radius, sphere->m_Radius);
transform.Translate(sphere->m_Center);
shader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
shader->Uniform(str_instancingTransform, transform);
shader->Uniform(str_color, sphere->m_Color);
deviceCommandContext->SetIndexBufferData(m->sphereIndexes.data());
deviceCommandContext->DrawIndexed(0, m->sphereIndexes.size(), 0);
g_Renderer.GetStats().m_DrawCalls++;

View File

@ -167,8 +167,6 @@ void ParticleRenderer::RenderParticles(
if (lastTech)
deviceCommandContext->EndPass();
CVertexBuffer::Unbind(deviceCommandContext);
}
void ParticleRenderer::RenderBounds(int cullGroup)

View File

@ -801,14 +801,24 @@ void CPatchRData::RenderBases(
for (VertexBufferBatches::iterator itv = itt->second.begin(); itv != itt->second.end(); ++itv)
{
GLsizei stride = sizeof(SBaseVertex);
SBaseVertex *base = (SBaseVertex *)itv->first->Bind(deviceCommandContext);
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base->m_Position[0]);
shader->NormalPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base->m_Normal[0]);
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base->m_Position[0]);
itv->first->UploadIfNeeded(deviceCommandContext);
const uint32_t stride = sizeof(SBaseVertex);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
offsetof(SBaseVertex, m_Position), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::NORMAL,
Renderer::Backend::Format::R32G32B32_SFLOAT,
offsetof(SBaseVertex, m_Normal), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32B32_SFLOAT,
offsetof(SBaseVertex, m_Position), stride, 0);
deviceCommandContext->SetVertexBuffer(0, itv->first->GetBuffer());
for (IndexBufferBatches::iterator it = itv->second.begin(); it != itv->second.end(); ++it)
{
@ -828,8 +838,6 @@ void CPatchRData::RenderBases(
deviceCommandContext->EndPass();
}
}
CVertexBuffer::Unbind(deviceCommandContext);
}
/**
@ -1027,17 +1035,29 @@ void CPatchRData::RenderBlends(
{
lastVB = itv->first;
previousShader = shader;
GLsizei stride = sizeof(SBlendVertex);
SBlendVertex *base = (SBlendVertex *)itv->first->Bind(deviceCommandContext);
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base->m_Position[0]);
shader->NormalPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base->m_Normal[0]);
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base->m_Position[0]);
shader->TexCoordPointer(
GL_TEXTURE1, Renderer::Backend::Format::R32G32_SFLOAT, stride, &base->m_AlphaUVs[0]);
itv->first->UploadIfNeeded(deviceCommandContext);
const uint32_t stride = sizeof(SBlendVertex);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
offsetof(SBlendVertex, m_Position), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::NORMAL,
Renderer::Backend::Format::R32G32B32_SFLOAT,
offsetof(SBlendVertex, m_Normal), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32B32_SFLOAT,
offsetof(SBlendVertex, m_Position), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
Renderer::Backend::Format::R32G32_SFLOAT,
offsetof(SBlendVertex, m_AlphaUVs), stride, 0);
deviceCommandContext->SetVertexBuffer(0, itv->first->GetBuffer());
}
for (IndexBufferBatches::iterator it = itv->second.begin(); it != itv->second.end(); ++it)
@ -1059,13 +1079,11 @@ void CPatchRData::RenderBlends(
deviceCommandContext->EndPass();
}
}
CVertexBuffer::Unbind(deviceCommandContext);
}
void CPatchRData::RenderStreams(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
const std::vector<CPatchRData*>& patches, Renderer::Backend::GL::CShaderProgram* shader,
const std::vector<CPatchRData*>& patches, Renderer::Backend::GL::CShaderProgram* UNUSED(shader),
const bool bindPositionAsTexCoord)
{
PROFILE3("render terrain streams");
@ -1095,19 +1113,26 @@ void CPatchRData::RenderStreams(
PROFILE_END("compute batches");
const uint32_t stride = sizeof(SBaseVertex);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
offsetof(SBaseVertex, m_Position), stride, 0);
if (bindPositionAsTexCoord)
{
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32B32_SFLOAT,
offsetof(SBaseVertex, m_Position), stride, 0);
}
// Render each batch
for (const std::pair<CVertexBuffer* const, StreamIndexBufferBatches>& streamBatch : batches)
{
GLsizei stride = sizeof(SBaseVertex);
SBaseVertex *base = (SBaseVertex *)streamBatch.first->Bind(deviceCommandContext);
streamBatch.first->UploadIfNeeded(deviceCommandContext);
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base->m_Position);
if (bindPositionAsTexCoord)
{
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base->m_Position);
}
deviceCommandContext->SetVertexBuffer(0, streamBatch.first->GetBuffer());
for (const std::pair<CVertexBuffer* const, StreamBatchElements>& batchIndexBuffer : streamBatch.second)
{
@ -1123,8 +1148,6 @@ void CPatchRData::RenderStreams(
g_Renderer.m_Stats.m_TerrainTris += std::accumulate(batch.first.begin(), batch.first.end(), 0) / 3;
}
}
CVertexBuffer::Unbind(deviceCommandContext);
}
void CPatchRData::RenderOutline()
@ -1161,11 +1184,20 @@ void CPatchRData::RenderOutline()
void CPatchRData::RenderSides(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
const std::vector<CPatchRData*>& patches, Renderer::Backend::GL::CShaderProgram* shader)
const std::vector<CPatchRData*>& patches, Renderer::Backend::GL::CShaderProgram* UNUSED(shader))
{
PROFILE3("render terrain sides");
GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain sides");
if (patches.empty())
return;
const uint32_t stride = sizeof(SSideVertex);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
offsetof(SSideVertex, m_Position), stride, 0);
CVertexBuffer* lastVB = nullptr;
for (CPatchRData* patch : patches)
{
@ -1175,12 +1207,9 @@ void CPatchRData::RenderSides(
if (lastVB != patch->m_VBSides->m_Owner)
{
lastVB = patch->m_VBSides->m_Owner;
SSideVertex *base = (SSideVertex*)patch->m_VBSides->m_Owner->Bind(deviceCommandContext);
patch->m_VBSides->m_Owner->UploadIfNeeded(deviceCommandContext);
// setup data pointers
GLsizei stride = sizeof(SSideVertex);
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base->m_Position);
deviceCommandContext->SetVertexBuffer(0, patch->m_VBSides->m_Owner->GetBuffer());
}
deviceCommandContext->Draw(patch->m_VBSides->m_Index, (GLsizei)patch->m_VBSides->m_Count);
@ -1189,8 +1218,6 @@ void CPatchRData::RenderSides(
g_Renderer.m_Stats.m_DrawCalls++;
g_Renderer.m_Stats.m_TerrainTris += patch->m_VBSides->m_Count / 3;
}
CVertexBuffer::Unbind(deviceCommandContext);
}
void CPatchRData::RenderPriorities(CTextRenderer& textRenderer)
@ -1422,63 +1449,69 @@ void CPatchRData::BuildWater()
void CPatchRData::RenderWaterSurface(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader, const bool bindWaterData)
Renderer::Backend::GL::CShaderProgram* UNUSED(shader), const bool bindWaterData)
{
ASSERT(m_UpdateFlags == 0);
if (!m_VBWater)
return;
m_VBWater->m_Owner->UploadIfNeeded(deviceCommandContext);
m_VBWaterIndices->m_Owner->UploadIfNeeded(deviceCommandContext);
SWaterVertex* base = reinterpret_cast<SWaterVertex*>(m_VBWater->m_Owner->Bind(deviceCommandContext));
const uint32_t stride = sizeof(SWaterVertex);
const uint32_t firstVertexOffset = m_VBWater->m_Index * stride;
// Setup data pointers.
const GLsizei stride = sizeof(SWaterVertex);
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base[m_VBWater->m_Index].m_Position);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
firstVertexOffset + offsetof(SWaterVertex, m_Position), stride, 0);
if (bindWaterData)
{
shader->VertexAttribPointer(
str_a_waterInfo, Renderer::Backend::Format::R32G32_SFLOAT, false, stride,
&base[m_VBWater->m_Index].m_WaterData);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
Renderer::Backend::Format::R32G32_SFLOAT,
firstVertexOffset + offsetof(SWaterVertex, m_WaterData), stride, 0);
}
deviceCommandContext->SetVertexBuffer(0, m_VBWater->m_Owner->GetBuffer());
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;
CVertexBuffer::Unbind(deviceCommandContext);
}
void CPatchRData::RenderWaterShore(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Renderer::Backend::GL::CShaderProgram* shader)
Renderer::Backend::GL::CShaderProgram* UNUSED(shader))
{
ASSERT(m_UpdateFlags == 0);
if (!m_VBWaterShore)
return;
m_VBWaterShore->m_Owner->UploadIfNeeded(deviceCommandContext);
m_VBWaterIndicesShore->m_Owner->UploadIfNeeded(deviceCommandContext);
SWaterVertex* base = reinterpret_cast<SWaterVertex*>(m_VBWaterShore->m_Owner->Bind(deviceCommandContext));
const uint32_t stride = sizeof(SWaterVertex);
const uint32_t firstVertexOffset = m_VBWaterShore->m_Index * stride;
const GLsizei stride = sizeof(SWaterVertex);
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride,
&base[m_VBWaterShore->m_Index].m_Position);
shader->VertexAttribPointer(
str_a_waterInfo, Renderer::Backend::Format::R32G32_SFLOAT, false, stride,
&base[m_VBWaterShore->m_Index].m_WaterData);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
firstVertexOffset + offsetof(SWaterVertex, m_Position), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
Renderer::Backend::Format::R32G32_SFLOAT,
firstVertexOffset + offsetof(SWaterVertex, m_WaterData), stride, 0);
deviceCommandContext->SetVertexBuffer(0, m_VBWaterShore->m_Owner->GetBuffer());
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;
CVertexBuffer::Unbind(deviceCommandContext);
}

View File

@ -208,6 +208,7 @@ void CPostprocManager::ApplyBlurDownscale2x(
const SViewPort vp = { 0, 0, inWidth / 2, inHeight / 2 };
g_Renderer.SetViewport(vp);
// TODO: remove the fullscreen quad drawing duplication.
float quadVerts[] =
{
1.0f, 1.0f,
@ -228,10 +229,17 @@ void CPostprocManager::ApplyBlurDownscale2x(
1.0f, 0.0f,
1.0f, 1.0f
};
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, 0, quadTex);
shader->VertexPointer(
Renderer::Backend::Format::R32G32_SFLOAT, 0, quadVerts);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
deviceCommandContext->SetVertexBufferData(0, quadVerts);
deviceCommandContext->SetVertexBufferData(1, quadTex);
deviceCommandContext->Draw(0, 6);
g_Renderer.SetViewport(oldVp);
@ -285,10 +293,17 @@ void CPostprocManager::ApplyBlurGauss(
1.0f, 0.0f,
1.0f, 1.0f
};
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, 0, quadTex);
shader->VertexPointer(
Renderer::Backend::Format::R32G32_SFLOAT, 0, quadVerts);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
deviceCommandContext->SetVertexBufferData(0, quadVerts);
deviceCommandContext->SetVertexBufferData(1, quadTex);
deviceCommandContext->Draw(0, 6);
g_Renderer.SetViewport(oldVp);
@ -313,10 +328,16 @@ void CPostprocManager::ApplyBlurGauss(
g_Renderer.SetViewport(vp);
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, 0, quadTex);
shader->VertexPointer(
Renderer::Backend::Format::R32G32_SFLOAT, 0, quadVerts);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
deviceCommandContext->SetVertexBufferData(0, quadVerts);
deviceCommandContext->SetVertexBufferData(1, quadTex);
deviceCommandContext->Draw(0, 6);
g_Renderer.SetViewport(oldVp);
@ -434,10 +455,17 @@ void CPostprocManager::ApplyEffect(
1.0f, 0.0f,
1.0f, 1.0f
};
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, 0, quadTex);
shader->VertexPointer(
Renderer::Backend::Format::R32G32_SFLOAT, 0, quadVerts);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
deviceCommandContext->SetVertexBufferData(0, quadVerts);
deviceCommandContext->SetVertexBufferData(1, quadTex);
deviceCommandContext->Draw(0, 6);
deviceCommandContext->EndPass();

View File

@ -749,10 +749,16 @@ void ShadowMap::RenderDebugTexture(
1,0, 0,1, 1,1
};
texShader->VertexPointer(
Renderer::Backend::Format::R32G32_SFLOAT, 0, boxVerts);
texShader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, 0, boxUV);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
deviceCommandContext->SetVertexBufferData(0, boxVerts);
deviceCommandContext->SetVertexBufferData(1, boxUV);
deviceCommandContext->Draw(0, 6);
deviceCommandContext->EndPass();

View File

@ -493,8 +493,13 @@ void SilhouetteRenderer::RenderDebugOverlays(
r.x1, r.y1,
r.x0, r.y1,
};
shader->VertexPointer(
Renderer::Backend::Format::R16G16_SINT, 0, verts);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R16G16_SINT, 0, 0, 0);
deviceCommandContext->SetVertexBufferData(0, verts);
deviceCommandContext->Draw(0, 6);
}

View File

@ -246,14 +246,19 @@ void SkyManager::RenderSky(
camera.GetViewProjection() * translate * rotate * scale);
m_VertexArray.PrepareForRendering();
m_VertexArray.UploadIfNeeded(deviceCommandContext);
u8* base = m_VertexArray.Bind(deviceCommandContext);
const GLsizei stride = static_cast<GLsizei>(m_VertexArray.GetStride());
const uint32_t stride = m_VertexArray.GetStride();
const uint32_t firstVertexOffset = m_VertexArray.GetOffset() * stride;
shader->VertexPointer(
m_AttributePosition.format, stride, base + m_AttributePosition.offset);
shader->TexCoordPointer(
GL_TEXTURE0, m_AttributeUV.format, stride, base + m_AttributeUV.offset);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION, m_AttributePosition.format,
firstVertexOffset + m_AttributePosition.offset, stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0, m_AttributeUV.format,
firstVertexOffset + m_AttributeUV.offset, stride, 0);
deviceCommandContext->SetVertexBuffer(0, m_VertexArray.GetBuffer());
deviceCommandContext->Draw(0, m_VertexArray.GetNumberOfVertices());

View File

@ -229,8 +229,11 @@ void TerrainOverlay::RenderTile(
overlayShader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
overlayShader->Uniform(str_color, color);
overlayShader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, vertices.data());
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexBufferData(0, vertices.data());
deviceCommandContext->Draw(0, vertices.size() / 3);
@ -297,8 +300,11 @@ void TerrainOverlay::RenderTileOutline(
overlayShader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
overlayShader->Uniform(str_color, color);
overlayShader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, vertices.data());
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexBufferData(0, vertices.data());
deviceCommandContext->Draw(0, vertices.size() / 3);

View File

@ -207,11 +207,14 @@ void TerrainRenderer::RenderTerrainOverlayTexture(
waterBounds[0].X, height, waterBounds[1].Z
};
const GLsizei stride = sizeof(float) * 3;
debugOverlayShader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, waterPos);
debugOverlayShader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32B32_SFLOAT, stride, waterPos);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
deviceCommandContext->SetVertexBufferData(0, waterPos);
deviceCommandContext->Draw(0, 6);
}

View File

@ -44,29 +44,32 @@ void CTexturedLineRData::Render(
// -- render main line quad strip ----------------------
const int streamFlags = shader->GetStreamFlags();
line.m_TextureBase->UploadBackendTextureIfNeeded(deviceCommandContext);
line.m_TextureMask->UploadBackendTextureIfNeeded(deviceCommandContext);
m_VB->m_Owner->UploadIfNeeded(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);
GLsizei stride = sizeof(CTexturedLineRData::SVertex);
CTexturedLineRData::SVertex* vertexBase =
reinterpret_cast<CTexturedLineRData::SVertex*>(m_VB->m_Owner->Bind(deviceCommandContext));
const uint32_t stride = sizeof(CTexturedLineRData::SVertex);
if (streamFlags & STREAM_POS)
shader->VertexPointer(Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &vertexBase->m_Position[0]);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
offsetof(CTexturedLineRData::SVertex, m_Position), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT,
offsetof(CTexturedLineRData::SVertex, m_UVs), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
Renderer::Backend::Format::R32G32_SFLOAT,
offsetof(CTexturedLineRData::SVertex, m_UVs), stride, 0);
if (streamFlags & STREAM_UV0)
shader->TexCoordPointer(GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, stride, &vertexBase->m_UVs[0]);
if (streamFlags & STREAM_UV1)
shader->TexCoordPointer(GL_TEXTURE1, Renderer::Backend::Format::R32G32_SFLOAT, stride, &vertexBase->m_UVs[0]);
deviceCommandContext->SetVertexBuffer(0, m_VB->m_Owner->GetBuffer());
deviceCommandContext->SetIndexBuffer(m_VBIndices->m_Owner->GetBuffer());
deviceCommandContext->DrawIndexed(m_VBIndices->m_Index, m_VBIndices->m_Count, 0);

View File

@ -282,21 +282,6 @@ void VertexArray::Upload()
m_VB->m_Owner->UpdateChunkVertices(m_VB.Get(), m_BackingStore);
}
// Bind this array, returns the base address for calls to glVertexPointer etc.
u8* VertexArray::Bind(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
{
if (!m_VB)
return nullptr;
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)
{

View File

@ -181,8 +181,7 @@ public:
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,

View File

@ -290,25 +290,6 @@ void CVertexBuffer::UploadIfNeeded(
}
}
// 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;
}
void CVertexBuffer::Unbind(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
{
deviceCommandContext->BindBuffer(
Renderer::Backend::GL::CBuffer::Type::VERTEX, nullptr);
deviceCommandContext->BindBuffer(
Renderer::Backend::GL::CBuffer::Type::INDEX, nullptr);
}
size_t CVertexBuffer::GetBytesReserved() const
{
return MAX_VB_SIZE_BYTES;

View File

@ -34,23 +34,23 @@
*
* The class can be used in two modes, depending on the usage parameter:
*
* GL_STATIC_DRAW: Call Allocate() with backingStore = NULL. Then call
* Static buffer: Call Allocate() with backingStore = nullptr. Then call
* UpdateChunkVertices() with any pointer - the data will be immediately copied
* to the VBO. This should be used for vertex data that rarely changes.
*
* GL_DYNAMIC_DRAW, GL_STREAM_DRAW: Call Allocate() with backingStore pointing
* Dynamic buffer: Call Allocate() with backingStore pointing
* at some memory that will remain valid for the lifetime of the CVertexBuffer.
* This should be used for vertex data that may change every frame.
* Rendering is expected to occur in two phases:
* - "Prepare" phase:
* If this chunk is going to be used for rendering during the next Bind phase,
* If this chunk is going to be used for rendering during the next rendering phase,
* you must call PrepareForRendering().
* If the vertex data in backingStore has been modified since the last Bind phase,
* If the vertex data in backingStore has been modified since the last uploading phase,
* you must call UpdateChunkVertices().
* - "Bind" phase:
* Bind() can be called (multiple times). The vertex data will be uploaded
* - "Upload" phase:
* UploadedIfNeeded() can be called (multiple times). The vertex data will be uploaded
* to the GPU if necessary.
* It is okay to have multiple prepare/bind cycles per frame (though slightly less
* It is okay to have multiple prepare/upload cycles per frame (though slightly less
* efficient), but they must occur sequentially.
*/
class CVertexBuffer
@ -76,7 +76,7 @@ public:
bool m_Dirty;
/// If true, we have been told this chunk is going to be used for
/// rendering in the next bind phase and will need to be uploaded
/// rendering in the next uploading phase and will need to be uploaded
bool m_Needed;
private:
@ -98,17 +98,9 @@ public:
const size_t maximumBufferSize);
~CVertexBuffer();
/// Bind to this buffer; return pointer to address required as parameter
/// 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);
/// Make the vertex data available for the next call to Bind()
/// Make the vertex data available for the next usage.
void PrepareForRendering(VBChunk* chunk);
/// Update vertex data for given chunk. Transfers the provided data to the actual OpenGL vertex buffer.

View File

@ -823,28 +823,44 @@ void WaterManager::RenderWaves(
continue;
CVertexBuffer::VBChunk* VBchunk = m_ShoreWaves[a]->m_VBVertices.Get();
SWavesVertex* base = (SWavesVertex*)VBchunk->m_Owner->Bind(deviceCommandContext);
VBchunk->m_Owner->UploadIfNeeded(deviceCommandContext);
m_ShoreWavesVBIndices->m_Owner->UploadIfNeeded(deviceCommandContext);
// setup data pointers
GLsizei stride = sizeof(SWavesVertex);
shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, &base[VBchunk->m_Index].m_BasePosition);
shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R8G8_UINT, stride, &base[VBchunk->m_Index].m_UV);
shader->NormalPointer(
Renderer::Backend::Format::R32G32_SFLOAT, stride, &base[VBchunk->m_Index].m_PerpVect);
shader->VertexAttribPointer(
str_a_apexPosition, Renderer::Backend::Format::R32G32B32_SFLOAT, false, stride, &base[VBchunk->m_Index].m_ApexPosition);
shader->VertexAttribPointer(
str_a_splashPosition, Renderer::Backend::Format::R32G32B32_SFLOAT, false, stride, &base[VBchunk->m_Index].m_SplashPosition);
shader->VertexAttribPointer(
str_a_retreatPosition, Renderer::Backend::Format::R32G32B32_SFLOAT, false, stride, &base[VBchunk->m_Index].m_RetreatPosition);
const uint32_t stride = sizeof(SWavesVertex);
const uint32_t firstVertexOffset = VBchunk->m_Index * stride;
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
firstVertexOffset + offsetof(SWavesVertex, m_BasePosition), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::NORMAL,
Renderer::Backend::Format::R32G32_SFLOAT,
firstVertexOffset + offsetof(SWavesVertex, m_PerpVect), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R8G8_UINT,
firstVertexOffset + offsetof(SWavesVertex, m_UV), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
Renderer::Backend::Format::R32G32B32_SFLOAT,
firstVertexOffset + offsetof(SWavesVertex, m_ApexPosition), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV2,
Renderer::Backend::Format::R32G32B32_SFLOAT,
firstVertexOffset + offsetof(SWavesVertex, m_SplashPosition), stride, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV3,
Renderer::Backend::Format::R32G32B32_SFLOAT,
firstVertexOffset + offsetof(SWavesVertex, m_RetreatPosition), stride, 0);
shader->Uniform(str_translation, m_ShoreWaves[a]->m_TimeDiff);
shader->Uniform(str_width, (int)m_ShoreWaves[a]->m_Width);
m_ShoreWavesVBIndices->m_Owner->UploadIfNeeded(deviceCommandContext);
deviceCommandContext->SetVertexBuffer(0, VBchunk->m_Owner->GetBuffer());
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);
@ -852,8 +868,6 @@ void WaterManager::RenderWaves(
// TODO: figure out why this doesn't work.
//g_Renderer.m_Stats.m_DrawCalls++;
//g_Renderer.m_Stats.m_WaterTris += m_ShoreWaves_VBIndices->m_Count / 3;
CVertexBuffer::Unbind(deviceCommandContext);
}
deviceCommandContext->EndPass();
deviceCommandContext->SetFramebuffer(

View File

@ -24,6 +24,21 @@ namespace Renderer
namespace Backend
{
enum class VertexAttributeStream : uint32_t
{
POSITION,
NORMAL,
COLOR,
UV0,
UV1,
UV2,
UV3,
UV4,
UV5,
UV6,
UV7,
};
/**
* IShaderProgram is a container for multiple shaders of different types.
*/

View File

@ -150,6 +150,21 @@ CDeviceCommandContext::CDeviceCommandContext(CDevice* device)
glBindTexture(GL_TEXTURE_2D, 0);
for (std::pair<GLenum, GLuint>& unit : m_BoundTextures)
unit.first = unit.second = 0;
for (size_t index = 0; index < m_VertexAttributeFormat.size(); ++index)
{
m_VertexAttributeFormat[index].active = false;
m_VertexAttributeFormat[index].initialized = false;
m_VertexAttributeFormat[index].bindingSlot = 0;
}
for (size_t index = 0; index < m_BoundBuffers.size(); ++index)
{
const CBuffer::Type type = static_cast<CBuffer::Type>(index);
const GLenum target = BufferTypeToGLTarget(type);
const GLuint handle = 0;
m_BoundBuffers[index].first = target;
m_BoundBuffers[index].second = handle;
}
}
CDeviceCommandContext::~CDeviceCommandContext() = default;
@ -302,7 +317,7 @@ void CDeviceCommandContext::UploadBufferRegion(
ENSURE(data);
ENSURE(dataOffset + dataSize <= buffer->GetSize());
const GLenum target = BufferTypeToGLTarget(buffer->GetType());
glBindBufferARB(target, buffer->GetHandle());
ScopedBufferBind scopedBufferBind(this, buffer);
if (buffer->IsDynamic())
{
// Tell the driver that it can reallocate the whole VBO
@ -322,7 +337,6 @@ void CDeviceCommandContext::UploadBufferRegion(
{
glBufferSubDataARB(target, dataOffset, dataSize, data);
}
glBindBufferARB(target, 0);
}
void CDeviceCommandContext::UploadBufferRegion(
@ -331,10 +345,9 @@ void CDeviceCommandContext::UploadBufferRegion(
{
ENSURE(dataOffset + dataSize <= buffer->GetSize());
const GLenum target = BufferTypeToGLTarget(buffer->GetType());
glBindBufferARB(target, buffer->GetHandle());
ScopedBufferBind scopedBufferBind(this, buffer);
ENSURE(buffer->IsDynamic());
UploadBufferRegionImpl(target, dataOffset, dataSize, uploadFunction);
glBindBufferARB(target, 0);
}
void CDeviceCommandContext::BeginScopedLabel(const char* name)
@ -381,13 +394,24 @@ void CDeviceCommandContext::BindTexture(const uint32_t unit, const GLenum target
void CDeviceCommandContext::BindBuffer(const CBuffer::Type type, CBuffer* buffer)
{
ENSURE(!buffer || buffer->GetType() == type);
if (type == CBuffer::Type::INDEX)
if (type == CBuffer::Type::VERTEX)
{
if (m_VertexBuffer == buffer)
return;
m_VertexBuffer = buffer;
}
else if (type == CBuffer::Type::INDEX)
{
if (!buffer)
m_IndexBuffer = nullptr;
m_IndexBufferData = nullptr;
}
glBindBufferARB(BufferTypeToGLTarget(type), buffer ? buffer->GetHandle() : 0);
const GLenum target = BufferTypeToGLTarget(type);
const GLuint handle = buffer ? buffer->GetHandle() : 0;
glBindBufferARB(target, handle);
const size_t cacheIndex = static_cast<size_t>(type);
ENSURE(cacheIndex < m_BoundBuffers.size());
m_BoundBuffers[cacheIndex].second = handle;
}
void CDeviceCommandContext::OnTextureDestroy(CTexture* texture)
@ -437,6 +461,13 @@ void CDeviceCommandContext::SetGraphicsPipelineStateImpl(
{
nextShaderProgram =
static_cast<CShaderProgram*>(pipelineStateDesc.shaderProgram);
for (size_t index = 0; index < m_VertexAttributeFormat.size(); ++index)
{
const VertexAttributeStream stream = static_cast<VertexAttributeStream>(index);
m_VertexAttributeFormat[index].active = nextShaderProgram->IsStreamActive(stream);
m_VertexAttributeFormat[index].initialized = false;
m_VertexAttributeFormat[index].bindingSlot = std::numeric_limits<uint32_t>::max();
}
}
if (nextShaderProgram)
nextShaderProgram->Bind(currentShaderProgram);
@ -709,6 +740,7 @@ void CDeviceCommandContext::ClearFramebuffer(const bool color, const bool depth,
mask |= GL_STENCIL_BUFFER_BIT;
}
glClear(mask);
ogl_WarnIfError();
if (needsColor)
ApplyColorMask(m_GraphicsPipelineStateDesc.blendState.colorWriteMask);
if (needsDepth)
@ -762,6 +794,71 @@ void CDeviceCommandContext::SetViewports(const uint32_t viewportCount, const Rec
glViewport(viewports[0].x, viewports[0].y, viewports[0].width, viewports[0].height);
}
void CDeviceCommandContext::SetVertexAttributeFormat(
const VertexAttributeStream stream,
const Format format,
const uint32_t offset,
const uint32_t stride,
const uint32_t bindingSlot)
{
const uint32_t index = static_cast<uint32_t>(stream);
ENSURE(index < m_VertexAttributeFormat.size());
ENSURE(bindingSlot < m_VertexAttributeFormat.size());
if (!m_VertexAttributeFormat[index].active)
return;
m_VertexAttributeFormat[index].format = format;
m_VertexAttributeFormat[index].offset = offset;
m_VertexAttributeFormat[index].stride = stride;
m_VertexAttributeFormat[index].bindingSlot = bindingSlot;
m_VertexAttributeFormat[index].initialized = true;
}
void CDeviceCommandContext::SetVertexBuffer(
const uint32_t bindingSlot, CBuffer* buffer)
{
ENSURE(buffer);
ENSURE(buffer->GetType() == CBuffer::Type::VERTEX);
ENSURE(m_GraphicsPipelineStateDesc.shaderProgram);
BindBuffer(buffer->GetType(), buffer);
CShaderProgram* shaderProgram =
static_cast<CShaderProgram*>(m_GraphicsPipelineStateDesc.shaderProgram);
for (size_t index = 0; index < m_VertexAttributeFormat.size(); ++index)
{
if (!m_VertexAttributeFormat[index].active || m_VertexAttributeFormat[index].bindingSlot != bindingSlot)
continue;
ENSURE(m_VertexAttributeFormat[index].initialized);
const VertexAttributeStream stream = static_cast<VertexAttributeStream>(index);
shaderProgram->VertexAttribPointer(stream,
m_VertexAttributeFormat[index].format,
m_VertexAttributeFormat[index].offset,
m_VertexAttributeFormat[index].stride,
nullptr);
}
}
void CDeviceCommandContext::SetVertexBufferData(
const uint32_t bindingSlot, const void* data)
{
ENSURE(data);
ENSURE(m_GraphicsPipelineStateDesc.shaderProgram);
BindBuffer(CBuffer::Type::VERTEX, nullptr);
CShaderProgram* shaderProgram =
static_cast<CShaderProgram*>(m_GraphicsPipelineStateDesc.shaderProgram);
for (size_t index = 0; index < m_VertexAttributeFormat.size(); ++index)
{
if (!m_VertexAttributeFormat[index].active || m_VertexAttributeFormat[index].bindingSlot != bindingSlot)
continue;
ENSURE(m_VertexAttributeFormat[index].initialized);
const VertexAttributeStream stream = static_cast<VertexAttributeStream>(index);
shaderProgram->VertexAttribPointer(stream,
m_VertexAttributeFormat[index].format,
m_VertexAttributeFormat[index].offset,
m_VertexAttributeFormat[index].stride,
data);
}
}
void CDeviceCommandContext::SetIndexBuffer(CBuffer* buffer)
{
ENSURE(buffer->GetType() == CBuffer::Type::INDEX);
@ -804,6 +901,7 @@ void CDeviceCommandContext::Draw(
static_cast<CShaderProgram*>(m_GraphicsPipelineStateDesc.shaderProgram)
->AssertPointersBound();
glDrawArrays(GL_TRIANGLES, firstVertex, vertexCount);
ogl_WarnIfError();
}
void CDeviceCommandContext::DrawIndexed(
@ -826,6 +924,7 @@ void CDeviceCommandContext::DrawIndexed(
// 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)));
ogl_WarnIfError();
}
void CDeviceCommandContext::DrawIndexedInRange(
@ -850,6 +949,7 @@ void CDeviceCommandContext::DrawIndexedInRange(
#else
glDrawRangeElementsEXT(GL_TRIANGLES, start, end, indexCount, GL_UNSIGNED_SHORT, indices);
#endif
ogl_WarnIfError();
}
CDeviceCommandContext::ScopedBind::ScopedBind(
@ -868,6 +968,24 @@ CDeviceCommandContext::ScopedBind::~ScopedBind()
m_DeviceCommandContext->m_ActiveTextureUnit, m_OldBindUnit.first, m_OldBindUnit.second);
}
CDeviceCommandContext::ScopedBufferBind::ScopedBufferBind(
CDeviceCommandContext* deviceCommandContext, CBuffer* buffer)
: m_DeviceCommandContext(deviceCommandContext)
{
ENSURE(buffer);
m_CacheIndex = static_cast<size_t>(buffer->GetType());
const GLenum target = BufferTypeToGLTarget(buffer->GetType());
const GLuint handle = buffer->GetHandle();
glBindBufferARB(target, handle);
}
CDeviceCommandContext::ScopedBufferBind::~ScopedBufferBind()
{
glBindBufferARB(
m_DeviceCommandContext->m_BoundBuffers[m_CacheIndex].first,
m_DeviceCommandContext->m_BoundBuffers[m_CacheIndex].second);
}
} // namespace GL
} // namespace Backend

View File

@ -88,6 +88,15 @@ public:
void SetScissors(const uint32_t scissorCount, const Rect* scissors);
void SetViewports(const uint32_t viewportCount, const Rect* viewports);
void SetVertexAttributeFormat(
const VertexAttributeStream stream,
const Format format,
const uint32_t offset,
const uint32_t stride,
const uint32_t bindingSlot);
void SetVertexBuffer(const uint32_t bindingSlot, CBuffer* buffer);
void SetVertexBufferData(const uint32_t bindingSlot, const void* data);
void SetIndexBuffer(CBuffer* buffer);
void SetIndexBufferData(const void* data);
@ -107,7 +116,7 @@ public:
// TODO: remove direct binding after moving shaders.
void BindTexture(const uint32_t unit, const GLenum target, const GLuint handle);
void BindBuffer(const CBuffer::Type type, CBuffer* buffer);
// We need to know when to invalidate our texture bind cache.
void OnTextureDestroy(CTexture* texture);
@ -125,6 +134,8 @@ private:
void SetGraphicsPipelineStateImpl(
const GraphicsPipelineStateDesc& pipelineStateDesc, const bool force);
void BindBuffer(const CBuffer::Type type, CBuffer* buffer);
CDevice* m_Device = nullptr;
GraphicsPipelineStateDesc m_GraphicsPipelineStateDesc{};
@ -135,6 +146,7 @@ private:
uint32_t m_ScopedLabelDepth = 0;
CBuffer* m_VertexBuffer = nullptr;
CBuffer* m_IndexBuffer = nullptr;
const void* m_IndexBufferData = nullptr;
@ -154,6 +166,34 @@ private:
CDeviceCommandContext* m_DeviceCommandContext = nullptr;
BindUnit m_OldBindUnit;
};
using BoundBuffer = std::pair<GLenum, GLuint>;
std::array<BoundBuffer, 2> m_BoundBuffers;
class ScopedBufferBind
{
public:
ScopedBufferBind(
CDeviceCommandContext* deviceCommandContext, CBuffer* buffer);
~ScopedBufferBind();
private:
CDeviceCommandContext* m_DeviceCommandContext = nullptr;
size_t m_CacheIndex = 0;
};
struct VertexAttributeFormat
{
Format format;
uint32_t offset;
uint32_t stride;
uint32_t bindingSlot;
bool active;
bool initialized;
};
std::array<
VertexAttributeFormat,
static_cast<size_t>(VertexAttributeStream::UV7) + 1> m_VertexAttributeFormat;
};
} // namespace GL

View File

@ -53,7 +53,12 @@ namespace GL
namespace
{
GLint GLSizeFromFormat(const Renderer::Backend::Format format)
int GetStreamMask(const VertexAttributeStream stream)
{
return 1 << static_cast<int>(stream);
}
GLint GLSizeFromFormat(const Format format)
{
GLint size = 1;
if (format == Renderer::Backend::Format::R32_SFLOAT ||
@ -77,7 +82,7 @@ GLint GLSizeFromFormat(const Renderer::Backend::Format format)
return size;
}
GLenum GLTypeFromFormat(const Renderer::Backend::Format format)
GLenum GLTypeFromFormat(const Format format)
{
GLenum type = GL_FLOAT;
if (format == Renderer::Backend::Format::R32_SFLOAT ||
@ -100,27 +105,31 @@ GLenum GLTypeFromFormat(const Renderer::Backend::Format format)
return type;
}
int GetAttributeLocationFromStream(Renderer::Backend::GL::CDevice* device, const int stream)
GLboolean NormalizedFromFormat(const Format format)
{
switch (format)
{
case Format::R8G8_UNORM: FALLTHROUGH;
case Format::R8G8B8_UNORM: FALLTHROUGH;
case Format::R8G8B8A8_UNORM: FALLTHROUGH;
case Format::R16_UNORM: FALLTHROUGH;
case Format::R16G16_UNORM:
return GL_TRUE;
default:
break;
}
return GL_FALSE;
}
int GetAttributeLocationFromStream(
CDevice* device, const VertexAttributeStream stream)
{
// Old mapping makes sense only if we have an old/low-end hardware. Else we
// need to use sequential numbering to fix #3054. We use presence of
// compute shaders as a check that the hardware has universal CUs.
if (device->GetCapabilities().computeShaders)
{
switch (stream)
{
case STREAM_POS: return 0;
case STREAM_NORMAL: return 1;
case STREAM_COLOR: return 2;
case STREAM_UV0: return 3;
case STREAM_UV1: return 4;
case STREAM_UV2: return 5;
case STREAM_UV3: return 6;
case STREAM_UV4: return 7;
case STREAM_UV5: return 8;
case STREAM_UV6: return 9;
case STREAM_UV7: return 10;
}
return static_cast<int>(stream);
}
else
{
@ -129,17 +138,17 @@ int GetAttributeLocationFromStream(Renderer::Backend::GL::CDevice* device, const
// https://developer.download.nvidia.com/opengl/glsl/glsl_release_notes.pdf
switch (stream)
{
case STREAM_POS: return 0;
case STREAM_NORMAL: return 2;
case STREAM_COLOR: return 3;
case STREAM_UV0: return 8;
case STREAM_UV1: return 9;
case STREAM_UV2: return 10;
case STREAM_UV3: return 11;
case STREAM_UV4: return 12;
case STREAM_UV5: return 13;
case STREAM_UV6: return 14;
case STREAM_UV7: return 15;
case VertexAttributeStream::POSITION: return 0;
case VertexAttributeStream::NORMAL: return 2;
case VertexAttributeStream::COLOR: return 3;
case VertexAttributeStream::UV0: return 8;
case VertexAttributeStream::UV1: return 9;
case VertexAttributeStream::UV2: return 10;
case VertexAttributeStream::UV3: return 11;
case VertexAttributeStream::UV4: return 12;
case VertexAttributeStream::UV5: return 13;
case VertexAttributeStream::UV6: return 14;
case VertexAttributeStream::UV7: return 15;
}
}
@ -269,11 +278,20 @@ public:
void Bind(CShaderProgram* previousShaderProgram) override
{
CShaderProgramARB* previousShaderProgramARB = nullptr;
if (previousShaderProgram)
previousShaderProgram->Unbind();
previousShaderProgramARB = static_cast<CShaderProgramARB*>(previousShaderProgramARB);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_VertexProgram);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_FragmentProgram);
if (previousShaderProgramARB)
previousShaderProgramARB->UnbindClientStates();
if (!previousShaderProgramARB ||
previousShaderProgramARB->m_VertexProgram != m_VertexProgram ||
previousShaderProgramARB->m_FragmentProgram != m_FragmentProgram)
{
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_VertexProgram);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_FragmentProgram);
}
BindClientStates();
}
@ -680,6 +698,8 @@ public:
for (const int index : m_ActiveVertexAttributes)
glEnableVertexAttribArray(index);
}
m_ValidStreams = 0;
}
void Unbind() override
@ -777,52 +797,21 @@ public:
}
}
// Map the various fixed-function Pointer functions onto generic vertex attributes
// (matching the attribute indexes from ShaderManager's ParseAttribSemantics):
void VertexPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer) override
{
const GLint size = GLSizeFromFormat(format);
const GLenum type = GLTypeFromFormat(format);
glVertexAttribPointer(0, size, type, GL_FALSE, stride, pointer);
m_ValidStreams |= STREAM_POS;
}
void NormalPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer) override
{
const GLint size = GLSizeFromFormat(format);
const GLenum type = GLTypeFromFormat(format);
glVertexAttribPointer(m_Device->GetCapabilities().computeShaders ? 1 : 2, size, type, (type == GL_FLOAT ? GL_FALSE : GL_TRUE), stride, pointer);
m_ValidStreams |= STREAM_NORMAL;
}
void ColorPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer) override
{
const GLint size = GLSizeFromFormat(format);
const GLenum type = GLTypeFromFormat(format);
glVertexAttribPointer(m_Device->GetCapabilities().computeShaders ? 2 : 3, size, type, (type == GL_FLOAT ? GL_FALSE : GL_TRUE), stride, pointer);
m_ValidStreams |= STREAM_COLOR;
}
void TexCoordPointer(GLenum texture, const Renderer::Backend::Format format, GLsizei stride, const void* pointer) override
void VertexAttribPointer(
const VertexAttributeStream stream, const Format format,
const uint32_t offset, const uint32_t stride, const void* data) override
{
const int attributeLocation = GetAttributeLocationFromStream(m_Device, stream);
std::vector<int>::const_iterator it =
std::lower_bound(m_ActiveVertexAttributes.begin(), m_ActiveVertexAttributes.end(), attributeLocation);
if (it == m_ActiveVertexAttributes.end() || *it != attributeLocation)
return;
const GLint size = GLSizeFromFormat(format);
const GLenum type = GLTypeFromFormat(format);
const GLboolean normalized = NormalizedFromFormat(format);
glVertexAttribPointer(
(m_Device->GetCapabilities().computeShaders ? 3 : 8) + texture - GL_TEXTURE0, size, type, GL_FALSE, stride, pointer);
m_ValidStreams |= STREAM_UV0 << (texture - GL_TEXTURE0);
}
void VertexAttribPointer(attrib_id_t id, const Renderer::Backend::Format format, GLboolean normalized, GLsizei stride, const void* pointer) override
{
std::map<CStrIntern, int>::iterator it = m_VertexAttribs.find(id);
if (it != m_VertexAttribs.end())
{
const GLint size = GLSizeFromFormat(format);
const GLenum type = GLTypeFromFormat(format);
glVertexAttribPointer(it->second, size, type, normalized, stride, pointer);
m_ValidStreams |= STREAM_UV0 << (it->second - (m_Device->GetCapabilities().computeShaders ? 3 : 8));
}
attributeLocation, size, type, normalized, stride, static_cast<const u8*>(data) + offset);
m_ValidStreams |= GetStreamMask(stream);
}
std::vector<VfsPath> GetFileDependencies() const override
@ -941,29 +930,30 @@ std::unique_ptr<CShaderProgram> CShaderProgram::Create(CDevice* device, const CS
if (attributeName.empty() && isGLSL)
LOGERROR("Empty attribute name in vertex shader description '%s'", vertexFile.string8().c_str());
int stream = 0;
VertexAttributeStream stream =
VertexAttributeStream::UV7;
if (streamName == "pos")
stream = STREAM_POS;
stream = VertexAttributeStream::POSITION;
else if (streamName == "normal")
stream = STREAM_NORMAL;
stream = VertexAttributeStream::NORMAL;
else if (streamName == "color")
stream = STREAM_COLOR;
stream = VertexAttributeStream::COLOR;
else if (streamName == "uv0")
stream = STREAM_UV0;
stream = VertexAttributeStream::UV0;
else if (streamName == "uv1")
stream = STREAM_UV1;
stream = VertexAttributeStream::UV1;
else if (streamName == "uv2")
stream = STREAM_UV2;
stream = VertexAttributeStream::UV2;
else if (streamName == "uv3")
stream = STREAM_UV3;
stream = VertexAttributeStream::UV3;
else if (streamName == "uv4")
stream = STREAM_UV4;
stream = VertexAttributeStream::UV4;
else if (streamName == "uv5")
stream = STREAM_UV5;
stream = VertexAttributeStream::UV5;
else if (streamName == "uv6")
stream = STREAM_UV6;
stream = VertexAttributeStream::UV6;
else if (streamName == "uv7")
stream = STREAM_UV7;
stream = VertexAttributeStream::UV7;
else
LOGERROR("Unknown stream '%s' in vertex shader description '%s'", streamName.c_str(), vertexFile.string8().c_str());
@ -972,7 +962,7 @@ std::unique_ptr<CShaderProgram> CShaderProgram::Create(CDevice* device, const CS
const int attributeLocation = GetAttributeLocationFromStream(device, stream);
vertexAttribs[CStrIntern(attributeName)] = attributeLocation;
}
streamFlags |= stream;
streamFlags |= GetStreamMask(stream);
}
}
}
@ -1061,11 +1051,6 @@ std::unique_ptr<CShaderProgram> CShaderProgram::ConstructGLSL(
device, name, vertexFile, fragmentFile, defines, vertexAttribs, streamflags);
}
int CShaderProgram::GetStreamFlags() const
{
return m_StreamFlags;
}
void CShaderProgram::BindTexture(texture_id_t id, const Renderer::Backend::GL::CTexture* tex)
{
BindTexture(id, tex->GetHandle());
@ -1190,14 +1175,14 @@ void CShaderProgram::VertexPointer(const Renderer::Backend::Format format, GLsiz
ENSURE(2 <= size && size <= 4);
const GLenum type = GLTypeFromFormat(format);
glVertexPointer(size, type, stride, pointer);
m_ValidStreams |= STREAM_POS;
m_ValidStreams |= GetStreamMask(VertexAttributeStream::POSITION);
}
void CShaderProgram::NormalPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer)
{
ENSURE(format == Renderer::Backend::Format::R32G32B32_SFLOAT);
glNormalPointer(GL_FLOAT, stride, pointer);
m_ValidStreams |= STREAM_NORMAL;
m_ValidStreams |= GetStreamMask(VertexAttributeStream::NORMAL);
}
void CShaderProgram::ColorPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer)
@ -1206,7 +1191,7 @@ void CShaderProgram::ColorPointer(const Renderer::Backend::Format format, GLsize
ENSURE(3 <= size && size <= 4);
const GLenum type = GLTypeFromFormat(format);
glColorPointer(size, type, stride, pointer);
m_ValidStreams |= STREAM_COLOR;
m_ValidStreams |= GetStreamMask(VertexAttributeStream::COLOR);
}
void CShaderProgram::TexCoordPointer(GLenum texture, const Renderer::Backend::Format format, GLsizei stride, const void* pointer)
@ -1217,26 +1202,34 @@ void CShaderProgram::TexCoordPointer(GLenum texture, const Renderer::Backend::Fo
const GLenum type = GLTypeFromFormat(format);
glTexCoordPointer(size, type, stride, pointer);
glClientActiveTextureARB(GL_TEXTURE0);
m_ValidStreams |= STREAM_UV0 << (texture - GL_TEXTURE0);
m_ValidStreams |= GetStreamMask(VertexAttributeStream::UV0) << (texture - GL_TEXTURE0);
}
void CShaderProgram::BindClientStates()
{
ENSURE(m_StreamFlags == (m_StreamFlags & (STREAM_POS|STREAM_NORMAL|STREAM_COLOR|STREAM_UV0|STREAM_UV1)));
ENSURE(m_StreamFlags == (m_StreamFlags & (
GetStreamMask(VertexAttributeStream::POSITION) |
GetStreamMask(VertexAttributeStream::NORMAL) |
GetStreamMask(VertexAttributeStream::COLOR) |
GetStreamMask(VertexAttributeStream::UV0) |
GetStreamMask(VertexAttributeStream::UV1))));
// Enable all the desired client states for non-GLSL rendering
if (m_StreamFlags & STREAM_POS) glEnableClientState(GL_VERTEX_ARRAY);
if (m_StreamFlags & STREAM_NORMAL) glEnableClientState(GL_NORMAL_ARRAY);
if (m_StreamFlags & STREAM_COLOR) glEnableClientState(GL_COLOR_ARRAY);
if (m_StreamFlags & GetStreamMask(VertexAttributeStream::POSITION))
glEnableClientState(GL_VERTEX_ARRAY);
if (m_StreamFlags & GetStreamMask(VertexAttributeStream::NORMAL))
glEnableClientState(GL_NORMAL_ARRAY);
if (m_StreamFlags & GetStreamMask(VertexAttributeStream::COLOR))
glEnableClientState(GL_COLOR_ARRAY);
if (m_StreamFlags & STREAM_UV0)
if (m_StreamFlags & GetStreamMask(VertexAttributeStream::UV0))
{
glClientActiveTextureARB(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
if (m_StreamFlags & STREAM_UV1)
if (m_StreamFlags & GetStreamMask(VertexAttributeStream::UV1))
{
glClientActiveTextureARB(GL_TEXTURE1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@ -1251,17 +1244,20 @@ void CShaderProgram::BindClientStates()
void CShaderProgram::UnbindClientStates()
{
if (m_StreamFlags & STREAM_POS) glDisableClientState(GL_VERTEX_ARRAY);
if (m_StreamFlags & STREAM_NORMAL) glDisableClientState(GL_NORMAL_ARRAY);
if (m_StreamFlags & STREAM_COLOR) glDisableClientState(GL_COLOR_ARRAY);
if (m_StreamFlags & GetStreamMask(VertexAttributeStream::POSITION))
glDisableClientState(GL_VERTEX_ARRAY);
if (m_StreamFlags & GetStreamMask(VertexAttributeStream::NORMAL))
glDisableClientState(GL_NORMAL_ARRAY);
if (m_StreamFlags & GetStreamMask(VertexAttributeStream::COLOR))
glDisableClientState(GL_COLOR_ARRAY);
if (m_StreamFlags & STREAM_UV0)
if (m_StreamFlags & GetStreamMask(VertexAttributeStream::UV0))
{
glClientActiveTextureARB(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
if (m_StreamFlags & STREAM_UV1)
if (m_StreamFlags & GetStreamMask(VertexAttributeStream::UV1))
{
glClientActiveTextureARB(GL_TEXTURE1);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
@ -1271,6 +1267,44 @@ void CShaderProgram::UnbindClientStates()
#endif // !CONFIG2_GLES
bool CShaderProgram::IsStreamActive(const VertexAttributeStream stream) const
{
return (m_StreamFlags & GetStreamMask(stream)) != 0;
}
void CShaderProgram::VertexAttribPointer(
const VertexAttributeStream stream, const Format format,
const uint32_t offset, const uint32_t stride, const void* data)
{
switch (stream)
{
case VertexAttributeStream::POSITION:
VertexPointer(format, stride, static_cast<const u8*>(data) + offset);
break;
case VertexAttributeStream::NORMAL:
NormalPointer(format, stride, static_cast<const u8*>(data) + offset);
break;
case VertexAttributeStream::COLOR:
ColorPointer(format, stride, static_cast<const u8*>(data) + offset);
break;
case VertexAttributeStream::UV0: FALLTHROUGH;
case VertexAttributeStream::UV1: FALLTHROUGH;
case VertexAttributeStream::UV2: FALLTHROUGH;
case VertexAttributeStream::UV3: FALLTHROUGH;
case VertexAttributeStream::UV4: FALLTHROUGH;
case VertexAttributeStream::UV5: FALLTHROUGH;
case VertexAttributeStream::UV6: FALLTHROUGH;
case VertexAttributeStream::UV7:
{
const int indexOffset = static_cast<int>(stream) - static_cast<int>(VertexAttributeStream::UV0);
TexCoordPointer(GL_TEXTURE0 + indexOffset, format, stride, static_cast<const u8*>(data) + offset);
break;
}
default:
debug_warn("Unsupported stream");
};
}
void CShaderProgram::AssertPointersBound()
{
ENSURE((m_StreamFlags & ~m_ValidStreams) == 0);

View File

@ -34,22 +34,6 @@ class CVector3D;
class CShaderDefines;
class CStrIntern;
// Vertex data stream flags
enum
{
STREAM_POS = (1 << 0),
STREAM_NORMAL = (1 << 1),
STREAM_COLOR = (1 << 2),
STREAM_UV0 = (1 << 3),
STREAM_UV1 = (1 << 4),
STREAM_UV2 = (1 << 5),
STREAM_UV3 = (1 << 6),
STREAM_UV4 = (1 << 7),
STREAM_UV5 = (1 << 8),
STREAM_UV6 = (1 << 9),
STREAM_UV7 = (1 << 10),
};
namespace Renderer
{
@ -124,12 +108,6 @@ public:
*/
virtual void Unbind() = 0;
/**
* Returns bitset of STREAM_* value, indicating what vertex data streams the
* vertex shader needs (e.g. position, color, UV, ...).
*/
int GetStreamFlags() const;
virtual Binding GetTextureBinding(texture_id_t id) = 0;
@ -165,11 +143,11 @@ public:
// Vertex attribute pointers (equivalent to glVertexPointer etc):
virtual void VertexPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
virtual void NormalPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
virtual void ColorPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
virtual void TexCoordPointer(GLenum texture, const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
virtual void VertexAttribPointer(attrib_id_t id, const Renderer::Backend::Format format, GLboolean normalized, GLsizei stride, const void* pointer);
virtual void VertexAttribPointer(
const VertexAttributeStream stream, const Format format,
const uint32_t offset, const uint32_t stride, const void* data);
bool IsStreamActive(const VertexAttributeStream stream) const;
/**
* Checks that all the required vertex attributes have been set.
@ -201,6 +179,12 @@ protected:
const std::map<CStrIntern, int>& vertexAttribs,
int streamflags);
void VertexPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
void NormalPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
void ColorPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
void TexCoordPointer(GLenum texture, const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
void VertexAttribPointer(attrib_id_t id, const Renderer::Backend::Format format, GLboolean normalized, GLsizei stride, const void* pointer);
virtual void BindTexture(texture_id_t id, GLuint tex) = 0;
virtual void BindTexture(Binding id, GLuint tex) = 0;