Index: ps/trunk/source/renderer/HWLightingModelRenderer.cpp
===================================================================
--- ps/trunk/source/renderer/HWLightingModelRenderer.cpp (revision 24598)
+++ ps/trunk/source/renderer/HWLightingModelRenderer.cpp (revision 24599)
@@ -1,314 +1,244 @@
-/* Copyright (C) 2020 Wildfire Games.
+/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
#include "precompiled.h"
#include "lib/bits.h"
#include "lib/ogl.h"
#include "lib/sysdep/rtl.h"
#include "maths/Vector3D.h"
#include "graphics/Color.h"
#include "graphics/LightEnv.h"
#include "graphics/Model.h"
#include "graphics/ModelDef.h"
#include "graphics/ShaderProgram.h"
#include "renderer/HWLightingModelRenderer.h"
#include "renderer/Renderer.h"
#include "renderer/RenderModifiers.h"
#include "renderer/VertexArray.h"
struct ShaderModelDef : public CModelDefRPrivate
{
/// Indices are the same for all models, so share them
VertexIndexArray m_IndexArray;
/// Static per-CModelDef vertex array
VertexArray m_Array;
/// The number of UVs is determined by the model
std::vector m_UVs;
ShaderModelDef(const CModelDefPtr& mdef);
};
ShaderModelDef::ShaderModelDef(const CModelDefPtr& mdef)
: m_IndexArray(GL_STATIC_DRAW), m_Array(GL_STATIC_DRAW)
{
size_t numVertices = mdef->GetNumVertices();
m_UVs.resize(mdef->GetNumUVsPerVertex());
for (size_t i = 0; i < mdef->GetNumUVsPerVertex(); ++i)
{
m_UVs[i].type = GL_FLOAT;
m_UVs[i].elems = 2;
m_Array.AddAttribute(&m_UVs[i]);
}
m_Array.SetNumVertices(numVertices);
m_Array.Layout();
for (size_t i = 0; i < mdef->GetNumUVsPerVertex(); ++i)
{
VertexArrayIterator UVit = m_UVs[i].GetIterator();
ModelRenderer::BuildUV(mdef, UVit, i);
}
m_Array.Upload();
m_Array.FreeBackingStore();
m_IndexArray.SetNumVertices(mdef->GetNumFaces()*3);
m_IndexArray.Layout();
ModelRenderer::BuildIndices(mdef, m_IndexArray.GetIterator());
m_IndexArray.Upload();
m_IndexArray.FreeBackingStore();
}
struct ShaderModel : public CModelRData
{
/// Dynamic per-CModel vertex array
VertexArray m_Array;
/// Position and normals/lighting are recalculated on CPU every frame
VertexArray::Attribute m_Position;
- VertexArray::Attribute m_Normal; // valid iff cpuLighting == false
- VertexArray::Attribute m_Color; // valid iff cpuLighting == true
+ VertexArray::Attribute m_Normal;
ShaderModel(const void* key) : CModelRData(key), m_Array(GL_DYNAMIC_DRAW) { }
};
struct ShaderModelVertexRenderer::ShaderModelRendererInternals
{
- bool cpuLighting;
-
- /**
- * Scratch space for normal vector calculation.
- * Only used if cpuLighting == true.
- * Space is reserved so we don't have to do frequent reallocations.
- * Allocated with rtl_AllocateAligned(normalsNumVertices*16, 16) for SSE writes.
- */
- char* normals;
- size_t normalsNumVertices;
-
/// Previously prepared modeldef
ShaderModelDef* shadermodeldef;
};
// Construction and Destruction
-ShaderModelVertexRenderer::ShaderModelVertexRenderer(bool cpuLighting)
+ShaderModelVertexRenderer::ShaderModelVertexRenderer()
{
m = new ShaderModelRendererInternals;
- m->cpuLighting = cpuLighting;
- m->normals = NULL;
- m->normalsNumVertices = 0;
- m->shadermodeldef = NULL;
+ m->shadermodeldef = nullptr;
}
ShaderModelVertexRenderer::~ShaderModelVertexRenderer()
{
- rtl_FreeAligned(m->normals);
-
delete m;
}
// Build model data (and modeldef data if necessary)
CModelRData* ShaderModelVertexRenderer::CreateModelData(const void* key, CModel* model)
{
CModelDefPtr mdef = model->GetModelDef();
ShaderModelDef* shadermodeldef = (ShaderModelDef*)mdef->GetRenderData(m);
if (!shadermodeldef)
{
shadermodeldef = new ShaderModelDef(mdef);
mdef->SetRenderData(m, shadermodeldef);
}
// Build the per-model data
ShaderModel* shadermodel = new ShaderModel(key);
- if (m->cpuLighting)
- {
- // Positions must be 16-byte aligned for SSE writes.
- // We can pack the color after the position; it will be corrupted by
- // BuildPositionAndNormals, but that's okay since we'll recompute the
- // colors afterwards.
-
- shadermodel->m_Color.type = GL_UNSIGNED_BYTE;
- shadermodel->m_Color.elems = 4;
- shadermodel->m_Array.AddAttribute(&shadermodel->m_Color);
-
- shadermodel->m_Position.type = GL_FLOAT;
- shadermodel->m_Position.elems = 3;
- shadermodel->m_Array.AddAttribute(&shadermodel->m_Position);
- }
- else
- {
- // Positions and normals must be 16-byte aligned for SSE writes.
+ // Positions and normals must be 16-byte aligned for SSE writes.
- shadermodel->m_Position.type = GL_FLOAT;
- shadermodel->m_Position.elems = 4;
- shadermodel->m_Array.AddAttribute(&shadermodel->m_Position);
-
- shadermodel->m_Normal.type = GL_FLOAT;
- shadermodel->m_Normal.elems = 4;
- shadermodel->m_Array.AddAttribute(&shadermodel->m_Normal);
- }
+ shadermodel->m_Position.type = GL_FLOAT;
+ shadermodel->m_Position.elems = 4;
+ shadermodel->m_Array.AddAttribute(&shadermodel->m_Position);
+
+ shadermodel->m_Normal.type = GL_FLOAT;
+ shadermodel->m_Normal.elems = 4;
+ shadermodel->m_Array.AddAttribute(&shadermodel->m_Normal);
shadermodel->m_Array.SetNumVertices(mdef->GetNumVertices());
shadermodel->m_Array.Layout();
// Verify alignment
ENSURE(shadermodel->m_Position.offset % 16 == 0);
- if (!m->cpuLighting)
- ENSURE(shadermodel->m_Normal.offset % 16 == 0);
+ ENSURE(shadermodel->m_Normal.offset % 16 == 0);
ENSURE(shadermodel->m_Array.GetStride() % 16 == 0);
return shadermodel;
}
// Fill in and upload dynamic vertex array
void ShaderModelVertexRenderer::UpdateModelData(CModel* model, CModelRData* data, int updateflags)
{
ShaderModel* shadermodel = static_cast(data);
- if (!m->cpuLighting && (updateflags & RENDERDATA_UPDATE_VERTICES))
+ if (updateflags & RENDERDATA_UPDATE_VERTICES)
{
// build vertices
VertexArrayIterator Position = shadermodel->m_Position.GetIterator();
VertexArrayIterator Normal = shadermodel->m_Normal.GetIterator();
ModelRenderer::BuildPositionAndNormals(model, Position, Normal);
// upload everything to vertex buffer
shadermodel->m_Array.Upload();
}
- if (m->cpuLighting && (updateflags & (RENDERDATA_UPDATE_VERTICES|RENDERDATA_UPDATE_COLOR)))
- {
- CModelDefPtr mdef = model->GetModelDef();
- size_t numVertices = mdef->GetNumVertices();
-
- // allocate working space for computing normals
- if (numVertices > m->normalsNumVertices)
- {
- rtl_FreeAligned(m->normals);
-
- size_t newSize = round_up_to_pow2(numVertices);
- m->normals = (char*)rtl_AllocateAligned(newSize*16, 16);
- m->normalsNumVertices = newSize;
- }
-
- VertexArrayIterator Position = shadermodel->m_Position.GetIterator();
- VertexArrayIterator Normal = VertexArrayIterator(m->normals, 16);
-
- ModelRenderer::BuildPositionAndNormals(model, Position, Normal);
-
- VertexArrayIterator Color = shadermodel->m_Color.GetIterator();
-
- ModelRenderer::BuildColor4ub(model, Normal, Color);
-
- // upload everything to vertex buffer
- shadermodel->m_Array.Upload();
- }
-
shadermodel->m_Array.PrepareForRendering();
}
// Setup one rendering pass
void ShaderModelVertexRenderer::BeginPass(int streamflags)
{
- if (m->cpuLighting)
- ENSURE(streamflags == (streamflags & (STREAM_POS | STREAM_UV0 | STREAM_UV1 | STREAM_COLOR)));
- else
- ENSURE(streamflags == (streamflags & (STREAM_POS | STREAM_UV0 | STREAM_UV1 | STREAM_NORMAL)));
+ ENSURE(streamflags == (streamflags & (STREAM_POS | STREAM_UV0 | STREAM_UV1 | STREAM_NORMAL)));
}
// Cleanup one rendering pass
void ShaderModelVertexRenderer::EndPass(int UNUSED(streamflags))
{
CVertexBuffer::Unbind();
}
// Prepare UV coordinates for this modeldef
void ShaderModelVertexRenderer::PrepareModelDef(const CShaderProgramPtr& shader, int streamflags, const CModelDef& def)
{
m->shadermodeldef = (ShaderModelDef*)def.GetRenderData(m);
ENSURE(m->shadermodeldef);
u8* base = m->shadermodeldef->m_Array.Bind();
GLsizei stride = (GLsizei)m->shadermodeldef->m_Array.GetStride();
if (streamflags & STREAM_UV0)
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, stride, base + m->shadermodeldef->m_UVs[0].offset);
if ((streamflags & STREAM_UV1) && def.GetNumUVsPerVertex() >= 2)
shader->TexCoordPointer(GL_TEXTURE1, 2, GL_FLOAT, stride, base + m->shadermodeldef->m_UVs[1].offset);
}
// Render one model
void ShaderModelVertexRenderer::RenderModel(const CShaderProgramPtr& shader, int streamflags, CModel* model, CModelRData* data)
{
const CModelDefPtr& mdldef = model->GetModelDef();
ShaderModel* shadermodel = static_cast(data);
u8* base = shadermodel->m_Array.Bind();
GLsizei stride = (GLsizei)shadermodel->m_Array.GetStride();
u8* indexBase = m->shadermodeldef->m_IndexArray.Bind();
if (streamflags & STREAM_POS)
shader->VertexPointer(3, GL_FLOAT, stride, base + shadermodel->m_Position.offset);
if (streamflags & STREAM_NORMAL)
shader->NormalPointer(GL_FLOAT, stride, base + shadermodel->m_Normal.offset);
- if (streamflags & STREAM_COLOR)
- shader->ColorPointer(3, GL_UNSIGNED_BYTE, stride, base + shadermodel->m_Color.offset);
-
shader->AssertPointersBound();
// render the lot
size_t numFaces = mdldef->GetNumFaces();
if (!g_Renderer.m_SkipSubmit)
{
// Draw with DrawRangeElements where available, since it might be more efficient
#if CONFIG2_GLES
glDrawElements(GL_TRIANGLES, (GLsizei)numFaces*3, GL_UNSIGNED_SHORT, indexBase);
#else
pglDrawRangeElementsEXT(GL_TRIANGLES, 0, (GLuint)mdldef->GetNumVertices()-1,
(GLsizei)numFaces*3, GL_UNSIGNED_SHORT, indexBase);
#endif
}
// bump stats
g_Renderer.m_Stats.m_DrawCalls++;
g_Renderer.m_Stats.m_ModelTris += numFaces;
}
Index: ps/trunk/source/renderer/HWLightingModelRenderer.h
===================================================================
--- ps/trunk/source/renderer/HWLightingModelRenderer.h (revision 24598)
+++ ps/trunk/source/renderer/HWLightingModelRenderer.h (revision 24599)
@@ -1,54 +1,54 @@
-/* Copyright (C) 2020 Wildfire Games.
+/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
/*
* ModelVertexRenderer that transforms models on the CPU but performs
* lighting in a vertex shader.
*/
#ifndef INCLUDED_HWLIGHTINGMODELRENDERER
#define INCLUDED_HWLIGHTINGMODELRENDERER
#include "renderer/ModelVertexRenderer.h"
/**
* Render animated models using a ShaderRenderModifier.
* This computes and binds per-vertex data; the modifier is responsible
* for setting any shader uniforms etc.
*/
class ShaderModelVertexRenderer : public ModelVertexRenderer
{
public:
- ShaderModelVertexRenderer(bool cpuLighting);
+ ShaderModelVertexRenderer();
~ShaderModelVertexRenderer();
// Implementations
CModelRData* CreateModelData(const void* key, CModel* model);
void UpdateModelData(CModel* model, CModelRData* data, int updateflags);
void BeginPass(int streamflags);
void EndPass(int streamflags);
void PrepareModelDef(const CShaderProgramPtr& shader, int streamflags, const CModelDef& def);
void RenderModel(const CShaderProgramPtr& shader, int streamflags, CModel* model, CModelRData* data);
protected:
struct ShaderModelRendererInternals;
ShaderModelRendererInternals* m;
};
#endif // INCLUDED_HWLIGHTINGMODELRENDERER
Index: ps/trunk/source/renderer/Renderer.cpp
===================================================================
--- ps/trunk/source/renderer/Renderer.cpp (revision 24598)
+++ ps/trunk/source/renderer/Renderer.cpp (revision 24599)
@@ -1,1965 +1,1965 @@
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
/*
* higher level interface on top of OpenGL to render basic objects:
* terrain, models, sprites, particles etc.
*/
#include "precompiled.h"
#include