glGetAttribLocation被执行时发生错误。而且我不知道为什么。我试图检查程序,着色器和逻辑。但是我无法解决这个问题...我认为创建程序或通过程序时发生了问题。但我不知道问题出在哪里。下面是执行日志和代码。
Log
Shader has loaded : 1, 2
D/Debug: Program has linked
E/Error: vPosition attribute: GL_INVALID_OPERATION
E/AndroidRuntime: FATAL EXCEPTION: GLThread 401
Process: com.sholgames.projd, PID: 11352
java.lang.RuntimeException: Cannot find value 'vPosition'.
at com.sholgames.projd.CModel.<init>(CModel.java:114)
at com.sholgames.projd.CGLRenderer.onSurfaceCreated(CGLRenderer.java:18)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1539)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)
D/EGL_emulation: eglMakeCurrent: 0x9f76b320: ver 3 1 (tinfo 0xefaf4a40)
Process 11352 terminated.
CModel.java
public CModel(float[] verticeCoords_, short[] drawOrder_, float[] color_, int vertexShaderId_, int fragmentShaderId_) {
LogManager.LOG_DEBUG_MESSAGE("Start creating model class");
//Input factor data to member variable
mVertexCoords = verticeCoords_;
mDrawOrder = drawOrder_;
mColor = color_;
//Shader Load
mVertexShader = IOManager.LoadShaderCode(GL_VERTEX_SHADER, vertexShaderId_);
mFragmentShader = IOManager.LoadShaderCode(GL_FRAGMENT_SHADER, fragmentShaderId_);
LogManager.LOG_DEBUG_MESSAGE("Shader has loaded : " + mVertexShader + ", " + mFragmentShader);
//Create program
mProgramObject = glCreateProgram();
//Attach shader
glAttachShader(mProgramObject, mVertexShader);
LogManager.CHECK_ERROR("Attach vertex shader");
glAttachShader(mProgramObject, mFragmentShader);
LogManager.CHECK_ERROR("Attach fragment shader");
//Bind shader
glBindAttribLocation(mProgramObject, 0, "vPosition");
LogManager.CHECK_ERROR("Bind position attrib");
glBindAttribLocation(mProgramObject, 1, "vColor");
LogManager.CHECK_ERROR("Bind color attrib");
//Link program
glLinkProgram(mProgramObject);
LogManager.CHECK_ERROR("Linking program");
LogManager.LOG_DEBUG_MESSAGE("Program has linked");
int[] result = new int[1];
glGetProgramiv(mProgramObject, GL_LINK_STATUS, result, 0);
if(result[0] == -1) throw new RuntimeException("ERROR : shader program link failed.");
//active data
glUseProgram(mProgramObject);
LogManager.CHECK_ERROR("Check using program");
LogManager.LOG_DEBUG_MESSAGE("Program has actived");
//Generate buffer id
mBuffersID = new int[10];
//Vertex buffer
mVertexBuffer = ByteBuffer.allocateDirect(mVertexCoords.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mVertexBuffer.put(mVertexCoords);
mVertexBuffer.position(0);
//Draw order buffer
mDrawOrderBuffer = ByteBuffer.allocateDirect(mDrawOrder.length * 2)
.order(ByteOrder.nativeOrder()).asShortBuffer();
mDrawOrderBuffer.put(mDrawOrder);
mDrawOrderBuffer.position(0);
//Color Buffer
mColorBuffer = ByteBuffer.allocateDirect(mColor.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mColorBuffer.put(mColor);
mColorBuffer.position(0);
//VBO
glGenBuffers(3, mBuffersID, 0);
glBindBuffer(GL_ARRAY_BUFFER, mBuffersID[0]);
glBufferData(GL_ARRAY_BUFFER, mVertexCoords.length, mVertexBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, mBuffersID[1]);
glBufferData(GL_ARRAY_BUFFER, mColor.length, mColorBuffer, GL_STATIC_DRAW);
//EBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffersID[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mDrawOrder.length, mDrawOrderBuffer, GL_STATIC_DRAW);
//VAO
int[] vaoIDs = new int[1];
glGenVertexArrays(1, vaoIDs, 0);
glBindVertexArray(vaoIDs[0]);
//Pointing vertex attribute
int vertexCoordAttrib = glGetAttribLocation(mProgramObject, "vPosition");
LogManager.CHECK_ERROR("vPosition attribute");
if(vertexCoordAttrib == -1) throw new RuntimeException("Cannot find value 'vPosition'.");
int colorAttrib = glGetAttribLocation(mProgramObject, "vColor");
LogManager.CHECK_ERROR("vColor attribute");
if(colorAttrib == -1) throw new RuntimeException("Cannot find value 'vColor'.");
glBindBuffer(GL_ARRAY_BUFFER, mBuffersID[0]);
glVertexAttribPointer(vertexCoordAttrib, 3, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(vertexCoordAttrib);
glBindBuffer(GL_ARRAY_BUFFER, mBuffersID[1]);
glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(colorAttrib);
LogManager.LOG_DEBUG_MESSAGE("Create model class done");
}
vertexshader.glsl
#version 300 es
attribute vec3 vPosition;
attribute vec4 vColor;
varying vec4 vPassColor;
void main() {
gl_Position = vec4(vPosition, 1.0);
vPassColor = vColor;
}
fragmentshader.glsl
#version 300 es
precision mediump float;
varying vec4 vPassColor;
void main() {
gl_FragColor = vPassColor;
}
着色器无法编译。 attribute
中不推荐使用关键字varying
和gl_FragColor
,例如内置片段着色器输出OpenGL ES Shading Language 3.00。
使用关键字in
,out
并为片段着色器输出指定out
变量:
顶点着色器:
#version 300 es in vec3 vPosition; in vec4 vColor; out vec4 vPassColor; void main() { gl_Position = vec4(vPosition, 1.0); vPassColor = vColor; }
片段着色器:
#version 300 es precision mediump float; in vec4 vPassColor; out vec4 fragColor; void main() { fragColor = vPassColor; }
注意,在OpenGL ES 3.0中仍然可以使用OpenGL ES Shading Language 1.00 着色器。 (在这种情况下,版本指令必须仍为
#version 100 es
)