Search code examples
pythonqtpyside6qt3d

How to resolve "Error 0x80070057: The parameter is incorrect" in PySide6 + Qt3D?


When I try to run the code below, which just attempts to draw a single line, I get the following error:

Qt3D.Renderer.RHI.Backend: Initializing RHI with DirectX backend
Failed to create input layout: Error 0x80070057: The parameter is incorrect.
Qt3D.Renderer.RHI.Backend: Failed to build graphics pipeline: Creation Failed

I am able to run the Simple Qt 3D Example with no issues, and I can modify it load objects from .stl files. I've also looked through a handful of github repositories that use QGeometryRenderer in a similar manner as below, but all the variations I've tried result in the same error.

Platform: Win 10 x64, Python 3.11.4, PySide6 6.4.2.

Here's a minimal example that reproduces the issue:

import struct
import sys
from PySide6.QtCore import (QByteArray)
from PySide6.QtGui import (QGuiApplication, QVector3D)
from PySide6.Qt3DCore import (Qt3DCore)
from PySide6.Qt3DExtras import (Qt3DExtras)
from PySide6.Qt3DRender import (Qt3DRender)


class Line(Qt3DCore.QEntity):
    def __init__(self, parent=None,
                 start=QVector3D(0.0, 0.0, 0.0),
                 end = QVector3D(10.0, 0.0, 0.0)):
        super().__init__(parent)

        self.start = start
        self.end = end
        self.geometry = Qt3DCore.QGeometry(self)

        # Create a vertex buffer to hold the vertex data
        points = QByteArray()
        points.append(struct.pack('f', start.x()))
        points.append(struct.pack('f', start.y()))
        points.append(struct.pack('f', start.z()))
        points.append(struct.pack('f', end.x()))
        points.append(struct.pack('f', end.y()))
        points.append(struct.pack('f', end.z()))
        self.vertexBuffer = Qt3DCore.QBuffer(self.geometry)
        self.vertexBuffer.setData(points)

        # Create an attribute to hold the vertex data
        attribute = Qt3DCore.QAttribute(self.geometry)
        attribute.setName(Qt3DCore.QAttribute.defaultPositionAttributeName())
        attribute.setVertexBaseType(Qt3DCore.QAttribute.VertexBaseType.Float)
        attribute.setVertexSize(3)
        attribute.setAttributeType(Qt3DCore.QAttribute.AttributeType.VertexAttribute)
        attribute.setBuffer(self.vertexBuffer)
        attribute.setByteOffset(0)
        attribute.setByteStride(3 * 4)
        attribute.setCount(2)
        self.geometry.addAttribute(attribute)

        # Create a renderer to render the line
        self.renderer = Qt3DRender.QGeometryRenderer()
        self.renderer.setPrimitiveType(Qt3DRender.QGeometryRenderer.Lines)
        self.renderer.setGeometry(self.geometry)
        self.addComponent(self.renderer)


class Window(Qt3DExtras.Qt3DWindow):
    def __init__(self):
        super().__init__()

        self.camera().lens().setPerspectiveProjection(45, 16 / 9, 0.1, 1000)
        self.camera().setPosition(QVector3D(0, 0, 10))
        self.camera().setViewCenter(QVector3D(0, 0, 0))

        self.rootEntity = Qt3DCore.QEntity()
        self.material = Qt3DExtras.QPhongMaterial(self.rootEntity)
        self.line = Line(self.rootEntity)
        self.line.addComponent(self.material)

        self.camController = Qt3DExtras.QOrbitCameraController(self.rootEntity)
        self.camController.setLinearSpeed(50)
        self.camController.setLookSpeed(180)
        self.camController.setCamera(self.camera())

        self.setRootEntity(self.rootEntity)

if __name__ == '__main__':
    app = QGuiApplication(sys.argv)
    view = Window()
    view.show()
    sys.exit(app.exec())


Solution

  • As suggested in the comment by relent95 above, setting the QT3D_RENDERER environment variable solved this issue entirely for me.

    At the top of the script, I added:

    os.environ['QT3D_RENDERER'] = 'opengl'
    

    The script then ran with no errors. I found some documentation related to this environment variable here: https://doc.qt.io/qtforpython-6/overviews/qt3drender-porting-to-rhi.html