glGetAttribLocation在我的一个属性上返回-1

时间:2018-05-09 11:55:51

标签: android c++ android-ndk shader opengl-es-2.0

glGetAttribLocation在我的3个属性之一(颜色)上返回-1。检查错误,状态等,一切都返回正面。在Android 7上使用OpenGL ES2。无法找到原因以及如何设置颜色与texcoord相同。

顶点着色器:

model = Sequential()
model.add(Conv3D(32, (3,3,3), activation='relu', input_shape=(1, 40, 40, 15), data_format='channels_first', padding='same'))
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 2, 2)))
model.add(Conv3D(64, (3,3,3), activation='relu', padding='same'))
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 2, 2)))
model.add(Conv3D(128, (3,3,3), activation='relu', padding='same'))
model.add(Conv3D(128, (3,3,3), activation='relu', padding='same'))
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 2, 2)))
model.add(Conv3D(256, (2,2,2), activation='relu', padding='same'))
model.add(Conv3D(256, (2,2,2), activation='relu', padding='same'))
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 2, 2)))

model.add(Flatten())

model.add(Dense(1024))
model.add(Dropout(0.5))
model.add(Dense(1024))
model.add(Dropout(0.5))
model.add(Dense(4, activation='softmax'))

model.summary()

Fragment Shader:

#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);
} 

这是我的readfile函数,以防它出错:

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;

1 个答案:

答案 0 :(得分:0)

请参阅OpenGL ES Shading Language 1.00 Specification; 7.2 Fragment Shader Special Variables; page 60

  

片段着色器的输出由OpenGL ES管道后端的固定功能操作处理。片段着色器使用内置变量gl_FragColorgl_FragData将值输出到OpenGL ES管道,除非执行discard关键字。

这意味着您必须在片段着色器(而不是可变gl_FragColor)中写入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,则不使用变量变量ColorTexcoord(由编译器优化)。这会导致未使用属性colortexcoord,但可能无效。

请参阅OpenGL ES 2 Specifications - 2.10.4 Shader Variables - p. 32

  

如果通用属性变量由编译器和链接器确定在执行着色器时可以访问该属性,则该属性变量被认为是活动的。在顶点着色器中声明但从未使用过的属性变量不被视为活动。如果编译器和链接器无法做出确定的决定,则属性将被视为活动。

     

.....

     

要确定程序使用的活动顶点属性集,并确定其类型,请使用以下命令:

     

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

     

.....

     

成功链接程序对象后,可以查询属性变量名称与索引的绑定。命令

     

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