QRhiWidget Class

QRhiWidget 클래스는 벌칸, 메탈 또는 다이렉트 3D와 같은 가속화된 그래픽 API를 통해 3D 그래픽을 렌더링하는 위젯입니다. 더 보기...

Header: #include <QRhiWidget>
CMake: find_package(Qt6 REQUIRED COMPONENTS Widgets)
target_link_libraries(mytarget PRIVATE Qt6::Widgets)
qmake: QT += widgets
이후: Qt 6.7
상속합니다: QWidget
상태: 예비

이 클래스는 개발 중이며 변경될 수 있습니다.

공용 유형

enum class Api { Null, OpenGL, Metal, Vulkan, Direct3D11, Direct3D12 }
enum class TextureFormat { RGBA8, RGBA16F, RGBA32F, RGB10A2 }

속성

공공 기능

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)

신호

void colorBufferFormatChanged(QRhiWidget::TextureFormat format)
void fixedColorBufferSizeChanged(const QSize &pixelSize)
void frameSubmitted()
void mirrorVerticallyChanged(bool enabled)
void renderFailed()
void sampleCountChanged(int samples)

보호된 함수

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)

재구현된 보호 함수

virtual bool event(QEvent *e) override
virtual void paintEvent(QPaintEvent *e) override
virtual void resizeEvent(QResizeEvent *e) override

상세 설명

참고: QRhiWidget은 Qt 6.7에서 기술 프리뷰 버전입니다. API는 개발 중이며 변경될 수 있습니다.

QRhiWidget은 QWidget 기반 애플리케이션 내에서 QRhi API를 통해 렌더링된 3D 콘텐츠를 표시하는 기능을 제공합니다. 여러 면에서 단일 3D 그래픽 API에 묶여 있지 않고 QRhi 에서 지원하는 모든 API(예: Direct 3D 11/12, Vulkan, Metal 및 OpenGL)와 함께 작동할 수 있는 휴대용 버전( QOpenGLWidget )과 동일합니다.

QRhiWidget은 서브클래싱될 예정입니다. QRhiWidget에서 암시적으로 생성 및 관리되는 2D 텍스처로 렌더링하려면 하위 클래스에서 가상 함수 initialize() 및 render()를 다시 구현해야 합니다.

텍스처의 크기는 기본적으로 위젯의 크기에 맞게 조정됩니다. 고정 크기를 선호하는 경우 setFixedColorBufferSize()를 호출하여 픽셀 단위로 지정된 고정 크기를 설정합니다.

색상 버퍼 역할을 하는 텍스처 외에도 깊이/스텐실 버퍼와 이를 함께 묶는 렌더 타겟도 암시적으로 유지됩니다.

위젯의 최상위 창에 대한 QRhi 은 기본적으로 플랫폼별 백엔드 및 그래픽 API를 사용하도록 구성됩니다: macOS 및 iOS에서는 Metal, Windows에서는 Direct 3D 11, 그 외에는 OpenGL을 사용합니다. 이를 재정의하려면 setApi()를 호출하세요.

참고: 하나의 위젯 창에는 하나의 QRhi 백엔드, 즉 하나의 3D 그래픽 API만 사용할 수 있습니다. 창의 위젯 계층 구조에 있는 두 개의 QRhiWidget 또는 QQuickWidget 위젯이 서로 다른 API를 요청하면 그 중 하나만 올바르게 작동합니다.

참고: QRhiWidget은 공용 Qt API이지만 QRhi, QShaderQShaderDescription 을 포함한 Qt GUI 모듈의 QRhi 클래스 제품군은 제한된 호환성을 보장합니다. 이러한 클래스에 대한 소스 또는 바이너리 호환성 보장은 없으므로 API는 애플리케이션이 개발된 Qt 버전에서만 작동하도록 보장됩니다. 그러나 소스와 호환되지 않는 변경은 최소한으로 유지하는 것을 목표로 하며 마이너 릴리스(6.7, 6.8 등)에서만 이루어집니다. qrhiwidget.h 에는 QRhi 관련 헤더가 직접 포함되지 않습니다. QRhiWidget 서브클래스를 구현할 때 해당 클래스를 사용하려면 Qt::GuiPrivate (CMake를 사용하는 경우)에 링크하고 rhi 접두사가 붙은 적절한 헤더를 포함하세요(예: #include <rhi/qrhi.h>).

삼각형을 렌더링하는 간단한 QRhiWidget 서브클래스의 예는 다음과 같습니다:

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();
}

