首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenGL不能在macOS绘制QtWidget

OpenGL不能在macOS绘制QtWidget
EN

Stack Overflow用户
提问于 2022-04-03 13:35:10
回答 1查看 202关注 0票数 0

我尝试将OpenGL与Qt结合在macOS平台上,系统的版本是:蒙特雷。

因为我希望自己创建OpenGL上下文,并将呈现线程与UI线程(主线程,这就是为什么我不能使用QOpenglWidget)分开,所以我执行了以下步骤:

  1. 使用openGlContext创建NSOpenGLContext
  2. 调用NSOpenGlContext.setView,setView的参数是(NSView*)QWidget::winId()
  3. 在Qt的showEvent中创建一个线程,用于调用OpenGL API

因此,窗口小部件可以出现,但没有出现。(甚至我也调用glClear来清除颜色,但是该颜色不能出现在窗口(视图)中。)

但同时,当我使用RenderDoc在macOS中捕获帧时,我可以得到正确的呈现结果。

我怀疑QT是否改变了默认的框架缓冲区,所以我尝试调用glBindFrameBuffer(GL_FRAMEBUFFER,0),但是它没有工作。

然后在Windows中使用相同的代码(使用wglXXX函数创建OpenGL上下文),它确实工作并呈现正确。

那么我应该如何在QtWidget中使用QtWidget呢?

守则如下:

在OpenGL中创建macOS上下文:

代码语言:javascript
复制
#import <Cocoa/Cocoa.h>
#include "MacosOpenGLContext.h"
#include <iostream>



#include "MacosOpenGLContext.h"

MacosOpenGLContext::MacosOpenGLContext(NSView* winID,SHK::Setting setting){
    this->createGLContext(winID,setting);
}

void MacosOpenGLContext::makeCurrent(){
    if(this->_openGLContext!=nullptr){
     [this->_openGLContext makeCurrentContext];
    }
}
void MacosOpenGLContext::flushBuffer(){
    if(this->_openGLContext!=nullptr){
        [this->_openGLContext flushBuffer];
    }
}
void MacosOpenGLContext::setView(WinID id){
    if(this->_openGLContext!=nullptr){
        [this->_openGLContext setView:(NSView*)id];
    }
}
void MacosOpenGLContext::update(){
    if(this->_openGLContext!=nullptr){
        [this->_openGLContext update];
    }
}
bool MacosOpenGLContext::isCreateSuccess(){
    return !(this->_openGLContext==nullptr);
}
void MacosOpenGLContext::makeNullCurrent(){

}
void MacosOpenGLContext::createGLContext(NSView* winID,SHK::Setting setting){
    _openGLContext=nullptr;
    NSOpenGLPixelFormatAttribute attrs[] = {
        NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core,
        NSOpenGLPFAColorSize,32,
        NSOpenGLPFADepthSize,16,
        NSOpenGLPFADoubleBuffer,
        NSOpenGLPFAAccelerated,
        0
    };
   NSOpenGLPixelFormat*  _pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
   _pixelFormat=[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
   if(_pixelFormat==nullptr){
       std::cout<<"create macos pixelFormat failed";
       return;
   }
   this->_openGLContext=
           [[NSOpenGLContext alloc] initWithFormat: _pixelFormat shareContext: nullptr];
    if(this->_openGLContext==nullptr){
        std::cout<<"the opengl context create failed";
        return;
    }
    [_pixelFormat release];
    _pixelFormat=nullptr;

    this->setView((WinID)winID);
//    this->makeCurrent();

}
MacosOpenGLContext::MacosOpenGLContext(WinID winID){
    SHK::Setting settings;
    settings.colorBits = 24;
    settings.depthBits = 24;
    settings.stencilBits = 8;
    settings.majorVersion = 4;
    settings.minorVersion = 1;
    this->createGLContext((NSView*)winID,settings);
}

Widget代码为blow:

代码语言:javascript
复制
#include "TestQtOpenGL.hpp"
#if defined(MACOS)
#include "../platform/Macos/MacosOpenGLContext.h"
#elif defined(WIN)
#include "../platform/Windows/Win32OpenGLContext.hpp"
#endif
#include <GL/glew.h>
#include <iostream>
#include "../Shader.hpp"

const char *vertexShaderSource = "#version 330 core\n"
                                 "layout (location = 0) in vec3 aPos;\n"
                                 "void main()\n"
                                 "{\n"
                                 "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
                                 "}\0";
const char *fragmentShaderSource = "#version 330 core\n"
                                   "out vec4 FragColor;\n"
                                   "void main()\n"
                                   "{\n"
                                   "   FragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
                                   "}\n\0";



TestQtOpenGL::TestQtOpenGL()
{
#if defined(MACOS)
    _context = std::make_shared<MacosOpenGLContext>((WinID)winId());
#elif defined(WIN)
    _context = std::make_shared<Win32OpenGLContext>((HWND)winId());
#endif
}
void TestQtOpenGL::paintEvent(QPaintEvent* event)
{
    QWidget::paintEvent(event);

}
void TestQtOpenGL::showEvent(QShowEvent* event)
{
    QWidget::showEvent(event);

    _thread=std::thread([this](){
        this->_context->setView(WinID (this->winId()));
        this->_context->update();
        this->_context->makeCurrent();
        if(!_inited){
            if(glewInit()!=GLEW_OK){
                std::cout<<"init glew failed"<<std::endl;
            }
            _inited = true;
        }


        {
            std::shared_ptr<TOOLS::Shader> _shader;
            unsigned int _vao, _vbo;
            if (glewInit() == GLEW_OK)
            {
                _shader = std::make_shared<TOOLS::Shader>("TestG3DShader");
                {
                    // this->makeCurrent();
                    float points[] = {0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
                    glGenVertexArrays(1, &_vao);
                    glBindVertexArray(_vao);
                    glGenBuffers(1, &_vbo);
                    glBindBuffer(GL_ARRAY_BUFFER, _vbo);
                    glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
                    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
                    glEnableVertexAttribArray(0);
                }
            }
            while(true){
                glBindFramebuffer(GL_FRAMEBUFFER,0);
                glViewport(0,0,400,400);
                glBindVertexArray(_vao);
                glClearColor(0.0f, 0.3f, 0.0f, 1.0f);
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                _shader->use();

                glDrawArrays(GL_TRIANGLES, 0, 3);
                this->_context->flushBuffer();
            }
        }
    });
    _thread.detach();


}
void TestQtOpenGL::resizeEvent(QResizeEvent* event)
{
    QWidget::resizeEvent(event);
    this->_context->update();
}

renderDoc macOS的结果为blow:renderDoc结果

QWidget的结果如下:在这里输入图像描述

EN

回答 1

Stack Overflow用户

发布于 2022-07-14 03:10:16

我也遇到了同样的问题。QWidget不能渲染,但QOpenGlWidget可以。这可能是NSView层的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71726409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档