void Program::setAttributes( const VertexFormat& reference ) { int attributeCount = reference.attributeCount(); std::set<std::string> referenceAttributes; // Attribute der Referenz in eine Map schreiben (schneller zugriff über Name) for(int i = 0; i < attributeCount; ++i) { referenceAttributes.insert(reference.attribute(i).name()); } // Schauen welche Atribute es im Shader, aber nicht in der Referenz gibt for(std::map<std::string, int>::const_iterator i = m_AttributeSizes.begin(); i != m_AttributeSizes.end(); ++i) { if(referenceAttributes.count(i->first) == 0) { // i ist nicht in reference enthalten! // Das IST schlimm! LogError("Shader %s needs the vertex attribute %s, which the format does not provide.", toString().c_str(), i->first.c_str() ); return; } } for(int i = 0; i < attributeCount; ++i) { const VertexAttribute& attribute = reference.attribute(i); std::map<std::string, int>::const_iterator targetSizeIter = m_AttributeSizes.find(attribute.name()); if(targetSizeIter == m_AttributeSizes.end()) { Log("Vertex format %s has overhead to %s, because %s is not present in the shader.", reference.asString().c_str(), toString().c_str(), attribute.name() ); continue; } // Sind sie vielleicht unterschiedlich groß? if(attribute.dataType().componentCount() != targetSizeIter->second) { LogError("Vertex format %s is incomplatible to %s, because the shader needs %s to consist of %d instead of %d components.", reference.asString().c_str(), toString().c_str(), attribute.name(), targetSizeIter->second, attribute.dataType().componentCount() ); return; } glBindAttribLocation(m_Handle, i, attribute.name()); m_Dirty = true; } linkSilent(); }
bool GeometryPool::allocateVertices(GL::VertexRange& range, uint count, const VertexFormat& format) { if (!count) { range = GL::VertexRange(); return true; } VertexBufferSlot* slot = NULL; for (auto i = vertexBufferPool.begin(); i != vertexBufferPool.end(); i++) { if (i->vertexBuffer->getFormat() == format && i->available >= count) { slot = &(*i); break; } } if (!slot) { vertexBufferPool.push_back(VertexBufferSlot()); slot = &(vertexBufferPool.back()); const uint actualCount = granularity * ((count + granularity - 1) / granularity); slot->vertexBuffer = GL::VertexBuffer::create(context, actualCount, format, GL::VertexBuffer::DYNAMIC); if (!slot->vertexBuffer) { vertexBufferPool.pop_back(); return false; } log("Allocated vertex pool of size %u format \'%s\'", actualCount, format.asString().c_str()); slot->available = slot->vertexBuffer->getCount(); } range = GL::VertexRange(*(slot->vertexBuffer), slot->vertexBuffer->getCount() - slot->available, count); slot->available -= count; return true; }