이 위젯은 지속적으로 업데이트를 요청하는 위젯으로, 표시 속도에 따라 조절됩니다(화면 재생률에 따라 vsync). 지속적인 렌더링을 원하지 않는 경우 render()의 update() 호출을 제거하고 렌더링된 콘텐츠를 업데이트해야 할 때만 호출해야 합니다. 예를 들어 큐브의 회전을 QSlider 의 값에 연결해야 하는 경우 슬라이더의 값 변경 신호를 새 값을 전달하고 update()를 호출하는 슬롯 또는 람다에 연결하면 충분합니다.

버텍스 및 프래그먼트 셰이더는 Vulkan 스타일의 GLSL로 제공되며 Qt 셰이더 인프라에서 먼저 처리해야 합니다. 이는 qsb 명령줄 도구를 수동으로 실행하거나 CMake의 qt_add_shaders() 함수를 사용하여 수행할 수 있습니다. QRhiWidget 구현은 애플리케이션과 함께 제공되는 이러한 사전 처리된 .qsb 파일을 로드합니다. Qt의 셰이더 변환 인프라에 대한 자세한 내용은 Qt Shader Tools 을 참조하십시오.

이러한 셰이더의 소스 코드는 다음과 같습니다:

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);
}

결과는 다음과 같은 위젯입니다:

완전한 최소한의 입문용 예제는 간단한 RHI 위젯 예제를 확인하세요.

더 많은 기능과 추가 개념에 대한 데모가 포함된 예제는 큐브 RHI 위젯 예제를 참조하세요.

QRhiWidget은 항상 창(기본 창에 대해 창 시스템이 제공하는 표면 또는 레이어)에 직접 렌더링하는 것이 아니라 백킹 텍스처에 렌더링합니다. 따라서 콘텐츠를 나머지 위젯 기반 UI와 적절하게 합성할 수 있으며, 간단하고 컴팩트한 API를 제공하여 쉽게 시작할 수 있습니다. 이 모든 것에는 추가 리소스가 필요하고 성능에 잠재적인 영향을 미칠 수 있습니다. 하지만 고급 사용자는 다양한 접근 방식의 장단점을 염두에 두어야 합니다. 두 가지 접근 방식에 대한 자세한 내용은 RHI 창 예시를 참조하고 단순 RHI 위젯 예시와 비교하세요.

다른 창(최상위 위젯)에 속하는 위젯 계층 구조로 QRhiWidget의 부모를 변경하거나 QRhiWidget 자체를 최상위 수준으로 만들려면(부모를 nullptr 로 설정하여) 관련 QRhi 을 변경해야 하며, 이전 위젯은 계속 살아있지만 파괴될 가능성이 있습니다. 이를 지원하기 위해 강력한 QRhiWidget 구현은 releaseResources() 가상 함수도 다시 구현하고 소멸자에서와 마찬가지로 QRhi 리소스를 삭제할 것으로 예상됩니다. 큐브 RHI 위젯 예제는 이를 실제로 보여줍니다.

주요 사용 사례는 아니지만 QRhiWidget을 사용하면 Vulkan, Metal, Direct 3D 또는 OpenGL과 같은 3D 그래픽 API를 직접 사용하는 렌더링 코드도 통합할 수 있습니다. QRhi 렌더 패스 내에서 네이티브 명령을 기록하는 방법에 대한 자세한 내용은 QRhiCommandBuffer::beginExternal(), 기존 네이티브 텍스처를 래핑한 다음 후속 렌더 패스에서 QRhi 와 함께 사용하는 방법은 QRhiTexture::createFrom()를 참조하세요. 그러나 QRhiWidget의 주요 목표는 임의적이고 잠재적으로 복잡한 외부 렌더링 엔진을 활성화하는 것이 아니라 QRhi 기반 렌더링 코드에 적합한 환경을 제공하는 것이므로 기본 그래픽 API의 구성 가능성(장치 또는 컨텍스트 기능, 레이어, 확장 등)이 제한될 수 있다는 점에 유의하세요.

QRhi, QShader, QOpenGLWidget, Simple RHI 위젯 예제Cube RHI 위젯 예제를참조하세요 .

멤버 유형 문서

enum class QRhiWidget::Api

사용할 3D API 및 QRhi 백엔드를 지정합니다.

Constant
QRhiWidget::Api::Null0
QRhiWidget::Api::OpenGL1
QRhiWidget::Api::Metal2
QRhiWidget::Api::Vulkan3
QRhiWidget::Api::Direct3D114
QRhiWidget::Api::Direct3D125

QRhi도 참조하세요 .

