QOpenGLShader::link error con gl_Position



  • Estoy teniendo problemas a la hora de hacer el link de mi shader program. La función en la que se lanza el error es esta:

    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(); //Aquí es donde salta el error
        if(!handler)
        {
            QString error = shaderP->log();
            std::cout<< error.toStdString()<<std::endl;
            return 0;
        }
        else {
            linked = true;
        }
        return handler;
    }
    

    shaderP es un objeto de la clase QOpenGLShaderProgram.
    El error que salta es : (0) : error C5145: must write to gl_Position.
    Pero gl_Position ies una built-in-variable de openGL sobre la que yo no tengo control, entonces no sé que está fallando. Tengo estos mismos shaders en Visual Studio pero usando C++ con las funciones de OpenGL y funciona a la perfección.

    Los shaders son:
    Vertex:

    #version 400
    
    layout (location = 0) in vec3 vPosition;
    
    uniform mat4 mvpMatrix;
    uniform vec3 vColor;
    uniform float pointSize;
    out vec4 destinationColor;
    
    void main()
    {
    	gl_PointSize = pointSize;
    	destinationColor = vec4(vColor, 1.0);
    	gl_Position = mvpMatrix * vec4(vPosition, 1.0);
    }
    
    

    Fragment:

    #version 400
    
    in vec4 destinationColor;
    
    out vec4 fColor;
    
    void main()
    {
    	vec2 coord = gl_PointCoord-vec2(0.5);
    	if(length(coord) > 0.5)
    	{
    		discard;
    	}
    	fColor = destinationColor;
    }
    

    Gracias de antemano



  • I found the solution. I let it here jusut in case someone need it:
    The problem was that I assigned a reference to a pointer in the compileShader method but when I exit the funtion the reference is destroyed.

    compileShader method :

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

    You must call the method like this:

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

 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.