I'd like to display on the screen 2 squares using instance rendering.
The problem is :
When I draw 2 squares, they are connected. I can't draw multiple separate square.
I know it has to do with PrimitiveType : i'm using Qt3DRender::QGeometryRenderer::LineLoop or Qt3DRender::QGeometryRenderer::TriangleFan but is there a way to tell Qt to separate my data buffer in multiple instances ? so that the PrimitiveType apply on each instances and not all the vertices.
I got a function that create shapes :
Qt3DCore::QEntity* SceneBuilder::createShapeInstancing(const QList<QVector3D> & listVertices, int nbPointGeometry, const QColor color, Qt3DCore::QEntity * rootEntity)
{
// Material
Qt3DExtras::QPhongMaterial *material = new Qt3DExtras::QPhongMaterial(rootEntity);
material->setAmbient(color);
// Custom entity
Qt3DCore::QEntity *customMeshEntity = new Qt3DCore::QEntity(rootEntity);
// Custom Mesh
Qt3DRender::QGeometryRenderer *customMeshRenderer = new Qt3DRender::QGeometryRenderer(rootEntity);
Qt3DRender::QGeometry *customGeometry = new Qt3DRender::QGeometry(customMeshRenderer);
Qt3DRender::QBuffer *vertexDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, customGeometry);
int nbPointGeometry = nbPoint;
QByteArray vertexBufferData;
vertexBufferData.resize(listVertices.size() * nbPointGeometry * sizeof(QVector3D));
QVector3D *posData = reinterpret_cast<QVector3D *>(vertexBufferData.data());
QList<QVector3D>::const_iterator it;
for (it = listVertices.begin(); it != listVertices.end(); it++)
{
*posData = *it;
++posData;
}
vertexDataBuffer->setData(vertexBufferData);
//Attributes
Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute();
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
positionAttribute->setBuffer(vertexDataBuffer);
positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
positionAttribute->setVertexSize(3);
positionAttribute->setByteOffset(0);
positionAttribute->setByteStride((0 + 3) * sizeof(float));
positionAttribute->setCount(listVertices.size());
//positionAttribute->setDivisor(1);
customGeometry->addAttribute(positionAttribute);
customMeshRenderer->setGeometry(customGeometry);
//customMeshRenderer->setInstanceCount(listVertices.size()/nbPoint);
if (nbPointGeometry == 1)
customMeshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Points);
else if (nbPointGeometry == 2)
customMeshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
else if (nbPointGeometry == 3)
customMeshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
else
customMeshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineLoop);
customMeshEntity->addComponent(customMeshRenderer);
customMeshEntity->addComponent(material);
return customMeshEntity;
}
When i call this function, i put my 2 squares inside the listVertices variables. So that all my squares are display in one draw call.
But the shapes are one way or another connected. Is there a way to remove that ? I'm not using InstanceCount or Divisor but i don't know how it works. I made some tests with it but nothing worked
Actually, I just found an example of instanced rendering here.
They subclassed QSphereGeometry
and performed the instanced rendering in a shader. You could create a RectangleGeometry
which holds the vertices for one triangle and equip it with the same functionality as the InstancedGeometry
in the example.
Result: