- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个可以通过OpenGL绘制三角形的函数
我通过按下一个按钮绘制两个三角形(函数on_drawMapPushButton_clicked())。
然后我在这些三角形上方绘制一个球体。现在我看到,该球体正确绘制在第一个三角形上,但是第二个三角形却绘制在该球体上,反之亦然。
如果我第二次按下按钮,则会在第一个和第二个三角形上正确绘制spehere。
当我第三次按下按钮时,第二个三角形再次在球体上绘制。
当我第四次按下按钮时,会在第一个和第二个三角形上正确绘制spehere,依此类推。
如果我在SphereMesh QPhongMaterial而不是QPhongAlphaMaterial中使用,则始终在第一个和第二个三角形上正确绘制spehere。喜欢它必须是。
我不明白我为使球体总是绘制在三角形上做错了什么。
代码,用于绘制透明球体:
selectModel_ = new Qt3DExtras::QSphereMesh(selectEntity_);
selectModel_->setRadius(75);
selectModel_->setSlices(150);
selectMaterial_ = new Qt3DExtras::QPhongAlphaMaterial(selectEntity_);
selectMaterial_->setAmbient(QColor(28, 61, 136));
selectMaterial_->setDiffuse(QColor(11, 56, 159));
selectMaterial_->setSpecular(QColor(10, 67, 199));
selectMaterial_->setShininess(0.8f);
selectEntity_->addComponent(selectModel_);
selectEntity_->addComponent(selectMaterial_);
void drawTriangles(QPolygonF triangles, QColor color){
int numOfVertices = triangles.size();
// Create and fill vertex buffer
QByteArray bufferBytes;
bufferBytes.resize(3 * numOfVertices * static_cast<int>(sizeof(float)));
float *positions = reinterpret_cast<float*>(bufferBytes.data());
for(auto point : triangles){
*positions++ = static_cast<float>(point.x());
*positions++ = 0.0f; //We need to drow only on the surface
*positions++ = static_cast<float>(point.y());
}
geometry_ = new Qt3DRender::QGeometry(mapEntity_);
auto *buf = new Qt3DRender::QBuffer(geometry_);
buf->setData(bufferBytes);
positionAttribute_ = new Qt3DRender::QAttribute(mapEntity_);
positionAttribute_->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
positionAttribute_->setVertexBaseType(Qt3DRender::QAttribute::Float); //In our buffer we will have only floats
positionAttribute_->setVertexSize(3); // Size of a vertex
positionAttribute_->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); // Attribute type
positionAttribute_->setByteStride(3 * sizeof(float));
positionAttribute_->setBuffer(buf);
geometry_->addAttribute(positionAttribute_); // Add attribute to ours Qt3DRender::QGeometry
// Create and fill an index buffer
QByteArray indexBytes;
indexBytes.resize(numOfVertices * static_cast<int>(sizeof(unsigned int))); // start to end
unsigned int *indices = reinterpret_cast<unsigned int*>(indexBytes.data());
for(unsigned int i = 0; i < static_cast<unsigned int>(numOfVertices); ++i) {
*indices++ = i;
}
auto *indexBuffer = new Qt3DRender::QBuffer(geometry_);
indexBuffer->setData(indexBytes);
indexAttribute_ = new Qt3DRender::QAttribute(geometry_);
indexAttribute_->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); //In our buffer we will have only unsigned ints
indexAttribute_->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); // Attribute type
indexAttribute_->setBuffer(indexBuffer);
indexAttribute_->setCount(static_cast<unsigned int>(numOfVertices)); // Set count of our vertices
geometry_->addAttribute(indexAttribute_); // Add the attribute to ours Qt3DRender::QGeometry
shape_ = new Qt3DRender::QGeometryRenderer(mapEntity_);
shape_->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
shape_->setGeometry(geometry_);
//Create material
material_ = new Qt3DExtras::QPhongMaterial(mapEntity_);
material_->setAmbient(color);
trianglesEntity_ = new Qt3DCore::QEntity(mapEntity_);
trianglesEntity_->addComponent(shape_);
trianglesEntity_->addComponent(material_);
}
void on_drawMapPushButton_clicked()
{
clearMap(); //Implementation is above
QPolygonF triangle1;
triangle1 << QPointF( 0 ,-1000) << QPointF(0 ,1000) << QPointF(1000, -1000);
drawTriangles(triangle1, Qt::black);
QPolygonF triangle2;
triangle2 << QPointF(-1000,-1000) << QPointF(-100,1000) << QPointF(-100,-1000);
drawTriangles(triangle2, Qt::red);
}
void clearMap()
{
if(mapEntity_){
delete mapEntity_;
mapEntity_ = nullptr;
mapEntity_ = new Qt3DCore::QEntity(view3dRootEntity_);
}
}
最佳答案
好的,这是扩展答案。
有时发生这种情况,有时不发生这种情况的原因取决于您实体的顺序。如果您尝试使用两个简单的球体,一个是透明球体,一个不是透明球体,那么您会发现,稍后添加透明球体时,它将在不透明对象上方绘制-就像您想要的那样。
发生这种情况是因为将首先绘制不透明的对象(它在场景图中首先出现),然后再绘制透明的对象,这将为您提供所需的结果。在其他情况下,首先绘制透明对象,因为 QPhongAlphaMaterial
具有 QNoDepthMask
渲染状态,该状态指示其不写入深度缓冲区,所以将不透明对象绘制在上方。因此,不透明对象始终通过深度测试,而透明对象实际上已经吸引到该深度测试。您需要做更多的工作才能为任意场景图和摄像机位置正确绘制透明对象。
Qt3D渲染图
要了解您必须做什么,您应该了解Qt3D渲染图的布局。如果您已经知道这一点,则可以跳过此部分。
斜体字在以下文本中引用了图形图像中的项目。
如果使用Qt3DWindow
,则无法访问渲染图的根节点。它由窗口维护。您可以通过函数activeFramegraph()
和renderSettings()
来访问QRenderSettings和框架图的根节点,这两个函数都可以在窗口上调用。您还可以通过setRootEntity()
的Qt3DWindow
函数设置场景图的根节点。窗口内部有一个 QAspectEngine
,它在其中设置整个图的根节点,这是上面图图像中渲染图的根节点。
如果要在3D窗口的现有框架图中插入框架图节点,则必须将其添加为 Activity 框架图的父级,这将在下一部分中进行解释。如果您有自己的自定义框架图形,可以通过setActiveFramegraph()
在窗口中设置,然后将其附加到末尾,就足够了。
使用QSortPolicy
正如您已经根据其他问题发现的那样,您可以在框架图中使用QSortPolicy
按与相机的距离对实体进行排序。您可以按如下所示添加排序策略(假设view
是您的Qt3DWindow
,而scene
是您的场景图的根实体,尽管我不知道为什么必须这样做):
Qt3DRender::QFrameGraphNode *framegraph = view.activeFrameGraph();
Qt3DRender::QSortPolicy *sortPolicy = new Qt3DRender::QSortPolicy(scene);
framegraph->setParent(sortPolicy);
QVector<Qt3DRender::QSortPolicy::SortType> sortTypes =
QVector<Qt3DRender::QSortPolicy::SortType>() << Qt3DRender::QSortPolicy::BackToFront;
sortPolicy->setSortTypes(sortTypes);
view.setActiveFrameGraph(framegraph);
此代码的问题在于,这种排序策略是按照实体的中心到相机的距离对它们进行排序的。如果其中一个不透明对象比透明对象更靠近摄影机,则无论如何它稍后都会被绘制并遮住透明对象。有关图形说明,请参见下面的图像。
QLayer
和
QLayerFilter
。您可以将图层附加到实体,然后将图层过滤器添加到框架图。这样,您可以排除实体进入框架图的某个分支。
Qt3DRender::QLayer *transparentLayer = new Qt3DRender::QLayer;
Qt3DRender::QLayer *opaqueLayer = new Qt3DRender::QLayer;
您必须将透明层作为组件附加到每个透明对象,将不透明层作为组件附加到每个不透明对象(使用
addComponent()
)。
view
是您的
Qt3DWindow
):
Qt3DRender::QRenderSurfaceSelector *renderSurfaceSelector
= new Qt3DRender::QRenderSurfaceSelector();
renderSurfaceSelector->setSurface(&view);
Qt3DRender::QClearBuffers *clearBuffers
= new Qt3DRender::QClearBuffers(renderSurfaceSelector);
clearBuffers->setBuffers(Qt3DRender::QClearBuffers::AllBuffers);
clearBuffers->setClearColor(Qt::white);
这是清除缓冲区的第一个分支。现在,添加以下代码:
Qt3DRender::QViewport *viewport = new Qt3DRender::QViewport(renderSurfaceSelector);
Qt3DRender::QCameraSelector *cameraSelector = new Qt3DRender::QCameraSelector(viewport);
Qt3DRender::QCamera *camera = new Qt3DRender::QCamera(cameraSelector);
// set your camera parameters here
cameraSelector->setCamera(camera);
由于您创建了
QViewport
作为
QRenderSurfaceSelector
的子代,因此相对于
QClearBuffers
,它现在是您的框架图中的同级。您可以看到示例框架图
here的图示。
// not entirely sure why transparent filter has to go first
// I would have expected the reversed order of the filters but this works...
Qt3DRender::QLayerFilter *transparentFilter = new Qt3DRender::QLayerFilter(camera);
transparentFilter->addLayer(transparentLayer);
Qt3DRender::QLayerFilter *opaqueFilter = new Qt3DRender::QLayerFilter(camera);
opaqueFilter->addLayer(opaqueLayer);
现在,两层滤镜是您的框架图分支中的叶节点,并且Qt3D首先绘制不透明的对象,然后,由于它使用相同的视口(viewport)并且所有内容都将在上方绘制透明的对象。它将正确绘制它们(即不在透明对象实际位于的不透明对象的前面,因为我们没有再次清除深度缓冲区->仅在相机节点上才拆分框架图)。
Qt3DWindow
上设置新的framegaph:
view.setActiveFrameGraph(renderSurfaceSelector);
结果:
关于c++ - Qt3d。在三角形上绘制透明的QSphereMesh,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55002979/
我想禁用我的 UIButton,所以我调用: button.enabled = FALSE; 然而,这会使按钮变得透明,我可以看到它下面的元素。我不介意它改变颜色,我只是不希望它是透明的。 我尝试在
一个常规的 NSButton 如果被禁用,它似乎是透明的。 图像显示了一个样式为“push”的按钮 但是,我想禁用没有透明度的按钮。 我试图以编程方式将 alphaValue 设置为 1.0 但似乎
我正在尝试将Memoji从iPhone/Mac转换为具有透明背景的一系列png,以便我可以创建一个 Sprite 表。当按下空格键时,我可以清楚地看到它具有透明背景,但是在运行 ffmpeg -i s
我想创建一个具有部分透明背景的 View (舞台、窗口)。我有一张包含 Alpha channel 的图像 我在JavaFx中使用了这种场景,我必须将场景填充设置为空,并将根节点背景颜色设置为透明。我
我想创建一个具有部分透明背景的 View (舞台、窗口)。我有一张包含 Alpha channel 的图像 我在JavaFx中使用了这种场景,我必须将场景填充设置为空,并将根节点背景颜色设置为透明。我
我想将 JDesktopPane 设置为透明,并允许我单击下面的内容(例如桌面图标等)。内部框架应保持不透明,并且能够像当前一样在屏幕周围重新定位。有什么想法吗? package test1;
我知道我不是第一个提出此类问题的人,但我认为我的问题有点不同。 我在 MS Paint 上绘制了一个 png 图像,它是一个播放器,当我使用图形对象绘制图像时,我希望图像的背景是透明的。我尝试了一些带
我在 Mac 的 swift 项目中想使用单选按钮,但与我的背景颜色相同。如何将背景设置为不透明或更改背景颜色? 最佳答案 我找到了解决此问题的方法。将单选按钮的文本设置为“”,将 rb 添加到水平堆
我无法将我的相对布局设置为透明。我尝试了很多不同的方法,从类中自定义 View ,添加 android:background="@android:color/transparent"等。它们要么像下图
在 Storyboard中,我创建了一个 ![UINavigationController] 及其 Root View Controller UIViewcontroller。在工具栏中,我有一个分段
我必须让我的导航栏透明,我试过这段代码: self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIB
我注意到,如果我将 View 背景颜色设置为透明,则在 segue 过渡结束后背景颜色会变成黑色(我猜这是默认的“视口(viewport)”颜色)。 我可以改变吗?当然,我可以将颜色从透明更改为紫色,
嘿,有没有可能让滚动条“隐藏”,我不想使用 overflow-y: hidden就像背景:透明或类似的东西 最佳答案 Here您会找到有关如何仅使用 CSS 隐藏滚动条的说明。 在第二个example
默认情况下,背景显示为白色。是否可以通过任何方式将其背景颜色更改为透明..? (function() { var cx = '005519348941191855053:d0uziw7c
我正在尝试添加一个在 div 的左右边缘具有透明度/淡出的嵌入框阴影。我设法添加了一个普通的嵌入框阴影,但我不知道如何为边缘添加透明度。我该怎么做? 这是我正在努力实现的一个例子。 .contai
如何删除 周围的边框并使其背景透明? 最佳答案 试试这个: border: none; border-color: transparent; 关于html - 透明、无边框的文本输入,我们在Stac
是否可以使 JButton 透明(包括边框)而不是文本?我扩展了 swing 的 JButton 并覆盖了它: @Override public void paint(Graphics g) {
众所周知,要使QWidget/QOpenGLWidget半透明/透明,只需: widget->setAttribute(Qt::WA_TranslucentBackground) 但是,由于 QWin
我想知道如何在 Ubuntu 中为所有应用程序制作透明 Gnome 终端,我知道我们可以为桌面制作透明终端,而不是为所有应用程序制作透明终端。我用谷歌搜索了很多,但找不到任何解决方案。谁能告诉我该怎么
我想让 SWT Canvas 的背景透明,以便可以看到它后面的其他小部件。 我尝试将 alpha 设置为 0 并用矩形填充 Canvas ,并且还使用选项 SWT.NO_BACKGROUND 无济于事
我是一名优秀的程序员,十分优秀!