이 페이지에서

QOpenGLWidget Class

QOpenGLWidget 클래스는 OpenGL 그래픽을 렌더링하기 위한 위젯입니다. 더 보기...

헤더: #include <qopenglwidget.h>
CMake: find_package(Qt6 REQUIRED COMPONENTS OpenGLWidgets)
target_link_libraries(mytarget PRIVATE Qt6::OpenGLWidgets)
qmake: QT += openglwidgets
상속: QWidget

공개 유형

(since 6.5) enum TargetBuffer { LeftBuffer, RightBuffer }
enum UpdateBehavior { NoPartialUpdate, PartialUpdate }

공개 함수

QOpenGLWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags())
virtual ~QOpenGLWidget()
QOpenGLContext *context() const
(since 6.5) QOpenGLWidget::TargetBuffer currentTargetBuffer() const
GLuint defaultFramebufferObject() const
(since 6.5) GLuint defaultFramebufferObject(QOpenGLWidget::TargetBuffer targetBuffer) const
void doneCurrent()
QSurfaceFormat format() const
QImage grabFramebuffer()
(since 6.5) QImage grabFramebuffer(QOpenGLWidget::TargetBuffer targetBuffer)
bool isValid() const
void makeCurrent()
(since 6.5) void makeCurrent(QOpenGLWidget::TargetBuffer targetBuffer)
void setFormat(const QSurfaceFormat &format)
void setTextureFormat(GLenum texFormat)
void setUpdateBehavior(QOpenGLWidget::UpdateBehavior updateBehavior)
GLenum textureFormat() const
QOpenGLWidget::UpdateBehavior updateBehavior() const

신호

void aboutToCompose()
void aboutToResize()
void frameSwapped()
void resized()

보호된 함수

virtual void initializeGL()
virtual void paintGL()
virtual void resizeGL(int w, int h)

재구현된 보호 함수

virtual bool event(QEvent *e) override
virtual int metric(QPaintDevice::PaintDeviceMetric metric) const override
virtual QPaintEngine *paintEngine() const override
virtual void paintEvent(QPaintEvent *e) override
virtual QPaintDevice *redirected(QPoint *p) const override
virtual void resizeEvent(QResizeEvent *e) override

상세 설명

Qt OpenGLWidget은 Qt 애플리케이션에 통합된 OpenGL 그래픽을 표시하는 기능을 제공합니다. 사용법은 매우 간단합니다. 클래스를 이 클래스에서 상속받게 한 다음, 다른 QWidget 와 마찬가지로 하위 클래스를 사용하면 됩니다. 단, QPainter 와 표준 OpenGL 렌더링 명령어 중 하나를 선택할 수 있다는 점이 다릅니다.

QOpenGLWidget은 일반적인 OpenGL 작업을 수행하기 위해 하위 클래스에서 재구현할 수 있는 세 가지 편리한 가상 함수를 제공합니다:

  • paintGL() - OpenGL 장면을 렌더링합니다. 위젯을 업데이트해야 할 때마다 호출됩니다.
  • resizeGL() - OpenGL 뷰포트, 투영 설정 등을 설정합니다. 위젯의 크기가 조정될 때마다 호출되며(또한 새로 생성된 모든 위젯은 자동으로 크기 조정 이벤트를 받기 때문에 처음 표시될 때도 호출됩니다).
  • initializeGL() - OpenGL 리소스와 상태를 설정합니다. resizeGL() 또는 paintGL()이 처음 호출되기 전에 한 번 호출됩니다.

paintGL() 이외의 곳에서 다시 그리기를 트리거해야 하는 경우(전형적인 예로는 timers 를 사용하여 장면을 애니메이션화할 때), 위젯의 update() 함수를 호출하여 업데이트를 예약해야 합니다.

paintGL(), resizeGL() 또는 initializeGL()이 호출되면 위젯의 OpenGL 렌더링 컨텍스트가 현재 컨텍스트로 설정됩니다. 다른 곳(예: 위젯의 생성자나 사용자 정의 페인트 함수 내)에서 표준 OpenGL API 함수를 호출해야 하는 경우, 먼저 makeCurrent()을 호출해야 합니다.

모든 렌더링은 OpenGL 프레임버퍼 객체에서 이루어집니다. ` makeCurrent()`는 해당 객체가 컨텍스트에 바인딩되도록 보장합니다. ` paintGL()`의 렌더링 코드에서 추가 프레임버퍼 객체를 생성하고 바인딩할 때 이 점을 유의하십시오. ID가 0인 프레임버퍼를 절대 다시 바인딩하지 마십시오. 대신 ` defaultFramebufferObject()`를 호출하여 바인딩해야 할 ID를 얻으십시오.

QOpenGLWidget은 플랫폼이 지원하는 경우 서로 다른 OpenGL 버전 및 프로필을 사용할 수 있도록 합니다. setFormat()을 통해 요청된 포맷을 설정하기만 하면 됩니다. 단, 동일한 창에 여러 개의 QOpenGLWidget 인스턴스가 있는 경우, 모든 인스턴스가 동일한 포맷을 사용해야 하거나, 최소한 컨텍스트를 공유할 수 없게 만들지 않는 포맷을 사용해야 한다는 점을 유의하십시오. 이 문제를 해결하려면 setFormat() 대신 QSurfaceFormat::setDefaultFormat()을 사용하는 것이 좋습니다.

참고: OpenGL 코어 프로파일 컨텍스트가 요청되는 경우, 일부 플랫폼(예: macOS)에서는 QApplication 인스턴스를 생성하기 전에 QSurfaceFormat::setDefaultFormat()을 호출해야 합니다. 이는 모든 내부 컨텍스트가 올바른 버전과 프로파일을 사용하여 생성되도록 하여, 컨텍스트 간의 리소스 공유 기능이 정상적으로 유지되도록 하기 위함입니다.

렌더링 기법

위에서 설명한 바와 같이, 다음과 같은 방식으로 QOpenGLWidget을 상속하여 순수 3D 콘텐츠를 렌더링하십시오:

  • initializeGL() 및 resizeGL() 함수를 재구현하여 OpenGL 상태를 설정하고 원근 변환을 적용하십시오.
  • paintGL()을 재구현하여 오직 OpenGL 함수만을 호출함으로써 3D 장면을 렌더링하십시오.

