我在将着色器链接到OpenGL ES 2.0中的程序时遇到问题。这是我的代码
package pl.projekcik;
import android.content.Context;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.logging.Logger;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import util.LoggerConfig;
import util.ShaderHelper;
import util.TextResourceReader;
import static android.opengl.GLES20.*;
import static android.opengl.GLUtils.*;
import static android.opengl.Matrix.*;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.util.Log;
public class ProjekcikRenderer implements Renderer {
private static final int POSITION_COMPONENT_COUNT = 3;
private static final int BYTES_PER_FLOAT = 4;
private final FloatBuffer vertexData;
private final Context context;
private int program;
private static final String U_COLOR = "u_COLOR";
private int uColorLocation;
private static final String A_POSITION = "a_Position";
private int aPositionLocation;
private static final String TAG = "ProjekcikRenderer";
public ProjekcikRenderer(Context context){
this.context = context;
float[] tableVertices = {
0f, 0f, 0f,
1f, 1f, 0f,
0f, 1f, 0f,
0f, 0f, 0f,
1f, 0f, 0f,
1, 1f, 0f
};
vertexData = ByteBuffer
.allocateDirect(tableVertices.length * BYTES_PER_FLOAT)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
vertexData.put(tableVertices);
}
@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config){
glClearColor(1.0f, 1.0f, 0.5f, 0.0f);
String vertexShaderSource = null;
String fragmentShaderSource = null;
try{
vertexShaderSource = TextResourceReader.readTextFileFromResource(context, R.raw.simple_vertex_shader);
fragmentShaderSource = TextResourceReader.readTextFileFromResource(context, R.raw.simple_fragment_shader);
} catch (IOException e){
throw new RuntimeException("IOException", e);
} catch (Exception e){
throw new RuntimeException("Other Exception", e);
}
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
Log.d(TAG, "CREATING VERTEX SHADER");
String s = new String(Integer.toString(vertexShader));
if(vertexShader == 0){
if(LoggerConfig.ON){
Log.w(TAG, "Could not create new VERTEX shader");
}
return;
} else {
if(LoggerConfig.ON){
Log.w(TAG, s);
}
}
GLES20.glShaderSource(vertexShader, vertexShaderSource);
GLES20.glCompileShader(vertexShader);
final int[] compileStatus = new int[1];
GLES20.glGetShaderiv(vertexShader, GL_COMPILE_STATUS, compileStatus, 0);
if(LoggerConfig.ON){
Log.v(TAG, "Results of compiling source:" + "\n" + vertexShaderSource + "\n" + glGetShaderInfoLog(vertexShader));
}
if(compileStatus[0] == 0){
glDeleteShader(vertexShader);
if(LoggerConfig.ON){
Log.w(TAG, "Compilation of shader failed");
}
return;
} else {
if(LoggerConfig.ON){
Log.v(TAG, "VERTEX SHADER COMPILED");
}
}
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
Log.d(TAG, "CREATING FRAGMENT SHADER");
s = new String(Integer.toString(fragmentShader));
if(fragmentShader == 0){
if(LoggerConfig.ON){
Log.w(TAG, "Could not create new FRAGMENT shader");
}
return;
} else {
if(LoggerConfig.ON){
Log.w(TAG, s);
}
}
GLES20.glShaderSource(fragmentShader, fragmentShaderSource);
GLES20.glCompileShader(vertexShader);
GLES20.glGetShaderiv(vertexShader, GL_COMPILE_STATUS, compileStatus, 0);
if(LoggerConfig.ON){
Log.v(TAG, "Results of compiling source:" + "\n" + fragmentShaderSource + "\n" + glGetShaderInfoLog(fragmentShader));
}
if(compileStatus[0] == 0){
glDeleteShader(fragmentShader);
if(LoggerConfig.ON){
Log.w(TAG, "Compilation of shader failed");
}
return;
} else {
if(LoggerConfig.ON){
Log.v(TAG, "FRAGMENT SHADER COMPILED");
}
}
program = GLES20.glCreateProgram();
s = new String(Integer.toString(program));
Log.v("PROGRAM ID: ", s);
if(program == 0){
if(LoggerConfig.ON){
Log.w(TAG, "Could not create new program");
}
return;
}
try{
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
} catch (Exception e){
Log.w("ATTACH", "COULD NOT ATTACH 1 OR MORE SHADERS");
}
try{
GLES20.glLinkProgram(program);
} catch (Exception e){
Log.w("LINK", "Link program failed");
}
final int[] linkStatus = new int[1];
glGetProgramiv(program, GL_LINK_STATUS, linkStatus, 0);
if(LoggerConfig.ON){
Log.v(TAG, "Results of linking program:\n" + glGetProgramInfoLog(program));
}
if(linkStatus[0] == 0){
glDeleteProgram(program);
if(LoggerConfig.ON){
Log.w(TAG, "Linking of program failed");
}
return;
}
if(LoggerConfig.ON){
validateProgram(program);
}
glUseProgram(program);
uColorLocation = glGetUniformLocation(program, U_COLOR);
aPositionLocation = glGetAttribLocation(program, A_POSITION);
vertexData.position(0);
glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, 0, vertexData);
glEnableVertexAttribArray(aPositionLocation);
}
@Override
public void onSurfaceChanged(GL10 glUnused, int width, int height){
glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 glUnused){
glClear(GL_COLOR_BUFFER_BIT);
glUniform4f(uColorLocation, 0.0f, 0.0f, 0.0f, 1.0f);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
public static boolean validateProgram(int programObjectId){
glValidateProgram(programObjectId);
final int[] validateStatus = new int[1];
glGetProgramiv(programObjectId, GL_VALIDATE_STATUS, validateStatus, 0);
Log.v(TAG, "Results of validating program: " + validateStatus[0] + "\nLog: " + glGetProgramInfoLog(programObjectId));
return validateStatus[0] != 0;
}
}
问题是,成功编译着色器后,我试图将着色器附加到程序中。看起来像ot的附加着色器,但链接没有。这是此操作的日志:
08-12 11:24:10.330 23044-23044/pl.projekcik D/libEGL﹕ loaded /system/lib/egl/libEGL_mali.so
08-12 11:24:10.330 23044-23044/pl.projekcik D/libEGL﹕ loaded /system/lib/egl/libGLESv1_CM_mali.so
08-12 11:24:10.340 23044-23044/pl.projekcik D/libEGL﹕ loaded /system/lib/egl/libGLESv2_mali.so
08-12 11:24:10.350 23044-23044/pl.projekcik D/OpenGLRenderer﹕ Enabling debug mode 0
08-12 11:24:10.420 23044-23057/pl.projekcik D/ProjekcikRenderer﹕ CREATING VERTEX SHADER
08-12 11:24:10.420 23044-23057/pl.projekcik W/ProjekcikRenderer﹕ 1
08-12 11:24:10.420 23044-23057/pl.projekcik V/ProjekcikRenderer﹕ Results of compiling source:
attribute highp vec4 a_Position;
void main(){
gl_Position = a_Position;
}
08-12 11:24:10.420 23044-23057/pl.projekcik V/ProjekcikRenderer﹕ VERTEX SHADER COMPILED
08-12 11:24:10.420 23044-23057/pl.projekcik D/ProjekcikRenderer﹕ CREATING FRAGMENT SHADER
08-12 11:24:10.420 23044-23057/pl.projekcik W/ProjekcikRenderer﹕ 2
08-12 11:24:10.420 23044-23057/pl.projekcik V/ProjekcikRenderer﹕ Results of compiling source:
precision mediump float;
uniform vec4 u_Color;
void main(){
gl_FragColor = u_Color;
}
08-12 11:24:10.420 23044-23057/pl.projekcik V/ProjekcikRenderer﹕ FRAGMENT SHADER COMPILED
08-12 11:24:10.420 23044-23057/pl.projekcik V/PROGRAM ID:﹕ 3
08-12 11:24:10.420 23044-23057/pl.projekcik V/ProjekcikRenderer﹕ Results of linking program:
L0101 All attached shaders must be compiled prior to linking
08-12 11:24:10.420 23044-23057/pl.projekcik W/ProjekcikRenderer﹕ Linking of program failed
08-12 11:24:10.430 23044-23046/pl.projekcik D/dalvikvm﹕ GC_CONCURRENT freed 270K, 8% free 6260K/6791K, paused 17ms+4ms, total 81ms
任何帮助将不胜感激
您的问题在这里:
GLES20.glShaderSource(fragmentShader, fragmentShaderSource);
GLES20.glCompileShader(vertexShader);
GLES20.glGetShaderiv(vertexShader, GL_COMPILE_STATUS, compileStatus, 0);
您正在编译vertexShader而不是fragmentShader,因此vertexShader被编译了两次,而fragmentShader根本没有被编译。