blob: 84d14cfe17eb7fa4e313f372c1ef5d6b1c9564d8 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qattribute.h"
#include "qattribute_p.h"
#include <Qt3DRender/qbuffer.h>
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
QAttributePrivate::QAttributePrivate()
: QNodePrivate()
, m_buffer(nullptr)
, m_name()
, m_vertexBaseType(QAttribute::Float)
, m_vertexSize(1)
, m_count(0)
, m_byteStride(0)
, m_byteOffset(0)
, m_divisor(0)
, m_attributeType(QAttribute::VertexAttribute)
{
}
/*!
* \qmltype Attribute
* \instantiates Qt3DRender::QAttribute
* \inqmlmodule Qt3D.Render
* \brief Defines an attribute and how data should be read from a Buffer.
*
* There are 3 types of attributes.
* \list
* \li VertexAttribute: used to define data to be read on a per vertex basis
* \li IndexAttribute: used to define vertex indices when indexed draw calls are
* to be used
*\li DrawIndirectAttribute: used to specify the DrawIndirect buffer to be used
* when indirect draw calls are to be used
* \endlist
*
* \note when an attribute is of type DrawIndirectAttribute, only count, stride
* and offset are relevant.
*
* When providing your own attributes, it may make sense to name your attribute
* using helpers such as QAttribute::defaultPositionAttributeName() as that
* will ensure your geometry will be compatible with picking and the various
* materials provided in the Qt3DExtras module.
*/
/*!
* \class Qt3DRender::QAttribute
* \inheaderfile Qt3DRender/QAttribute
* \inmodule Qt3DRender
*
* \inherits Qt3DCore::QNode
*
* \brief Defines an attribute and how data should be read from a QBuffer.
*
* There are 3 types of attributes.
* \list
* \li VertexAttribute: used to define data to be read on a per vertex basis
* \li IndexAttribute: used to define vertex indices when indexed draw calls are
* to be used
*\li DrawIndirectAttribute: used to specify the DrawIndirect buffer to be used
* when indirect draw calls are to be used
* \endlist
*
* \note when an attribute is of type DrawIndirectAttribute, only count, stride
* and offset are relevant.
*
* When providing your own attributes, it may make sense to name your attribute
* using helpers such as QAttribute::defaultPositionAttributeName() as that
* will ensure your geometry will be compatible with picking and the various
* materials provided in the Qt3DExtras module.
*
* \sa QBuffer
*/
/*!
* \typedef Qt3DRender::QBufferPtr
* \relates Qt3DRender::QAttribute
*/
/*!
* \enum QAttribute::AttributeType
*
* The type of the attribute.
*
* \value VertexAttribute
* \value IndexAttribute
* \value DrawIndirectAttribute
*/
/*!
* \enum QAttribute::VertexBaseType
*
* The type of the data.
*
* \value Byte
* \value UnsignedByte
* \value Short
* \value UnsignedShort
* \value Int
* \value UnsignedInt
* \value HalfFloat
* \value Float
* \value Double
*/
/*!
* Constructs a new QAttribute with \a parent.
*/
QAttribute::QAttribute(QNode *parent)
: QNode(*new QAttributePrivate(), parent)
{
}
/*!
* Constructs a new QAttribute from \a buf of \a type, \a dataSize, \a count, \a offset,
* and \a stride with \a parent.
*/
QAttribute::QAttribute(QBuffer *buf, VertexBaseType type, uint dataSize, uint count, uint offset, uint stride, QNode *parent)
: QAttribute(parent)
{
Q_D(QAttribute);
setBuffer(buf);
d->m_count = count;
d->m_byteOffset = offset;
d->m_vertexBaseType = type;
d->m_vertexSize = dataSize;
d->m_byteStride = stride;
}
/*!
* Constructs a new QAttribute named \a name from \a buf of \a type, \a
* dataSize, \a count, \a offset, and \a stride with \a parent.
*/
QAttribute::QAttribute(QBuffer *buf, const QString &name, VertexBaseType type, uint dataSize, uint count, uint offset, uint stride, QNode *parent)
: QAttribute(parent)
{
Q_D(QAttribute);
setBuffer(buf);
d->m_name = name;
d->m_count = count;
d->m_byteOffset = offset;
d->m_vertexBaseType = type;
d->m_vertexSize = dataSize;
d->m_byteStride = stride;
}
/*! \internal */
QAttribute::~QAttribute()
{
}
/*!
* \property QAttribute::buffer
*
* Holds the buffer.
*/
QBuffer *QAttribute::buffer() const
{
Q_D(const QAttribute);
return d->m_buffer;
}
/*!
* \property QAttribute::name
*
* Holds the name.
*/
QString QAttribute::name() const
{
Q_D(const QAttribute);
return d->m_name;
}
/*!
* \property QAttribute::vertexSize
*
* Holds the data size, it can only be 1 to 4 units (scalars and vectors),
* 9 units (3x3 matrices) or 16 units (4x4 matrices).
*/
uint QAttribute::vertexSize() const
{
Q_D(const QAttribute);
return d->m_vertexSize;
}
/*!
* \property QAttribute::vertexBaseType
*
* Holds the data type.
*/
QAttribute::VertexBaseType QAttribute::vertexBaseType() const
{
Q_D(const QAttribute);
return d->m_vertexBaseType;
}
/*!
* \property QAttribute::count
*
* Holds the count.
*/
uint QAttribute::count() const
{
Q_D(const QAttribute);
return d->m_count;
}
/*!
* \property QAttribute::byteStride
*
* Holds the byte stride.
*/
uint QAttribute::byteStride() const
{
Q_D(const QAttribute);
return d->m_byteStride;
}
/*!
* \property QAttribute::byteOffset
*
* Holds the byte offset.
*/
uint QAttribute::byteOffset() const
{
Q_D(const QAttribute);
return d->m_byteOffset;
}
/*!
* \property QAttribute::divisor
*
* Holds the divisor.
*/
uint QAttribute::divisor() const
{
Q_D(const QAttribute);
return d->m_divisor;
}
/*!
* \property QAttribute::attributeType
*
* Holds the attribute type.
*/
QAttribute::AttributeType QAttribute::attributeType() const
{
Q_D(const QAttribute);
return d->m_attributeType;
}
void QAttribute::setBuffer(QBuffer *buffer)
{
Q_D(QAttribute);
if (d->m_buffer == buffer)
return;
if (d->m_buffer)
d->unregisterDestructionHelper(d->m_buffer);
// We need to add it as a child of the current node if it has been declared inline
// Or not previously added as a child of the current node so that
// 1) The backend gets notified about it's creation
// 2) When the current node is destroyed, it gets destroyed as well
if (buffer && !buffer->parent())
buffer->setParent(this);
d->m_buffer = buffer;
// Ensures proper bookkeeping
if (d->m_buffer)
d->registerDestructionHelper(d->m_buffer, &QAttribute::setBuffer, d->m_buffer);
emit bufferChanged(buffer);
}
void QAttribute::setName(const QString &name)
{
Q_D(QAttribute);
if (d->m_name == name)
return;
d->m_name = name;
emit nameChanged(name);
}
void QAttribute::setVertexBaseType(VertexBaseType type)
{
Q_D(QAttribute);
if (d->m_vertexBaseType == type)
return;
d->m_vertexBaseType = type;
emit vertexBaseTypeChanged(type);
emit dataTypeChanged(type);
}
void QAttribute::setVertexSize(uint size)
{
Q_D(QAttribute);
if (d->m_vertexSize == size)
return;
Q_ASSERT((size >= 1 && size <= 4) || (size == 9) || (size == 16));
d->m_vertexSize = size;
emit vertexSizeChanged(size);
emit dataSizeChanged(size);
}
void QAttribute::setDataType(VertexBaseType type)
{
setVertexBaseType(type);
}
void QAttribute::setDataSize(uint size)
{
setVertexSize(size);
}
void QAttribute::setCount(uint count)
{
Q_D(QAttribute);
if (d->m_count == count)
return;
d->m_count = count;
emit countChanged(count);
}
void QAttribute::setByteStride(uint byteStride)
{
Q_D(QAttribute);
if (d->m_byteStride == byteStride)
return;
d->m_byteStride = byteStride;
emit byteStrideChanged(byteStride);
}
void QAttribute::setByteOffset(uint byteOffset)
{
Q_D(QAttribute);
if (d->m_byteOffset == byteOffset)
return;
d->m_byteOffset = byteOffset;
emit byteOffsetChanged(byteOffset);
}
void QAttribute::setDivisor(uint divisor)
{
Q_D(QAttribute);
if (d->m_divisor == divisor)
return;
d->m_divisor = divisor;
emit divisorChanged(divisor);
}
void QAttribute::setAttributeType(AttributeType attributeType)
{
Q_D(QAttribute);
if (d->m_attributeType == attributeType)
return;
d->m_attributeType = attributeType;
emit attributeTypeChanged(attributeType);
}
/*!
* \brief QAttribute::defaultPositionAttributeName
* \return the name of the default position attribute
*/
QString QAttribute::defaultPositionAttributeName()
{
return QStringLiteral("vertexPosition");
}
/*!
* \brief QAttribute::defaultNormalAttributeName
* \return the name of the default normal attribute
*/
QString QAttribute::defaultNormalAttributeName()
{
return QStringLiteral("vertexNormal");
}
/*!
* \brief QAttribute::defaultColorAttributeName
* \return the name of the default color attribute
*/
QString QAttribute::defaultColorAttributeName()
{
return QStringLiteral("vertexColor");
}
/*!
* \brief QAttribute::defaultTextureCoordinateAttributeName
* \return the name of the default texture coordinate attribute
*/
QString QAttribute::defaultTextureCoordinateAttributeName()
{
return QStringLiteral("vertexTexCoord");
}
/*!
* \brief QAttribute::defaultTangentAttributeName
* \return the name of the default tangent attribute
*/
QString QAttribute::defaultTangentAttributeName()
{
return QStringLiteral("vertexTangent");
}
/*!
* \brief QAttribute::defaultJointIndicesAttributeName
* \return the name of the default joint indices attribute
*/
QString QAttribute::defaultJointIndicesAttributeName()
{
return QStringLiteral("vertexJointIndices");
}
/*!
* \brief QAttribute::defaultJointIndicesAttributeName
* \return the name of the default joint weights attribute
*/
QString QAttribute::defaultJointWeightsAttributeName()
{
return QStringLiteral("vertexJointWeights");
}
/*!
* \brief QAttribute::defaultTextureCoordinate1AttributeName
* \return the name of the default attribute for the second layer of texture
* coordinates
*/
QString QAttribute::defaultTextureCoordinate1AttributeName()
{
return QStringLiteral("vertexTexCoord1");
}
/*!
* \brief QAttribute::defaultTextureCoordinate2AttributeName
* \return the name of the default attribute for the third layer of texture
* coordinates
*/
QString QAttribute::defaultTextureCoordinate2AttributeName()
{
return QStringLiteral("vertexTexCoord2");
}
Qt3DCore::QNodeCreatedChangeBasePtr QAttribute::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QAttributeData>::create(this);
auto &data = creationChange->data;
Q_D(const QAttribute);
data.bufferId = qIdForNode(d->m_buffer);
data.name = d->m_name;
data.vertexBaseType = d->m_vertexBaseType;
data.vertexSize = d->m_vertexSize;
data.count = d->m_count;
data.byteStride = d->m_byteStride;
data.byteOffset = d->m_byteOffset;
data.divisor = d->m_divisor;
data.attributeType = d->m_attributeType;
return creationChange;
}
/*!
\fn Qt3DRender::QAttribute::dataSizeChanged(uint vertexSize)
The signal is emitted with \a vertexSize when the dataSize changes.
*/
/*!
\fn Qt3DRender::QAttribute::dataTypeChanged(Qt3DRender::QAttribute::VertexBaseType vertexBaseType)
The signal is emitted with \a vertexBaseType when the dataType changed.
*/
} // Qt3DRender
QT_END_NAMESPACE