또한 QPainter 를 사용하여 QOpenGLWidget 서브클래스에 2D 그래픽을 그릴 수도 있습니다:

  • paintGL()에서 OpenGL 명령을 내리는 대신, 위젯에서 사용할 QPainter 객체를 생성하십시오.
  • QPainter 의 멤버 함수를 사용하여 프리미티브를 그립니다.
  • 직접 OpenGL 명령을 내리는 것도 여전히 가능합니다. 다만, 이러한 명령은 반드시 painter의 beginNativePainting() 및 endNativePainting() 호출 범위 내에 포함되어야 합니다.

QPainter 만을 사용하여 그리기를 수행할 때, 일반 위젯에서와 마찬가지로 paintEvent()을 재구현하여 페인팅을 수행할 수도 있습니다.

  • paintEvent() 함수를 재구현합니다.
  • 위젯을 대상으로 하는 QPainter 객체를 생성하십시오. 생성자에 위젯을 전달하거나 QPainter::begin() 함수를 호출하십시오.
  • QPainter 의 멤버 함수를 사용하여 프리미티브를 그립니다.
  • 그리기 작업이 완료되면 QPainter 인스턴스가 소멸됩니다. 또는 QPainter::end() 함수를 명시적으로 호출할 수도 있습니다.

OpenGL 함수 호출, 헤더 및 QOpenGLFunctions

OpenGL 함수를 호출할 때는 함수를 직접 호출하지 않는 것이 강력히 권장됩니다. 대신, (이식 가능한 애플리케이션을 제작할 때는) QOpenGLFunctions 를 사용하거나, (최신 데스크톱 전용 OpenGL을 대상으로 할 때는 QOpenGLFunctions_3_2_Core 및 이와 유사한 버전 지정 변형 함수를 사용하는 것이 좋습니다). 이렇게 하면 동적 OpenGL 구현 로딩을 수행하는 구성을 포함하여 모든 Qt 빌드 구성에서 애플리케이션이 올바르게 작동합니다. 즉, 애플리케이션이 GL 구현에 직접 링크되지 않으므로 직접적인 함수 호출은 불가능합니다.

paintGL()에서는 QOpenGLContext::currentContext()를 호출하여 항상 현재 컨텍스트에 접근할 수 있습니다. 이 컨텍스트에서 QOpenGLContext::functions()를 호출하여 이미 초기화되어 사용 준비가 된 QOpenGLFunctions 인스턴스를 가져올 수 있습니다. 모든 GL 호출 앞에 접두사를 붙이는 대신, QOpenGLFunctions 을 상속받고 initializeGL()에서 QOpenGLFunctions::initializeOpenGLFunctions()를 호출하는 방법도 있습니다.

OpenGL 헤더의 경우, 대부분의 경우 GL.h와 같은 헤더를 직접 포함할 필요가 없다는 점에 유의하십시오. Qt OpenGL 헤더는 qopengl.h를 포함하며, qopengl.h는 다시 해당 시스템에 적합한 헤더를 포함합니다. 이는 OpenGL ES 3.x 또는 2.0 헤더, 사용 가능한 최신 버전, 혹은 시스템에서 제공하는 gl.h일 수 있습니다. 또한, OpenGL 및 OpenGL ES 모두에 대해 확장 헤더(일부 시스템에서는 glext.h라고 함)의 사본이 Qt의 일부로 제공됩니다. 이러한 헤더는 가능한 플랫폼에서 자동으로 포함됩니다. 즉, ARB, EXT, OES 확장 기능의 상수 및 함수 포인터 typedef를 자동으로 사용할 수 있습니다.

코드 예제

시작하기 위해, 가장 간단한 QOpenGLWidget 서브클래스는 다음과 같을 수 있습니다:

class MyGLWidget : public QOpenGLWidget
{
public:
    MyGLWidget(QWidget *parent) : QOpenGLWidget(parent) { }

protected:
    void initializeGL() override
    {
        // Set up the rendering context, load shaders and other resources, etc.:
        QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
        f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        ...
    }

    void resizeGL(int w, int h) override
    {
        // Update projection matrix and other size related settings:
        m_projection.setToIdentity();
        m_projection.perspective(45.0f, w / float(h), 0.01f, 100.0f);
        ...
    }

    void paintGL() override
    {
        // Draw the scene:
        QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
        f->glClear(GL_COLOR_BUFFER_BIT);
        ...
    }

};

또는, QOpenGLFunctions 을 상속받음으로써 모든 OpenGL 호출에 접두사를 붙이는 과정을 생략할 수 있습니다:

class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    ...
    void initializeGL() override
    {
        initializeOpenGLFunctions();
        glClearColor(...);
        ...
    }
    ...
};

특정 OpenGL 버전이나 프로필과 호환되는 컨텍스트를 얻거나, 뎁스 및 스텐실 버퍼를 요청하려면 setFormat()를 호출하십시오:

QOpenGLWidget *widget = new QOpenGLWidget(parent);
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setVersion(3, 2);
format.setProfile(QSurfaceFormat::CoreProfile);
widget->setFormat(format); // must be called before the widget or its parent window gets shown

참고: 기본 윈도우 시스템 인터페이스에서 깊이 버퍼와 스텐실 버퍼를 요청하는것은 애플리케이션의책임입니다 . 0이 아닌 깊이 버퍼 크기를 요청하지 않으면 깊이 버퍼를 사용할 수 있다는 보장이 없으며, 그 결과 깊이 테스트와 관련된 OpenGL 작업이 예상대로 작동하지 않을 수 있습니다. 일반적으로 사용되는 깊이 버퍼 및 스텐실 버퍼 크기 요청 값은 각각 24와 8입니다.

OpenGL 3.0 이상 컨텍스트에서 이식성이 중요하지 않은 경우, 버전이 지정된 ` QOpenGLFunctions ` 변형을 사용하면 주어진 버전에서 사용할 수 있는 모든 최신 OpenGL 함수에 쉽게 접근할 수 있습니다:

    ...
    void paintGL() override
    {
        QOpenGLFunctions_3_2_Core *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>();
        ...
        f->glDrawArraysInstanced(...);
        ...
    }
    ...

앞서 설명한 바와 같이, 요청된 형식을 전역적으로 설정하여 애플리케이션의 수명 주기 동안 모든 창과 컨텍스트에 적용되도록 하는 것이 더 간단하고 안정적입니다. 다음은 이에 대한 예시입니다:

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    QSurfaceFormat format;
    format.setDepthBufferSize(24);
    format.setStencilBufferSize(8);
    format.setVersion(3, 2);
    format.setProfile(QSurfaceFormat::CoreProfile);
    QSurfaceFormat::setDefaultFormat(format);

    MyWidget widget;
    widget.show();

    return app.exec();
}