enum class QRhiWidget::TextureFormat

QRhiWidget 렌더링할 텍스처의 형식을 지정합니다.

Constant설명
QRhiWidget::TextureFormat::RGBA80QRhiTexture::RGBA8 을 참조하십시오.
QRhiWidget::TextureFormat::RGBA16F1QRhiTexture::RGBA16F 를 참조하십시오.
QRhiWidget::TextureFormat::RGBA32F2QRhiTexture::RGBA32F 을 참조하십시오.
QRhiWidget::TextureFormat::RGB10A23QRhiTexture::RGB10A2 참조 .

또한 QRhiTexture참조하십시오 .

속성 문서

autoRenderTarget : const bool

자동 뎁스 스텐실 버퍼 및 렌더 타깃 유지 관리를 위한 현재 설정입니다.

기본값은 true 입니다.

colorBufferFormat : TextureFormat

이 속성은 컬러 버퍼로 사용되는 텍스처(또는 렌더버퍼)의 텍스처 형식을 제어합니다. 기본값은 TextureFormat::RGBA8 입니다. QRhiWidgetQRhiTexture 에서 지원하는 형식의 하위 집합에 대한 렌더링을 지원합니다. QRhi::isTextureFormatSupported ()에서 지원되는 것으로 보고된 형식만 지정해야 하며, 그렇지 않으면 렌더링이 작동하지 않습니다.

참고: 위젯이 이미 초기화되어 렌더링된 상태에서 새 형식을 설정하면 연결된 QRhiRenderPassDescriptor 이 다른 텍스처 형식으로 인해 호환되지 않는 경우 렌더러에서 생성된 모든 QRhiGraphicsPipeline 객체를 사용할 수 없게 될 수 있습니다. sampleCount 을 동적으로 변경하는 것과 마찬가지로 initialize() 또는 render() 구현은 기존 파이프라인을 해제하고 새 파이프라인을 생성해야 합니다.

함수 액세스:

QRhiWidget::TextureFormat colorBufferFormat() const
void setColorBufferFormat(QRhiWidget::TextureFormat format)

알림 신호:

void colorBufferFormatChanged(QRhiWidget::TextureFormat format)

fixedColorBufferSize : QSize

QRhiWidget 관련 텍스처의 고정 크기(픽셀 단위)입니다. 위젯의 크기에 의존하지 않는 고정 텍스처 크기가 필요한 경우에 적합합니다. 이 크기는 위젯의 지오메트리(위젯의 크기 및 최상위 창 내 배치)에 영향을 주지 않으므로 텍스처의 콘텐츠가 위젯의 영역에 맞게 늘어나거나(확대) 축소되어 표시됩니다.

예를 들어 위젯(픽셀) 크기의 정확히 두 배인 크기를 설정하면 2배 슈퍼샘플링(창에서 위젯에 해당하는 쿼드를 텍스처링할 때 해상도를 두 배로 렌더링한 다음 암시적으로 축소)이 효과적으로 수행됩니다.

기본적으로 값은 널 QSize 입니다. 널 또는 비어 있는 QSize 은 텍스처의 크기가 QRhiWidget 의 크기를 따른다는 의미입니다. (texture size = widget size * device pixel ratio).

함수에 액세스합니다:

QSize fixedColorBufferSize() const
void setFixedColorBufferSize(QSize pixelSize)
void setFixedColorBufferSize(int w, int h)

알림 신호:

void fixedColorBufferSizeChanged(const QSize &pixelSize)

mirrorVertically : bool

활성화하면 QRhiWidget 의 배경 텍스처를 최상위 창에서 나머지 위젯 콘텐츠와 합성할 때 이미지를 X 축을 중심으로 뒤집습니다.

기본값은 false 입니다.

기능에 액세스합니다:

bool isMirrorVerticallyEnabled() const
void setMirrorVertically(bool enabled)

알림 신호:

void mirrorVerticallyChanged(bool enabled)

sampleCount : int

이 프로퍼티는 다중 샘플 앤티앨리어싱의 샘플 수를 제어합니다. 기본값은 1, 즉 MSAA가 비활성화되어 있습니다.

유효한 값은 1, 4, 8, 때로는 16과 32입니다. QRhi::supportedSampleCounts()를 사용하여 런타임에 지원되는 샘플 수를 쿼리할 수 있지만 일반적으로 애플리케이션은 1(MSAA 없음), 4배(일반 MSAA) 또는 8배(높은 MSAA)를 요청해야 합니다.

