顶点着色器错误C5145:必须使用QShaderProgram写入gl_Position [英] Vertex shader error C5145: must write to gl_Position using QShaderProgram

查看:815
本文介绍了顶点着色器错误C5145:必须使用QShaderProgram写入gl_Position的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am translating a Visual Studio C++ OpenGL project to a Qt project to implement a UI.

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

I have all the code translated and I am using Qt classes to implement OpenGL part.

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

The problem I am having now is that when I link the shaderProgram it throws me an error that says:

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

Vertex info (0) : error C5145: must write to gl_Position

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

I am implementing QOpenGLFunctions_4_1_Core and I debug the compile function to see if the code was well read and yes

读取所有代码,并且编译函​​数返回true(经过良好编译).

All the code is read and the compile function returns a true (well compiled).

GLuint shaderProgram::createShaderProgram(const char *fileName) {
    // Creamos el shader program y almacenamos su identificador
    if (handler) {
        shaderP = new QOpenGLShaderProgram();
        handler = shaderP->create();
        if (!handler) {
            fprintf(stderr, "Cannot create shader program: %s.\n", fileName);
            return 0;
        }
    }
    // Cargamos y compilamos cada uno de los shader objects que componen este
    // shader program
    char fileNameComplete[256];
    strcpy_s(fileNameComplete, fileName);
    strcat_s(fileNameComplete, "-vert.glsl");
    QOpenGLShader* vertex = new QOpenGLShader(QOpenGLShader::Vertex);
    GLuint vertexShaderObject = compileShader(fileNameComplete, QOpenGLShader::Vertex,vertex);
    if (vertexShaderObject == 0) {
        return 0;
    }
    strcpy_s(fileNameComplete, fileName);
    strcat_s(fileNameComplete, "-frag.glsl");
    QOpenGLShader* fragment = new QOpenGLShader(QOpenGLShader::Fragment);
    GLuint fragmentShaderObject = compileShader(fileNameComplete, QOpenGLShader::Fragment, fragment);
    if (fragmentShaderObject == 0) {
        return 0;
    }
    // Asociamos los shader objects compilados sin errores al shader program
    shaderP->addShader(vertex);
    shaderP->addShader(fragment);

    // Enlazamos el shader program y comprobamos si hay errores
    handler = shaderP->link(); //Here is where the error is thrown
    if(!handler)
    {
        QString error = shaderP->log();
        std::cout<< error.toStdString()<<std::endl;
        return 0;
    }
    else {
        linked = true;
    }
    return handler;
}

bool shaderProgram::compileShader(const char *filename, QOpenGLShader::ShaderTypeBit type,QOpenGLShader* shaderComp) {
    // 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 0;
    }
    // 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 0;
    }
    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
    QOpenGLShader shader(type);

    QString code(QString::fromStdString(shaderSourceString));

    bool result = shader.compileSourceCode(code);

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

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

I expect the shader program link well and I would be able to draw my objects on screen.

推荐答案

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

There are some issues in your code.

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

First of all I recommend to us QOpenGLShader::compileSourceFile:

例如

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


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


In the function shaderProgram::compileShader a local variable shader is used:

QOpenGLShader shader(type);

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

but then a pointer to this variable is assigned to the output parameter shaderComp.

shaderComp = &shader;

函数终止后,本地对象shader被破坏,指针最终无处可寻.

When the function has terminated, the local object shader is destructed and the pointer finally goes to nowhere.

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

The parameter has to be an input parameter. Get rid of the local variable and use the existing object to compile the shader.
You can create a new QOpenGLShader object in the shaderProgram::compileShader and return that object by the return value:

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

这篇关于顶点着色器错误C5145:必须使用QShaderProgram写入gl_Position的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