У меня есть класс, который создает OpenGL-программы, прикрепляет шейдеры и хранит идентификатор этих программ в простой std::map <std::string, GLuint>.
Вот код двух основных функций этого класса:
GLuint ShaderBuilder::build_shader(GLenum type, const GLchar * shaderStr)
{
GLuint shader = glCreateShader(type);
OutputTraceMsg(9, "glCreateShader: %x", glGetError());
if(shader == 0)
return 0;
glShaderSource(shader, 1, &shaderStr, 0);
OutputTraceMsg(9, "glShaderSource: %x", glGetError());
glCompileShader(shader);
OutputTraceMsg(9, "glCompileShader: %x", glGetError());
#ifdef DEBUG
GLint status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
//OutputTraceMsg(9, "glGetShaderiv: %d", glGetError());
if (status != GL_TRUE)
{
GLint logLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0)
{
GLchar *log = (GLchar *)malloc(logLength);
glGetShaderInfoLog(shader, logLength, &logLength, log);
OutputTraceMsg(1, "Error compiling shader: %s", log);
free(log);
}
glDeleteShader(shader);
return 0;
}
#endif
return shader;
}
GLuint ShaderBuilder::create_program(const GLchar * vertexStr, const GLchar * fragmentStr)
{
GLuint vertexShader = this->build_shader(GL_VERTEX_SHADER, vertexStr);
GLuint fragmentShader = this->build_shader(GL_FRAGMENT_SHADER, fragmentStr);
GLuint program = glCreateProgram();
if (program == 0)
{
OutputTraceMsg(3, "Filter: create program failed");
return 0;
}
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glValidateProgram(program);
#ifdef DEBUG
GLint linked;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if(!linked)
{
GLint infoLen = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 0)
{
char * infoLog = (char *)malloc(sizeof(char) * infoLen);
glGetProgramInfoLog(program, infoLen, &infoLen, infoLog);
OutputTraceMsg(3, "Error linking program: %s", infoLog);
free(infoLog);
}
glDeleteProgram(program);
return 0;
}
#endif
return program;
}
И у меня есть следующая ситуация: все шейдеры и программы компилируются на этапе инициализации, и я успешно заполняю эту std :: map идентификатором этих программ. Но после этого, когда я пытаюсь использовать любой из этих идентификаторов с некоторыми функциями OpenGL, такими как glGetAttribLocation (программа, "позиция"), OpenGL возвращает мне GL_INVALID_VALUE. Странно, потому что если я в этот момент сразу вызываю функцию create_program с теми же шейдерами, которые раньше использовал в моем классе, glGetAttribLocation (program, "position") возвращает 0. Кроме того, Instruments сообщает мне, чтобы гарантировать, что объекты программы не были удалены, но этот класс является классическим одноэлементным Мейерсом, поэтому срок жизни объекта этого класса должен быть равен времени жизни этой программы.
Убедитесь, что значение de-referenced, возвращаемое с std::map
соответствует значению объекта программы, когда оно создано при компиляции.
Убедитесь, что вы действительно выбрали программу, используя метод glUseProgram
прежде чем пытаться получить доступ к любому унифицированному/атрибуту.
Также убедитесь, что ваш текущий контекст GL установлен правильно.
EAGLContext* context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:context];
[context release];
Надеюсь, поможет.
glCreateProgram
ли выGL_INVALID_VALUE
при создании объекта программы сglCreateProgram
?