참고: 새 값을 설정하면 렌더러에서 생성된 모든 QRhiGraphicsPipeline 오브젝트는 그 이후부터 동일한 샘플 수를 사용해야 합니다. 다른 샘플 수로 생성된 기존 QRhiGraphicsPipeline 오브젝트는 더 이상 사용할 수 없습니다. 값이 변경되면 모든 색상 및 깊이 스텐실 버퍼가 자동으로 소멸되고 다시 생성되며 initialize()가 다시 호출됩니다. 그러나 autoRenderTargetfalse 인 경우 뎁스 스텐실 버퍼 또는 추가 색상 버퍼와 관련하여 이를 관리하는 것은 애플리케이션의 몫입니다.

샘플 수를 기본값인 1에서 더 높은 값으로 변경하면 colorTexture()가 nullptr 이 되고 msaaColorBuffer()가 유효한 객체를 반환하기 시작합니다. 다시 1(또는 0)로 전환하면 그 반대의 의미로 initialize() 다음 호출에서 msaaColorBuffer()은 nullptr 를 반환하고 colorTexture()는 다시 유효하게 됩니다. 또한 resolveTexture()는 샘플 수가 1보다 클 때마다(즉, MSAA가 사용 중일 때) 유효한(다중 샘플이 아닌) QRhiTexture 을 반환합니다.

함수 액세스:

int sampleCount() const
void setSampleCount(int samples)

알림 신호:

void sampleCountChanged(int samples)

msaaColorBuffer() 및 resolveTexture()도 참조하세요 .

멤버 함수 문서

[explicit] QRhiWidget::QRhiWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {})

위젯 플래그가 f 으로 설정된 parent 의 자식인 위젯을 생성합니다.

[override virtual noexcept] QRhiWidget::~QRhiWidget()

파괴자.

QRhiWidget::Api QRhiWidget::api() const

현재 설정된 그래픽 API(QRhi 백엔드)를 반환합니다.

setApi()도 참조하세요 .

[protected] QRhiTexture *QRhiWidget::colorTexture() const

위젯의 컬러 버퍼 역할을 하는 텍스처를 반환합니다.

initialize() 및 render()에서만 호출해야 합니다.

뎁스 스텐실 버퍼 및 QRhiRenderTarget 와 달리 이 텍스처는 항상 사용 가능하며 autoRenderTarget 의 값과 관계없이 QRhiWidget 에서 관리합니다.

참고: sampleCount 이 1보다 커서 다중 샘플 앤티앨리어싱이 활성화된 경우 반환 값은 nullptr 입니다. 대신 msaaColorBuffer()를 호출하여 QRhiRenderBuffer 을 쿼리합니다.

참고: renderTarget()에서 반환된 QRhiRenderTarget 을 통해서도 백킹 텍스처 크기와 샘플 수를 쿼리할 수 있습니다. 이는 멀티샘플링 사용 여부와 관계없이 작동하므로 QRhiTexture 또는 QRhiRenderBuffer 에서 쿼리하는 것보다 더 편리하고 간결할 수 있습니다.

msaaColorBuffer(), depthStencilBuffer(), renderTarget() 및 resolveTexture()도 참조하세요 .

[protected] QRhiRenderBuffer *QRhiWidget::depthStencilBuffer() const

위젯의 렌더링에 사용되는 뎁스 스텐실 버퍼를 반환합니다.

initialize() 및 render()에서만 호출해야 합니다.

autoRenderTargettrue 일 때만 사용할 수 있습니다. 그렇지 않으면 반환되는 값은 nullptr 이며 initialize()를 다시 구현하여 깊이 스텐실 버퍼와 QRhiTextureRenderTarget 를 생성하고 관리해야 합니다.

colorTexture() 및 renderTarget()도 참조하세요 .

[override virtual protected] bool QRhiWidget::event(QEvent *e)

다시 구현합니다: QWidget::event(QEvent * 이벤트).

[signal] void QRhiWidget::frameSubmitted()

이 신호는 위젯의 최상위 창이 구성을 완료하고 submitted a frame.

QImage QRhiWidget::grabFramebuffer() const

새 프레임을 렌더링하고 텍스처의 내용을 다시 읽은 다음 QImage 로 반환합니다.

오류가 발생하면 null QImage 이 반환됩니다.

반환된 QImagecolorBufferFormat()에 따라 QImage::Format_RGBA8888, QImage::Format_RGBA16FPx4, QImage::Format_RGBA32FPx4 또는 QImage::Format_BGR30 의 형식을 갖습니다.

