bool VertexDeclaration::push_back(const VertexElement& element)
{
	if (has(element.usage())) return false;

	_usageMask = _usageMask | vertexAttributeUsageMask(element.usage());
	
	_totalSize += vertexAttributeTypeSize(element.type());
	_list.push_back(element);

	if (_interleaved)
	{
		for (auto& i : _list)
			i.setStride(static_cast<int>(_totalSize));
	}

	return true;
}
uint32_t
VertexStream::id (const VertexElement& element) 
{ 
    uint32_t id = (1 << (element.usage() + 16)); 
    if (element.usageIndex() >= 0)
    {
        id |= (1 << ((element.usageIndex()+1)));
    }
    
    //LOG ("Element Stream Id is " << id);
    return id;
}
void RenderState::setVertexAttribPointer(const VertexElement& e, size_t baseIndex, bool force)
{
#if !defined(ET_CONSOLE_APPLICATION)
	(void)force;
	
	if (e.dataType() == DataType::Int)
	{
		glVertexAttribIPointer(GLuint(e.usage()), static_cast<GLint>(e.components()), dataTypeValue(e.dataType()),
			e.stride(), reinterpret_cast<GLvoid*>(e.offset() + baseIndex));
	}
	else if (e.dataType() == DataType::Float)
	{
		glVertexAttribPointer(GLuint(e.usage()), static_cast<GLint>(e.components()), dataTypeValue(e.dataType()),
			false, e.stride(), reinterpret_cast<GLvoid*>(e.offset() + baseIndex));
	}
	else
	{
		ET_FAIL("Unhandled vertex attribute data type.");
	}

	checkOpenGLError("glVertexAttribPointer");
#endif
}
bool
VertexElement::operator != (const VertexElement &src) const
{
    if (_usageIndex != src.usageIndex())
        return true;
    if (_usage != src.usage())
        return true;
    if (_method != src.method())
        return true;
    if (_type != src.type())
        return true;
    if (_offset != src.offset())
        return true;
    if (_stream != src.stream())
        return true;

    return false;
}