멀티샘플링

멀티샘플링을 활성화하려면, ` setFormat()`에 전달되는 ` QSurfaceFormat `에서 요청되는 샘플 수를 설정하십시오. 이를 지원하지 않는 시스템에서는 해당 요청이 무시될 수 있습니다.

멀티샘플링을 지원하려면 멀티샘플링된 렌더 버퍼와 프레임버퍼 블릿이 지원되어야 합니다. OpenGL ES 2.0 구현 환경에서는 이러한 기능이 제공되지 않을 가능성이 높습니다. 즉, 멀티샘플링을 사용할 수 없습니다. 최신 OpenGL 버전과 OpenGL ES 3.0 이상에서는 일반적으로 더 이상 문제가 되지 않습니다.

스레딩

예를 들어, paintGL()에서 GUI/메인 스레드에서 사용되는 텍스처를 생성하기 위해 워커 스레드에서 오프스크린 렌더링을 수행하는 것은, 위젯의 QOpenGLContext 를 노출하여 각 스레드에서 이를 공유하는 추가 컨텍스트를 생성할 수 있도록 함으로써 지원됩니다.

paintEvent()을 아무 작업도 수행하지 않도록 재구현하면, GUI/메인 스레드 외부에서 QOpenGLWidget의 프레임버퍼에 직접 그리기가 가능합니다. 컨텍스트의 스레드 어피니티는 QObject::moveToThread()를 통해 변경해야 합니다. 그 후, 작업자 스레드에서 makeCurrent() 및 doneCurrent()를 사용할 수 있습니다. 이후에는 컨텍스트를 다시 GUI/메인 스레드로 되돌리는 데 주의해야 합니다.

QOpenGLWidget만을 위해 버퍼 스왑을 트리거하는 것은 불가능합니다. 이 위젯에는 화면에 표시되는 실제 네이티브 서페이스가 없기 때문입니다. GUI 스레드에서의 합성 및 버퍼 스왑 관리는 위젯 스택의 몫입니다. 스레드가 프레임버퍼 업데이트를 완료하면, GUI/메인 스레드에서 update()를 호출하여 합성을 스케줄링해야 합니다.

GUI/메인 스레드가 합성 작업을 수행 중일 때는 프레임버퍼 사용을 피하기 위해 각별한 주의를 기울여야 합니다. 합성이 시작되고 끝날 때 aboutToCompose() 및 frameSwapped() 신호가 발생합니다. 이 신호들은 GUI/메인 스레드에서 발생합니다. 즉, 직접 연결( aboutToCompose())을 사용할 경우, 작업자 스레드가 렌더링을 완료할 때까지 GUI/메인 스레드가 차단될 수 있습니다. 그 후, 작업자 스레드는 frameSwapped() 신호가 발송될 때까지 더 이상 렌더링을 수행해서는 안 됩니다. 이것이 용납될 수 없는 경우, 워커 스레드는 더블 버퍼링 메커니즘을 구현해야 합니다. 여기에는 스레드가 완전히 제어하는 대체 렌더 타깃(예: 추가 프레임버퍼 객체)을 사용하여 그리기를 수행하고, 적절한 시점에 QOpenGLWidget의 프레임버퍼로 블리팅하는 과정이 포함됩니다.

컨텍스트 공유

여러 QOpenGLWidget이 동일한 최상위 위젯의 자식 요소로 추가되면, 이들의 컨텍스트는 서로 공유됩니다. 이는 서로 다른 창에 속한 QOpenGLWidget 인스턴스에는 적용되지 않습니다.

즉, 동일한 창에 있는 모든 QOpenGLWidget은 텍스처와 같은 공유 가능한 리소스에 서로 접근할 수 있으며, 별도의 "글로벌 공유" 컨텍스트가 필요하지 않습니다.

서로 다른 창에 속한 QOpenGLWidget 인스턴스 간에 공유를 설정하려면, QApplication 를 인스턴스화하기 전에 Qt::AA_ShareOpenGLContexts 애플리케이션 속성을 설정하십시오. 이렇게 하면 별도의 단계 없이 모든 QOpenGLWidget 인스턴스 간에 공유가 활성화됩니다.

QOpenGLWidget의 컨텍스트와 텍스처 같은 리소스를 공유하는 추가적인 ` QOpenGLContext ` 인스턴스를 생성하는 것도 가능합니다. ` context()`에서 반환된 포인터를 ` QOpenGLContext::setShareContext()`에 전달한 후 ` QOpenGLContext::create()`를 호출하기만 하면 됩니다. 이렇게 생성된 컨텍스트는 다른 스레드에서도 사용할 수 있으므로, 스레드 기반의 텍스처 생성 및 비동기 텍스처 업로드가 가능합니다.

QOpenGLWidget은 기본 그래픽 드라이버와 관련하여 표준을 준수하는 리소스 공유 구현을 기대한다는 점에 유의하십시오. 예를 들어, 특히 모바일 및 임베디드 하드웨어용 일부 드라이버의 경우, 기존 컨텍스트와 나중에 생성된 다른 컨텍스트 간의 공유 설정에 문제가 있을 수 있습니다. 다른 일부 드라이버는 서로 다른 스레드 간에 공유 리소스를 활용하려고 할 때 예상치 못한 방식으로 동작할 수도 있습니다.

리소스 초기화 및 정리

initializeGL() 및 paintGL()이 호출될 때마다 QOpenGLWidget에 연결된 OpenGL 컨텍스트는 반드시 최신 상태임을 보장합니다. initializeGL()이 호출되기 전에 OpenGL 리소스를 생성하려고 시도하지 마십시오. 예를 들어, 서브클래스의 생성자에서 셰이더를 컴파일하거나, 버텍스 버퍼 객체를 초기화하거나, 텍스처 데이터를 업로드하려고 시도하면 실패합니다. 이러한 작업은 initializeGL()로 연기되어야 합니다. QOpenGLBuffer 이나 QOpenGLVertexArrayObject 와 같은 Qt의 일부 OpenGL 헬퍼 클래스는 이에 상응하는 연기된 동작을 가집니다. 즉, 컨텍스트 없이 인스턴스화할 수 있지만, 모든 초기화는 create() 또는 이와 유사한 함수가 호출될 때까지 연기됩니다. 이는 이러한 클래스들이 QOpenGLWidget 하위 클래스에서 일반적인(포인터가 아닌) 멤버 변수로 사용될 수 있지만, create()이나 이와 유사한 함수는 initializeGL()에서만 호출될 수 있음을 의미합니다. 그러나 모든 클래스가 이와 같이 설계된 것은 아니라는 점에 유의하십시오. 확실하지 않은 경우에는 멤버 변수를 포인터로 선언하고, initializeGL()에서 인스턴스를 동적으로 생성하고, 소멸자에서 동적으로 소멸시키십시오.