QRhiWidget 는 렌더러의 블렌딩 및 컴포지션 방식을 알지 못하므로 출력에 RGB 색상 값에 알파가 미리 곱해져 있는지 알 수 없습니다. 따라서 _Premultiplied QImage 형식은 적절한 경우에도 반환된 QImage 에 사용되지 않습니다. 결과 데이터를 적절하게 재해석하는 것은 호출자의 몫입니다.

참고: 이 함수는 화면 최상위 창에 속하는 위젯 계층 구조에 QRhiWidget 이 추가되지 않은 경우에도 호출할 수 있습니다. 이를 통해 화면 밖에서 3D 렌더링에서 이미지를 생성할 수 있습니다.

이 함수는 QOpenGLWidgetQQuickWidget 과의 일관성을 위해 grabFramebuffer()로 명명되었습니다. QRhiWidget 의 콘텐츠에서 CPU 측 이미지 데이터를 가져오는 유일한 방법은 아닙니다. QRhiWidget 또는 그 조상에서 QWidget::grab()를 호출하는 것도 작동합니다( QPixmap 반환). QImage 로 직접 작업하는 것 외에도 grabFramebuffer()의 또 다른 장점은 나머지 QWidget 인프라를 거칠 필요 없이 바로 새 프레임 렌더링을 트리거한 다음 읽기백을 수행할 수 있기 때문에 성능이 약간 더 좋을 수 있다는 것입니다.

setColorBufferFormat()도 참조하세요 .

[virtual protected] void QRhiWidget::initialize(QRhiCommandBuffer *cb)

위젯이 처음 초기화될 때, 연결된 텍스처의 크기, 형식 또는 샘플 수가 변경될 때, 또는 QRhi 및 텍스처가 어떤 이유로든 변경될 때 호출됩니다. 이 함수는 render()의 렌더링 코드에서 사용하는 그래픽 리소스를 유지(아직 생성되지 않은 경우 생성, 크기가 변경된 경우 조정 및 다시 빌드)해야 합니다.

QRhi, QRhiTexture, 기타 관련 객체를 쿼리하려면 rhi(), colorTexture(), depthStencilBuffer(), renderTarget()를 호출하세요.

위젯 크기가 변경되면 QRhi 객체, 색상 버퍼 텍스처 및 깊이 스텐실 버퍼 객체는 모두 이전과 동일한 인스턴스(따라서 게터는 동일한 포인터를 반환)이지만 색상 및 깊이/스텐실 버퍼는 다시 빌드되었을 가능성이 있으므로 size 및 기본 네이티브 텍스처 리소스가 마지막 호출 때와 다를 수 있습니다.

또한 이 함수를 호출할 때마다 QRhi 객체와 컬러 버퍼 텍스처가 변경될 수 있으므로 재구현을 준비해야 합니다. 객체가 달라지는 한 가지 특별한 경우는 아직 표시되지 않은 위젯으로 grabFramebuffer()를 수행한 다음 최상위 위젯 내에서 위젯을 화면에 표시하는 경우입니다. 이 경우 전용 QRhi 으로 그랩이 이루어지며, 이후 초기화() 및 render() 호출에서 최상위 창에 연결된 QRhi 으로 대체됩니다. 또 다른 일반적인 경우는 위젯이 새로운 최상위 창에 속하도록 부모를 다시 지정하는 경우입니다. 이 경우 QRhiQRhiWidget 에서 관리하는 모든 관련 리소스는 이후 이 함수를 호출할 때 이전과 다른 인스턴스가 됩니다. 그러면 이전에 하위 클래스에 의해 생성된 모든 기존 QRhi 리소스는 더 이상 위젯에서 사용해서는 안 되는 이전 QRhi 에 속하기 때문에 파괴됩니다.

autoRenderTarget 가 기본값인 true 인 경우, colorTexture() (또는 msaaColorBuffer()) 및 깊이 스텐실 버퍼와 연결된 QRhiRenderBufferQRhiTextureRenderTarget 가 자동으로 생성되고 관리됩니다. 초기화() 및 render()의 재구현은 depthStencilBuffer() 및 renderTarget()를 통해 해당 객체를 쿼리할 수 있습니다. autoRenderTargetfalse 로 설정되면 이러한 객체는 더 이상 자동으로 생성 및 관리되지 않습니다. 대신 초기화() 구현에서 버퍼를 생성하고 렌더링 대상을 적절하게 설정해야 합니다. 렌더링 대상에 대한 추가 색상 또는 깊이 스텐실 첨부 파일을 수동으로 관리할 때 크기와 샘플 수는 항상 colorTexture() / msaaColorBuffer()의 크기와 샘플 수를 따라야 하며, 그렇지 않으면 렌더링 또는 3D API 유효성 검사 오류가 발생할 수 있습니다.

