After following a set of OpenGL tutorials which were great but didn't let me understand the basics, I'm trying some very basic OpenGL coding with C++. My program is supposed to read a vertex and fragment shader and draw a triangle.
I get an error when linking the shaders (I suspect the error can be tracked down to the compiling of the shader though). I know my shaders are read by my program, but any changes to them doesn't affect my error. By running:
glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success); I receive the error: "Link called without any attached shader object". The programs builds, and my triangle shows, but is not affected by the shaders.
UPDATE
I no longer get the above error after fixing a mistake. I now get a complain after glCompileShader():
"Error: 0:3 'location' : syntax error parse error"
So I imagine it has to do with my shader files (will add them below). The shader files are taken from a tutorial, so I assumed they would work.
Shader files:
Vertex shader:
#version 330 layout (location = 0) in vec3 Position; void main() { gl_Position = vec4(0.5*Position.x, 0.5*Position.y, Position.z, 1.0); } Fragment shader:
#version 330 out vec4 FragColor; void main() { FragColor = vec4(1.0, 0.0, 0.0, 1.0); } In my main function i run:
compileShader(); Attach shaders:
static void AddShader(GLuint ShaderProgram, GLenum ShaderType, std::string filePath){ //create shader object GLuint ShaderObj = glCreateShader(ShaderType); //error if no shader if (ShaderObj == 0){ fprintf(stderr, "Error creating shader type %d\n", ShaderType); exit(0); } //"specify source code" //readShaderFile returns the shader file as a string std::string shaderFile = readShaderFile(filePath); const char* shaderFilePointer = shaderFile.c_str(); GLint ShaderFileLength[1]; ShaderFileLength[0] = strlen(shaderFilePointer); glShaderSource(ShaderObj, 1, &shaderFilePointer, ShaderFileLength); //compile the shader glCompileShader(ShaderObj); //check if compile successful GLint success; glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success); if (!success){ GLchar InfoLog[1024]; glGetShaderInfoLog(ShaderObj, sizeof(InfoLog), NULL, InfoLog); fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog); exit(1); } glAttachShader(ShaderProgram, ShaderObj); } And here are the functions used:
static void compileShaders(){ //create program GLuint ShaderProgram = glCreateProgram(); //check error if (ShaderProgram == 0){ fprintf(stderr, "Error creating shader program!\n"); exit(1); } //attach compiled shaders std::string vertexShaderFilePath = "Shaders/colShading.vert"; std::string fragShaderFilePath = "Shaders/colShading.frag"; AddShader(ShaderProgram, GL_VERTEX_SHADER, vertexShaderFilePath); AddShader(ShaderProgram, GL_FRAGMENT_SHADER, fragShaderFilePath); GLint Success = 0; GLchar ErrorLog[1024] = { 0 }; //link shader to program glLinkProgram(ShaderProgram); //check link error glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success); if (Success == 0) { glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog); fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog); } //use the linked shader program glUseProgram(ShaderProgram); } I doubt more of the code is needed to find the problem here, but just let me know. Thanks a lot in advance!
SOLUTION
The first answer below did the trick. I removed:
layout (location = 0) from the vertex shader and then added:
glBindAttribLocation(ShaderProgram, 0, "Position"); before the linking.
glBindAttribLocationfor?if (ShaderObj = 0){line to use comparison (==) instead of assignment (=)? It is possible it is then reassigningShaderObjto be always0, which possibly does not exist, or has the wrong type.