不能链接编译着色器的OpenGL ES 2.0编程Android版 [英] Can't link compiled shaders to program OpenGL ES 2.0 Android
问题描述
我有一个链接着色器OpenGL ES 2.0的编程问题。
这里是我的code
I have a problem with linking shaders to program in OpenGL ES 2.0. Here's my code
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的附加着色器,但是连接不。下面是该操作的日志:
The problem is, after succesfully compiling shaders I'm trying to attach my shaders to my program. It looks like ot's attaching shaders, but linking doesn't. Here's log of from this operation:
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
任何帮助将大大AP preciated
Any help would be greatly appreciated
推荐答案
您的问题就在这里:
GLES20.glShaderSource(fragmentShader, fragmentShaderSource);
GLES20.glCompileShader(vertexShader);
GLES20.glGetShaderiv(vertexShader, GL_COMPILE_STATUS, compileStatus, 0);
您正在编译vertexShader代替fragmentShader,所以vertexShader是越来越编译两次,fragmentShader是没有得到根本编译。
You're compiling the vertexShader instead of the fragmentShader, so the vertexShader is getting compiled twice, and the fragmentShader isn't getting compiled at all.
这篇关于不能链接编译着色器的OpenGL ES 2.0编程Android版的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!