리소스를 해제할 때도 컨텍스트가 현재 상태여야 합니다. 따라서 이러한 정리 작업을 수행하는 소멸자는 OpenGL 리소스나 래퍼를 파괴하기 전에 makeCurrent()를 호출해야 합니다. deleteLater()를 통한 지연 삭제나 QObject 의 부모-자식 메커니즘은 피하십시오. 해당 인스턴스가 실제로 파괴될 시점에 올바른 컨텍스트가 현재 상태로 유지될 것이라는 보장은 없습니다.

따라서 일반적인 하위 클래스는 리소스 초기화 및 소멸과 관련하여 다음과 같은 형태를 띠는 경우가 많습니다:

class MyGLWidget : public QOpenGLWidget
{
    ...

private:
    QOpenGLVertexArrayObject m_vao;
    QOpenGLBuffer m_vbo;
    QOpenGLShaderProgram *m_program;
    QOpenGLShader *m_shader;
    QOpenGLTexture *m_texture;
};

MyGLWidget::MyGLWidget()
    : m_program(0), m_shader(0), m_texture(0)
{
    // No OpenGL resource initialization is done here.
}

MyGLWidget::~MyGLWidget()
{
    // Make sure the context is current and then explicitly
    // destroy all underlying OpenGL resources.
    makeCurrent();

    delete m_texture;
    delete m_shader;
    delete m_program;

    m_vbo.destroy();
    m_vao.destroy();

    doneCurrent();
}

void MyGLWidget::initializeGL()
{
    m_vao.create();
    if (m_vao.isCreated())
        m_vao.bind();

    m_vbo.create();
    m_vbo.bind();
    m_vbo.allocate(...);

    m_texture = new QOpenGLTexture(QImage(...));

    m_shader = new QOpenGLShader(...);
    m_program = new QOpenGLShaderProgram(...);

    ...
}

이 방법은 대부분의 경우 작동하지만, 범용적인 해결책으로는 완전히 이상적이지 않습니다. 위젯이 부모 변경을 통해 완전히 다른 최상위 창에 배치될 때는 추가 조치가 필요합니다. QOpenGLContext 의 aboutToBeDestroyed() 신호에 연결하면, OpenGL 컨텍스트가 해제되기 직전에 정리 작업을 수행할 수 있습니다.

참고: 수명 주기 동안 연관된 최상위 창을 여러 번 변경하는 위젯의 경우 , 아래 코드 예제에서 보여주는 것과 같은 통합 정리 방식이 필수적입니다. 위젯이나 그 부모가 재연결되어 최상위 창이 달라질 때마다, 위젯과 연관된 컨텍스트는 소멸되고 새로운 컨텍스트가 생성됩니다. 그 후 initializeGL()을 호출하여 모든 OpenGL 리소스를 재초기화해야 합니다. 이 때문에 적절한 정리 작업을 수행할 수 있는 유일한 방법은 컨텍스트의 aboutToBeDestroyed() 신호에 연결하는 것입니다. 신호가 발송될 때 해당 컨텍스트가 현재 컨텍스트와 다를 수 있다는 점에 유의하십시오. 따라서 연결된 슬롯에서 ` makeCurrent()`를 호출하는 것이 좋은 관행입니다. 또한, 위젯이 소멸될 때 신호에 연결된 슬롯이나 람다가 호출되지 않을 수 있으므로, 파생 클래스의 소멸자에서도 동일한 정리 단계를 수행해야 합니다.

MyGLWidget::~MyGLWidget()
{
    cleanup();
}

void MyGLWidget::initializeGL()
{
    ...
    connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &MyGLWidget::cleanup);
}

void MyGLWidget::cleanup()
{
    makeCurrent();
    delete m_texture;
    m_texture = 0;
    ...
    doneCurrent();
    disconnect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &MyGLWidget::cleanup);
}

참고: ` Qt::AA_ShareOpenGLContexts `가 설정된경우 , 위젯의 연관된 텍스처는 새로운 최상위 컨텍스트에서도 접근 가능하므로, 부모 변경 시에도 위젯의 컨텍스트는 절대 변경되지 않습니다. 따라서 이 플래그가 설정된 상태에서는 컨텍스트의 `aboutToBeDestroyed()` 신호에 대응하는 것이 필수는 아닙니다.

컨텍스트 공유로 인해 적절한 정리 작업은 특히 중요합니다. 각 QOpenGLWidget에 연결된 컨텍스트는 QOpenGLWidget과 함께 소멸되지만, 텍스처와 같은 해당 컨텍스트 내의 공유 가능한 리소스는 QOpenGLWidget이 속해 있던 최상위 창이 소멸될 때까지 유효한 상태로 유지됩니다. 또한, ` Qt::AA_ShareOpenGLContexts ` 설정이나 일부 Qt 모듈은 컨텍스트 공유 범위를 더욱 넓힐 수 있으며, 이로 인해 해당 리소스가 애플리케이션의 전체 수명 동안 유지될 가능성이 있습니다. 따라서 가장 안전하고 견고한 방법은 QOpenGLWidget에서 사용된 모든 리소스와 리소스 래퍼에 대해 항상 명시적인 정리 작업을 수행하는 것입니다.

제한 사항 및 기타 고려 사항

다른 위젯을 아래에 배치하고 QOpenGLWidget을 투명하게 설정하더라도 기대하는 결과를 얻지 못합니다. 즉, 아래에 있는 위젯은 보이지 않습니다. 이는 실제로 QOpenGLWidget이 다른 모든 일반(OpenGL이 아닌) 위젯보다 먼저 그려지기 때문에, 투명하게 만드는 방식의 해결책은 실현 불가능하기 때문입니다. QOpenGLWidget 위에 위젯을 배치하는 것과 같은 다른 유형의 레이아웃은 예상대로 작동합니다.

부득이하게 필요한 경우, QOpenGLWidget에 Qt::WA_AlwaysStackOnTop 속성을 설정하여 이 제한 사항을 극복할 수 있습니다. 그러나 이 경우 중첩 순서가 깨진다는 점에 유의하십시오. 예를 들어, QOpenGLWidget 위에 다른 위젯을 배치할 수 없게 되므로, 이 속성은 반투명한 QOpenGLWidget 아래에 다른 위젯이 보이도록 해야 하는 상황에서만 사용해야 합니다.

