2013-04-13 185 views
1

我学习gles2.0(我是一个新的叮咬:))在Android上,我要画一个正方形纹理,但是我不能。我GOOGLE了很多,但我无法弄清楚答案,我只得到一个黑色的方块。Android的OpenGL ES 2.0的黑色纹理

我建立了一个GLSurfaceView,然后渲染:

public class MySurfaceRenderer implements GLSurfaceView.Renderer { 

    private Context context; 
    private Sprite sprite1; 

    @Override 
    public void onDrawFrame(GL10 gl) { 
     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 
     sprite1.Draw(); 
    } 

    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 
     GLES20.glViewport(0, 0, width, height); 
    } 

    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
     GLES20.glEnable(GLES20.GL_BLEND); 
     GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA,GLES20.GL_ONE_MINUS_SRC_ALPHA); 
     GLES20.glClearColor(0.0f, 0.3f, 0.0f, 1.0f); 
     sprite1 = new Sprite(context, R.drawable.test); 
    } 

} 

Sprite类:

public class Sprite { 

    private static String TAG = "SpriteRender"; 

    private Context context; 

    private FloatBuffer databuffer; 
    private FloatBuffer texturebuffer; 
    // x, y, 
    float data[] = {-0.5f, -0.5f, 
        -0.5f, 0.5f, 
        0.5f, 0.5f, 
        0.5f, -0.5f}; 
    // u,v 
    float texturedata[] = {0.0f, 0.0f, 
          0.0f, 1.0f, 
          1.0f, 1.0f, 
          1.0f, 0.0f}; 
    private int mProgram; 
    private int vertexShader; 
    private int fragmentShader; 
    private int texture; 
    private int positionHandler; 
    private int texCoordHandler; 
    private int textureHandler; 

    public Sprite(Context context, int textureid){ 
     this.context = context; 

     ByteBuffer bb_data = ByteBuffer.allocateDirect(data.length * 4); 
     bb_data.order(ByteOrder.nativeOrder()); 
     ByteBuffer bb_texture = ByteBuffer.allocateDirect(texturedata.length * 4); 
     bb_texture.order(ByteOrder.nativeOrder()); 

     databuffer = bb_data.asFloatBuffer(); 
     databuffer.put(data); 
     databuffer.position(0); 
     texturebuffer = bb_texture.asFloatBuffer(); 
     texturebuffer.put(texturedata); 
     texturebuffer.position(0); 

     vertexShader = ShaderLoader.loadShader(GLES20.GL_VERTEX_SHADER, ShaderLoader.readFromAssert(context, R.raw.tvs)); 
     fragmentShader = ShaderLoader.loadShader(GLES20.GL_FRAGMENT_SHADER, ShaderLoader.readFromAssert(context, R.raw.tfs)); 

     mProgram = GLES20.glCreateProgram(); 
     GLES20.glAttachShader(mProgram, fragmentShader); 
     GLES20.glAttachShader(mProgram, vertexShader); 
     GLES20.glLinkProgram(mProgram); 

     int[] linkStatus = new int[1]; 
     GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linkStatus, 0); 

     if (linkStatus[0] == 0){ 
      // Displays error message 
     } 
     positionHandler  = GLES20.glGetAttribLocation(mProgram, "a_Position"); 
     texCoordHandler  = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate"); 
     textureHandler  = GLES20.glGetUniformLocation(mProgram, "u_Texture"); 

     texture = TextureLoader.loadTexture(context, textureid); 
    } 

    public void Draw(){ 
     GLES20.glUseProgram(mProgram); 
     databuffer.position(0); 
     texturebuffer.position(0); 

     GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture); 

     GLES20.glUniform1i(textureHandler, 0); 

     GLES20.glEnableVertexAttribArray(texCoordHandler); 
     GLES20.glEnableVertexAttribArray(positionHandler); 

     GLES20.glVertexAttribPointer(positionHandler, 2, GLES20.GL_FLOAT, false, 8, databuffer); 
     GLES20.glVertexAttribPointer(texCoordHandler, 2, GLES20.GL_FLOAT, false, 8, texturebuffer); 

     GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4); 
    } 

} 

ShaderLoader.loadShader从文件中装载的着色器(在res /生), TextureLoader。 loadTexture加载从资源纹理:

public static int loadTexture(Context context, int resource){ 
    int[] texture = new int[1]; 

    GLES20.glGenTextures(1, texture, 0); 

    BitmapFactory.Options bo = new BitmapFactory.Options(); 
    bo.inScaled = false; 
    Bitmap tex = BitmapFactory.decodeResource(context.getResources(), resource, bo); 

    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, tex, 0); 
    tex.recycle(); 

    if(texture[0] == 0){ 
     // Displays error 
    } 

    return texture[0]; 

} 

顶点着色器:

attribute vec4 a_Position; 
attribute vec2 a_TexCoordinate; 
varying vec2 v_TexCoordinate; 

void main() { 
    v_TexCoordinate = a_TexCoordinate; 
    gl_Position = a_Position; 
} 

片段着色器:

precision mediump float; 
varying vec2 v_TexCoordinate; 
uniform sampler2D u_Texture; 

void main() { 
    gl_FragColor = texture2D(u_Texture, v_TexCoordinate); 
} 

我看了一些东西:

  • 与PNG,JPG,BMP(565),分辨率测试:32×32和64×64
  • 在绘制函数所有线glGetError()返回0
  • 后当加载一个纹理,Sprite.texture不为0(它的约700 01)
  • 如果我改变片段着色器以gl_FragColor = vec4(1.0,0.0,0.0,0.5);它正在工作。

感谢您的帮助!

回答

0

我已经想通了答案:

当我装纹理,我没有把它正确地传递给OpenGL的。

我添加TextureLoader.loadTexture一个GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,纹理[0]);这样的线:

... 
Bitmap tex = BitmapFactory.decodeResource(context.getResources(), resource, bo);  
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[0]); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
... 

现在它的工作。