Error 1282 glUseProgram, very strange...

Started by
6 comments, last by Brother Bob 11 years, 6 months ago
Hi!
I have the next code, where I get an error and the program close:

main

[...]
glUseProgram(shader->ID);
ExitOnGLError("ERROR: Could use the shader");
[...]


util.cpp

void ExitOnGLError(const char* error_message)
{
const GLenum ErrorValue = glGetError();
cout<<ErrorValue<<endl; //output '1282'
if(ErrorValue != GL_NO_ERROR)
{
cout<<"hola "<<ErrorValue<<endl;
const char* APPEND_DETAIL_STRING = ": %s\n";
// strlen: retorna un numero de caracteres
const size_t APPEND_LENGTH = strlen(APPEND_DETAIL_STRING) + 1;
const size_t message_length = strlen(error_message);
char* display_message = (char*)malloc(message_length + APPEND_LENGTH);
memcpy(display_message, error_message, message_length);
memcpy(&display_message[message_length], APPEND_DETAIL_STRING, APPEND_LENGTH);
fprintf(stderr, display_message, gluErrorString(ErrorValue));
free(display_message);
exit(EXIT_FAILURE);
}
}


But if I use this code, I don´t get any error and the program works!

main


glUseProgram(shader->ID);
const GLenum ErrorValue = glGetError();
cout<<ErrorValue<<endl; // output '0'
ExitOnGLError("ERROR: Could use the shader"); // Any error here and the program continue..


Does anyone know why this is happening?
Advertisement
The reason the latter works is that glGetError() is called twice, and as the first one is called without resulting in an error, glGetError() returns 0 inside the ExitOnGLError() function.

IIRC, 1282 Means invalid value. - Are you sure that shader->ID was created from a glLinkProgram() successfully prior to that?

The reason the latter works is that glGetError() is called twice, and as the first one is called without resulting in an error, glGetError() returns 0 inside the ExitOnGLError() function.

IIRC, 1282 Means invalid value. - Are you sure that shader->ID was created from a glLinkProgram() successfully prior to that?


I think that the program was linked successfully.


