QRhiWidget Class
La clase QRhiWidget es un widget para renderizar gráficos 3D a través de una API gráfica acelerada, como Vulkan, Metal o Direct 3D. Más...
| Cabecera: | #include <QRhiWidget> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Widgets)target_link_libraries(mytarget PRIVATE Qt6::Widgets) |
| qmake: | QT += widgets |
| Desde: | Qt 6.7 |
| Hereda: | QWidget |
Tipos Públicos
| enum class | Api { Null, OpenGL, Metal, Vulkan, Direct3D11, Direct3D12 } |
| enum class | TextureFormat { RGBA8, RGBA16F, RGBA32F, RGB10A2 } |
Propiedades
|
|
Funciones públicas
| QRhiWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {}) | |
| virtual | ~QRhiWidget() override |
| QRhiWidget::Api | api() const |
| QRhiWidget::TextureFormat | colorBufferFormat() const |
| QSize | fixedColorBufferSize() const |
| QImage | grabFramebuffer() const |
| bool | isDebugLayerEnabled() const |
| bool | isMirrorVerticallyEnabled() const |
| int | sampleCount() const |
| void | setApi(QRhiWidget::Api api) |
| void | setColorBufferFormat(QRhiWidget::TextureFormat format) |
| void | setDebugLayerEnabled(bool enable) |
| void | setFixedColorBufferSize(QSize pixelSize) |
| void | setFixedColorBufferSize(int w, int h) |
| void | setMirrorVertically(bool enabled) |
| void | setSampleCount(int samples) |
Señales
| void | colorBufferFormatChanged(QRhiWidget::TextureFormat format) |
| void | fixedColorBufferSizeChanged(const QSize &pixelSize) |
| void | frameSubmitted() |
| void | mirrorVerticallyChanged(bool enabled) |
| void | renderFailed() |
| void | sampleCountChanged(int samples) |
Funciones protegidas
| QRhiTexture * | colorTexture() const |
| QRhiRenderBuffer * | depthStencilBuffer() const |
| virtual void | initialize(QRhiCommandBuffer *cb) |
| QRhiRenderBuffer * | msaaColorBuffer() const |
| virtual void | releaseResources() |
| virtual void | render(QRhiCommandBuffer *cb) |
| QRhiRenderTarget * | renderTarget() const |
| QRhiTexture * | resolveTexture() const |
| QRhi * | rhi() const |
| void | setAutoRenderTarget(bool enabled) |
Funciones protegidas reimplementadas
| virtual bool | event(QEvent *e) override |
| virtual void | paintEvent(QPaintEvent *e) override |
| virtual void | resizeEvent(QResizeEvent *e) override |
Descripción detallada
QRhiWidget proporciona funcionalidad para mostrar contenido 3D renderizado a través de las APIs QRhi dentro de una aplicación basada en QWidget. En muchos sentidos, es el equivalente portátil de QOpenGLWidget que no está vinculado a una única API de gráficos 3D, sino que puede funcionar con todas las API compatibles con QRhi (como Direct 3D 11/12, Vulkan, Metal y OpenGL).
Se espera que QRhiWidget sea subclasificado. Para renderizar en la textura 2D creada y gestionada implícitamente por QRhiWidget, las subclases deben reimplementar las funciones virtuales initialize() y render().
El tamaño de la textura se adaptará por defecto al tamaño del widget. Si se prefiere un tamaño fijo, establezca un tamaño fijo especificado en píxeles llamando a setFixedColorBufferSize().
Además de la textura que sirve como búfer de color, también se mantiene implícitamente un búfer de profundidad/esténcil y un objetivo de renderizado que los une.
El QRhi para la ventana de nivel superior del widget está configurado para utilizar un backend específico de la plataforma y la API de gráficos por defecto: Metal en macOS e iOS, Direct 3D 11 en Windows, OpenGL en otros casos. Llame a setApi() para anular esta opción.
Nota: Una única ventana widget sólo puede utilizar un backend QRhi, y por lo tanto una única API de gráficos 3D. Si dos widgets QRhiWidget o QQuickWidget en la jerarquía de widgets de la ventana solicitan APIs diferentes, sólo uno de ellos funcionará correctamente.
Nota: Aunque QRhiWidget es una API pública de Qt, la familia de clases QRhi del módulo Qt Gui, que incluye QRhi, QShader y QShaderDescription, ofrece garantías de compatibilidad limitadas. No existen garantías de compatibilidad binaria o de código fuente para estas clases, lo que significa que sólo se garantiza que la API funcione con la versión de Qt con la que se desarrolló la aplicación. Sin embargo, los cambios incompatibles con el código fuente se mantendrán al mínimo y sólo se realizarán en versiones menores (6.7, 6.8, etc.). qrhiwidget.h no incluye directamente ninguna cabecera relacionada con QRhi. Para usar esas clases al implementar una subclase de QRhiWidget, enlaza con Qt::GuiPrivate (si usas CMake), e incluye las cabeceras apropiadas con el prefijo rhi, por ejemplo #include <rhi/qrhi.h>.
Un ejemplo de una simple subclase QRhiWidget renderizando un triángulo es el siguiente:
class ExampleRhiWidget : public QRhiWidget { public: ExampleRhiWidget(QWidget *parent = nullptr) : QRhiWidget(parent) { } void initialize(QRhiCommandBuffer *cb) override; void render(QRhiCommandBuffer *cb) override; private: QRhi *m_rhi = nullptr; std::unique_ptr<QRhiBuffer> m_vbuf; std::unique_ptr<QRhiBuffer> m_ubuf; std::unique_ptr<QRhiShaderResourceBindings> m_srb; std::unique_ptr<QRhiGraphicsPipeline> m_pipeline; QMatrix4x4 m_viewProjection; float m_rotation = 0.0f; }; float vertexData[] = { 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, }; QShader getShader(const QString &name) { QFile f(name); return f.open(QIODevice::ReadOnly) ? QShader::fromSerialized(f.readAll()) : QShader(); } void ExampleRhiWidget::initialize(QRhiCommandBuffer *cb) { if (m_rhi != rhi()) { m_pipeline.reset(); m_rhi = rhi(); } if (!m_pipeline) { m_vbuf.reset(m_rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData))); m_vbuf->create(); m_ubuf.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64)); m_ubuf->create(); m_srb.reset(m_rhi->newShaderResourceBindings()); m_srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, m_ubuf.get()), }); m_srb->create(); m_pipeline.reset(m_rhi->newGraphicsPipeline()); m_pipeline->setShaderStages({ { QRhiShaderStage::Vertex, getShader(QLatin1String(":/shader_assets/color.vert.qsb")) }, { QRhiShaderStage::Fragment, getShader(QLatin1String(":/shader_assets/color.frag.qsb")) } }); QRhiVertexInputLayout inputLayout; inputLayout.setBindings({ { 5 * sizeof(float) } }); inputLayout.setAttributes({ { 0, 0, QRhiVertexInputAttribute::Float2, 0 }, { 0, 1, QRhiVertexInputAttribute::Float3, 2 * sizeof(float) } }); m_pipeline->setVertexInputLayout(inputLayout); m_pipeline->setShaderResourceBindings(m_srb.get()); m_pipeline->setRenderPassDescriptor(renderTarget()->renderPassDescriptor()); m_pipeline->create(); QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch(); resourceUpdates->uploadStaticBuffer(m_vbuf.get(), vertexData); cb->resourceUpdate(resourceUpdates); } const QSize outputSize = colorTexture()->pixelSize(); m_viewProjection = m_rhi->clipSpaceCorrMatrix(); m_viewProjection.perspective(45.0f, outputSize.width() / (float) outputSize.height(), 0.01f, 1000.0f); m_viewProjection.translate(0, 0, -4); } void ExampleRhiWidget::render(QRhiCommandBuffer *cb) { QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch(); m_rotation += 1.0f; QMatrix4x4 modelViewProjection = m_viewProjection; modelViewProjection.rotate(m_rotation, 0, 1, 0); resourceUpdates->updateDynamicBuffer(m_ubuf.get(), 0, 64, modelViewProjection.constData()); const QColor clearColor = QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f); cb->beginPass(renderTarget(), clearColor, { 1.0f, 0 }, resourceUpdates); cb->setGraphicsPipeline(m_pipeline.get()); const QSize outputSize = colorTexture()->pixelSize(); cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height())); cb->setShaderResources(); const QRhiCommandBuffer::VertexInput vbufBinding(m_vbuf.get(), 0); cb->setVertexInput(0, 1, &vbufBinding); cb->draw(3); cb->endPass(); update(); }
Este es un widget que continuamente solicita actualizaciones, estrangulado por la tasa de presentación (vsync, dependiendo de la tasa de refresco de la pantalla). Si no se desea renderizar continuamente, la llamada a update() en render() debería ser eliminada, y en su lugar ser emitida sólo cuando sea necesario actualizar el contenido renderizado. Por ejemplo, si la rotación del cubo debe estar ligada al valor de un QSlider, entonces conectar la señal de cambio de valor del deslizador a una ranura o lambda que reenvíe el nuevo valor y llame a update() es suficiente.
Los sombreadores de vértices y fragmentos se proporcionan como GLSL al estilo Vulkan y deben ser procesados primero por la infraestructura de sombreadores de Qt. Esto se consigue ejecutando manualmente la herramienta de línea de comandos qsb, o utilizando la función qt_add_shaders() en CMake. La implementación de QRhiWidget carga estos archivos .qsb preprocesados que se envían con la aplicación. Ver Qt Shader Tools para más información sobre la infraestructura de traducción de shaders de Qt.
El código fuente de estos shaders podría ser el siguiente:
color.vert
#version 440
layout(location = 0) in vec4 position;
layout(location = 1) in vec3 color;
layout(location = 0) out vec3 v_color;
layout(std140, binding = 0) uniform buf {
mat4 mvp;
};
void main()
{
v_color = color;
gl_Position = mvp * position;
}color.frag
#version 440
layout(location = 0) in vec3 v_color;
layout(location = 0) out vec4 fragColor;
void main()
{
fragColor = vec4(v_color, 1.0);
}El resultado es un widget que muestra lo siguiente:

Para un ejemplo completo, mínimo e introductorio echa un vistazo a Simple RHI Widget Example.
Para un ejemplo con más funcionalidad y demostración de otros conceptos, vea el Ejemplo de Widget RHI Cubo.
QRhiWidget siempre implica renderizar en una textura de respaldo, no directamente en la ventana (la superficie o capa proporcionada por el sistema de ventanas para la ventana nativa). Esto permite componer adecuadamente el contenido con el resto de la interfaz de usuario basada en widgets, y ofrecer una API sencilla y compacta, lo que facilita los primeros pasos. Todo esto se consigue a costa de recursos adicionales y de un posible efecto sobre el rendimiento. Esto suele ser perfectamente aceptable en la práctica, pero los usuarios avanzados deberían tener en cuenta los pros y los contras de los distintos enfoques. Consulte el Ejemplo de Ventana RHI y compárelo con el Ejemplo de Widget RHI Simple para más detalles sobre los dos enfoques.
Reparenting a QRhiWidget into a widget hierarchy that belongs to a different window (top-level widget), or making the QRhiWidget itself a top-level (by setting the parent to nullptr), involves changing the associated QRhi (and potentially destroying the old one) while the QRhiWidget continues to stay alive and well. Para soportar esto, se espera que las implementaciones robustas de QRhiWidget reimplementen también la función virtual releaseResources(), y dejen caer sus recursos QRhi tal y como lo hacen en el destructor. El ejemplo del widget Cube RHI demuestra esto en la práctica.
Aunque no es un caso de uso primario, QRhiWidget también permite incorporar código de renderizado que utiliza directamente una API de gráficos 3D como Vulkan, Metal, Direct 3D u OpenGL. Ver QRhiCommandBuffer::beginExternal() para más detalles sobre la grabación de comandos nativos dentro de un pase de render QRhi, así como QRhiTexture::createFrom() para una forma de envolver una textura nativa existente y luego usarla con QRhi en un pase de render posterior. Ten en cuenta, sin embargo, que la configurabilidad de la API gráfica subyacente (sus características de dispositivo o contexto, capas, extensiones, etc.) va a ser limitada, ya que el objetivo principal de QRhiWidget es proporcionar un entorno adecuado para el código de renderizado basado en QRhi, no permitir motores de renderizado arbitrarios, potencialmente complejos y ajenos.
Ver también QRhi, QShader, QOpenGLWidget, Ejemplo de Widget RHI Simple, y Ejemplo de Widget RHI Cubo.
Documentación de tipos de miembros
enum class QRhiWidget::Api
Especifica la API 3D y el backend QRhi a utilizar
| Constante | Valor |
|---|---|
QRhiWidget::Api::Null | 0 |
QRhiWidget::Api::OpenGL | 1 |
QRhiWidget::Api::Metal | 2 |
QRhiWidget::Api::Vulkan | 3 |
QRhiWidget::Api::Direct3D11 | 4 |
QRhiWidget::Api::Direct3D12 | 5 |
Véase también QRhi.
enum class QRhiWidget::TextureFormat
Especifica el formato de la textura a la que renderiza QRhiWidget.
| Constante | Valor | Descripción |
|---|---|---|
QRhiWidget::TextureFormat::RGBA8 | 0 | Véase QRhiTexture::RGBA8. |
QRhiWidget::TextureFormat::RGBA16F | 1 | Véase QRhiTexture::RGBA16F. |
QRhiWidget::TextureFormat::RGBA32F | 2 | Véase QRhiTexture::RGBA32F. |
QRhiWidget::TextureFormat::RGB10A2 | 3 | Véase QRhiTexture::RGB10A2. |
Véase también QRhiTexture.
Documentación de propiedades
autoRenderTarget : bool
La configuración actual para el mantenimiento automático del búfer de profundidad y del objetivo de renderizado.
Por defecto, el valor es true.
colorBufferFormat : TextureFormat
Esta propiedad controla el formato de textura de la textura (o renderbuffer) utilizada como búfer de color. El valor por defecto es TextureFormat::RGBA8. QRhiWidget soporta el renderizado a un subconjunto de formatos soportados por QRhiTexture. Sólo deben especificarse los formatos soportados por QRhi::isTextureFormatSupported(), de lo contrario el renderizado no será funcional.
Nota: Establecer un nuevo formato cuando el widget ya está inicializado y ha renderizado implica que todos los objetos QRhiGraphicsPipeline creados por el renderizador pueden quedar inutilizables, si el QRhiRenderPassDescriptor asociado es ahora incompatible debido al diferente formato de textura. De forma similar al cambio dinámico de sampleCount, esto significa que las implementaciones de initialize() o render() deben entonces encargarse de liberar las canalizaciones existentes y crear otras nuevas.
Funciones de acceso:
| QRhiWidget::TextureFormat | colorBufferFormat() const |
| void | setColorBufferFormat(QRhiWidget::TextureFormat format) |
Señal notificadora:
| void | colorBufferFormatChanged(QRhiWidget::TextureFormat format) |
fixedColorBufferSize : QSize
El tamaño fijo, en píxeles, de la textura asociada a QRhiWidget. Relevante cuando se desea un tamaño de textura fijo que no dependa del tamaño del widget. Este tamaño no tiene ningún efecto sobre la geometría del widget (su tamaño y ubicación dentro de la ventana de nivel superior), lo que significa que el contenido de la textura aparecerá estirado (ampliado) o reducido en el área del widget.
Por ejemplo, si se establece un tamaño que sea exactamente el doble del tamaño (en píxeles) del widget, se realizará un supermuestreo 2x (renderizando al doble de resolución y reduciendo implícitamente la escala al texturizar el cuadrante correspondiente al widget en la ventana). Por otro lado, establecer un tamaño que sea la mitad del tamaño del widget permite renderizar a la mitad de la resolución y luego aumentar la escala de los resultados.
Por defecto, el valor es un QSize nulo. Un QSize nulo o vacío significa que el tamaño de la textura sigue el tamaño de QRhiWidget. (texture size = widget size * device pixel ratio).
Nota: La relación de píxeles del dispositivo (el factor de escala del compositor del sistema) puede tener un gran impacto en el rendimiento, ya que un factor de escala de 2 (200%) significa renderizar al doble de la resolución, es decir, el doble de lo que el desarrollador y el diseñador de la interfaz de usuario perciben como el tamaño del widget, y luego reducir efectivamente la escala del contenido, de forma similar a lo que ocurre cuando se establece esta propiedad al doble del tamaño de píxeles del widget en un sistema donde la relación de píxeles del dispositivo es 1. Por lo tanto, se espera que esta propiedad sea el valor predeterminado. Por lo tanto, se espera que esta propiedad se utilice raramente con tamaños mayores que el tamaño de píxel del widget, ya que muchos sistemas de escritorio modernos no tienen ni la necesidad ni el presupuesto de rendimiento para ello, cuando el sistema utiliza de todos modos una relación de píxeles del dispositivo mayor que 1. En su lugar, el principal caso de uso para esta propiedad es establecer un tamaño más pequeño, con el fin de renderizar a una resolución más pequeña razonable en lugar de seguir ciegamente la geometría de la ventana, por grande que sea.
Funciones de acceso:
| QSize | fixedColorBufferSize() const |
| void | setFixedColorBufferSize(QSize pixelSize) |
| void | setFixedColorBufferSize(int w, int h) |
Señal del notificador:
| void | fixedColorBufferSizeChanged(const QSize &pixelSize) |
mirrorVertically : bool
Cuando se activa, invierte la imagen alrededor del eje X al componer la textura de fondo de QRhiWidget con el resto del contenido del widget en la ventana de nivel superior.
El valor por defecto es false.
Funciones de acceso:
| bool | isMirrorVerticallyEnabled() const |
| void | setMirrorVertically(bool enabled) |
Señal del notificador:
| void | mirrorVerticallyChanged(bool enabled) |
sampleCount : int
Esta propiedad controla el número de muestras para el antialiasing multimuestra. Por defecto el valor es 1 lo que significa que el MSAA está desactivado.
Los valores válidos son 1, 4, 8, y a veces 16 y 32. QRhi::supportedSampleCounts() puede utilizarse para consultar los recuentos de muestras admitidos en tiempo de ejecución, pero normalmente las aplicaciones deberían solicitar 1 (sin MSAA), 4x (MSAA normal) u 8x (MSAA alto).
Nota: Establecer un nuevo valor implica que todos los objetos QRhiGraphicsPipeline creados por el renderizador deben utilizar el mismo recuento de muestras a partir de ese momento. Los objetos QRhiGraphicsPipeline existentes creados con un recuento de muestras diferente ya no deben utilizarse. Cuando el valor cambia, todas las memorias intermedias de color y profundidad se destruyen y se vuelven a crear automáticamente, y initialize() se invoca de nuevo. Sin embargo, cuando autoRenderTarget es false, dependerá de la aplicación gestionar esto con respecto al búfer de profundidad-esténcil o los búferes de color adicionales.
Cambiar el recuento de muestras del valor por defecto 1 a un valor superior implica que colorTexture() se convierte en nullptr y msaaColorBuffer() empieza a devolver un objeto válido. Volver a 1 (o 0), implica lo contrario: en la siguiente llamada a initialize() msaaColorBuffer() va a devolver nullptr, mientras que colorTexture() vuelve a ser válido. Además, resolveTexture() devuelve un QRhiTexture válido (no multimuestra) siempre que el recuento de muestras sea superior a 1 (es decir, que se esté utilizando MSAA).
Funciones de acceso:
| int | sampleCount() const |
| void | setSampleCount(int samples) |
Señal de notificador:
| void | sampleCountChanged(int samples) |
Véase también msaaColorBuffer() y resolveTexture().
Documentación de las funciones miembro
[explicit] QRhiWidget::QRhiWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {})
Construye un widget hijo de parent, con las banderas de widget establecidas en f.
[override virtual noexcept] QRhiWidget::~QRhiWidget()
Destructor.
QRhiWidget::Api QRhiWidget::api() const
Devuelve la API gráfica configurada actualmente (QRhi backend).
Véase también setApi().
[protected] QRhiTexture *QRhiWidget::colorTexture() const
Devuelve la textura que sirve como buffer de color para el widget.
Sólo debe llamarse desde initialize() y render().
A diferencia del búfer de profundidad y de QRhiRenderTarget, esta textura está siempre disponible y es gestionada por QRhiWidget, independientemente del valor de autoRenderTarget.
Nota: Cuando sampleCount es mayor que 1, y por lo tanto el antialiasing multimuestra está activado, el valor de retorno es nullptr. En su lugar, consulte el QRhiRenderBuffer llamando a msaaColorBuffer().
Nota: El tamaño de la textura de soporte y el número de muestras también pueden consultarse a través de QRhiRenderTarget devuelto por renderTarget(). Esto puede ser más conveniente y compacto que la consulta desde QRhiTexture o QRhiRenderBuffer, porque funciona independientemente de si el multimuestreo está en uso o no.
Véase también msaaColorBuffer(), depthStencilBuffer(), renderTarget() y resolveTexture().
[protected] QRhiRenderBuffer *QRhiWidget::depthStencilBuffer() const
Devuelve el búfer del patrón de profundidad utilizado por el renderizado del widget.
Sólo debe invocarse desde initialize() y render().
Disponible sólo cuando autoRenderTarget es true. En caso contrario, el valor devuelto es nullptr y corresponde a la reimplementación de initialize() crear y gestionar un búfer de profundidad y un QRhiTextureRenderTarget.
Véase también colorTexture() y renderTarget().
[override virtual protected] bool QRhiWidget::event(QEvent *e)
Reimplementa: QWidget::event(QEvent *event).
[signal] void QRhiWidget::frameSubmitted()
Esta señal se emite después de que la ventana de nivel superior del widget haya terminado de componerse y tenga submitted a frame.
QImage QRhiWidget::grabFramebuffer() const
Renderiza un nuevo fotograma, lee el contenido de la textura y lo devuelve como QImage.
Si se produce un error, se devuelve un QImage nulo.
El QImage devuelto tendrá un formato de QImage::Format_RGBA8888, QImage::Format_RGBA16FPx4, QImage::Format_RGBA32FPx4, o QImage::Format_BGR30, dependiendo de colorBufferFormat().
QRhiWidget no conoce la aproximación del renderizador a la mezcla y composición, y por lo tanto no puede saber si la salida tiene alfa premultiplicado en los valores de color RGB. Por lo tanto, los formatos _Premultiplied QImage nunca se utilizan para el QImage devuelto, incluso cuando sería apropiado. Corresponde a quien llama reinterpretar los datos resultantes como considere oportuno.
Nota: Esta función también puede llamarse cuando el QRhiWidget no se añade a una jerarquía de widgets perteneciente a una ventana de nivel superior en pantalla. Esto permite generar una imagen a partir de un renderizado 3D fuera de la pantalla.
La función se denomina grabFramebuffer() por coherencia con QOpenGLWidget y QQuickWidget. No es la única forma de obtener datos de imagen del lado de la CPU a partir del contenido de QRhiWidget: llamar a QWidget::grab() sobre un QRhiWidget, o un ancestro de éste, también es funcional (devolviendo un QPixmap). Además de trabajar directamente con QImage, otra ventaja de grabFramebuffer() es que puede tener un rendimiento ligeramente superior, simplemente porque no tiene que pasar por el resto de la infraestructura de QWidget, sino que puede activar directamente el renderizado de un nuevo fotograma y luego hacer la lectura de vuelta.
Véase también setColorBufferFormat().
[virtual protected] void QRhiWidget::initialize(QRhiCommandBuffer *cb)
Llamada cuando el widget es inicializado por primera vez, cuando el tamaño de la textura asociada, el formato, o el conteo de muestras cambia, o cuando el QRhi y la textura cambian por cualquier razón. Se espera que la función mantenga (cree si aún no se ha creado, ajuste y reconstruya si el tamaño ha cambiado) los recursos gráficos utilizados por el código de renderizado en render().
Para consultar los objetos QRhi, QRhiTexture, y otros objetos relacionados, llame a rhi(), colorTexture(), depthStencilBuffer(), y renderTarget().
Cuando el tamaño del widget cambia, el objeto QRhi, la textura del buffer de color, y los objetos del buffer del stencil de profundidad son todos las mismas instancias (por lo que los getters devuelven los mismos punteros) que antes, pero los buffers de color y profundidad/estencil probablemente habrán sido reconstruidos, lo que significa que el size y el recurso de textura nativa subyacente pueden ser diferentes que en la última invocación.
Las reimplementaciones también deben estar preparadas para que el objeto QRhi y la textura del búfer de color puedan cambiar entre invocaciones de esta función. Un caso especial en el que los objetos serán diferentes es cuando se realiza un grabFramebuffer() con un widget que aún no se muestra, y luego se hace visible el widget en pantalla dentro de un widget de nivel superior. En este caso, la captura se realizará con un QRhi específico que se sustituirá por el QRhi asociado a la ventana de nivel superior en las invocaciones posteriores a initialize() y render(). Otro caso, más común, es cuando el widget se reasigna para que pertenezca a una nueva ventana de nivel superior. En este caso el QRhi y todos los recursos relacionados gestionados por el QRhiWidget serán instancias diferentes que antes en la llamada posterior a esta función. Es importante entonces que todos los recursos QRhi creados previamente por la subclase sean destruidos porque pertenecen al QRhi anterior que ya no debe ser utilizado por el widget.
Cuando autoRenderTarget es true, que es el valor por defecto, se crean y gestionan automáticamente un depth-stencil QRhiRenderBuffer y un QRhiTextureRenderTarget asociados con colorTexture() (o msaaColorBuffer()) y el buffer depth-stencil. Las reimplementaciones de initialize() y render() pueden consultar estos objetos a través de depthStencilBuffer() y renderTarget(). Cuando autoRenderTarget se establece en false, estos objetos ya no se crean y gestionan automáticamente. En su lugar, será la implementación de initialize() la que cree los buffers y configure el objetivo de renderizado como considere oportuno. Cuando se gestionen manualmente adjuntos adicionales de color o profundidad para el objetivo de renderizado, su tamaño y número de muestras deben seguir siempre el tamaño y número de muestras de colorTexture() / msaaColorBuffer(), de lo contrario pueden producirse errores de validación de la API 3D o de renderizado.
Se espera que los recursos gráficos creados por la subclase se liberen en la implementación del destructor de la subclase.
cb es QRhiCommandBuffer para el fotograma actual del widget. La función es llamada con un fotograma siendo grabado, pero sin un pase de render activo. El buffer de comandos se proporciona principalmente para permitir la puesta en cola de resource updates sin diferir a render().
Véase también render().
bool QRhiWidget::isDebugLayerEnabled() const
Devuelve true si se solicitará una capa de depuración o validación si es aplicable a la API gráfica en uso.
Véase también setDebugLayerEnabled().
[protected] QRhiRenderBuffer *QRhiWidget::msaaColorBuffer() const
Devuelve el búfer de renderizado que sirve como búfer de color multimuestra para el widget.
Sólo debe ser llamado desde initialize() y render().
Cuando sampleCount es mayor que 1, y por lo tanto el antialising multimuestra está habilitado, el QRhiRenderBuffer devuelto tiene un recuento de muestras coincidente y sirve como búfer de color. Los conductos gráficos utilizados para renderizar en este búfer deben crearse con el mismo recuento de muestras, y el recuento de muestras del búfer de profundidad también debe coincidir. Se espera que el contenido multimuestra se resuelva en la textura devuelta por resolveTexture(). Cuando autoRenderTarget es true, renderTarget() se configura automáticamente para hacer esto, estableciendo msaaColorBuffer() como el renderbuffer del adjunto de color 0 y resolveTexture() como su resolveTexture.
Cuando MSAA no está en uso, el valor de retorno es nullptr. Utilice entonces colorTexture() en su lugar.
Dependiendo de la API de gráficos 3D subyacente, puede que no haya diferencia práctica entre las texturas multimuestra y los renderbuffers de color con un recuento de muestras superior a 1 (QRhi puede simplemente asignar ambos al mismo tipo de recurso nativo). Sin embargo, algunas API más antiguas pueden diferenciar entre texturas y renderbuffers. Con el fin de soportar OpenGL ES 3.0, donde los renderbuffers multimuestra están disponibles, pero las texturas multimuestra no, QRhiWidget siempre realiza MSAA utilizando una multimuestra QRhiRenderBuffer como adjunto de color (y nunca una multimuestra QRhiTexture).
Nota: El tamaño de la textura de respaldo y el recuento de muestras también se pueden consultar a través del QRhiRenderTarget devuelto por renderTarget(). Esto puede ser más conveniente y compacto que consultar desde QRhiTexture o QRhiRenderBuffer, ya que funciona independientemente de si se está utilizando multimuestreo o no.
Véase también colorTexture(), depthStencilBuffer(), renderTarget() y resolveTexture().
[override virtual protected] void QRhiWidget::paintEvent(QPaintEvent *e)
Reimplementa: QWidget::paintEvent(QPaintEvent *event).
Maneja eventos de pintura.
Llamando a QWidget::update() se enviará un evento de pintura e, y por tanto se invocará a esta función. El envío del evento es asíncrono y ocurrirá en algún momento después de volver de update(). Esta función entonces, después de alguna preparación, llamará a la virtual render() para actualizar el contenido de la textura asociada a QRhiWidget. La ventana de nivel superior del widget compondrá entonces la textura con el resto de la ventana.
[virtual protected] void QRhiWidget::releaseResources()
Llamada cuando surge la necesidad de liberar anticipadamente los recursos gráficos.
Esto no suele ocurrir en el caso de QRhiWidget, que se añade a la jerarquía de widgets hijos de un widget de nivel superior y permanece allí durante el resto de su vida y la del widget de nivel superior. Por lo tanto, en muchos casos no es necesario volver a implementar esta función, por ejemplo, porque la aplicación sólo tiene un widget de nivel superior (ventana nativa). Sin embargo, cuando se trata de reparenting del widget (o de un ancestro del mismo), será necesario reimplementar esta función en subclases robustas y bien escritas de QRhiWidget.
Cuando se llama a esta función, se espera que la implementación destruya todos los recursos de QRhi (objetosQRhiBuffer, QRhiTexture, etc.), de forma similar a como se espera que lo haga en el destructor. Nulling out, utilizando un puntero inteligente, o el establecimiento de un resources-invalid bandera va a ser necesario también, porque initialize() eventualmente será llamado después. Tenga en cuenta, sin embargo, que el aplazamiento de la liberación de los recursos a la posterior initialize() es un error. Si se llama a esta función, el recurso debe ser liberado antes de volver. Tenga en cuenta también que la implementación de esta función no sustituye al destructor de la clase (o a los punteros inteligentes): los recursos gráficos deben seguir siendo liberados en ambos.
Vea el ejemplo del Widget Cube RHI para un ejemplo de esto en acción. Allí el botón que cambia el QRhiWidget entre ser un widget hijo (debido a tener un widget padre) y ser un widget de nivel superior (debido a no tener un widget padre), activará la invocación de esta función ya que el widget de nivel superior asociado, la ventana nativa, y QRhi cambian durante la vida del QRhiWidget, con el QRhi usado previamente siendo destruido lo que implica una liberación temprana de los recursos asociados gestionados por el QRhiWidget aún vivo.
Otro caso en el que se llama a esta función es cuando se utiliza grabFramebuffer() con un QRhiWidget que no se añade a una ventana visible, es decir, el renderizado se realiza fuera de la pantalla. Si más tarde este QRhiWidget se hace visible, o se añade a una jerarquía de widgets visible, el QRhi asociado cambiará del temporal utilizado para el renderizado fuera de pantalla al dedicado de la ventana, activando así también esta función.
Véase también initialize().
[virtual protected] void QRhiWidget::render(QRhiCommandBuffer *cb)
Llamada cuando el contenido del widget (es decir, el contenido de la textura) necesita actualizarse.
Siempre hay al menos una llamada a initialize() antes de llamar a esta función.
Para solicitar actualizaciones, llame a QWidget::update(). Si se llama a update() desde render(), la actualización se realizará de forma continua, ralentizada por vsync.
cb es el QRhiCommandBuffer para el fotograma actual del widget. La función es llamada con un frame siendo grabado, pero sin un pase de render activo.
Véase también initialize().
[signal] void QRhiWidget::renderFailed()
Esta señal se emite siempre que el widget se supone que debe renderizar a su textura de respaldo (ya sea debido a un widget update o debido a una llamada a grabFramebuffer()), pero no hay QRhi para que el widget utilice, probablemente debido a problemas relacionados con la configuración de gráficos.
Esta señal puede ser emitida varias veces cuando surge un problema. No asumas que se emite sólo una vez. Conecta con Qt::SingleShotConnection si el código de gestión de errores debe ser notificado sólo una vez.
[protected] QRhiRenderTarget *QRhiWidget::renderTarget() const
Devuelve el objeto de destino de renderizado que debe utilizarse con QRhiCommandBuffer::beginPass() en reimplementaciones de render().
Sólo debe llamarse desde initialize() y render().
Disponible sólo cuando autoRenderTarget es true. En caso contrario, el valor devuelto es nullptr y corresponde a la reimplementación de initialize() crear y gestionar un búfer de profundidad y un QRhiTextureRenderTarget.
Al crear graphics pipelines, se necesita un QRhiRenderPassDescriptor. Éste puede consultarse a partir del QRhiTextureRenderTarget devuelto llamando a renderPassDescriptor().
Véase también colorTexture() y depthStencilBuffer().
[override virtual protected] void QRhiWidget::resizeEvent(QResizeEvent *e)
Reimplementa: QWidget::resizeEvent(QResizeEvent *event).
Maneja eventos de redimensionamiento que son pasados en el parámetro de evento e. Llama a la función virtual initialize().
Nota: Evita sobreescribir esta función en clases derivadas. Si no es posible, asegúrate de que la implementación de QRhiWidget también es invocada. De lo contrario, el objeto de textura subyacente y los recursos relacionados no serán redimensionados correctamente y darán lugar a un renderizado incorrecto.
[protected] QRhiTexture *QRhiWidget::resolveTexture() const
Devuelve la textura no multimuestra a la que se resuelve el contenido multimuestra.
El resultado es nullptr cuando el antialiasing multimuestra no está activado.
Sólo debe invocarse desde initialize() y render().
Con MSAA activado, esta es la textura que se compone con el resto del contenido de QWidget en pantalla. Sin embargo, el renderizado de QRhiWidget debe apuntar al (multimuestra) QRhiRenderBuffer devuelto desde msaaColorBuffer(). Cuando autoRenderTarget es true, de esto se encarga el QRhiRenderTarget devuelto por renderTarget(). De lo contrario, depende del código de la subclase configurar correctamente un objeto de destino de renderizado tanto con el búfer de color como con las texturas de resolución.
Véase también colorTexture().
[protected] QRhi *QRhiWidget::rhi() const
Devuelve el objeto QRhi actual.
Sólo debe invocarse desde initialize() y render().
void QRhiWidget::setApi(QRhiWidget::Api api)
Establece la API gráfica y el backend QRhi a utilizar en api.
Advertencia: Esta función debe ser llamada lo suficientemente pronto, antes de que el widget sea añadido a una jerarquía de widgets y mostrado en pantalla. Por ejemplo, intenta llamar a la función para el constructor de la subclase. Si se llama demasiado tarde, la función no tendrá ningún efecto.
El valor por defecto depende de la plataforma: Metal en macOS e iOS, Direct 3D 11 en Windows, OpenGL en caso contrario.
api sólo se puede establecer una vez para el widget y su ventana de nivel superior, una vez que se hace y tiene efecto, la ventana sólo puede utilizar esa API y QRhi backend para renderizar. Intentar establecer otro valor, o añadir otro QRhiWidget con un api diferente no funcionará como se espera.
Véase también setColorBufferFormat(), setDebugLayerEnabled(), y api().
[protected] void QRhiWidget::setAutoRenderTarget(bool enabled)
Controla si un depth-stencil QRhiRenderBuffer y un QRhiTextureRenderTarget son creados y mantenidos automáticamente por el widget. El valor por defecto es true.
En modo automático, el tamaño y el número de muestras del búfer del patrón de profundidad siguen la configuración de la textura del búfer de color. En modo no automático, renderTarget() y depthStencilBuffer() siempre devuelven nullptr y depende de la implementación de la aplicación de initialize() encargarse de configurar y gestionar estos objetos.
Llame a esta función con enabled establecido en false desde el principio, por ejemplo en el constructor de la clase derivada, para desactivar el modo automático.
void QRhiWidget::setDebugLayerEnabled(bool enable)
Solicita la capa de depuración o validación de la API gráfica subyacente cuando enable es true.
Advertencia: Esta función debe llamarse con suficiente antelación, antes de que el widget se añada a una jerarquía de widgets y se muestre en pantalla. Por ejemplo, intenta llamar a la función para el constructor de la subclase. Si se llama demasiado tarde, la función no tendrá ningún efecto.
Aplicable para Vulkan y Direct 3D.
Por defecto está desactivado.
Véase también setApi() y isDebugLayerEnabled().
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.