std::size_t StaticVertexBuffer::lookupAttribute(const VertexAttribute &attribute) { for (unsigned int element = 0; element < mCache.size(); element++) { if (mCache[element].type == attribute.mType && mCache[element].size == attribute.mSize && mCache[element].stride == attribute.stride() && mCache[element].normalized == attribute.mNormalized) { if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride()) { return mCache[element].streamOffset; } } } return -1; }
std::size_t VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute, GLsizei instances) { Buffer *buffer = attribute.mBoundBuffer.get(); int inputStride = attribute.stride(); int elementSize = attribute.typeSize(); const FormatConverter &converter = formatConverter(attribute); std::size_t streamOffset = 0; void *output = NULL; if (vertexBuffer) { output = vertexBuffer->map(attribute, spaceRequired(attribute, count, instances), &streamOffset); } if (output == NULL) { ERR("Failed to map vertex buffer."); return -1; } const char *input = NULL; if (buffer) { int offset = attribute.mOffset; input = static_cast<const char*>(buffer->data()) + offset; } else { input = static_cast<const char*>(attribute.mPointer); } if (instances == 0 || attribute.mDivisor == 0) { input += inputStride * start; } if (converter.identity && inputStride == elementSize) { memcpy(output, input, count * inputStride); } else { converter.convertArray(input, inputStride, count, output); } vertexBuffer->unmap(); return streamOffset; }
int elementsInBuffer(const VertexAttribute &attribute, int size) { int stride = attribute.stride(); return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride; }