简体   繁体   English

Qt OpengGL Shader程序失败

[英]Qt OpengGL Shader Program fails

I am trying to write a modern OpenGL (programmable pipeline) program using Qt SDK .Qt OpenGL examples show only the fixed pipeline implementation.The documentation on how to initialize Shader Program is very poor.This is the best example on how to setup a shader program and load shaders they have:http://doc.trolltech.com/4.6/qglshaderprogram.html#details This is not very descriptive as one can see. 我正在尝试使用Qt SDK编写现代OpenGL(可编程管线)程序.Qt OpenGL示例仅显示固定管线实现。有关如何初始化Shader Program的文档非常少,这是有关如何设置着色器的最佳示例他们拥有的程序和负载着色器:http://doc.trolltech.com/4.6/qglshaderprogram.html#details正如人们所看到的那样,这不是很描述。 I tried to follow this doc and cann't get the Shader program working .Getting segmentation error when the program tries to assign attributes to the shaders.I think the problem is that I access the context in the wrong way.But I can't find any reference on how to setup or retrieve the rendering context.My code goes like this: 我试图遵循此文档并且无法使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");
}

And here is the rendering loop: 这是渲染循环:

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);
}

Anybody has can help with this setup? 有人可以帮助您进行此设置吗? Thanks a lot . 非常感谢 。

You create a local program variable and let your pprogram pointer point to its address. 您创建一个本地program变量,并让您的pprogram指针指向其地址。 But when initShaderProgram returns, the local program 's lifetime ends and you pprogram points to garbage, therefore the segfault when you try to use it. 但是,当initShaderProgram返回时,本地program的生命周期结束,您pprogram指向垃圾,因此尝试使用它时会出现段错误。 You should rather create the program dynamically and let Qt handle the memory management: 您应该宁愿动态创建程序,并让Qt处理内存管理:

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

This assumes OpenGLWrapper derives somewhoe from QObject , if not, then you need to delete the program in its destructor manually (or use some smart pointer, or whatever). 这假设OpenGLWrapperQObject派生了一些东西,如果不是,那么您需要手动删除其析构函数中的程序(或使用一些智能指针,或其他方法)。

Otherwise your initialization code looks quite reasonable. 否则,您的初始化代码看起来很合理。 Your matrix variable should be a uniform and not an attribute, but I'm willing to classfiy this as a typo. 您的矩阵变量应该是统一的,而不是属性,但是我愿意将其归类为错字。 You should also not bind the program for the whole lifetime, as this is equivalent to a call to glUseProgram . 您也不应该在整个生命周期中都bind该程序,因为这等效于对glUseProgram的调用。 You should rather use bind (and release , which does glUseProgram(0) ) in your render routine. 您应该在渲染例程中使用bind (和release ,它执行glUseProgram(0) )。

In my experience the Qt wrappers for OpenGL objects are rather poor and limited, I just made a thin-wrapper for straight OpenGL objects (made cross-platform and easy via GLEW), and made the usual OpenGL calls in QGLWidget. 以我的经验,用于OpenGL对象的Qt包装器相当差且受限制,我只是为直接的OpenGL对象制作了薄包装纸(通过GLEW制作了跨平台的文件并很容易),并在QGLWidget中进行了通常的OpenGL调用。 It worked no problem, after struggling for awhile with Qt's equivalents. 在与Qt的同类产品苦苦挣扎了一段时间后,它没有任何问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM