Skip to content
This repository has been archived by the owner on Jan 25, 2023. It is now read-only.

Commit

Permalink
Initial freeform vertex declarations for D3D9.
Browse files Browse the repository at this point in the history
  • Loading branch information
cadaver committed Apr 4, 2016
1 parent 55d1d82 commit a458d30
Show file tree
Hide file tree
Showing 25 changed files with 514 additions and 420 deletions.
7 changes: 2 additions & 5 deletions Source/Urho3D/AngelScript/GraphicsAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,6 @@ static void RegisterBuffers(asIScriptEngine* engine)
engine->RegisterGlobalProperty("const uint MASK_INSTANCEMATRIX2", (void*)&MASK_INSTANCEMATRIX2);
engine->RegisterGlobalProperty("const uint MASK_INSTANCEMATRIX3", (void*)&MASK_INSTANCEMATRIX3);
engine->RegisterGlobalProperty("const uint MASK_OBJECTINDEX", (void*)&MASK_OBJECTINDEX);
engine->RegisterGlobalProperty("const uint MASK_DEFAULT", (void*)&MASK_DEFAULT);

engine->RegisterEnum("PrimitiveType");
engine->RegisterEnumValue("PrimitiveType", "TRIANGLE_LIST", TRIANGLE_LIST);
Expand All @@ -762,7 +761,7 @@ static void RegisterBuffers(asIScriptEngine* engine)

RegisterObject<VertexBuffer>(engine, "VertexBuffer");
RegisterObjectConstructor<VertexBuffer>(engine, "VertexBuffer");
engine->RegisterObjectMethod("VertexBuffer", "void SetSize(uint, uint, bool dynamic = false)", asMETHOD(VertexBuffer, SetSize), asCALL_THISCALL);
// engine->RegisterObjectMethod("VertexBuffer", "void SetSize(uint, uint, bool dynamic = false)", asMETHOD(VertexBuffer, SetSize), asCALL_THISCALL);
engine->RegisterObjectMethod("VertexBuffer", "bool SetData(VectorBuffer&)", asFUNCTION(VertexBufferSetData), asCALL_CDECL_OBJLAST);
engine->RegisterObjectMethod("VertexBuffer", "bool SetDataRange(VectorBuffer&, uint, uint, bool discard = false)", asFUNCTION(VertexBufferSetDataRange), asCALL_CDECL_OBJLAST);
engine->RegisterObjectMethod("VertexBuffer", "VectorBuffer GetData()", asFUNCTION(VertexBufferGetData), asCALL_CDECL_OBJLAST);
Expand All @@ -771,7 +770,6 @@ static void RegisterBuffers(asIScriptEngine* engine)
engine->RegisterObjectMethod("VertexBuffer", "bool get_dynamic() const", asMETHOD(VertexBuffer, IsDynamic), asCALL_THISCALL);
engine->RegisterObjectMethod("VertexBuffer", "uint get_vertexCount() const", asMETHOD(VertexBuffer, GetVertexCount), asCALL_THISCALL);
engine->RegisterObjectMethod("VertexBuffer", "uint get_vertexSize() const", asMETHODPR(VertexBuffer, GetVertexSize, () const, unsigned), asCALL_THISCALL);
engine->RegisterObjectMethod("VertexBuffer", "uint get_elementMask() const", asMETHOD(VertexBuffer, GetElementMask), asCALL_THISCALL);

RegisterObject<IndexBuffer>(engine, "IndexBuffer");
RegisterObjectConstructor<IndexBuffer>(engine, "IndexBuffer");
Expand All @@ -789,12 +787,11 @@ static void RegisterBuffers(asIScriptEngine* engine)
RegisterObjectConstructor<Geometry>(engine, "Geometry");
engine->RegisterObjectMethod("Geometry", "void set_numVertexBuffers(uint)", asMETHOD(Geometry, SetNumVertexBuffers), asCALL_THISCALL);
engine->RegisterObjectMethod("Geometry", "uint get_numVertexBuffers() const", asMETHOD(Geometry, GetNumVertexBuffers), asCALL_THISCALL);
engine->RegisterObjectMethod("Geometry", "bool SetVertexBuffer(uint, VertexBuffer@+, uint elementMask = MASK_DEFAULT)", asMETHOD(Geometry, SetVertexBuffer), asCALL_THISCALL);
engine->RegisterObjectMethod("Geometry", "bool SetVertexBuffer(uint, VertexBuffer@+)", asMETHOD(Geometry, SetVertexBuffer), asCALL_THISCALL);
engine->RegisterObjectMethod("Geometry", "void SetIndexBuffer(IndexBuffer@+)", asMETHOD(Geometry, SetIndexBuffer), asCALL_THISCALL);
engine->RegisterObjectMethod("Geometry", "bool SetDrawRange(PrimitiveType, uint, uint, bool getUsedVertexRange = true)", asMETHODPR(Geometry, SetDrawRange, (PrimitiveType, unsigned, unsigned, bool), bool),asCALL_THISCALL);
engine->RegisterObjectMethod("Geometry", "bool SetDrawRange(PrimitiveType, uint, uint, uint, uint, bool checkIllegal = true)", asMETHODPR(Geometry, SetDrawRange, (PrimitiveType, unsigned, unsigned, unsigned, unsigned, bool), bool), asCALL_THISCALL);
engine->RegisterObjectMethod("Geometry", "VertexBuffer@+ get_vertexBuffers(uint) const", asMETHOD(Geometry, GetVertexBuffer), asCALL_THISCALL);
engine->RegisterObjectMethod("Geometry", "uint get_vertexElementMasks(uint) const", asMETHOD(Geometry, GetVertexElementMask), asCALL_THISCALL);
engine->RegisterObjectMethod("Geometry", "void set_indexBuffer(IndexBuffer@+)", asMETHOD(Geometry, SetIndexBuffer), asCALL_THISCALL);
engine->RegisterObjectMethod("Geometry", "IndexBuffer@+ get_indexBuffer() const", asMETHOD(Geometry, GetIndexBuffer), asCALL_THISCALL);
engine->RegisterObjectMethod("Geometry", "PrimitiveType get_primitiveType() const", asMETHOD(Geometry, GetPrimitiveType), asCALL_THISCALL);
Expand Down
16 changes: 8 additions & 8 deletions Source/Urho3D/Graphics/AnimatedModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1137,16 +1137,16 @@ void AnimatedModel::CloneGeometries()
for (unsigned k = 0; k < originalBuffers.Size(); ++k)
{
VertexBuffer* originalBuffer = originalBuffers[k];
unsigned originalMask = original->GetVertexElementMask(k);

if (clonedVertexBuffers.Contains(originalBuffer))
{
VertexBuffer* clonedBuffer = clonedVertexBuffers[originalBuffer];
clone->SetVertexBuffer(l++, originalBuffer, originalMask & ~clonedBuffer->GetElementMask());
clone->SetVertexBuffer(l++, clonedBuffer, originalMask & clonedBuffer->GetElementMask());
clone->SetVertexBuffer(l++, originalBuffer);
// Specify the morph buffer at a greater index to override the model's original positions/normals/tangents
clone->SetVertexBuffer(l++, clonedBuffer);
}
else
clone->SetVertexBuffer(l++, originalBuffer, originalMask);
clone->SetVertexBuffer(l++, originalBuffer);
}

clone->SetIndexBuffer(original->GetIndexBuffer());
Expand All @@ -1166,8 +1166,8 @@ void AnimatedModel::CopyMorphVertices(void* destVertexData, void* srcVertexData,
VertexBuffer* srcBuffer)
{
unsigned mask = destBuffer->GetElementMask() & srcBuffer->GetElementMask();
unsigned normalOffset = srcBuffer->GetElementOffset(ELEMENT_NORMAL);
unsigned tangentOffset = srcBuffer->GetElementOffset(ELEMENT_TANGENT);
unsigned normalOffset = srcBuffer->GetElementOffset(SEM_NORMAL);
unsigned tangentOffset = srcBuffer->GetElementOffset(SEM_TANGENT);
unsigned vertexSize = srcBuffer->GetVertexSize();
float* dest = (float*)destVertexData;
unsigned char* src = (unsigned char*)srcVertexData;
Expand Down Expand Up @@ -1367,8 +1367,8 @@ void AnimatedModel::ApplyMorph(VertexBuffer* buffer, void* destVertexData, unsig
{
unsigned elementMask = morph.elementMask_ & buffer->GetElementMask();
unsigned vertexCount = morph.vertexCount_;
unsigned normalOffset = buffer->GetElementOffset(ELEMENT_NORMAL);
unsigned tangentOffset = buffer->GetElementOffset(ELEMENT_TANGENT);
unsigned normalOffset = buffer->GetElementOffset(SEM_NORMAL);
unsigned tangentOffset = buffer->GetElementOffset(SEM_TANGENT);
unsigned vertexSize = buffer->GetVertexSize();

unsigned char* srcData = morph.morphData_;
Expand Down
7 changes: 2 additions & 5 deletions Source/Urho3D/Graphics/Batch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ void BatchGroup::Draw(View* view, Camera* camera, bool allowDepthWrite) const
Batch::Prepare(view, camera, false, allowDepthWrite);

graphics->SetIndexBuffer(geometry_->GetIndexBuffer());
graphics->SetVertexBuffers(geometry_->GetVertexBuffers(), geometry_->GetVertexElementMasks());
graphics->SetVertexBuffers(geometry_->GetVertexBuffers());

for (unsigned i = 0; i < instances_.Size(); ++i)
{
Expand All @@ -665,18 +665,15 @@ void BatchGroup::Draw(View* view, Camera* camera, bool allowDepthWrite) const
// Hack: use a const_cast to avoid dynamic allocation of new temp vectors
Vector<SharedPtr<VertexBuffer> >& vertexBuffers = const_cast<Vector<SharedPtr<VertexBuffer> >&>(
geometry_->GetVertexBuffers());
PODVector<unsigned>& elementMasks = const_cast<PODVector<unsigned>&>(geometry_->GetVertexElementMasks());
vertexBuffers.Push(SharedPtr<VertexBuffer>(instanceBuffer));
elementMasks.Push(instanceBuffer->GetElementMask());

graphics->SetIndexBuffer(geometry_->GetIndexBuffer());
graphics->SetVertexBuffers(vertexBuffers, elementMasks, startIndex_);
graphics->SetVertexBuffers(vertexBuffers, startIndex_);
graphics->DrawInstanced(geometry_->GetPrimitiveType(), geometry_->GetIndexStart(), geometry_->GetIndexCount(),
geometry_->GetVertexStart(), geometry_->GetVertexCount(), instances_.Size());

// Remove the instancing buffer & element mask now
vertexBuffers.Pop();
elementMasks.Pop();
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions Source/Urho3D/Graphics/BillboardSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ BillboardSet::BillboardSet(Context* context) :
sortFrameNumber_(0),
previousOffset_(Vector3::ZERO)
{
// Vertex buffer doesn't have its format defined yet, so manually define the elements into Geometry now
geometry_->SetVertexBuffer(0, vertexBuffer_, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1 | MASK_TEXCOORD2);
geometry_->SetVertexBuffer(0, vertexBuffer_);
geometry_->SetIndexBuffer(indexBuffer_);

batches_.Resize(1);
Expand Down
10 changes: 5 additions & 5 deletions Source/Urho3D/Graphics/CustomGeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,11 @@ bool CustomGeometry::DrawOcclusion(OcclusionBuffer* buffer)
unsigned vertexSize;
const unsigned char* indexData;
unsigned indexSize;
unsigned elementMask;
const PODVector<VertexElement>* elements;

geometry->GetRawData(vertexData, vertexSize, indexData, indexSize, elementMask);
geometry->GetRawData(vertexData, vertexSize, indexData, indexSize, elements);
// Check for valid geometry data
if (!vertexData)
if (!vertexData || !elements || VertexBuffer::GetElementOffset(*elements, TYPE_VECTOR3, SEM_POSITION) != 0)
continue;

// Draw and check for running out of triangles
Expand Down Expand Up @@ -389,7 +389,7 @@ void CustomGeometry::Commit()
++vertexCount;
}

geometries_[i]->SetVertexBuffer(0, vertexBuffer_, elementMask_);
geometries_[i]->SetVertexBuffer(0, vertexBuffer_);
geometries_[i]->SetDrawRange(primitiveTypes_[i], 0, 0, vertexStart, vertexCount);
vertexStart += vertexCount;
}
Expand All @@ -403,7 +403,7 @@ void CustomGeometry::Commit()
{
for (unsigned i = 0; i < geometries_.Size(); ++i)
{
geometries_[i]->SetVertexBuffer(0, vertexBuffer_, elementMask_);
geometries_[i]->SetVertexBuffer(0, vertexBuffer_);
geometries_[i]->SetDrawRange(primitiveTypes_[i], 0, 0, 0, 0);
}
}
Expand Down
10 changes: 5 additions & 5 deletions Source/Urho3D/Graphics/DecalSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ void DecalSet::GetFaces(Vector<PODVector<DecalVertex> >& faces, Drawable* target
if (!vb)
continue;

unsigned elementMask = geometry->GetVertexElementMask(i);
unsigned elementMask = vb->GetElementMask();
unsigned char* data = vb->GetShadowData();
if (!data)
continue;
Expand All @@ -729,12 +729,12 @@ void DecalSet::GetFaces(Vector<PODVector<DecalVertex> >& faces, Drawable* target
}
if (elementMask & MASK_NORMAL)
{
normalData = data + vb->GetElementOffset(ELEMENT_NORMAL);
normalData = data + vb->GetElementOffset(SEM_NORMAL);
normalStride = vb->GetVertexSize();
}
if (elementMask & MASK_BLENDWEIGHTS)
{
skinningData = data + vb->GetElementOffset(ELEMENT_BLENDWEIGHTS);
skinningData = data + vb->GetElementOffset(SEM_BLENDWEIGHTS);
skinningStride = vb->GetVertexSize();
}
}
Expand All @@ -743,8 +743,8 @@ void DecalSet::GetFaces(Vector<PODVector<DecalVertex> >& faces, Drawable* target
if (!positionData)
{
// As a fallback, try to get the geometry's raw vertex/index data
unsigned elementMask;
geometry->GetRawData(positionData, positionStride, indexData, indexStride, elementMask);
const PODVector<VertexElement>* elements;
geometry->GetRawData(positionData, positionStride, indexData, indexStride, elements);
if (!positionData)
{
URHO3D_LOGWARNING("Can not add decal, target drawable has no CPU-side geometry data");
Expand Down
33 changes: 14 additions & 19 deletions Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,9 @@ void Graphics::DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned i
VertexBuffer* buffer = vertexBuffers_[i];
if (buffer)
{
if (buffer->GetElementMask() & MASK_INSTANCEMATRIX1)
const PODVector<VertexElement>& elements = buffer->GetElements();
// Check if buffer has per-instance data
if (elements.Size() && elements[0].perInstance_)
SetStreamFrequency(i, D3DSTREAMSOURCE_INSTANCEDATA | 1u);
else
SetStreamFrequency(i, D3DSTREAMSOURCE_INDEXEDDATA | instanceCount);
Expand All @@ -934,42 +936,34 @@ void Graphics::SetVertexBuffer(VertexBuffer* buffer)
{
// Note: this is not multi-instance safe
static PODVector<VertexBuffer*> vertexBuffers(1);
static PODVector<unsigned> elementMasks(1);
vertexBuffers[0] = buffer;
elementMasks[0] = MASK_DEFAULT;
SetVertexBuffers(vertexBuffers, elementMasks);
SetVertexBuffers(vertexBuffers);
}

bool Graphics::SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, const PODVector<unsigned>& elementMasks,
unsigned instanceOffset)
bool Graphics::SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, unsigned instanceOffset)
{
if (buffers.Size() > MAX_VERTEX_STREAMS)
{
URHO3D_LOGERROR("Too many vertex buffers");
return false;
}
if (buffers.Size() != elementMasks.Size())
{
URHO3D_LOGERROR("Amount of element masks and vertex buffers does not match");
return false;
}

// Build vertex declaration hash code out of the buffers & masks
// Build vertex declaration hash code out of the buffers
unsigned long long hash = 0;
for (unsigned i = 0; i < buffers.Size(); ++i)
{
if (!buffers[i])
continue;

hash |= buffers[i]->GetBufferHash(i, elementMasks[i]);
hash |= buffers[i]->GetBufferHash(i);
}

if (hash)
{
// If no previous vertex declaration for that hash, create new
if (!vertexDeclarations_.Contains(hash))
{
SharedPtr<VertexDeclaration> newDeclaration(new VertexDeclaration(this, buffers, elementMasks));
SharedPtr<VertexDeclaration> newDeclaration(new VertexDeclaration(this, buffers));
if (!newDeclaration->GetDeclaration())
return false;

Expand All @@ -989,10 +983,12 @@ bool Graphics::SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, const P
VertexBuffer* buffer = 0;
unsigned offset = 0;

if (i < buffers.Size())
if (i < buffers.Size() && buffers[i])
{
buffer = buffers[i];
if (buffer && buffer->GetElementMask() & MASK_INSTANCEMATRIX1)
const PODVector<VertexElement>& elements = buffer->GetElements();
// Check if buffer has per-instance data; add instance offset in that case
if (elements.Size() && elements[0].perInstance_)
offset = instanceOffset * buffer->GetVertexSize();
}

Expand All @@ -1012,10 +1008,9 @@ bool Graphics::SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, const P
return true;
}

bool Graphics::SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, const PODVector<unsigned>& elementMasks,
unsigned instanceOffset)
bool Graphics::SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, unsigned instanceOffset)
{
return SetVertexBuffers(reinterpret_cast<const PODVector<VertexBuffer*>&>(buffers), elementMasks, instanceOffset);
return SetVertexBuffers(reinterpret_cast<const PODVector<VertexBuffer*>&>(buffers), instanceOffset);
}

void Graphics::SetIndexBuffer(IndexBuffer* buffer)
Expand Down
6 changes: 2 additions & 4 deletions Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,9 @@ class URHO3D_API Graphics : public Object
/// Set vertex buffer.
void SetVertexBuffer(VertexBuffer* buffer);
/// Set multiple vertex buffers.
bool SetVertexBuffers
(const PODVector<VertexBuffer*>& buffers, const PODVector<unsigned>& elementMasks, unsigned instanceOffset = 0);
bool SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, unsigned instanceOffset = 0);
/// Set multiple vertex buffers.
bool SetVertexBuffers
(const Vector<SharedPtr<VertexBuffer> >& buffers, const PODVector<unsigned>& elementMasks, unsigned instanceOffset = 0);
bool SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, unsigned instanceOffset = 0);
/// Set index buffer.
void SetIndexBuffer(IndexBuffer* buffer);
/// Set shaders.
Expand Down

0 comments on commit a458d30

Please sign in to comment.