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:
parent
ddb8b08508
commit
aba7a170d9
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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++;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -291,8 +291,7 @@ class CProfiler2GPUARB
|
||||
public:
|
||||
};
|
||||
|
||||
CProfiler2GPU::CProfiler2GPU(CProfiler2& profiler) :
|
||||
m_Profiler(profiler)
|
||||
CProfiler2GPU::CProfiler2GPU(CProfiler2& UNUSED(profiler))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,9 @@ public:
|
||||
void RegionLeave(const char* id);
|
||||
|
||||
private:
|
||||
#if !CONFIG2_GLES
|
||||
CProfiler2& m_Profiler;
|
||||
#endif
|
||||
|
||||
std::unique_ptr<CProfiler2GPUARB> m_ProfilerARB;
|
||||
};
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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++;
|
||||
|
@ -167,8 +167,6 @@ void ParticleRenderer::RenderParticles(
|
||||
|
||||
if (lastTech)
|
||||
deviceCommandContext->EndPass();
|
||||
|
||||
CVertexBuffer::Unbind(deviceCommandContext);
|
||||
}
|
||||
|
||||
void ParticleRenderer::RenderBounds(int cullGroup)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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(
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user