glGetAttribLocation / glGetUniformLocation возвращает 0, вызывая EXC_BAD_ACCESS при вызове glDrawArrays (iOS) - PullRequest
3 голосов
/ 22 июля 2011

Я создаю простое приложение OpenGL ES 2.0 для iOS и всякий раз, когда я вызываю glDrawArrays. Я обнаружил, что это происходило, когда я ранее вызывал glEnableVertexAttribArray для двух моих атрибутов (position и color), а затем обнаружил, что glGetAttribLocation возвращал 1 для позиции, и 0 для цвета, а затем также обнаружил, что glGetUniformLocation возвращал 0 для моего MVP матрица. Я не уверен, является ли 0 допустимым значением или почему glEnableVertexAttribArray вызывает EXC_BAD_ACCESS, когда вызывается glDrawArrays.

Вот мой код:

функция compileShaders:

-(void)compileShaders {
GLuint vertShader = [self compileShader:@"Shader" ofType:GL_VERTEX_SHADER];
GLuint fragShader = [self compileShader:@"Shader" ofType:GL_FRAGMENT_SHADER];

GLuint program = glCreateProgram();
glAttachShader(program, vertShader);
glAttachShader(program, fragShader);
glLinkProgram(program);

GLint success;
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (success == GL_FALSE) {
    GLchar messages[256];
    glGetProgramInfoLog(program, sizeof(messages), 0, &messages[0]);
    NSLog(@"%@", [NSString stringWithUTF8String:messages]);
    exit(1);
}

glUseProgram(program);

_positionSlot = glGetAttribLocation(program, "position");
_colorSlot = glGetAttribLocation(program, "color"); //Returns 0
_mvpSlot = glGetUniformLocation(program, "MVP"); //Returns 0

if (!_positionSlot || !_colorSlot || !_mvpSlot) {
    NSLog(@"Failed to retrieve the locations of the shader variables:\n Position:%i\n Color:%i\n MVP:%i", _positionSlot, _colorSlot, _mvpSlot); //Prints out the values of 1, 0, 0
}

glEnableVertexAttribArray(_positionSlot);
glEnableVertexAttribArray(_colorSlot);

Моя функция рендеринга:

-(void)render:(CADisplayLink *)displayLink {
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

GLfloat mvp[16] = {
    1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f,
};

glUniformMatrix4fv(_mvpSlot, 1, 0, mvp);

glViewport(0, 0, width, height);

glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(_colorSlot, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, colors);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

[_context presentRenderbuffer:GL_RENDERBUFFER];
}

И мой вершинный шейдер:

attribute vec4 position;
attribute vec4 color;

uniform mat4 MVP;

varying vec4 v_color;

void main(void) {
    gl_Position = MVP * position;
    v_color = color;
}

Ответы [ 2 ]

6 голосов
/ 22 июля 2011

0 - допустимое значение, -1 - значение «ошибка» или «не найдено». Пространство для однородных местоположений и местоположений атрибутов является отдельным, поэтому хорошо иметь как единицу местоположения 0, так и атрибут местоположения 0.

Вы должны опубликовать вершины и массивы цветов, чтобы проверить, имеют ли они правильные размеры, это может вызвать сбой.

1 голос
/ 06 июля 2012

У меня та же проблема, но у меня нет решения, однако я попытался отладить ее очень широко, поэтому подумал, что, возможно, будет полезно поделиться.

Я отследил проблему до glCreateProgram() и glCreateShader()звонки.Они оба возвращают ноль, что является ошибкой возврата.Однако в обоих случаях glGetError() возвращает GL_NO_ERROR.На самом деле ни одна ошибка не появляется на протяжении всей цепочки компиляции и ссылки после вызовов create.

У меня тот же симптом, что glGetAttribLocation, а также униформа всегда возвращает ноль (вместо -1 для ошибки!),Но я даже могу кормить испорченные файлы шейдеров, и это не приведет к ошибке компиляции или какой-либо информации журнала.Была проверена правильная строка для ввода в компиляцию.

Я полностью ошеломлен поведением, потому что явно glCreateProgram ошибки, но не устанавливает ошибку.И мне совершенно не понятно, почему это делает ошибку.Что особенно запутанно, так это то, что целая цепочка вызовов функций GL не возвращает ошибок.Я получаю свою первую ошибку, когда я вызываю программу gl, которая работает с униформой, такой как glUniformMatrix4fv() или glUniform1i().Но ясно, что все сломано намного раньше, потому что все формы возвращаются как 0, хотя все они не могут быть равны нулю.

Редактировать: Я нашел решение в моем случае .Opengles1 кажется достаточно гибким при настройке кадровых буферов.Но мне нужно было заставить установку кадрового буфера, прежде чем начинать с шейдеров, чтобы избавиться от проблемы.например, если следовать старому шаблону eaglview, кадровые буферы создаются в layoutSubviews, однако это слишком поздно для типичной инициализации шейдеров, скажем, initwithcoder.Симптомы вышеупомянутые в противном случае.

...