OpenGL падает на виртуальной машине (Ubuntu 16.04), настроенной на VMWare Fusion Версия 10.1.3.

Я пытаюсь нарисовать графику, используя OpenGL.
я использую VMWare Fusion Version 10.1.3 с Ubuntu 16.04 а также QtCreator 4.6.2.

Моя задача — воспроизвести запись с некоторым рисунком в OpenGL.
В этом случае мне нужно, чтобы FBO увеличивало содержание моего рисунка и создавало изображение в конце записи, а также мне нужно, чтобы текстура отображалась на экране во время воспроизведения записи.

Моя проблема в том, что у меня постоянный сбой при уничтожении объекта, в котором я использую OpenGL.

Вот мой код:

void DrawingView::paint(QPainter *painter) {

painter->beginNativePainting();
if(_needsErase) {

QOpenGLContext  *context = QOpenGLContext::currentContext();

_frameBuffer = new QOpenGLFramebufferObject(QSize(_rect.width(), _rect.height()), _format);

glBindTexture(GL_TEXTURE_2D, _frameBuffer->texture());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _rect.width(), _rect.height(), 0,  GL_RGBA , GL_UNSIGNED_BYTE, 0);

glBindTexture(GL_TEXTURE_2D, 0);

_frameBuffer->bind();
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
_frameBuffer->release();

_needsErase = false;
}

glEnable(GL_BLEND);

_frameBuffer->bind();
{ // here I'm drawing to my fbo, this part is irrelevant. }
_frameBuffer->release();

_shaderProgram->release();

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

glUniform1i(_tex0Uniform, 0);
_copyBuffer->bind();

glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _frameBuffer->texture());

glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glActiveTexture(GL_TEXTURE0);
glBindTexture( GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);

_copyBuffer->release();

glDisable(GL_BLEND);

painter->endNativePainting();
}

Приложение вылетает при разрушении моего DrawingView Объект после строки delete _frameBuffer; с журналом:

context mismatch in svga_surface_destroy
VMware: vmw_ioctl_command error Invalid argument.

Вот как я освобождаю DrawingView Объект.

void DrawingView::cleanupGL() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);

_shaderProgram->release();
_frameBuffer->release();
_copyBuffer->release();

delete _shaderProgram;
delete _copyBuffer;
delete _frameBuffer;

glDeleteBuffers(1, &_ebo);
glDeleteBuffers(1, &_vbo);
}

Я заметил, что приложение перестает работать, когда я стираю строку с glDrawArrays(...) команда, но мне нужна эта команда для отображения чертежа во время воспроизведения записи.

Я использовал этот код также на macOS, и там все работало ОТЛИЧНО, но, к сожалению, мне нужно использовать этот код на виртуальной машине с Ubuntu.

Вот также код моих вершинных и фрагментных шейдеров:

Вершинный шейдер:

uniform vec2 screenSize;
attribute vec2 position;
varying vec2 coord;

void main(void)
{
coord = position;
vec2 halfScreenSize = screenSize * 0.5f;
vec2 pos = halfScreenSize * position + halfScreenSize;
gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
}

Фрагмент шейдера:

uniform sampler2D tex0;
varying vec2 coord;

void main(void)
{
vec2 coords = coord * 0.5 + 0.5;
gl_FragColor = texture2D(tex0, coords.xy);
}

У кого-нибудь есть идеи, почему он не хочет работать на виртуальной машине?

Я действительно хотел быть конкретным, описывая мою проблему, но если у вас есть какие-либо дополнительные вопросы, пожалуйста, задавайте.

-1

Решение

Вы создаете (новый) экземпляр QOpenGLFramebufferObject, только если _needsErase когда-либо установлен верно.

if(_needsErase) {
QOpenGLContext  *context = QOpenGLContext::currentContext();
_frameBuffer = new QOpenGLFramebufferObject(…

Если этого не произойдет, это будет неинициализированный указатель, и вызов функций-членов для него вызовет неопределенное поведение. Этот конкретный код неверен в любом случае, потому что он никогда не удаляет тот экземпляр, на который может указывать _frameBuffer перед перезаписью указателя.

Вместо ручного управления памятью я настоятельно советую использовать автоматические конструкции. Я ценю необходимость динамического создания экземпляра в этом конкретном случае. Способ обойти это через либо std::shared_ptr или же std::unique_ptr, Я настоятельно рекомендую начать с std::unique_ptr и измените его на общий указатель, только если это абсолютно необходимо.

В вашем DrawingView class

#include <memory>
class DrawingView : public ... {
...
protected:
std::unique_ptr<QOpenGLFramebufferObject> _frameBuffer;
...
};

в DrawingView::paint метод:

 if(_needsErase) {
QOpenGLContext  *context = QOpenGLContext::currentContext();
_frameBuffer = std::make_unique<QOpenGLFramebufferObject>(…

Не использовать new или же delete,

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]