단, 아래에 다른 위젯이 없고 반투명한 창을 만들려는 경우에는 이 제한 사항이 적용되지 않습니다. 이 경우 최상위 창에 Qt::WA_TranslucentBackground 을 설정하는 기존의 방식만으로도 충분합니다. 단, QOpenGLWidget 내에서만 투명 영역을 원할 경우, ` Qt::WA_TranslucentBackground`을 활성화한 후 ` Qt::WA_NoSystemBackground `을 다시 ` false `으로 되돌려야 합니다. 또한 시스템에 따라 ` setFormat()`를 통해 QOpenGLWidget 컨텍스트에 대한 알파 채널을 요청해야 할 수도 있습니다.

QOpenGLWidget은 QOpenGLWindow 와 마찬가지로 여러 가지 업데이트 동작을 지원합니다. 보존 모드에서는 이전 paintGL() 호출에서 렌더링된 내용이 다음 호출에서도 유지되므로 증분 렌더링이 가능합니다. 비보존 모드에서는 내용이 소실되며, paintGL() 구현체는 뷰의 모든 내용을 다시 그려야 합니다.

Qt 5.5 이전에는 QOpenGLWidget의 기본 동작이 paintGL() 호출 간에 렌더링된 내용을 보존하는 것이었습니다. Qt 5.5부터는 성능이 더 우수하고 대부분의 애플리케이션이 이전 콘텐츠를 필요로 하지 않기 때문에 기본 동작이 비보존(non-preserved)으로 변경되었습니다. 이는 OpenGL 기반의 ` QWindow `의 의미론과 유사하며, 각 프레임마다 색상 및 보조 버퍼가 무효화된다는 점에서 ` QOpenGLWindow `의 기본 동작과도 일치합니다. 보존된 동작을 복원하려면 ` PartialUpdate`을 사용하여 ` setUpdateBehavior()`를 호출하십시오.

참고: 위젯 계층 구조에 QOpenGLWidget을 동적으로 추가할때 (예: 해당 최상위 위젯이 이미 화면에 표시된 상태에서 새로운 QOpenGLWidget을 위젯의 자식으로 추가하는 경우), QOpenGLWidget이 해당 창 내에서 같은 종류의 첫 번째 위젯인 경우, 관련 네이티브 창이 암묵적으로 파괴되었다가 다시 생성될 수 있습니다. 이는 창 유형이 ` RasterSurface `에서 ` OpenGLSurface `로 변경되며, 이로 인해 플랫폼별 영향이 발생하기 때문입니다. 이 동작은 Qt 6.4에서 새롭게 도입되었습니다.

QOpenGLWidget이 위젯 계층 구조에 추가되면, 최상위 창의 내용은 OpenGL 기반 렌더링을 통해 플러시됩니다. QOpenGLWidget 이외의 위젯은 소프트웨어 기반 페인터를 사용하여 계속해서 내용을 그립니다만, 최종 합성은 3D API를 통해 수행됩니다.

참고: QOpenGLWidget을표시하려면 다른 QWidget 기반 콘텐츠와의 합성 방식 때문에, 관련 최상위 창의 백킹 스토어에 알파 채널이 필요합니다. 알파 채널이 없으면 QOpenGLWidget이 렌더링한 콘텐츠가 표시되지 않습니다. 이는 특히 Linux/X11 환경에서 원격 디스플레이 설정(예: Xvnc 사용 시)에서 색상 심도가 24보다 낮은 경우 문제가 될 수 있습니다. 예를 들어, 색심도가 16인 경우 일반적으로 QImage::Format_RGB16 (RGB565) 형식의 백킹 스토어 이미지가 사용되므로 알파 채널을 위한 공간이 남아 있지 않습니다. 따라서 QOpenGLWidget의 내용이 창 내의 다른 위젯과 올바르게 합성되지 않는 문제가 발생한다면, 서버(예: vncserver)가 16비트 대신 24비트 또는 32비트 색 심도로 설정되어 있는지 확인하십시오.

대안

창에 QOpenGLWidget을 추가하면 창 전체에 대해 OpenGL 기반 합성 기능이 활성화됩니다. 일부 특수한 경우에는 이것이 이상적이지 않을 수 있으며, 별도의 네이티브 자식 창을 사용하는 기존의 QGLWidget 스타일 동작이 더 바람직할 수 있습니다. 이 접근 방식의 한계(예: 중첩, 투명도, 스크롤 뷰 및 MDI 영역 관련)를 이해하는 데스크톱 애플리케이션은 ` QOpenGLWindow `와 ` QWidget::createWindowContainer()`를 함께 사용할 수 있습니다. 이는 QGLWidget의 현대적인 대안이며, 추가적인 합성 단계가 필요하지 않아 QOpenGLWidget보다 빠릅니다. 이 접근 방식의 사용은 다른 대안이 없는 경우로만 제한할 것을 강력히 권장합니다. 이 옵션은 대부분의 임베디드 및 모바일 플랫폼에는 적합하지 않으며, 특정 데스크톱 플랫폼(예: macOS)에서도 문제가 발생하는 것으로 알려져 있습니다. 안정적이고 크로스 플랫폼인 솔루션은 언제나 QOpenGLWidget입니다.

입체 렌더링

6.5 버전부터 QOpenGLWidget은 입체 렌더링을 지원합니다. 이를 활성화하려면, 창이 생성되기 전에 QSurfaceFormat::SetDefaultFormat()을 사용하여 QSurfaceFormat::StereoBuffers 플래그를 전역적으로 설정하십시오.

참고: 플래그가 내부적으로 처리되는 방식 때문에 setFormat()를 사용한다고 해서 반드시 작동하는 것은 아닙니다.

이렇게 하면 프레임마다 paintGL()이 두 번 호출되며, 각 QOpenGLWidget::TargetBuffer 에 대해 한 번씩 호출됩니다. paintGL()에서 currentTargetBuffer()를 호출하여 현재 어느 버퍼에 렌더링되고 있는지 확인하십시오.

참고: 좌측 및 우측 컬러 버퍼를 더 세밀하게제어하려면 대신 QOpenGLWindow + QWidget::createWindowContainer()를 사용하는 것을 고려해 보십시오.

