0ad/source/renderer/ModelDefRData.cpp
prefect 6fc1f45fa6 Stab at fixing the VertexArray compile error on VC++.
Added float-to-byte color conversion, including an SSE assembler
version.
Model renderer: Push UV coordinates into a shared vertex array and use
bytes instead of floats for the color array, thereby, significantly
reducing
the total size of vertex arrays.

This was SVN commit r2827.
2005-10-03 03:41:42 +00:00

125 lines
2.7 KiB
C++

#include "precompiled.h"
#include "ogl.h"
#include "Vector3D.h"
#include "Vector4D.h"
#include "ps/CLogger.h"
#include "graphics/Color.h"
#include "graphics/Model.h"
#include "renderer/ModelRData.h"
#include "renderer/ModelDefRData.h"
#include "renderer/Renderer.h"
#define LOG_CATEGORY "graphics"
// Shared list of all submitted models this frame, sorted by CModelDef
CModelDefRData* CModelDefRData::m_Submissions = 0;
CModelDefRData::CModelDefRData(CModelDef* mdef)
: m_ModelDef(mdef), m_Array(false)
{
m_SubmissionNext = 0;
m_SubmissionSlots = 0;
Build();
}
CModelDefRData::~CModelDefRData()
{
}
// Create and upload shared vertex arrays
void CModelDefRData::Build()
{
size_t numVertices = m_ModelDef->GetNumVertices();
m_UV.type = GL_FLOAT;
m_UV.elems = 2;
m_Array.AddAttribute(&m_UV);
m_Array.SetNumVertices(numVertices);
m_Array.Layout();
SModelVertex* vertices = m_ModelDef->GetVertices();
VertexArrayIterator<float[2]> UVit = m_UV.GetIterator<float[2]>();
for (uint j=0; j < numVertices; ++j, ++UVit) {
(*UVit)[0] = vertices[j].m_U;
(*UVit)[1] = 1.0-vertices[j].m_V;
}
m_Array.Upload();
m_Array.FreeBackingStore();
}
// Setup shared vertex arrays as needed.
void CModelDefRData::PrepareStream(uint streamflags)
{
if (!(streamflags & STREAM_UV0))
return;
u8* base = m_Array.Bind();
size_t stride = m_Array.GetStride();
glTexCoordPointer(2, GL_FLOAT, stride, base + m_UV.offset);
}
// Submit one model.
// Models are sorted into a hash-table to avoid ping-ponging between
// different render states later on.
void CModelDefRData::Submit(CModelRData* data)
{
debug_assert(data->GetModel()->GetModelDef()->GetRenderData() == this);
if (!m_SubmissionSlots)
{
m_SubmissionNext = m_Submissions;
m_Submissions = this;
}
Handle htex = data->GetModel()->GetTexture()->GetHandle();
uint idx;
for(idx = 0; idx < m_SubmissionSlots; ++idx)
{
CModelRData* in = m_SubmissionModels[idx];
if (in->GetModel()->GetTexture()->GetHandle() == htex)
break;
}
if (idx >= m_SubmissionSlots)
{
++m_SubmissionSlots;
if (m_SubmissionSlots > m_SubmissionModels.size())
{
m_SubmissionModels.push_back(0);
debug_assert(m_SubmissionModels.size() == m_SubmissionSlots);
}
m_SubmissionModels[idx] = 0;
}
data->m_SubmissionNext = m_SubmissionModels[idx];
m_SubmissionModels[idx] = data;
}
// Clear all submissions for this CModelDef
// Do not shrink the submissions array immediately to avoid unnecessary
// allocate/free roundtrips through memory management.
void CModelDefRData::ClearSubmissions()
{
static uint mostslots = 1;
if (m_SubmissionSlots > mostslots)
{
mostslots = m_SubmissionSlots;
debug_printf("CModelDefRData: SubmissionSlots maximum: %u\n", mostslots);
}
m_SubmissionSlots = 0;
}