У меня есть класс, который создает программу OpenGL, присоединяет шейдер и хранят идентификаторы этих программ в простом std::map <std::string, GLuint>.
программа Повторного использования в OpenGL на прошивке
Вот код из двух основных функций этого класса:
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 сообщает мне, чтобы гарантировать, что объекты программы не были удалены, но этот класс является классическим одноэлементным Мейерсом, поэтому срок жизни объекта этого класса должен быть равен времени жизни этой программы.
Выделенное значение соответствует значению программного объекта, который я создал на этапе инициализации. И я использую glUseProgram сразу после того, как у меня есть идентификатор программы. Он также возвращает GL_INVALID_VALUE :( – vglazkov
Вы получаете 'GL_INVALID_VALUE', когда вы создаете объект программы с помощью' glCreateProgram'? –
№. Контекст тоже настроен правильно. Примечание: если я вызову glUseProgram сразу после создания программы - это нормально, верните значение равно 0, но если я попытаюсь использовать этот идентификатор после завершения инициализации класса в одной функции, у меня такая же ошибка, в другом я получил 0. Между этими функциями нет вызовов OpenGL ES, и они следуют один за другим. – vglazkov