我觉得这应该是非常简单的,但对于我的生活,我无法弄清楚如何使用Qt 3D绘制基本线。我能够在这个主题上找到的唯一指导是this obscure video,其中有一个令人生畏的原始字节缓冲区和内存操作通过scarcely documented classes进行。
有没有更好的方法来使用我缺少的闪亮的新API?
答案 0 :(得分:10)
From the video you linked, I came up with the code below (also posted in Qt forums: https://forum.qt.io/topic/66808/qt3d-draw-grid-axis-lines/3).
First, you need to create your QGeometry. As it is a simple line, it is only composed of 2 vertices (start point, end point), and 2 indices (that links the vertices). To do so, you need to create 2 QByteArray and store them into a QBuffer. In the first one, you store the 2 vertices (x, y, and z coordinates for each). In the second, you just say that you want to link your first vertex to the second. As we use Qt3DRender::QGeometryRenderer::Lines
on the renderer, only 2 indices are required.
Once it is done, you just have to put your QGeometry in a QGeometryRenderer to have a mesh, and put the mesh in a QEntity so it appears in the tree and it is rendered.
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DRender/QAttribute>
#include <Qt3DRender/QBuffer>
#include <Qt3DRender/QGeometry>
void drawLine(const QVector3D& start, const QVector3D& end, const QColor& color, Qt3DCore::QEntity *_rootEntity)
{
auto *geometry = new Qt3DRender::QGeometry(_rootEntity);
// position vertices (start and end)
QByteArray bufferBytes;
bufferBytes.resize(3 * 2 * sizeof(float)); // start.x, start.y, start.end + end.x, end.y, end.z
float *positions = reinterpret_cast<float*>(bufferBytes.data());
*positions++ = start.x();
*positions++ = start.y();
*positions++ = start.z();
*positions++ = end.x();
*positions++ = end.y();
*positions++ = end.z();
auto *buf = new Qt3DRender::QBuffer(geometry);
buf->setData(bufferBytes);
auto *positionAttribute = new Qt3DRender::QAttribute(geometry);
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
positionAttribute->setVertexSize(3);
positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
positionAttribute->setBuffer(buf);
positionAttribute->setByteStride(3 * sizeof(float));
positionAttribute->setCount(2);
geometry->addAttribute(positionAttribute); // We add the vertices in the geometry
// connectivity between vertices
QByteArray indexBytes;
indexBytes.resize(2 * sizeof(unsigned int)); // start to end
unsigned int *indices = reinterpret_cast<unsigned int*>(indexBytes.data());
*indices++ = 0;
*indices++ = 1;
auto *indexBuffer = new Qt3DRender::QBuffer(geometry);
indexBuffer->setData(indexBytes);
auto *indexAttribute = new Qt3DRender::QAttribute(geometry);
indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
indexAttribute->setBuffer(indexBuffer);
indexAttribute->setCount(2);
geometry->addAttribute(indexAttribute); // We add the indices linking the points in the geometry
// mesh
auto *line = new Qt3DRender::QGeometryRenderer(_rootEntity);
line->setGeometry(geometry);
line->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
auto *material = new Qt3DExtras::QPhongMaterial(_rootEntity);
material->setAmbient(color);
// entity
auto *lineEntity = new Qt3DCore::QEntity(_rootEntity);
lineEntity->addComponent(line);
lineEntity->addComponent(material);
}
答案 1 :(得分:0)
以下分别是我对缓冲区类型(我现在假设已弃用)所做的更正:
auto *buf = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, geometry);
auto *indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, geometry);
在Win 10上,我的Qt 5.9。
答案 2 :(得分:-3)
我建议看一下https://doc-snapshots.qt.io/qt5-5.9/qt3d-basicshapes-cpp-example.html,就像前一段时间我问自己一个类似的问题,即如何绘制一个圆圈。嗯,3D中的圆是一个圆环,其半径有一个特殊的比例:
from . model_managers import CustomManager
class Restaurant(models.Model):
name = models.CharField(max_length=25)
rating = models.PositiveIntegerField(validators=[MaxValueValidator(100), MinValueValidator(0)], default=50)
objects = CustomManager()
def __unicode__(self):
return self.name
那么3D中的线条是什么?它将是一个外半径非常小的圆柱体。