Сбой программы Qt OpengGL Shader - PullRequest
       3

Сбой программы Qt OpengGL Shader

1 голос
/ 13 сентября 2011

Я пытаюсь написать современную программу OpenGL (программируемый конвейер) с использованием Qt SDK. Примеры OpenGL показывают только реализацию с фиксированным конвейером. Документация по инициализации Shader Program очень плохая. Это лучший пример того, как настройте программу шейдера и загрузите шейдеры, которые у них есть: http://doc.trolltech.com/4.6/qglshaderprogram.html#details Это не очень описательно, как можно видеть. Я пытался следовать этому документу и не могу заставить программу Shader работать. Получение ошибки сегментации, когда программа пытается присвоить атрибуты шейдерам. Я думаю, проблема в том, что я обращаюсь к контексту неправильно. Но я не могу найти любую ссылку о том, как настроить или получить контекст рендеринга. Мой код выглядит так:

static GLfloat const triangleVertices[] = {
    60.0f,  10.0f,  0.0f,
    110.0f, 110.0f, 0.0f,
    10.0f,  110.0f, 0.0f
};

QColor color(0, 255, 0, 255);
int vertexLocation =0;
int matrixLocation =0;
int colorLocation =0;
QGLShaderProgram *pprogram=0;
void OpenGLWrapper::initShaderProgram(){
    QGLContext context(QGLFormat::defaultFormat());

    QGLShaderProgram program(context.currentContext());
    pprogram=&program;
    program.addShaderFromSourceCode(QGLShader::Vertex,
     "attribute highp vec4 vertex;\n"
     "attribute mediump mat4 matrix;\n"
     "void main(void)\n"
     "{\n"
     "   gl_Position = matrix * vertex;\n"
     "}");
     program.addShaderFromSourceCode(QGLShader::Fragment,
     "uniform mediump vec4 color;\n"
     "void main(void)\n"
     "{\n"
     "   gl_FragColor = color;\n"
     "}");
     program.link();
     program.bind();

vertexLocation= pprogram->attributeLocation("vertex");
matrixLocation= pprogram->attributeLocation("matrix");
colorLocation=  pprogram->uniformLocation("color");
}

А вот цикл рендеринга:

void OpenGLWrapper::paintGL()
{
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


     QMatrix4x4 pmvMatrix;
     pmvMatrix.ortho(rect());

    pprogram->enableAttributeArray(vertexLocation);
    pprogram->setAttributeArray(vertexLocation, triangleVertices, 3);
    pprogram->setUniformValue(matrixLocation, pmvMatrix);
    pprogram->setUniformValue(colorLocation, color);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    pprogram->disableAttributeArray(vertexLocation);
}

Кто-нибудь может помочь с этой настройкой? Большое спасибо.

Ответы [ 2 ]

2 голосов
/ 13 сентября 2011

Вы создаете локальную переменную program и указатель pprogram указывает на ее адрес. Но когда возвращается initShaderProgram, время жизни локального program заканчивается, и ваша pprogram указывает на мусор, поэтому при попытке его использовать возникает ошибка. Вы должны скорее создать программу динамически и позволить Qt обрабатывать управление памятью:

pprogram = new QGLShaderProgram(context.currentContext(), this);

Предполагается, что OpenGLWrapper наследуется от QObject, если нет, то вам нужно вручную удалить программу в ее деструкторе (или использовать какой-нибудь умный указатель, или что-то еще).

В противном случае ваш код инициализации выглядит вполне разумно. Ваша матричная переменная должна быть униформой, а не атрибутом, но я хочу классифицировать это как опечатку. Вы также не должны bind программу на протяжении всей жизни, поскольку это эквивалентно вызову glUseProgram. Вам лучше использовать bindrelease, что делает glUseProgram(0)) в вашей процедуре рендеринга.

1 голос
/ 13 сентября 2011

По моему опыту, обертки Qt для объектов OpenGL довольно скудны и ограничены, я просто создал тонкую обертку для прямых объектов OpenGL (сделанную кроссплатформенной и простой с помощью GLEW) и сделал обычные вызовы OpenGL в QGLWidget. Это не сработало, после некоторой борьбы с эквивалентами Qt.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...