顶点着色器错误C5145:必须使用QShaderProgram写入gl_Position

时间:2019-05-01 08:14:10

标签: c++ qt opengl glsl shader

我正在将Visual Studio C ++ python项目转换为Qt项目以实现OpenGL

我已经翻译了所有代码,并且正在使用Qt类来实现UI部分。

我现在遇到的问题是,当我链接OpenGL时,抛出一个错误:

  

顶点信息(0):错误C5145:必须写入gl_Position

我正在实现shaderProgram并调试编译功能,以查看代码是否被正确阅读,是的

读取所有代码,并且编译函​​数返回true(编译正确)。

QOpenGLFunctions_4_1_Core

我希望着色器程序链接良好,并且可以在屏幕上绘制对象。

1 个答案:

答案 0 :(得分:1)

您的代码中存在一些问题。

首先,我向我们推荐QOpenGLShader::compileSourceFile

例如

QOpenGLShader* vertex = new QOpenGLShader(QOpenGLShader::Vertex);
vertex->compileSourceFile( fileNameComplete );

在函数shaderProgram::compileShader中使用了局部变量shader

QOpenGLShader shader(type);

,但随后将此变量的指针分配给输出参数shaderComp

shaderComp = &shader;

函数终止后,本地对象shader被破坏,指针最终消失。

该参数必须是输入参数。摆脱局部变量,并使用现有对象来编译着色器。
您可以在QOpenGLShader中创建一个新的shaderProgram::compileShader对象,并通过返回值返回该对象:

QOpenGLShader* shaderProgram::compileShader(
    const char *filename, 
    QOpenGLShader::ShaderTypeBit type)
{
    // Comprobamos si en la solución existe algún archivo de recursos con el
    // nombre que se pasa como argumento
    if (!fileExists(filename)) {
        fprintf(stderr, "Shader source file %s not found.\n", filename);
        return nullptr;
    }
    // Si existe se lee en una cadena de caracteres que contiene el listado
    // completo del shader source
    std::ifstream shaderSourceFile;
    shaderSourceFile.open(filename);
    if (!shaderSourceFile) {
        fprintf(stderr, "Cannot open shader source file.\n");
        return nullptr;
    }
    std::stringstream shaderSourceStream;
    shaderSourceStream << shaderSourceFile.rdbuf();
    std::string shaderSourceString = shaderSourceStream.str();
    shaderSourceFile.close();

    // - Creamos un shader object para ese archivo que se ha leído
    QString code(QString::fromStdString(shaderSourceString));

    QOpenGLShader* shader = new QOpenGLShader(QOpenGLShader::Vertex);
    bool result = shader->compileSourceCode(code);

    if(!result){
        const QString qs = shader->log();
        std::cout << qs.toStdString();
        this->logString = qs.toStdString();
        delete shader;
        return nullptr;
    }
    //si ha compilado bien, creamos el shader
    return shader;
}

调用这样的方法:

std::string vertFileName = std::string(fileName) + "-vert.glsl";
QOpenGLShader* vertex = compileShader(vertFileName.c_str(), QOpenGLShader::Vertex);
if (!vertex) {
    return 0;
}

std::string fragFileName = std::string(fileName) + "-frag.glsl";
QOpenGLShader* fragment = compileShader(fragFileName.c_str(), QOpenGLShader::Fragment);
if (!fragment) {
    return 0;
}