참고: 이러한 유형의 3D 렌더링에는 그래픽 카드가 스테레오를 지원하도록 설정되어 있어야 하는 등 특정 하드웨어 요구 사항이 있습니다.

OpenGL은 미국 및 기타 국가에서 Silicon Graphics, Inc.의 상표입니다.

QOpenGLFunctions, QOpenGLWindow, Qt::AA_ShareOpenGLContexts 및 UpdateBehavior도 참조하십시오 .

멤버 유형 문서

[since 6.5] enum QOpenGLWidget::TargetBuffer

QSurfaceFormat::StereoBuffers 를 설정하여 켜고 끌 수 있는 입체 렌더링이 활성화되었을 때 사용할 버퍼를 지정합니다.

참고: LeftBuffer는 항상 기본값이며, 입체 렌더링이 비활성화되었거나 그래픽 드라이버에서 지원되지 않을 때 대체 값으로 사용됩니다.

상수값
QOpenGLWidget::LeftBuffer0
QOpenGLWidget::RightBuffer1

이 열거형은 Qt 6.5에서 도입되었습니다.

enum QOpenGLWidget::UpdateBehavior

이 열거형은 QOpenGLWidget 의 업데이트 세미언틱을 설명합니다.

상수값설명
QOpenGLWidget::NoPartialUpdate0QOpenGLWidget 는 QOpenGLWidget 가 화면에 렌더링된 후 컬러 버퍼와 보조 버퍼의 내용을 삭제합니다. 이는 기본 OpenGL이 활성화된 QWindow 를 인수로 사용하여 QOpenGLContext::swapBuffers 를 호출했을 때 예상되는 동작과 동일합니다. NoPartialUpdate는 프레임버퍼 객체가 렌더링 대상으로 사용될 때, 모바일 및 임베디드 분야에서 흔히 볼 수 있는 특정 하드웨어 아키텍처에서 성능상의 이점을 제공할 수 있습니다. 프레임버퍼 객체는 glInvalidateFramebuffer(지원되는 경우)를 통해 프레임 사이에 무효화되거나, 대체 방법으로 glDiscardFramebufferEXT(지원되는 경우) 또는 glClear 호출을 통해 무효화됩니다.
QOpenGLWidget::PartialUpdate1프레임 간에 프레임버퍼 객체의 색상 버퍼와 보조 버퍼는 무효화되지 않습니다.

updateBehavior() 및 setUpdateBehavior()도 참조하십시오 .

멤버 함수 설명서

[explicit] QOpenGLWidget::QOpenGLWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags())

parent 의 자식 위젯을 생성하며, 위젯 플래그는 f 로 설정됩니다.

[virtual noexcept] QOpenGLWidget::~QOpenGLWidget()

QOpenGLWidget 인스턴스를 소멸시키고 해당 리소스를 해제합니다.

소멸자에서 QOpenGLWidget 의 컨텍스트를 현재 컨텍스트로 설정하여, 이 위젯이 제공하는 컨텍스트에 속한 OpenGL 리소스를 해제해야 할 수 있는 모든 자식 객체를 안전하게 소멸시킬 수 있도록 합니다.

경고: OpenGLWidget 하위 클래스의 멤버로 OpenGL 리소스( QOpenGLBuffer, QOpenGLShaderProgram 등)를 래핑하는 객체가 있는경우 , 해당 하위 클래스의 소멸자에서도 makeCurrent() 호출을 추가해야 할 수 있습니다. C++ 객체 소멸 규칙에 따라, 해당 객체들은 이 함수가 호출되기 전에 소멸되지만(단, 하위 클래스의 소멸자가 실행된 후), 이로 인해 이 함수 내에서 OpenGL 컨텍스트를 현재 컨텍스트로 설정하는 시점이 해당 객체들을 안전하게 처리하기에는 너무 늦어집니다.

makeCurrent도 참조하십시오 .

[signal] void QOpenGLWidget::aboutToCompose()

이 신호는 위젯의 최상위 창이 ` QOpenGLWidget ` 자식 요소와 다른 위젯들의 텍스처 합성을 시작하려 할 때 발생합니다.

[signal] void QOpenGLWidget::aboutToResize()

이 신호는 위젯의 크기가 변경되어 프레임버퍼 객체가 다시 생성될 때 발생합니다.

QOpenGLContext *QOpenGLWidget::context() const

이 위젯에서 사용하는 QOpenGLContext 를 반환하거나, 아직 초기화되지 않은 경우 0 를 반환합니다.

참고: setParent()을 통해 위젯의 부모를 변경하면 위젯이 사용하는컨텍스트와 프레임버퍼 객체가 변경됩니다.

QOpenGLContext::setShareContext() 및 defaultFramebufferObject()도 참조하십시오 .

[since 6.5] QOpenGLWidget::TargetBuffer QOpenGLWidget::currentTargetBuffer() const

현재 활성화된 대상 버퍼를 반환합니다. 기본적으로 왼쪽 버퍼가 반환되며, 오른쪽 버퍼는 QSurfaceFormat::StereoBuffers 가 활성화된 경우에만 사용됩니다. 입체 렌더링이 활성화된 경우, paintGL()를 호출하여 현재 어떤 버퍼가 사용 중인지 확인할 수 있습니다. paintGL()는 각 대상에 대해 한 번씩, 총 두 번 호출됩니다.

이 함수는 Qt 6.5에서 도입되었습니다.

paintGL()도 참조하십시오 .

GLuint QOpenGLWidget::defaultFramebufferObject() const

프레임버퍼 객체 핸들을 반환하거나, 아직 초기화되지 않은 경우 ` 0 `를 반환합니다.

참고: 프레임버퍼객체는 context() 함수가 반환한 컨텍스트에 속하며, 다른 컨텍스트에서는 접근할 수 없을 수 있습니다.

참고: setParent()을 통해 위젯의 부모를 변경하면 위젯이 사용하는컨텍스트와 프레임버퍼 객체가 변경됩니다. 또한, 크기를 조정할 때마다 프레임버퍼 객체가 변경됩니다.

context()도 참조하십시오 .

[since 6.5] GLuint QOpenGLWidget::defaultFramebufferObject(QOpenGLWidget::TargetBuffer targetBuffer) const

지정된 대상 버퍼의 프레임버퍼 객체 핸들을 반환하거나, 아직 초기화되지 않은 경우 ` 0 `를 반환합니다.

이 오버로드를 호출하는 것은 QSurfaceFormat::StereoBuffers 가 활성화되어 있고 하드웨어에서 지원되는 경우에만 의미가 있습니다. 그렇지 않은 경우, 이 메서드는 기본 버퍼를 반환합니다.

참고: 프레임버퍼객체는 context()이 반환하는 컨텍스트에 속하며, 다른 컨텍스트에서는 접근할 수 없을 수도 있습니다. setParent()을 통해 위젯의 부모를 변경하면 위젯이 사용하는 컨텍스트와 프레임버퍼 객체가 변경됩니다. 또한, 크기를 조정할 때마다 프레임버퍼 객체가 변경됩니다.

이 함수는 Qt 6.5에서 도입되었습니다.

context()도 참조하십시오 .

void QOpenGLWidget::doneCurrent()

컨텍스트를 해제합니다.

대부분의 경우 이 함수를 호출할 필요가 없습니다. 위젯은 ` paintGL()`를 호출할 때 컨텍스트가 올바르게 바인딩되고 해제되도록 처리하기 때문입니다.

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

QWidget::event(QEvent *event)를 재구현합니다.

QSurfaceFormat QOpenGLWidget::format() const

이 위젯과 그 최상위 창에서 사용되는 컨텍스트 및 표면 형식을 반환합니다.

위젯과 그 최상위 창이 모두 생성되고, 크기가 조정되며 표시된 후, 이 함수는 컨텍스트의 실제 포맷을 반환합니다. 플랫폼에서 요청을 처리할 수 없는 경우, 반환된 포맷은 요청된 포맷과 다를 수 있습니다. 또한 요청한 것보다 더 큰 색상 버퍼 크기를 얻을 수도 있습니다.

위젯의 창과 관련 OpenGL 리소스가 아직 초기화되지 않은 경우, 반환 값은 setFormat()를 통해 설정된 포맷입니다.

setFormat() 및 context()도 참조하십시오 .

[signal] void QOpenGLWidget::frameSwapped()

이 신호는 위젯의 최상위 창이 합성 작업을 완료하고, 잠재적으로 차단될 수 있는 ` QOpenGLContext::swapBuffers()` 호출에서 반환된 후에 발생합니다.

QImage QOpenGLWidget::grabFramebuffer()

프레임버퍼의 32비트 RGB 이미지를 렌더링하여 반환합니다.

참고: 이 작업은 glReadPixels()를 사용하여 픽셀을 다시 읽어오기 때문에 처리 비용이 높을 수 있습니다. 이로 인해 속도가 느려지거나 GPU 파이프라인이 정지될 수 있습니다.

[since 6.5] QImage QOpenGLWidget::grabFramebuffer(QOpenGLWidget::TargetBuffer targetBuffer)

지정된 대상 버퍼의 프레임버퍼를 32비트 RGB 이미지로 렌더링하여 반환합니다. 이 오버로드는 ‘ QSurfaceFormat::StereoBuffers ’가 활성화된 경우에만 호출하는 것이 타당합니다. 올바른 대상 버퍼의 프레임버퍼를 가져올 때, 입체 렌더링이 비활성화되었거나 하드웨어에서 지원되지 않는 경우 기본 이미지가 반환됩니다.

참고: 이 작업은 glReadPixels()를 사용하여 픽셀을 다시 읽어오기 때문에 처리 비용이 높을 수 있습니다. 이로 인해 속도가 느려지거나 GPU 파이프라인이 정지될 수 있습니다.

이 함수는 Qt 6.5에서 도입되었습니다.

[virtual protected] void QOpenGLWidget::initializeGL()

이 가상 함수는 paintGL() 또는 resizeGL()이 처음 호출되기 전에 한 번 호출됩니다. 하위 클래스에서 이 함수를 재구현하십시오.

이 함수는 필요한 모든 OpenGL 리소스를 초기화해야 합니다.

makeCurrent()을 호출할 필요는 없습니다. 이 함수가 호출될 때 이미 해당 작업이 수행되었기 때문입니다. 다만, 이 단계에서는 프레임버퍼를 아직 사용할 수 없으므로, 여기서 드로우 호출을 수행하지 마십시오. 대신 paintGL()에서 해당 호출을 수행하십시오.

paintGL() 및 resizeGL()도 참조하십시오 .

bool QOpenGLWidget::isValid() const

위젯과 컨텍스트와 같은 OpenGL 리소스가 성공적으로 초기화되면 true를 반환합니다. 위젯이 표시되기 전까지는 반환값이 항상 false임을 유의하십시오.

void QOpenGLWidget::makeCurrent()

해당 컨텍스트를 현재 컨텍스트로 설정하고, 해당 컨텍스트에 프레임버퍼 객체를 바인딩하여 이 위젯의 OpenGL 콘텐츠 렌더링을 준비합니다.

대부분의 경우 이 함수를 직접 호출할 필요가 없는데, 이는 paintGL()를 호출하기 전에 자동으로 호출되기 때문입니다.

context(), paintGL() 및 doneCurrent()도 참조하십시오 .

[since 6.5] void QOpenGLWidget::makeCurrent(QOpenGLWidget::TargetBuffer targetBuffer)

전달된 버퍼에 대한 컨텍스트를 현재 컨텍스트로 설정하고, 해당 컨텍스트에 프레임버퍼 객체를 바인딩하여 이 위젯의 OpenGL 콘텐츠 렌더링을 준비합니다.

참고: 이 함수는 입체 렌더링이 활성화된 경우에만 호출하는 것이 타당합니다. 입체 렌더링이 비활성화된 상태에서 오른쪽 버퍼를 요청하더라도 아무런 동작도 발생하지 않습니다.

paintGL()를 호출하기 전에 이 함수가 자동으로 호출되므로, 대부분의 경우 이 함수를 별도로 호출할 필요가 없습니다.

이 함수는 Qt 6.5에서 도입되었습니다.

context(), paintGL() 및 doneCurrent()도 참조하십시오 .

[override virtual protected] int QOpenGLWidget::metric(QPaintDevice::PaintDeviceMetric metric) const

QWidget::metric(QPaintDevice::PaintDeviceMetric m) const를 재구현합니다.

[override virtual protected] QPaintEngine *QOpenGLWidget::paintEngine() const

QWidget::paintEngine() const를 재구현합니다.

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

QWidget::paintEvent(QPaintEvent *event)를 재구현합니다.

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