서브클래스에서 생성된 그래픽 리소스는 서브클래스의 디스트럭터 구현에서 해제될 것으로 예상됩니다.

cb 는 위젯의 현재 프레임에 대한 QRhiCommandBuffer 입니다. 이 함수는 프레임이 기록되고 있지만 활성 렌더 패스가 없는 상태에서 호출됩니다. 명령 버퍼는 주로 render()로 지연시키지 않고 resource updates 을 큐에 넣을 수 있도록 하기 위해 제공됩니다.

render()도 참조하세요 .

bool QRhiWidget::isDebugLayerEnabled() const

사용 중인 그래픽 API에 해당되는 경우 디버그 또는 유효성 검사 레이어가 요청될 경우 true를 반환합니다.

setDebugLayerEnabled()도 참조하세요 .

[protected] QRhiRenderBuffer *QRhiWidget::msaaColorBuffer() const

위젯의 멀티샘플 컬러 버퍼 역할을 하는 렌더버퍼를 반환합니다.

initialize() 및 render()에서만 호출해야 합니다.

sampleCount 이 1보다 커서 멀티샘플 안티앨리어싱이 활성화된 경우 반환된 QRhiRenderBuffer 은 샘플 수가 일치하며 컬러 버퍼로 사용됩니다. 이 버퍼로 렌더링하는 데 사용되는 그래픽 파이프라인은 동일한 샘플 수로 생성되어야 하며 깊이 스텐실 버퍼의 샘플 수 역시 일치해야 합니다. 멀티 샘플 콘텐츠는 resolveTexture()에서 반환된 텍스처로 해석될 것으로 예상됩니다. autoRenderTargettrue 인 경우 renderTarget()는 이를 위해 자동으로 설정되며, msaaColorBuffer()를 색상 첨부 0의 renderbuffer 로 설정하고 resolveTexture()를 해당 resolveTexture 로 설정합니다.

MSAA를 사용하지 않는 경우 반환 값은 nullptr 입니다. 대신 colorTexture()를 사용하십시오.

기본 3D 그래픽 API에 따라 샘플 수가 1보다 큰 멀티샘플 텍스처와 컬러 렌더버퍼 간에 실질적인 차이가 없을 수 있습니다(QRhi 는 둘 다 동일한 기본 리소스 유형에 매핑할 수 있습니다). 그러나 일부 구형 API는 텍스처와 렌더버퍼를 구분할 수 있습니다. 멀티샘플 렌더버퍼는 사용할 수 있지만 멀티샘플 텍스처는 사용할 수 없는 OpenGL ES 3.0을 지원하기 위해 QRhiWidget 에서는 항상 멀티샘플 QRhiRenderBuffer 을 색상 어태치먼트로 사용하여 MSAA를 수행합니다(멀티샘플 QRhiTexture 은 사용하지 않음).

참고: 백킹 텍스처 크기와 샘플 수는 renderTarget()에서 반환된 QRhiRenderTarget 을 통해서도 쿼리할 수 있습니다. 이는 멀티샘플링 사용 여부와 관계없이 작동하므로 QRhiTexture 또는 QRhiRenderBuffer 에서 쿼리하는 것보다 더 편리하고 간결할 수 있습니다.

colorTexture(), depthStencilBuffer(), renderTarget() 및 resolveTexture()도 참조하세요 .

[override virtual protected] void QRhiWidget::paintEvent(QPaintEvent *e)

다시 구현합니다: QWidget::paintEvent(QPaintEvent * 이벤트).

페인트 이벤트를 처리합니다.

QWidget::update()를 호출하면 페인트 이벤트 e 를 전송하여 이 함수를 호출합니다. 이벤트 전송은 비동기식이며 update()에서 반환된 후 어느 시점에 발생합니다. 그러면 이 함수는 약간의 준비 과정을 거쳐 가상 render()를 호출하여 QRhiWidget 의 연관된 텍스처의 내용을 업데이트합니다. 그러면 위젯의 최상위 창이 텍스처를 나머지 창과 합성합니다.

[virtual protected] void QRhiWidget::releaseResources()

그래픽 리소스를 조기 릴리스해야 할 필요가 있을 때 호출됩니다.

