目前的情况不允许我使用电脑。它会像这样一段时间。我使用Android IDE(AIDE)在手机上进行编程。
在我的代码中,我使用glGetShaderiv()来获取编译状态,并注意到状态值为0.但是,没有迹象表明顶点着色器代码包含错误或加载GLSL代码有问题来自文本文件。
以下是代码。请注意,我将所有代码混杂在一起,以便代码的执行尽可能迭代。这意味着代码不会使用函数调用大量跳转,以便于调试。
RenderView类:
package p.e;
import android.opengl.GLSurfaceView;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import static android.opengl.GLES20.*;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.opengl.Matrix;
public class RenderView extends GLSurfaceView implements GLSurfaceView.Renderer{
private Context context;
private Table table;
private int texture;
private final float[] projectionMatrix=new float[16];
private final float[] modelMatrix=new float[16];
private Shader shader;
public RenderView(Context context){
super(context);
this.context=context;
}
@Override
public void onSurfaceCreated(GL10 p1, EGLConfig p2)
{
// TODO: Implement this method
glClearColor(1f,0f,1f,1f);
this.shader=new Shader(context);
this.table=new Table();
final int[] textureID=new int[1];
glGenTextures(1,textureID,0);
texture=textureID[0];
BitmapFactory.Options options=new BitmapFactory.Options();
options.inScaled=false;
Bitmap bitmap=BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher, options);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
GLUtils.texImage2D(GL_TEXTURE_2D,0,bitmap,0);
glGenerateMipmap(GL_TEXTURE_2D);
bitmap.recycle();
glBindTexture(GL_TEXTURE_2D,0);
}
@Override
public void onSurfaceChanged(GL10 p1, int width, int height)
{
// TODO: Implement this method
glViewport(0,0,width,height);
perspectiveM(projectionMatrix,45f, (float)width/(float)height,1f,10f);
Matrix.setIdentityM(modelMatrix, 0);
Matrix.translateM(modelMatrix,0,0f,0f,-2.5f);
Matrix.rotateM(modelMatrix,0,-60f,1f,0f,0f);
final float[] temp=new float[16];
Matrix.multiplyMM(temp,0,projectionMatrix,0,modelMatrix,0);
System.arraycopy(temp,0,projectionMatrix,0,temp.length);
}
@Override
public void onDrawFrame(GL10 p1)
{
// TODO: Implement this method
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader.getProgram());
glUniformMatrix4fv(shader.uMatrixLocation, 1, false, projectionMatrix,0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texture);
glUniform1i(shader.uTextureUnitLocation,0);
table.getVertexBuffer().position(0);
glVertexAttribPointer(shader.aPositionLocation, 2, GL_FLOAT,false,2*4,table.getVertexBuffer());
//glBindBuffer(GL_ARRAY_BUFFER, table.vertexBufferPointer);
//table.getVertexBuffer().position(0);
glEnableVertexAttribArray(shader.aPositionLocation);
//table.getVertexBuffer().rewind();
table.getVertexBuffer().position(0);
//table.getTexBuffer().position(0);
//glBindBuffer(GL_ARRAY_BUFFER, table.texBufferPointer);
table.getTexBuffer().position(0);
glVertexAttribPointer(shader.aTexPositionLocaton,2,GL_FLOAT,false,2*4,table.getTexBuffer());
glEnableVertexAttribArray(shader.aTexPositionLocaton);
//table.getTexBuffer().rewind();
table.getTexBuffer().position(0);
glDrawArrays(GL_TRIANGLE_FAN,0,4);
//glDisableVertexAttribArray(shader.aPositionLocation);
//glDisableVertexAttribArray(shader.aTexPositionLocaton);
}
public static void perspectiveM(float[] m, float yFovInDegrees, float aspect, float n, float f) {
final float angleInRadians = (float) (yFovInDegrees * Math.PI / 180.0);
final float a = (float) (1.0 / Math.tan(angleInRadians / 2.0));
m[0] = a / aspect;
m[1] = 0f;
m[2] = 0f;
m[3] = 0f;
m[4] = 0f;
m[5] = a;
m[6] = 0f;
m[7] = 0f;
m[8] = 0f;
m[9] = 0f;
m[10] = -((f + n) / (f - n));
m[11] = -1f;
m[12] = 0f;
m[13] = 0f;
m[14] = -((2f * f * n) / (f - n));
m[15] = 0f;
}
} `
表类:
package p.e;
import java.nio.*;
import static android.opengl.GLES20.*;
public class Table
{
private FloatBuffer vertexBuffer;
private FloatBuffer texBuffer;
public int vertexBufferPointer;
public int texBufferPointer;
private final float[] vertexData={
-0.5f,-0.5f,
0.5f,-0.5f,
0.5f,0.5f,
-0.5f,0.5f
};
private final float[] texData={
0f,1f,
1f,1f,
1f,0f,
0f,0f
};
public Table(){
int[] bufferPointer=new int[1];
glGenBuffers(1,bufferPointer,0);
vertexBuffer=ByteBuffer.allocateDirect(vertexData.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexBuffer.put(vertexData);
vertexBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, bufferPointer[0]);
glBufferData(GL_ARRAY_BUFFER, vertexData.length*4, vertexBuffer, GL_STATIC_DRAW);
vertexBufferPointer=bufferPointer[0];
texBuffer=ByteBuffer.allocateDirect(texData.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
texBuffer.put(texData);
texBuffer.flip();
glGenBuffers(1, bufferPointer,0);
glBindBuffer(GL_ARRAY_BUFFER,bufferPointer[0]);
glBufferData(GL_ARRAY_BUFFER,texData.length*4, texBuffer, GL_STATIC_DRAW);
}
public FloatBuffer getVertexBuffer(){
return vertexBuffer;
}
public FloatBuffer getTexBuffer(){
return texBuffer;
}
}
着色器类:
package p.e;
import java.io.*;
import android.content.Context;
import static android.opengl.GLES20.*;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ByteBuffer;
import android.util.Log;
import java.nio.ByteOrder;
public class Shader
{
private int program;
private final String U_MATRIX="u_matrix";
private final String U_TEXTUREUNIT="u_texUnit";
private final String A_POSITION="a_position";
private final String A_TEXCOORDS="a_texPos";
public int uMatrixLocation;
public int uTextureUnitLocation;
public int aPositionLocation;
public int aTexPositionLocaton;
public Shader(Context context){
int vertex=glCreateShader(GL_VERTEX_SHADER);
IntBuffer intBuf=ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
Log.wtf("Code",Shader.loadString(context,R.raw.tex_vert));
glShaderSource(vertex,Shader.loadString(context,R.raw.tex_vert));
glCompileShader(vertex);
//check
int status;
glGetShaderiv(vertex, GL_COMPILE_STATUS, intBuf);
status=intBuf.get(0);
if(status==0){
glGetShaderiv(vertex,GL_INFO_LOG_LENGTH,intBuf);
status=intBuf.get(0);
if (status>1){
Log.i("Shader","Vertex Shader: "+glGetShaderInfoLog(vertex));
}
glDeleteShader(vertex);
Log.w("Shader","Vertex Shader error.");
return;
}
//check end
int fragment=glCreateShader(GL_FRAGMENT_SHADER);
Log.wtf("Code",Shader.loadString(context,R.raw.tex_frag));
glShaderSource(fragment, Shader.loadString(context,R.raw.tex_frag));
glCompileShader(fragment);
//check
glGetShaderiv(fragment, GL_COMPILE_STATUS, intBuf);
status=intBuf.get(0);
Log.i("Shader","Fragment Shader: "+glGetShaderInfoLog(fragment));
if(status==0){
glDeleteShader(fragment);
Log.w("Shader","Fragment Shader error.");
return;
}
//check end
program=glCreateProgram();
//check
Log.i("Shader","Program: "+glGetProgramInfoLog(program));
if(program==0){
Log.w("Shader","Program not created.");
return;
}
//check end
glAttachShader(program,vertex);
glAttachShader(program,fragment);
glLinkProgram(program);
//check
glValidateProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, intBuf);
status=intBuf.get(0);
if(status==0){
glDeleteProgram(program);
Log.w("Shader","Program unable to link.");
return;
}
//check end
//check
glGetProgramiv(program, GL_VALIDATE_STATUS, intBuf);
status=intBuf.get(0);
Log.i("Shader","Program validation: "+glGetProgramInfoLog(program));
if(status==0){
glDeleteProgram(program);
Log.w("Shader","Program validation failed.");
return;
}
//check end
uMatrixLocation=glGetUniformLocation(program,U_MATRIX);
uTextureUnitLocation=glGetUniformLocation(program,U_TEXTUREUNIT);
aPositionLocation=glGetAttribLocation(program,A_POSITION);
aTexPositionLocaton=glGetAttribLocation(program,A_TEXCOORDS);
}
public void setVertexAttributePointer(int location, int offset, int componentCount, int type, boolean isTranspose, int stride, FloatBuffer buffer){
buffer.position(offset);
glVertexAttribPointer(location, componentCount,type,isTranspose,stride,buffer);
glEnableVertexAttribArray(location);
buffer.rewind();
}
public void setup(FloatBuffer vertexBuffer, FloatBuffer texBuffer){
vertexBuffer.position(0);
glVertexAttribPointer(aPositionLocation, 2, GL_FLOAT,false,0,vertexBuffer);
glEnableVertexAttribArray(aPositionLocation);
vertexBuffer.rewind();
texBuffer.position(0);
glVertexAttribPointer(aTexPositionLocaton,2,GL_FLOAT,false,0,texBuffer);
glEnableVertexAttribArray(aTexPositionLocaton);
texBuffer.rewind();
}
public int getProgram(){
return program;
}
public void bind(int texture, float[] matrix){
glUniformMatrix4fv(uMatrixLocation, 1, false, matrix,0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texture);
glUniform1i(uTextureUnitLocation,0);
}
private static String loadString(Context context, int resourceID){
StringBuilder builder=new StringBuilder();
try{
BufferedReader reader=new BufferedReader(new InputStreamReader(context.getResources().openRawResource(resourceID)));
String line;
while((line=reader.readLine())!=null){
builder.append(line);
builder.append('\n');
}
}
catch(Exception e){
}
return builder.toString();
}
}
以下是着色器源代码。
顶点着色器:
uniform mat4 u_matrix;
attribute vec4 a_position;
attribute vec2 a_texPos;
varying vec2 v_texPos;
void main{
v_texPos=a_texPos;
gl_Position=u_matrix*a_position;
}
Fragment Shader:
precision mediump float;
uniform sampler2D u_texUnit;
varying vec2 v_texPos;
void main(){
gl_FragColor=texture2D(u_texUnit,v_texPos);
}
我将发布Logcat的屏幕截图,只显示短语“Vertex shader error”调试消息。 GL_INVALID_OPERATION是由顶点着色器状态为0,被删除并返回到onSurfaceCreated()而无法指向矩阵位置引起的,因为在该时间点不存在顶点着色器。
答案 0 :(得分:0)
我认为这只是一个简单的错字。在main:
之后缺少顶点着色器()void main{
需要:
void main(){