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