void CheckLink(GLuint id)
{
//CheckAndLog(id,GL_LINK_STATUS,"conexion");
GLint compiled = 0;
GLint length = 0;
glGetProgramiv(id, GL_LINK_STATUS, &compiled);
if(compiled == 0)
{
std::cerr<<"ERROR: linking fail"<<std::endl;
glGetProgramiv(id, GL_INFO_LOG_LENGTH, &length);
if(length > 1) {
std::string log(length, '\0');
glGetProgramInfoLog(id, length, &length, &log[0]);
std::cerr<<log<<std::endl;
exit(1);
}
}else
{
std::cout<<"linkage was successfully"<<std::endl;
}


This code don´t give me any error
Show more code, preferably a minimum complete program. There is likely more to this problem that what you have shown. For example, if you're only checking the error state after glUseProgram, then the error could be at any point before that because error bits are never reset by functions other that glGetError so the error can come from earlier functions within your program.
engine.cpp



void Engine::CreateMesh(void)
{
mesh = content.Load<Mesh>("Models/cube2.obj");

shader = content.Load<Shader>("Shaders/simpleshader.glsl");

ModelMatrixUniformLocation = shader->GetUniformLocation("ModelMatrix");
ViewMatrixUniformLocation = shader->GetUniformLocation("ViewMatrix");
ProjectionMatrixUniformLocation = shader->GetUniformLocation("ProjectionMatrix");
ExitOnGLError("ERROR: Could not get the uniform locations");

Texture* texture0 = content.Load<Texture>("Textures/cube.bmp");
Tex0Loc = shader->GetUniformLocation("texture0");
ExitOnGLError("Error: Could not load texture");
}

void Engine::DrawMesh(void)
{

glUseProgram(shader->ID);
ExitOnGLError("ERROR: Could not use the shader"); // Error 1282

glUniformMatrix4fv(ModelMatrixUniformLocation, 1, GL_FALSE, value_ptr(ModelMatrix));
ExitOnGLError("ERROR: Could not set the model matrix");

ViewMatrix = lookAt(
vec3(0.0, 2.0, 4.0), //eye
vec3(0.0 ,0.0 , 0.0), //direction
vec3(0.0, 1.0, 0.0) //up
);
glUniformMatrix4fv(ViewMatrixUniformLocation, 1, GL_FALSE, value_ptr(ViewMatrix));
ExitOnGLError("ERROR: Could not set the view matrix");

ProjectionMatrix = perspective(45.0f, (float) CurrentWidth / CurrentHeight , 0.1f, 100.0f);
glUniformMatrix4fv(ProjectionMatrixUniformLocation, 1, GL_FALSE, value_ptr(ProjectionMatrix));
ExitOnGLError("ERROR: Could not set the projection matrix");
glUniform1i(Tex0Loc, 0);
mesh->Draw();
glUseProgram(0);
}


Shader.cpp


void Shader::Load(const char* filename)
{
ifstream in(filename, ios::binary);
if(!in)
{
cerr << "Could not open the file" << filename << endl; // Lanzamos un mensaje de error
exit(1); // exit(1) usado para abortar el programa
}
//Leemos los datos
std::string glsl_source((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
// Terminamos de leer el documento
in.close();
//miramos si hay algo
if(glsl_source.length() == 0)
{
cerr<<"ERROR: Any data in the file"<<endl;
exit(1);
}
std::string fs_shader = "#version 330\n #define COMPILING_FS\n" + glsl_source;
std::string vs_shader = "#version 330\n #define COMPILING_VS\n" + glsl_source;
// Creamos el programa
ID = glCreateProgram();
fragmentShaderID = CreateShader(fs_shader,GL_FRAGMENT_SHADER);
vertexShaderID = CreateShader(vs_shader,GL_VERTEX_SHADER);
Initialize();
}

GLuint Shader::CreateShader(std::string shader, GLenum type_shader)
{
GLuint shader_id = 0;
const char* glsl_cstr;
shader_id = glCreateShader(type_shader);
glShaderSource(shader_id, 1, &(glsl_cstr=shader.c_str()),NULL);
glCompileShader(shader_id);
ExitOnGLError("Could not compile the shader");
CheckCompile(shader_id);
return shader_id;
}

void Shader::Initialize(void)
{
glAttachShader(ID, fragmentShaderID);
ExitOnGLError("No se puede vincular el Fragment Shader");
glAttachShader(ID, vertexShaderID);
ExitOnGLError("No se puede vincular el Vertex Shader");
glLinkProgram(ID);
ExitOnGLError("No se puede conectar al programa");
CheckLink(ID);
}

GLint Shader::GetUniformLocation(const char* param)
{
return glGetUniformLocation(ID, param);
}

void CheckCompile(GLuint id)
{
GLint compiled = 0;
GLint length = 0;
glGetShaderiv(id, GL_COMPILE_STATUS, &compiled);
if(compiled == 0)
{
std::cerr<<"ERROR: The shader´s compilation fail"<<std::endl;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
if(length > 1) {
std::string log(length, '\0');
glGetShaderInfoLog(id, length, &length, &log[0]);
std::cerr<<log<<std::endl;
exit(1);
}
}else
{
std::cout<<"The shader´s compilation was successfully"<<std::endl;
}
}

void CheckLink(GLuint id)
{
//CheckAndLog(id,GL_LINK_STATUS,"conexion");
GLint compiled = 0;
GLint length = 0;
glGetProgramiv(id, GL_LINK_STATUS, &compiled);
if(compiled == 0)
{
std::cerr<<"ERROR: The linking fail"<<std::endl;
glGetProgramiv(id, GL_INFO_LOG_LENGTH, &length);
if(length > 1) {
std::string log(length, '\0');
glGetProgramInfoLog(id, length, &length, &log[0]);
std::cerr<<log<<std::endl;
exit(1);
}
}else
{
std::cout<<"The linking was successfully"<<std::endl;
}
}
Have you implemented proper copy or move semantics for your shader objects?
Sorry, I can´t understand your question.What do you mean exactly?
In Engine::CreateMesh you're creating the shader and returning it by value. This means the shader object has to be copied from the function content.Load<Shader>() to the object shader. If you have not written a proper constructors, an assignment operator and a destructor to treat the object as a value, you cannot use the shader object as if it was a value either but that is what you're currently doing.

Look up the Rule of Three; here's a clicky for an example.

This topic is closed to new replies.

Advertisement