我想使用 QOffscreenSurface 和 QOpenglContext 类在屏幕外渲染纹理。这是我的代码:
OffscreenRender.h
class OffscreenRender:public QOffscreenSurface,protected QOpenGLFunctions_4_3_Core
{
Q_OBJECT
public:
explicit OffscreenRender(QObject *parent = 0);
virtual ~OffscreenRender();
void paint();
GLuint* getTBO();
QOpenGLContext *getCurrentContext(){return openGLContext;}
private:
void initialGL();
private:
bool glInitialized = false;
QOpenGLContext *openGLContext = nullptr;
GLuint proGen = 0,
vaoGen = 0,
vboGen = 0,
tbo = 0,
fbo = 0;
};
OffscreenRender.cpp
OffscreenRender::OffscreenRender(QObject *parent)
{
setParent(parent);
QSurfaceFormat surfaceFormat;
surfaceFormat.setMajorVersion(4);
surfaceFormat.setMinorVersion(3);
surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
openGLContext = new QOpenGLContext();
openGLContext->setFormat(surfaceFormat);
QOpenGLContext *share = QOpenGLContext::globalShareContext();
openGLContext->setShareContext(share);
if(openGLContext->create()){
setFormat(surfaceFormat);
create();
if(!isValid())
qDebug("Unable to create the Offscreen surface");
initialGL();
}
else{
qDebug("Unable to create the context");
}
}
OffscreenRender::~OffscreenRender(){
openGLContext->makeCurrent(this);
if(glIsProgram(proGen)){
glDeleteProgram(proGen);
}
if(glIsVertexArray(vaoGen)){
glDeleteVertexArrays(1,&vaoGen);
}
if(glIsBuffer(vboGen)){
glDeleteBuffers(1,&vboGen);
}
if(glIsTexture(tbo)){
glDeleteTextures(1,&tbo);
}
if(glIsFramebuffer(fbo)){
glDeleteFramebuffers(1,&fbo);
}
openGLContext->doneCurrent();
if(openGLContext){
delete openGLContext;
}
}
void OffscreenRender::paint(){
if(glInitialized){
openGLContext->makeCurrent(this);
glViewport(0, 0, 100, 100);
glClearColor(1,0,1,1);
glUseProgram(proGen);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vaoGen);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
openGLContext->doneCurrent();
}
}
GLuint *OffscreenRender::getTBO(){return &tbo;}
void OffscreenRender::initialGL(){
openGLContext->makeCurrent(this);
if(!initializeOpenGLFunctions()){
qDebug("Unable to initialize the functions");
return;
}
proGen = loadShaders();
glGenVertexArrays(1, &vaoGen);
glBindVertexArray(vaoGen);
glGenBuffers(1, &vboGen);
glBindBuffer(GL_ARRAY_BUFFER,vboGen);
int nBytes = sizeof(float) * 16;
glBufferData(GL_ARRAY_BUFFER,nBytes,vertexCord,GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, NULL);
glEnableVertexAttribArray(0);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &tbo);
glBindTexture(GL_TEXTURE_2D, tbo);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 100, 100);
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tbo, 0);
openGLContext->doneCurrent();
glInitialized = true;
}
调用OffscreenRender::paint()后,该类将在纹理中心渲染一个矩形
tbo
。但是在destroy函数中,当调用delete openGLContext;
时,Qt报告ASSERT: "d_1_0_Core->refs.load()" in file opengl\qopenglfunctions_4_3_core.cpp, line 93
。删除此删除调用后,程序运行良好.我不知道原因。
在加载 OpenGL 函数之前,您需要有 OpenGL 上下文。当调用 OpenGL 函数加载器 (
QOpenGLFunctions_4_3_Core
) 的析构函数时,上下文必须仍然有效 - 这不会在您的代码中发生,因为:
QOffscreenSurface
、QOpenGLFunctions_4_3_Core
、OffscreenRender
OffscreenRender
上下文的析构函数中被删除QOpenGLFunctions_4_3_Core
和 QOffscreenSurface
的默认析构函数第(5)点
QOpenGLFunctions_4_3_Core
的构造函数期望加载GL函数时使用的上下文仍然有效,但事实并非如此。
您可以添加
QOpenGLFunctions_4_3_Core
的数据成员,然后在获得OpenGL上下文时对其进行初始化,并通过该对象调用任何GL函数。然后您可以在删除上下文之前删除 GL 函数加载器。