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? - developerbmwif (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. - Sebastian Mendez