Model rendering to mesh builder
This commit is contained in:
parent
f2d86d0073
commit
cfe282f4bd
4 changed files with 192 additions and 2 deletions
|
|
@ -71,7 +71,7 @@ enum ModelRendererType
|
|||
{
|
||||
GLModelRendererType,
|
||||
SWModelRendererType,
|
||||
PolyModelRendererType,
|
||||
MeshBuilderRendererType,
|
||||
NumModelRendererTypes
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ void MeshBuilder::Apply()
|
|||
{
|
||||
MeshApplyState state;
|
||||
|
||||
state.vertexBuffer = static_cast<MeshBuilderBuffer<FModelVertex>*>(mVertexBuffer);
|
||||
state.indexBuffer = static_cast<MeshBuilderBuffer<unsigned int>*>(mIndexBuffer);
|
||||
state.applyData.RenderStyle = mRenderStyle;
|
||||
state.applyData.SpecialEffect = mSpecialEffect;
|
||||
state.applyData.TextureEnabled = mTextureEnabled;
|
||||
|
|
@ -81,3 +83,78 @@ std::pair<FFlatVertex*, unsigned int> MeshBuilder::AllocVertices(unsigned int co
|
|||
unsigned int offset = mVertices.Reserve(count);
|
||||
return { &mVertices[offset], offset };
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MeshBuilderModelRender::MeshBuilderModelRender(MeshBuilder& renderstate) : renderstate(renderstate)
|
||||
{
|
||||
}
|
||||
|
||||
void MeshBuilderModelRender::BeginDrawModel(FRenderStyle style, int smf_flags, const VSMatrix& objectToWorldMatrix, bool mirrored)
|
||||
{
|
||||
renderstate.EnableTexture(true);
|
||||
|
||||
VSMatrix normalModelMatrix;
|
||||
normalModelMatrix.computeNormalMatrix(objectToWorldMatrix);
|
||||
renderstate.SetModelMatrix(objectToWorldMatrix, normalModelMatrix);
|
||||
}
|
||||
|
||||
void MeshBuilderModelRender::EndDrawModel(FRenderStyle style, int smf_flags)
|
||||
{
|
||||
renderstate.SetBoneIndexBase(-1);
|
||||
renderstate.SetModelMatrix(VSMatrix::identity(), VSMatrix::identity());
|
||||
}
|
||||
|
||||
IModelVertexBuffer* MeshBuilderModelRender::CreateVertexBuffer(bool needindex, bool singleframe)
|
||||
{
|
||||
return new MeshBuilderModelVertexBuffer();
|
||||
}
|
||||
|
||||
VSMatrix MeshBuilderModelRender::GetViewToWorldMatrix()
|
||||
{
|
||||
return VSMatrix::identity();
|
||||
}
|
||||
|
||||
void MeshBuilderModelRender::BeginDrawHUDModel(FRenderStyle style, const VSMatrix& objectToWorldMatrix, bool mirrored, int smf_flags)
|
||||
{
|
||||
}
|
||||
|
||||
void MeshBuilderModelRender::EndDrawHUDModel(FRenderStyle style, int smf_flags)
|
||||
{
|
||||
}
|
||||
|
||||
void MeshBuilderModelRender::SetInterpolation(double interpolation)
|
||||
{
|
||||
renderstate.SetInterpolationFactor((double)interpolation);
|
||||
}
|
||||
|
||||
void MeshBuilderModelRender::SetMaterial(FGameTexture* skin, bool clampNoFilter, FTranslationID translation, void* act_v)
|
||||
{
|
||||
renderstate.SetMaterial(skin, UF_Skin, 0, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1, nullptr);
|
||||
}
|
||||
|
||||
void MeshBuilderModelRender::DrawArrays(int start, int count)
|
||||
{
|
||||
renderstate.Draw(DT_Triangles, start, count);
|
||||
}
|
||||
|
||||
void MeshBuilderModelRender::DrawElements(int numIndices, size_t offset)
|
||||
{
|
||||
renderstate.DrawIndexed(DT_Triangles, int(offset / sizeof(unsigned int)), numIndices);
|
||||
}
|
||||
|
||||
void MeshBuilderModelRender::SetupFrame(FModel* model, unsigned int frame1, unsigned int frame2, unsigned int size, int boneStartIndex)
|
||||
{
|
||||
auto mdbuff = static_cast<MeshBuilderModelVertexBuffer*>(model->GetVertexBuffer(GetType()));
|
||||
renderstate.SetBoneIndexBase(boneStartIndex);
|
||||
if (mdbuff)
|
||||
{
|
||||
renderstate.SetVertexBuffer(&mdbuff->vbuf, frame1, frame2);
|
||||
renderstate.SetIndexBuffer(&mdbuff->ibuf);
|
||||
}
|
||||
}
|
||||
|
||||
int MeshBuilderModelRender::UploadBones(const TArray<VSMatrix>& bones)
|
||||
{
|
||||
return renderstate.UploadBones(bones);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,38 @@
|
|||
#include "hw_renderstate.h"
|
||||
#include "hw_material.h"
|
||||
#include "flatvertices.h"
|
||||
#include "modelrenderer.h"
|
||||
#include "buffers.h"
|
||||
#include <map>
|
||||
|
||||
class Mesh;
|
||||
|
||||
template<typename T>
|
||||
class MeshBuilderBuffer : public IBuffer
|
||||
{
|
||||
public:
|
||||
TArray<T> Data;
|
||||
|
||||
void SetData(size_t size, const void* data, BufferUsageType type) override
|
||||
{
|
||||
Data.resize(size);
|
||||
memcpy(Data.data(), data, size);
|
||||
}
|
||||
|
||||
void SetSubData(size_t offset, size_t size, const void* data) override
|
||||
{
|
||||
memcpy(reinterpret_cast<uint8_t*>(Data.data()) + offset, data, size);
|
||||
}
|
||||
|
||||
void* Lock(unsigned int size) override
|
||||
{
|
||||
Data.Resize(size);
|
||||
return Data.data();
|
||||
}
|
||||
|
||||
void Unlock() override {}
|
||||
};
|
||||
|
||||
struct MeshApplyData
|
||||
{
|
||||
FRenderStyle RenderStyle;
|
||||
|
|
@ -28,6 +56,8 @@ public:
|
|||
SurfaceUniforms surfaceUniforms;
|
||||
FMaterialState material;
|
||||
VSMatrix textureMatrix;
|
||||
MeshBuilderBuffer<FModelVertex>* vertexBuffer = nullptr;
|
||||
MeshBuilderBuffer<unsigned int>* indexBuffer = nullptr;
|
||||
|
||||
bool operator<(const MeshApplyState& other) const
|
||||
{
|
||||
|
|
@ -40,6 +70,11 @@ public:
|
|||
if (material.mOverrideShader != other.material.mOverrideShader)
|
||||
return material.mOverrideShader < other.material.mOverrideShader;
|
||||
|
||||
if (vertexBuffer != other.vertexBuffer)
|
||||
return vertexBuffer < other.vertexBuffer;
|
||||
if (indexBuffer != other.indexBuffer)
|
||||
return indexBuffer < other.indexBuffer;
|
||||
|
||||
int result = memcmp(&applyData, &other.applyData, sizeof(MeshApplyData));
|
||||
if (result != 0)
|
||||
return result < 0;
|
||||
|
|
@ -122,3 +157,56 @@ private:
|
|||
VSMatrix mTextureMatrix = VSMatrix::identity();
|
||||
DrawLists* mDrawLists = nullptr;
|
||||
};
|
||||
|
||||
class MeshBuilderModelVertexBuffer : public IModelVertexBuffer
|
||||
{
|
||||
public:
|
||||
FModelVertex* LockVertexBuffer(unsigned int size) override
|
||||
{
|
||||
return static_cast<FModelVertex*>(vbuf.Lock(size));
|
||||
}
|
||||
|
||||
void UnlockVertexBuffer() override
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int* LockIndexBuffer(unsigned int size) override
|
||||
{
|
||||
return static_cast<unsigned int*>(ibuf.Lock(size));
|
||||
}
|
||||
|
||||
void UnlockIndexBuffer() override
|
||||
{
|
||||
}
|
||||
|
||||
MeshBuilderBuffer<FModelVertex> vbuf;
|
||||
MeshBuilderBuffer<unsigned int> ibuf;
|
||||
};
|
||||
|
||||
class MeshBuilderModelRender : public FModelRenderer
|
||||
{
|
||||
public:
|
||||
MeshBuilderModelRender(MeshBuilder& renderstate);
|
||||
|
||||
ModelRendererType GetType() const override { return ModelRendererType::MeshBuilderRendererType; }
|
||||
|
||||
void BeginDrawModel(FRenderStyle style, int smf_flags, const VSMatrix& objectToWorldMatrix, bool mirrored) override;
|
||||
void EndDrawModel(FRenderStyle style, int smf_flags) override;
|
||||
|
||||
IModelVertexBuffer* CreateVertexBuffer(bool needindex, bool singleframe) override;
|
||||
|
||||
VSMatrix GetViewToWorldMatrix() override;
|
||||
|
||||
void BeginDrawHUDModel(FRenderStyle style, const VSMatrix& objectToWorldMatrix, bool mirrored, int smf_flags) override;
|
||||
void EndDrawHUDModel(FRenderStyle style, int smf_flags) override;
|
||||
|
||||
void SetInterpolation(double interpolation) override;
|
||||
void SetMaterial(FGameTexture* skin, bool clampNoFilter, FTranslationID translation, void* act) override;
|
||||
void DrawArrays(int start, int count) override;
|
||||
void DrawElements(int numIndices, size_t offset) override;
|
||||
void SetupFrame(FModel* model, unsigned int frame1, unsigned int frame2, unsigned int size, int boneStartIndex) override;
|
||||
int UploadBones(const TArray<VSMatrix>& bones) override;
|
||||
|
||||
private:
|
||||
MeshBuilder& renderstate;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "texturemanager.h"
|
||||
#include "playsim/p_lnspec.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "models.h"
|
||||
#include "a_dynlight.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "hw_vertexbuilder.h"
|
||||
|
|
@ -277,6 +277,31 @@ DoomLevelMesh::DoomLevelMesh(FLevelLocals& doomMap)
|
|||
tile.NeedsInitialBake = true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Collect all the models we want to bake into the level mesh
|
||||
auto it = doomMap.GetThinkerIterator<AActor>();
|
||||
AActor* thing;
|
||||
while ((thing = it.Next()) != nullptr)
|
||||
{
|
||||
bool isPicnumOverride = thing->picnum.isValid();
|
||||
int spritenum = thing->sprite;
|
||||
FSpriteModelFrame* modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing, spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
|
||||
if (modelframe && modelframe->modelIDs.size() != 0)
|
||||
{
|
||||
DVector3 thingpos = thing->Pos();
|
||||
double x = thingpos.X + thing->WorldOffset.X;
|
||||
double z = thingpos.Z + thing->WorldOffset.Z;
|
||||
double y = thingpos.Y + thing->WorldOffset.Y;
|
||||
|
||||
MeshBuilder builder;
|
||||
MeshBuilderModelRender renderer(builder);
|
||||
RenderModel(&renderer, x, y, z, modelframe, thing, 0.0);
|
||||
|
||||
// To do: add the MeshBuilder output as surfaces
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CreateCollision();
|
||||
UploadPortals();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue