|
@@ -995,99 +995,7 @@ bool Graphics::SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, const P
|
|
|
bool Graphics::SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, const PODVector<unsigned>&
|
|
bool Graphics::SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, const PODVector<unsigned>&
|
|
|
elementMasks, unsigned instanceOffset)
|
|
elementMasks, unsigned instanceOffset)
|
|
|
{
|
|
{
|
|
|
- if (buffers.Size() > MAX_VERTEX_STREAMS)
|
|
|
|
|
- {
|
|
|
|
|
- LOGERROR("Too many vertex buffers");
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- if (buffers.Size() != elementMasks.Size())
|
|
|
|
|
- {
|
|
|
|
|
- LOGERROR("Amount of element masks and vertex buffers does not match");
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- bool changed = false;
|
|
|
|
|
- unsigned newAttributes = 0;
|
|
|
|
|
-
|
|
|
|
|
- for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i)
|
|
|
|
|
- {
|
|
|
|
|
- VertexBuffer* buffer = 0;
|
|
|
|
|
- unsigned elementMask = 0;
|
|
|
|
|
-
|
|
|
|
|
- if (i < buffers.Size() && buffers[i])
|
|
|
|
|
- {
|
|
|
|
|
- buffer = buffers[i];
|
|
|
|
|
- if (elementMasks[i] == MASK_DEFAULT)
|
|
|
|
|
- elementMask = buffer->GetElementMask();
|
|
|
|
|
- else
|
|
|
|
|
- elementMask = buffer->GetElementMask() & elementMasks[i];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // If buffer and element mask have stayed the same, skip to the next buffer
|
|
|
|
|
- if (buffer == vertexBuffers_[i] && elementMask == elementMasks_[i] && instanceOffset == lastInstanceOffset_ && !changed)
|
|
|
|
|
- {
|
|
|
|
|
- newAttributes |= elementMask;
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- vertexBuffers_[i] = buffer;
|
|
|
|
|
- elementMasks_[i] = elementMask;
|
|
|
|
|
- changed = true;
|
|
|
|
|
-
|
|
|
|
|
- // Beware buffers with missing OpenGL objects, as binding a zero buffer object means accessing CPU memory for vertex data,
|
|
|
|
|
- // in which case the pointer will be invalid and cause a crash
|
|
|
|
|
- if (!buffer || !buffer->GetGPUObject())
|
|
|
|
|
- continue;
|
|
|
|
|
-
|
|
|
|
|
- SetVBO(buffer->GetGPUObject());
|
|
|
|
|
- unsigned vertexSize = buffer->GetVertexSize();
|
|
|
|
|
-
|
|
|
|
|
- for (unsigned j = 0; j < MAX_VERTEX_ELEMENTS; ++j)
|
|
|
|
|
- {
|
|
|
|
|
- unsigned attrIndex = glVertexAttrIndex[j];
|
|
|
|
|
- unsigned elementBit = 1 << j;
|
|
|
|
|
-
|
|
|
|
|
- if (elementMask & elementBit)
|
|
|
|
|
- {
|
|
|
|
|
- newAttributes |= elementBit;
|
|
|
|
|
-
|
|
|
|
|
- // Enable attribute if not enabled yet
|
|
|
|
|
- if ((impl_->enabledAttributes_ & elementBit) == 0)
|
|
|
|
|
- {
|
|
|
|
|
- glEnableVertexAttribArray(attrIndex);
|
|
|
|
|
- impl_->enabledAttributes_ |= elementBit;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Set the attribute pointer. Add instance offset for the instance matrix pointers
|
|
|
|
|
- unsigned offset = j >= ELEMENT_INSTANCEMATRIX1 ? instanceOffset * vertexSize : 0;
|
|
|
|
|
- glVertexAttribPointer(attrIndex, VertexBuffer::elementComponents[j], VertexBuffer::elementType[j],
|
|
|
|
|
- VertexBuffer::elementNormalize[j], vertexSize, reinterpret_cast<const GLvoid*>(buffer->GetElementOffset((VertexElement)j)
|
|
|
|
|
- + offset));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (!changed)
|
|
|
|
|
- return true;
|
|
|
|
|
-
|
|
|
|
|
- lastInstanceOffset_ = instanceOffset;
|
|
|
|
|
-
|
|
|
|
|
- // Now check which vertex attributes should be disabled
|
|
|
|
|
- unsigned disableAttributes = impl_->enabledAttributes_ & (~newAttributes);
|
|
|
|
|
- unsigned disableIndex = 0;
|
|
|
|
|
-
|
|
|
|
|
- while (disableAttributes)
|
|
|
|
|
- {
|
|
|
|
|
- if (disableAttributes & 1)
|
|
|
|
|
- {
|
|
|
|
|
- glDisableVertexAttribArray(glVertexAttrIndex[disableIndex]);
|
|
|
|
|
- impl_->enabledAttributes_ &= ~(1 << disableIndex);
|
|
|
|
|
- }
|
|
|
|
|
- disableAttributes >>= 1;
|
|
|
|
|
- ++disableIndex;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return true;
|
|
|
|
|
|
|
+ return SetVertexBuffers(reinterpret_cast<const PODVector<VertexBuffer*>&>(buffers), elementMasks, instanceOffset);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Graphics::SetIndexBuffer(IndexBuffer* buffer)
|
|
void Graphics::SetIndexBuffer(IndexBuffer* buffer)
|