glGetAttribLocation возвращает -1 для одного из моих атрибутов - PullRequest
0 голосов
/ 09 мая 2018

glGetAttribLocation возвращает -1 для одного из 3 моих атрибутов (цвет). Проверка на ошибки, состояние и т. Д. И все возвращается положительным. Использование OpenGL ES2 на Android 7. Просто не могу найти причину, а способ настройки цвета для меня идентичен texcoord.

Вершинный шейдер:

#version 100
attribute vec2 position;
attribute vec3 color;
attribute vec2 texcoord;

varying vec3 Color;
varying vec2 Texcoord;


void main()
   {
         Color = color;
         gl_Position = vec4(position, 0.0, 1.0);
         Texcoord = texcoord;
   }

Фрагмент шейдера:

#version 100
precision mediump float;
varying vec3 Color;
varying vec2 Texcoord;

vec4 outColor;
uniform sampler2D tex;

void main()

{
   outColor = texture2D(tex, Texcoord) * vec4(Color, 1.0);
} 

Код:

GLuint GlHelper::loadShader(char* fragment, char* vertex)
{
off_t fLength;
const char *vertexSource = FileManager::ReadFile(vertex,fLength);


// Create vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);


GLint status; GLint logLength;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
glGetShaderiv(vertexShader,GL_INFO_LOG_LENGTH,&logLength);


if (status != GL_TRUE)
{

    char buffer[logLength];
    glGetShaderInfoLog(vertexShader, logLength, NULL, buffer);

    __android_log_print(ANDROID_LOG_ERROR, QS_OPENGLTAG, "%s",buffer);

    return 0;
}

off_t fLength2;
const char *fragmentSource = FileManager::ReadFile(fragment,fLength2);

GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);

glGetShaderiv(fragmentShader,GL_COMPILE_STATUS, &status);
glGetShaderiv(fragmentShader,GL_INFO_LOG_LENGTH,&logLength);


if (status != GL_TRUE)
{

    char buffer[logLength];
    glGetShaderInfoLog(fragmentShader, logLength, NULL, buffer);

    __android_log_print(ANDROID_LOG_ERROR, QS_OPENGLTAG,"%s", buffer);
    return 0;
}

GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);

glLinkProgram(shaderProgram);

glGetProgramiv(shaderProgram,GL_LINK_STATUS,&status);
glGetProgramiv(shaderProgram,GL_INFO_LOG_LENGTH,&logLength);

if(status != GL_TRUE)
{
    char buffer[logLength];
    glGetProgramInfoLog(shaderProgram,logLength,NULL,buffer);
    __android_log_print(ANDROID_LOG_ERROR,QS_OPENGLTAG,"%s",buffer);
    return 0;
}

// Validate and error check.
glValidateProgram(shaderProgram);

glGetProgramiv(shaderProgram, GL_VALIDATE_STATUS, &status);
if(status != GL_TRUE)
{
    char buffer[512];
    glGetProgramInfoLog(shaderProgram,512,NULL,buffer);
    __android_log_print(ANDROID_LOG_ERROR,QS_OPENGLTAG,"%s",buffer);
    return 0;
}

glUseProgram(shaderProgram);

GLenum  err = glGetError();
if(err != GL_NO_ERROR)
{
    __android_log_print(ANDROID_LOG_ERROR,QS_OPENGLTAG,"%s","OpenGL error code: "); 
    return 0;
}


GLint posAttrib = glGetAttribLocation(shaderProgram, "position"); // works
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 7*sizeof(float), 0);

GLint colAttrib = glGetAttribLocation(shaderProgram, "color"); // returns -1
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 7*sizeof(float), (void*)(2*sizeof(float)));


GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord"); // works
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 7*sizeof(float), (void*)(5*sizeof(float)));

return shaderProgram;

Вот моя функция readfile, если она что-то делает не так:

const char* FileManager::ReadFile(const char *path, off_t& length)
{
  AAsset* 
asset=AAssetManager_open(FileManager::assetManager,path,AASSET_MODE_BUFFER);

  char* buff = new char[AAsset_getLength(asset)];
  length = AAsset_getLength(asset);
  AAsset_read(asset,buff,(size_t)length);
  AAsset_close(asset);
  return buff;
}

1 Ответ

0 голосов
/ 09 мая 2018

См. Спецификация OpenGL ES Shading Language 1.00;7.2. Специальные переменные шейдера фрагмента;стр. 60 :

Вывод фрагментного шейдера обрабатывается операциями с фиксированными функциями на заднем конце конвейера OpenGL ES.Фрагментные шейдеры выводят значения в конвейер OpenGL ES, используя встроенные переменные gl_FragColor и gl_FragData, если только не выполняется ключевое слово discard.

Это означает, что вы должны записать в gl_FragColor вфрагментный шейдер (вместо varaible outColor):

gl_FragColor = texture2D(tex, Texcoord) * vec4(Color, 1.0);

В OpenGL ES Shading Language 3.00 вы можете использовать квалификатор out для вывода фрагментного шейдерапеременная:

out vec4 outColor;

void main()
{
    outColor = texture2D(tex, Texcoord) * vec4(Color, 1.0);
} 

Обратите внимание, что если вы не пишете в gl_FragColor, переменные переменные Color и Texcoord не используются (оптимизировано компилятором).Это приводит к тому, что атрибуты color и texcoord не используются и могут быть неактивными.

См. Спецификации OpenGL ES 2 - 2.10.4 Переменные шейдера - с.32 :

Общая переменная атрибута считается активной, если она определена компилятором и компоновщиком, что атрибут может быть доступен при выполнении шейдера.Переменные атрибутов, которые объявлены в вершинном шейдере, но никогда не используются, не считаются активными.В случаях, когда компилятор и компоновщик не могут сделать окончательное определение, атрибут будет считаться активным.

.....

Чтобы определить набор active vertexАтрибуты, используемые программой, и для определения их типов используйте команду:

void GetActiveAttrib( uint program, uint index, sizei bufSize, sizei *length, int *size, enum *type, char *name );

.....

После того, как программный объект был успешно связанможно связать привязки имен переменных атрибутов к индексам.Команда

int GetAttribLocation( uint program, const char *name );

...