일반적으로 최상위 위젯의 하위 계층 구조에 추가되어 해당 위젯과 최상위 위젯의 나머지 수명 기간 동안 유지되는 QRhiWidget 에는 이런 일이 발생하지 않습니다. 따라서 애플리케이션에 최상위 위젯(기본 창)이 하나만 있는 경우 등 많은 경우 이 기능을 다시 구현할 필요가 없습니다. 그러나 위젯(또는 위젯의 조상)의 리패런팅이 필요한 경우, 견고하고 잘 작성된 QRhiWidget 서브클래스에서 이 함수를 다시 구현해야 합니다.

이 함수가 호출되면 구현은 모든 QRhi 리소스(QRhiBuffer, QRhiTexture 등 객체)를 소멸자에서 예상되는 방식과 유사하게 소멸할 것으로 예상됩니다. 결국 initialize()가 나중에 호출될 것이므로 널링 아웃, 스마트 포인터 사용 또는 resources-invalid 플래그 설정도 필요합니다. 그러나 리소스 릴리스를 후속 initialize()로 연기하는 것은 잘못된 방법입니다. 이 함수가 호출되면 리소스가 반환되기 전에 삭제되어야 합니다. 또한 이 함수를 구현해도 클래스 소멸자(또는 스마트 포인터)가 대체되지 않으므로 그래픽 리소스는 여전히 둘 다에서 해제되어야 합니다.

실제 예제는 큐브 RHI 위젯 예제를 참조하세요. 여기서 QRhiWidget 을 자식 위젯(부모 위젯이 있기 때문에)과 최상위 위젯(부모 위젯이 없기 때문에)으로 전환하는 버튼은 QRhiWidget 의 수명 동안 연결된 최상위 위젯, 기본 창 및 QRhi 이 모두 변경되고 이전에 사용된 QRhi 이 소멸되므로 아직 살아있는 QRhiWidget 에서 관리하는 관련 리소스가 조기 해제되므로 이 함수 호출을 트리거합니다 .

이 함수가 호출되는 또 다른 경우는 grabFramebuffer()가 보이는 창에 추가되지 않은 QRhiWidget 과 함께 사용되는 경우, 즉 렌더링이 화면 밖에서 수행되는 경우입니다. 나중에 QRhiWidget 이 표시되거나 표시되는 위젯 계층 구조에 추가되면 관련 QRhi 이 화면 밖 렌더링에 사용되는 임시에서 창 전용으로 변경되어 이 함수도 트리거됩니다.

initialize()도 참조하세요 .

[virtual protected] void QRhiWidget::render(QRhiCommandBuffer *cb)

위젯 콘텐츠(즉, 텍스처의 콘텐츠)를 업데이트해야 할 때 호출됩니다.

이 함수가 호출되기 전에 항상 initialize()를 한 번 이상 호출합니다.

업데이트를 요청하려면 QWidget::update()를 호출합니다. render() 내에서 update()를 호출하면 vsync에 의해 스로틀링되어 지속적으로 업데이트됩니다.

cb 는 위젯의 현재 프레임에 대한 QRhiCommandBuffer 입니다. 이 함수는 프레임이 기록되고 있지만 활성 렌더 패스가 없는 상태에서 호출됩니다.

initialize()도 참조하세요 .

[signal] void QRhiWidget::renderFailed()

이 신호는 위젯이 백그라운드 텍스처로 렌더링해야 하는데( widget update 또는 grabFramebuffer() 호출로 인해) 그래픽 구성과 관련된 문제로 인해 위젯이 사용할 QRhi 이 없을 때마다 발생합니다.

이 신호는 문제가 발생할 때 여러 번 발생할 수 있습니다. 한 번만 발생한다고 가정하지 마세요. 오류 처리 코드가 한 번만 알림을 받으려면 Qt::SingleShotConnection 에 연결하세요.

[protected] QRhiRenderTarget *QRhiWidget::renderTarget() const

render()의 재구현에서 QRhiCommandBuffer::beginPass()와 함께 사용해야 하는 렌더링 대상 객체를 반환합니다.

initialize() 및 render()에서만 호출해야 합니다.

autoRenderTargettrue 일 때만 사용할 수 있습니다. 그렇지 않으면 반환되는 값은 nullptr 이며 initialize()의 재구현에 따라 깊이 스텐실 버퍼와 QRhiTextureRenderTarget 를 생성하고 관리합니다.

graphics pipelines 을 생성할 때는 QRhiRenderPassDescriptor 이 필요합니다. 반환된 QRhiTextureRenderTarget 에서 renderPassDescriptor()을 호출하여 쿼리할 수 있습니다.

colorTexture() 및 depthStencilBuffer()도 참조하세요 .

