18 #include "precompiled.h"
45 #include <boost/weak_ptr.hpp>
55 static bool g_EnableSSE =
false;
72 size_t numVertices = mdef->GetNumVertices();
75 for(
size_t j = 0; j < numVertices; ++j)
78 Normal[j] = vertices[j].
m_Norm;
89 size_t numVertices = mdef->GetNumVertices();
98 if (numVertices && vertices[0].m_Blend.m_Bone[0] == 0xff)
100 LOGERROR(L
"Model %ls is boned with unboned animation", mdef->GetName().string().c_str());
107 CModelDef::SkinPointsAndNormals_SSE(numVertices, Position, Normal, vertices, mdef->GetBlendIndices(), model->
GetAnimatedBoneMatrices());
117 PROFILE(
"software transform" );
121 for (
size_t j=0; j<numVertices; j++)
123 transform.
Transform(vertices[j].m_Coords,Position[j]);
136 PROFILE(
"lighting vertices" );
139 size_t numVertices = mdef->GetNumVertices();
143 for (
size_t j=0; j<numVertices; j++)
146 tempcolor.
X *= shadingColor.
r;
147 tempcolor.
Y *= shadingColor.
g;
148 tempcolor.
Z *= shadingColor.
b;
156 MikkTSpace ms(mdef, newVertices, gpuSkinning);
168 size_t numVertices = mdef->GetNumVertices();
171 for (
size_t j=0; j < numVertices; ++j)
173 UV[j][0] = vertices[j].
m_UVs[UVset * 2];
174 UV[j][1] = 1.0-vertices[j].
m_UVs[UVset * 2 + 1];
187 for (
size_t j = 0; j < mdef->GetNumFaces(); ++j) {
189 Indices[idxidx++]=face.
m_Verts[0];
190 Indices[idxidx++]=face.
m_Verts[1];
191 Indices[idxidx++]=face.
m_Verts[2];
318 : effect(effect), defines(defines) { }
367 g_Renderer.GetViewCamera().m_Orientation.GetInverse(worldToCam);
424 typedef std::vector<CModel*, ArenaProxyAllocator> ModelList_t;
428 MaterialBuckets_t materialBuckets((MaterialBuckets_t::allocator_type(arena)));
440 for (
size_t j = 0; j < condefs.
GetSize(); ++j)
449 float dist = worldToCam.
Transform(modelpos).
Z;
454 if ((dmin < 0 || dist >= dmin) && (dmax < 0 || dist < dmax))
455 condFlags |= (1 << j);
465 MaterialBuckets_t::iterator it = materialBuckets.find(
key);
466 if (it == materialBuckets.end())
468 std::pair<MaterialBuckets_t::iterator, bool> inserted = materialBuckets.insert(
469 std::make_pair(
key, ModelList_t(ModelList_t::allocator_type(arena))));
470 inserted.first->second.reserve(32);
471 inserted.first->second.push_back(model);
475 it->second.push_back(model);
480 std::vector<SMRSortByDistItem, ArenaProxyAllocator> sortByDistItems((ArenaProxyAllocator(arena)));
482 std::vector<CShaderTechniquePtr, ArenaProxyAllocator> sortByDistTechs((ArenaProxyAllocator(arena)));
489 std::vector<SMRTechBucket, ArenaProxyAllocator> techBuckets((ArenaProxyAllocator(arena)));
492 PROFILE3(
"processing material buckets");
493 for (MaterialBuckets_t::iterator it = materialBuckets.begin(); it != materialBuckets.end(); ++it)
501 if (tech->GetSortByDistance())
505 if (sortByDistTechs.empty() || sortByDistTechs.back() != tech)
506 sortByDistTechs.push_back(tech);
507 size_t techIdx = sortByDistTechs.size()-1;
510 for (
size_t i = 0; i < it->second.size(); ++i)
513 itemWithDist.
techIdx = techIdx;
521 sortByDistItems.push_back(itemWithDist);
530 std::sort(it->second.begin(), it->second.end(),
SMRBatchModel());
533 SMRTechBucket techBucket = { tech, &it->second[0], it->second.size() };
534 techBuckets.push_back(techBucket);
549 std::vector<CModel*, ArenaProxyAllocator> sortByDistModels((ArenaProxyAllocator(arena)));
551 if (!sortByDistItems.empty())
559 PROFILE3(
"batching dist-sorted items");
561 sortByDistModels.reserve(sortByDistItems.size());
567 size_t currentTechIdx = sortByDistItems[start].techIdx;
569 for (
size_t end = 0; end < sortByDistItems.size(); ++end)
571 sortByDistModels.push_back(sortByDistItems[end].
model);
573 size_t techIdx = sortByDistItems[end].techIdx;
574 if (techIdx != currentTechIdx)
577 SMRTechBucket techBucket = { sortByDistTechs[currentTechIdx], &sortByDistModels[start], end-start };
578 techBuckets.push_back(techBucket);
580 currentTechIdx = techIdx;
585 SMRTechBucket techBucket = { sortByDistTechs[currentTechIdx], &sortByDistModels[start], sortByDistItems.size()-start };
586 techBuckets.push_back(techBucket);
591 PROFILE3(
"rendering bucketed submissions");
593 size_t idxTechStart = 0;
598 std::vector<CTexture*, ArenaProxyAllocator> currentTexs((ArenaProxyAllocator(arena)));
599 currentTexs.reserve(64);
604 std::vector<CShaderProgram::Binding, ArenaProxyAllocator> texBindings((ArenaProxyAllocator(arena)));
605 texBindings.reserve(64);
606 std::vector<CStrIntern, ArenaProxyAllocator> texBindingNames((ArenaProxyAllocator(arena)));
607 texBindingNames.reserve(64);
609 while (idxTechStart < techBuckets.size())
615 for (idxTechEnd = idxTechStart + 1; idxTechEnd < techBuckets.size(); ++idxTechEnd)
617 if (techBuckets[idxTechEnd].tech != currentTech)
622 for (
int pass = 0; pass < currentTech->GetNumPasses(); ++pass)
624 currentTech->BeginPass(pass);
627 int streamflags = shader->GetStreamFlags();
629 modifier->BeginPass(shader);
638 texBindingNames.clear();
643 for (
size_t idx = idxTechStart; idx < idxTechEnd; ++idx)
645 CModel** models = techBuckets[idx].models;
646 size_t numModels = techBuckets[idx].numModels;
647 for (
size_t i = 0; i < numModels; ++i)
651 if (flags && !(model->
GetFlags() & flags))
655 size_t samplersNum = samplers.size();
659 if (currentTexs.size() != samplersNum)
661 currentTexs.resize(samplersNum, NULL);
663 texBindingNames.resize(samplersNum,
CStrIntern());
667 std::fill(currentTexs.begin(), currentTexs.end(), (
CTexture*)NULL);
668 std::fill(texBindingNames.begin(), texBindingNames.end(),
CStrIntern());
672 for (
size_t s = 0; s < samplersNum; ++s)
679 if (texBindingNames[s] == samp.
Name && bind.
Active())
681 bind = texBindings[s];
685 bind = shader->GetTextureBinding(samp.
Name);
686 texBindings[s] = bind;
687 texBindingNames[s] = samp.
Name;
692 if (bind.
Active() && newTex != currentTexs[s])
694 shader->BindTexture(bind, samp.
Sampler->GetHandle());
695 currentTexs[s] = newTex;
701 if (newModeldef != currentModeldef)
703 currentModeldef = newModeldef;
704 m->
vertexRenderer->PrepareModelDef(shader, streamflags, *currentModeldef);
709 if (newStaticUniforms != currentStaticUniforms)
711 currentStaticUniforms = newStaticUniforms;
717 for (
size_t q = 0; q < renderQueries.
GetSize(); q++)
725 double time =
g_Renderer.GetTimeManager().GetGlobalTime();
726 shader->Uniform(binding, time, 0,0,0);
734 int curTex = (int)(time*60/period) % 60;
737 shader->BindTexture(str_waterTex, WaterMgr->
m_NormalMap[curTex]);
739 shader->BindTexture(str_waterTex,
g_Renderer.GetTextureManager().GetErrorTexture());
743 shader->BindTexture(str_skyCube,
g_Renderer.GetSkyManager()->GetSkyCube());
747 modifier->PrepareModel(shader, model);
758 currentTech->EndPass(pass);
761 idxTechStart = idxTechEnd;
772 if (flags && !(model->
GetFlags() & flags))
virtual ~ShaderModelRenderer()
const CShaderRenderQueries & GetRenderQueries() const
virtual void EndFrame()
EndFrame: Remove all models from the list of submitted models.
static void BuildUV(const CModelDefPtr &mdef, const VertexArrayIterator< float[2]> &UV, int UVset)
BuildUV: Copy UV coordinates into the given vertex array.
const CMatrix3D & GetInvTransform() const
bool operator()(const SMRSortByDistItem &a, const SMRSortByDistItem &b)
ShaderModelRendererInternals * m
static void CopyPositionAndNormals(const CModelDefPtr &mdef, const VertexArrayIterator< CVector3D > &Position, const VertexArrayIterator< CVector3D > &Normal)
CopyPositionAndNormals: Copy unanimated object-space vertices and normals into the given vertex array...
size_t operator()(const SMRMaterialBucketKey &key) const
Internal data of the ShaderModelRenderer.
shared_ptr< RenderModifier > RenderModifierPtr
virtual void Render(const RenderModifierPtr &modifier, const CShaderDefines &context, int flags)
Render: Render submitted models, using the given RenderModifier to setup the fragment stage...
CVector3D Transform(const CVector3D &vector) const
CTexturePtr m_NormalMap[60]
shared_ptr< CShaderTechnique > CShaderTechniquePtr
Implementation of ModelRenderer that loads the appropriate shaders for rendering each model...
bool operator==(const SMRMaterialBucketKey &b) const
virtual void PrepareModels()
PrepareModels: Calculate renderer data for all previously submitted models.
static void BuildColor4ub(CModel *model, const VertexArrayIterator< CVector3D > &Normal, const VertexArrayIterator< SColor4ub > &Color)
BuildColor4ub: Build lighting colors for the given model, based on previously calculated world space ...
Uniform values that need to be evaluated in the renderer.
const CTexturePtr & GetDiffuseTexture() const
RenderQuery GetItem(size_t i) const
std::vector< float > m_CondArgs
RGBColor EvaluateUnitScaled(const CVector3D &normal) const
Calculate brightness of a point of a unit with the given normal vector, for rendering with CPU lighti...
const CMatrix3D * GetAnimatedBoneMatrices()
u32 GetHash() const
Returns cached FNV1-A hash of the string.
virtual bool Filter(CModel *model)=0
static void SkinPointsAndNormals(size_t numVertices, const VertexArrayIterator< CVector3D > &Position, const VertexArrayIterator< CVector3D > &Normal, const SModelVertex *vertices, const size_t *blendIndices, const CMatrix3D newPoseMatrices[])
Transform vertices' positions and normals.
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
static void Init()
Initialise global settings.
CRenderData * GetRenderData()
Return object renderdata - can be null if renderer hasn't yet created the renderdata.
friend struct ShaderModelRendererInternals
bool IsSkinned()
Return whether this is a skinned/skeletal model.
static void BuildPositionAndNormals(CModel *model, const VertexArrayIterator< CVector3D > &Position, const VertexArrayIterator< CVector3D > &Normal)
BuildPositionAndNormals: Build animated vertices and normals, transformed into world space...
SMRMaterialBucketKey & operator=(const SMRMaterialBucketKey &)
shared_ptr< ModelVertexRenderer > ModelVertexRendererPtr
SColor4ub(* ConvertRGBColorTo4ub)(const RGBColor &src)
void SetRenderData(CRenderData *renderdata)
static void BuildIndices(const CModelDefPtr &mdef, const VertexArrayIterator< u16 > &Indices)
BuildIndices: Create the indices array for the given CModelDef.
Represents a texture object.
void SetDirty(u32 dirtyflags)
void RotateTransposed(const CVector3D &vector, CVector3D &result) const
virtual void Submit(CModel *model)
Submit: Submit a model for rendering this frame.
ShaderModelRenderer * m_Renderer
Back-link to "our" renderer.
SMRMaterialBucketKey(CStrIntern effect, const CShaderDefines &defines)
size_t GetHash() const
Return a hash of the current mapping.
Represents a mapping of name strings to value strings, for use with #if and #ifdef and similar condit...
fully STL-compatible allocator that simply draws upon another Allocator.
static void GenTangents(const CModelDefPtr &mdef, std::vector< float > &newVertices, bool gpuSkinning)
GenTangents: Generate tangents for the given CModelDef.
bool WillRenderFancyWater()
Returns true if fancy water shaders will be used (i.e.
const SamplersVector & GetSamplers() const
const CondDefine & GetItem(size_t i) const
Represents a uniform attribute or texture binding.
Class CModelRData: Render data that is maintained per CModel.
const CShaderUniforms & GetStaticUniforms() const
bool operator()(const SMRTechBucket &a, const SMRTechBucket &b)
std::vector< TextureSampler > SamplersVector
bool operator()(CModel *a, CModel *b)
allocator design parameters:
const CMatrix3D & GetTransform() const
const void * GetKey() const
GetKey: Retrieve the key that can be used to identify the ModelRenderer that created this data...
const CShaderDefines & GetShaderDefines(uint32_t conditionFlags) const
virtual CColor GetShadingColor() const
const CModelDefPtr & GetModelDef()
ShaderModelRendererInternals(ShaderModelRenderer *r)
ModelVertexRendererPtr vertexRenderer
ModelVertexRenderer used for vertex transformations.
const CShaderConditionalDefines & GetConditionalDefines() const
CMaterial & GetMaterial()
CVector3D GetTranslation() const
Class CLightEnv: description of a lighting environment - contains all the necessary parameters for re...
CStrIntern GetShaderEffect() const
virtual void Filter(CModelFilter &filter, int passed, int flags)
Filter: Filter submitted models, setting the passed flags on any models that pass the filter...
shared_ptr< CShaderProgram > CShaderProgramPtr
std::vector< CModel * > submissions
List of submitted models for rendering in this frame.
bool Active()
Returns whether this uniform attribute is active in the shader.
ShaderModelRenderer(ModelVertexRendererPtr vertexrender)
std::pair< int, CStrIntern > RenderQuery
boost::shared_ptr< CModelDef > CModelDefPtr
Class WaterManager: Maintain water settings and textures.
std::vector< float > m_UVs