QWidget::update()를 호출하면 페인트 이벤트 e 가 전송되어 이 함수가 호출됩니다. (주의: 이는 비동기적이며, update()에서 반환된 후 어느 시점에 발생합니다.) 그런 다음 이 함수는 약간의 준비 과정을 거친 후, 가상 함수 paintGL()를 호출하여 QOpenGLWidget 의 프레임버퍼 내용을 업데이트합니다. 그런 다음 위젯의 최상위 창은 프레임버퍼의 텍스처를 창의 나머지 부분과 합성합니다.

[virtual protected] void QOpenGLWidget::paintGL()

이 가상 함수는 위젯을 그리기 위해 필요한 때마다 호출됩니다. 하위 클래스에서 이 함수를 재구현하십시오.

makeCurrent()을 호출할 필요는 없습니다. 이 함수가 호출될 때 이미 해당 작업이 수행되었기 때문입니다.

이 함수를 호출하기 전에 컨텍스트와 프레임버퍼가 바인딩되며, glViewport() 호출을 통해 뷰포트가 설정됩니다. 프레임워크 측에서는 다른 상태를 설정하지 않으며, 화면 지우기나 그리기 작업도 수행하지 않습니다.

기본 구현은 glClear()를 수행합니다. 서브클래스는 베이스 클래스의 구현을 호출해서는 안 되며, 자체적으로 클리어링을 수행해야 합니다.

참고: 이식성을 보장하기위해 , ` initializeGL()`에서 설정된 상태가 유지될 것이라고 기대하지 마십시오. 대신, paintGL()에서 glEnable()을 호출하는 등의 방법으로 필요한 모든 상태를 직접 설정해야 합니다. 이는 WebGL을 사용하는 WebAssembly와 같은 일부 플랫폼에서 특정 상황에서 OpenGL 컨텍스트에 제한이 있을 수 있으며, 이로 인해 QOpenGLWidget 와 함께 사용된 컨텍스트가 다른 용도로도 사용될 수 있기 때문입니다.

QSurfaceFormat::StereoBuffers 가 활성화되면 이 함수는 각 버퍼에 대해 한 번씩, 총 두 번 호출됩니다. currentTargetBuffer()를 호출하여 현재 어떤 버퍼가 바인딩되어 있는지 확인하십시오.

참고: 하드웨어에서 입체 렌더링을 지원하지 않는 경우에도 각 타깃의프레임버퍼에 렌더링이 수행됩니다. 창에서는 실제로 왼쪽 버퍼만 표시됩니다.

initializeGL(), resizeGL(), currentTargetBuffer()도 참조하십시오 .

[override virtual protected] QPaintDevice *QOpenGLWidget::redirected(QPoint *p) const

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

QWidget::resizeEvent(QResizeEvent *event)를 재구현합니다.

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

참고: 파생 클래스에서 이 함수를 재정의하지마십시오 . 부득이하게 재정의해야 하는 경우, QOpenGLWidget 의 구현도 반드시 호출되도록 해야 합니다. 그렇지 않으면 기본 프레임버퍼 객체 및 관련 리소스의 크기가 제대로 조정되지 않아 렌더링 오류가 발생할 수 있습니다.

[virtual protected] void QOpenGLWidget::resizeGL(int w, int h)

이 가상 함수는 위젯의 크기가 조정될 때마다 호출됩니다. 하위 클래스에서 이 함수를 재구현하십시오. 새로운 크기는 ` w `와 ` h`에 전달됩니다.

makeCurrent()을 호출할 필요는 없습니다. 이 함수가 호출될 때 이미 해당 작업이 수행되었기 때문입니다. 또한 프레임버퍼도 이미 바인딩되어 있습니다.

initializeGL() 및 paintGL()도 참조하십시오 .

[signal] void QOpenGLWidget::resized()

이 신호는 위젯의 크기가 조정되어 프레임버퍼 객체가 재 생성된 직후에 발생합니다.

void QOpenGLWidget::setFormat(const QSurfaceFormat &format)

요청된 표면 format 을 설정합니다.

이 함수를 통해 형식이 명시적으로 설정되지 않은 경우, ` QSurfaceFormat::defaultFormat()`가 반환하는 형식이 사용됩니다. 즉, 여러 OpenGL 위젯이 있는 경우, 첫 번째 위젯을 생성하기 전에 이 함수를 개별적으로 호출하는 대신 ` QSurfaceFormat::setDefaultFormat()`를 한 번만 호출하면 됩니다.

참고: 이 함수를 통해 알파 버퍼를요청하는 것은 그 아래에 있는 다른 위젯을 보이게 하려는 의도일 때 원하는 결과를 얻지 못합니다. 대신, Qt::WA_AlwaysStackOnTop 를 사용하여 그 아래에 있는 다른 위젯이 보이도록 반투명한 QOpenGLWidget 인스턴스를 활성화하십시오. 다만, 이 경우 레이어 순서가 깨지므로 더 이상 QOpenGLWidget 위에 다른 위젯을 배치할 수 없게 된다는 점을 유의하십시오.

format(), Qt::WA_AlwaysStackOnTop, QSurfaceFormat::setDefaultFormat()도 참조하십시오 .

void QOpenGLWidget::setTextureFormat(GLenum texFormat)

texFormat 의 사용자 정의 내부 텍스처 형식을 설정합니다.

sRGB 프레임버퍼를 사용할 때는 GL_SRGB8_ALPHA8 와 같은 형식을 지정해야 합니다. 이 함수를 호출하면 이를 구현할 수 있습니다.

참고: 위젯이 이미 표시되어 초기화가 완료된 후이 함수를 호출하면 아무런 효과가 없습니다.

참고: 이 함수는 일반적으로 색 공간을 QColorSpace::SRgb 로 설정하는 QSurfaceFormat::setColorSpace() 호출과 함께 사용해야 합니다.

textureFormat()도 참조하십시오 .

void QOpenGLWidget::setUpdateBehavior(QOpenGLWidget::UpdateBehavior updateBehavior)

이 위젯의 업데이트 동작을 ` updateBehavior`로 설정합니다.

updateBehavior()도 참조하십시오 .

GLenum QOpenGLWidget::textureFormat() const

위젯이 이미 초기화된 경우 활성 내부 텍스처 형식을 반환하고, 형식이 설정되었으나 위젯이 아직 표시되지 않은 경우 요청된 형식을 반환하며, setTextureFormat()가 호출되지 않았고 위젯이 아직 표시되지 않은 경우 nullptr 를 반환합니다.

setTextureFormat()도 참조하십시오 .

QOpenGLWidget::UpdateBehavior QOpenGLWidget::updateBehavior() const

위젯의 업데이트 동작을 반환합니다.

setUpdateBehavior()도 참조하십시오 .

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