[override virtual protected] void QRhiWidget::resizeEvent(QResizeEvent *e)

다시 구현합니다: QWidget::resizeEvent(QResizeEvent * 이벤트).

e 이벤트 매개변수로 전달된 크기 조정 이벤트를 처리합니다. 가상 함수 initialize()를 호출합니다.

참고: 파생 클래스에서 이 함수를 재정의하지 마세요. 이것이 가능하지 않은 경우 QRhiWidget 의 구현도 호출되는지 확인하세요. 그렇지 않으면 기본 텍스처 객체 및 관련 리소스의 크기가 제대로 조정되지 않아 렌더링이 잘못될 수 있습니다.

[protected] QRhiTexture *QRhiWidget::resolveTexture() const

멀티샘플 콘텐츠가 해결되는 비멀티샘플 텍스처를 반환합니다.

멀티샘플 앤티앨리어싱이 활성화되지 않은 경우 결과는 nullptr 입니다.

initialize() 및 render()에서만 호출해야 합니다.

MSAA가 활성화된 경우 이 텍스처가 화면의 나머지 QWidget 콘텐츠와 합성됩니다. 그러나 QRhiWidget 의 렌더링은 msaaColorBuffer()에서 반환된 (멀티샘플) QRhiRenderBuffer 을 대상으로 해야 합니다. autoRenderTargettrue 인 경우 이는 renderTarget()에서 반환된 QRhiRenderTarget 에 의해 처리됩니다. 그렇지 않으면 서브클래스 코드가 컬러 버퍼와 리졸브 텍스처를 모두 사용하여 렌더링 대상 객체를 올바르게 구성해야 합니다.

colorTexture()도 참조하세요 .

[protected] QRhi *QRhiWidget::rhi() const

현재 QRhi 객체를 반환합니다.

initialize() 및 render()에서만 호출해야 합니다.

void QRhiWidget::setApi(QRhiWidget::Api api)

사용할 그래픽 API 및 QRhi 백엔드를 api 으로 설정합니다.

경고: 이 함수는 위젯이 위젯 계층 구조에 추가되어 화면에 표시되기 전에 충분히 일찍 호출되어야 합니다. 예를 들어 하위 클래스 생성자 함수를 호출하는 것을 목표로 하세요. 너무 늦게 호출하면 함수가 효과가 없습니다.

기본값은 플랫폼에 따라 다릅니다: macOS 및 iOS의 경우 Metal, Windows의 경우 Direct 3D 11, 그 외의 경우 OpenGL입니다.

api 은 위젯과 그 최상위 창에 대해 한 번만 설정할 수 있으며, 설정이 완료되고 적용되면 창은 해당 API와 QRhi 백엔드만 사용하여 렌더링할 수 있습니다. 다른 값을 설정하거나 다른 api 을 사용하여 QRhiWidget 을 추가하려고 시도하면 예상대로 작동하지 않습니다.

setColorBufferFormat(), setDebugLayerEnabled() 및 api()도 참조하세요 .

[protected] void QRhiWidget::setAutoRenderTarget(bool enabled)

위젯에서 깊이 스텐실 QRhiRenderBufferQRhiTextureRenderTarget 을 자동으로 생성하고 유지 관리할지 여부를 제어합니다. 기본값은 true 입니다.

자동 모드에서는 뎁스 스텐실 버퍼의 크기와 샘플 수가 컬러 버퍼 텍스처의 설정을 따릅니다. 비자동 모드에서 renderTarget() 및 depthStencilBuffer()은 항상 nullptr 을 반환하며, 이러한 객체를 설정하고 관리하는 것은 애플리케이션의 initialize() 구현에 달려 있습니다.

자동 모드를 비활성화하려면 파생 클래스의 생성자 등에서 enabledfalse 으로 설정한 상태에서 이 함수를 호출하세요.

void QRhiWidget::setDebugLayerEnabled(bool enable)

enable 이 참이면 기본 그래픽 API의 디버그 또는 유효성 검사 계층을 요청합니다.

경고: 이 함수는 위젯이 위젯 계층 구조에 추가되어 화면에 표시되기 전에 충분히 일찍 호출해야 합니다. 예를 들어 하위 클래스 생성자 함수를 호출하는 것을 목표로 하세요. 너무 늦게 호출하면 함수가 효과가 없습니다.

벌칸 및 다이렉트 3D에 적용됩니다.

기본적으로 이 기능은 비활성화되어 있습니다.

setApi() 및 isDebugLayerEnabled()도 참조하세요 .

© 2025 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.