OpenGL ES 2.0:Vertex Shader编译状态结果为0,没有着色器日志信息

时间:2014-01-16 08:27:13

标签: java android opengl-es compilation shader

目前的情况不允许我使用电脑。它会像这样一段时间。我使用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()而无法指向矩阵位置引起的,因为在该时间点不存在顶点着色器。

Screenshot

1 个答案:

答案 0 :(得分:0)

我认为这只是一个简单的错字。在main:

之后缺少顶点着色器()
void main{

需要:

void main(){