2012-02-19 125 views
1

我在Android平台上编码。我正在尝试为三角形使用纹理(从资源文件夹加载图像)。当我的应用程序运行时,它只是三角形中的空白(不是我想要的纹理)。OpenGL ES:使用纹理:空白而不是纹理图像

我读过一些说图像必须是两个幂的源。我已经检查过,我的形象是两个权力。 (128 x 128)。这就是为什么让我头痛的原因。

这里是我的代码(你应该在方法主要看代码,它包含了我使用的渲染代码)

package com.test; 

import java.io.IOException; 
import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 

import android.app.Activity; 
import android.content.res.AssetManager; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.opengl.GLSurfaceView; 
import android.opengl.GLSurfaceView.Renderer; 
import android.opengl.GLUtils; 
import android.os.Bundle; 
import android.util.Log; 

public class TextureTriangleTest extends Activity{ 

    GLSurfaceView glView; 
    ByteBuffer byteBuffer; 
    FloatBuffer vertices; 
    AssetManager assets; 

    @Override 
    public void onCreate(Bundle savedInstanceState){ 

     super.onCreate(savedInstanceState); 
     assets = getAssets(); 

     int VERTEX_SIZE = (2+2)*4; 
     byteBuffer = ByteBuffer.allocateDirect(3*VERTEX_SIZE); 
     byteBuffer.order(ByteOrder.nativeOrder()); 
     vertices = byteBuffer.asFloatBuffer(); 
     vertices.put(new float[] { 0.0f, 0.0f, 0.0f, 1.0f, 
            319.0f, 0.0f, 1.0f, 1.0f, 
            160.0f, 479.0f, 0.5f, 0.0f }); 
     vertices.flip(); 

     glView = new GLSurfaceView(this); 
     glView.setRenderer(new Render()); 
     setContentView(glView); 

    } 



    class Render implements Renderer{ 

     @Override 
     public void onDrawFrame(GL10 gl) { 

      try { 

       Bitmap bitmap = BitmapFactory.decodeStream(assets.open("bobrgb888.png")); 
       int textureIds[] = new int[1]; 
       gl.glGenTextures(1, textureIds, 0); 
       int textureId = textureIds[0]; 

       gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); 
       GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 
       gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); 
       gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); 
       gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); 

       bitmap.recycle(); 

      } catch (IOException e) { 
       Log.d("", "FAILED LOAD FILE"); 
       throw new RuntimeException("Couldn't load asset!"); 
      } 

      gl.glViewport(0, 0, glView.getWidth(), glView.getHeight()); 
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 
      gl.glMatrixMode(GL10.GL_PROJECTION); 
      gl.glLoadIdentity(); 
      gl.glOrthof(0, 320, 0, 480, 1, -1); 

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
      gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 

      int VERTEX_SIZE = (2+2)*4; 
      vertices.position(0); 
      gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices); 
      vertices.position(2); 
      gl.glTexCoordPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices); 

      gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); 

     } 

     @Override 
     public void onSurfaceChanged(GL10 gl, int width, int height) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
      // TODO Auto-generated method stub 

     } 

    } 

} 

我的代码只是一个简单的例子。我有调试和所有事情是真实的。 (如:成功加载图片)。但是,我不知道如何调试OpenGL应用程序。 (这意味着:当调试时,我可以查看变量的参数,但我不知道它是怎么回事,因为OpenGL比Canvas复杂 - 你只需使用一行代码并且有结果:))

感谢您的帮助:)

回答

2

哦。我已经修复了我的全部解决方案,下面是我的完整代码。我张贴在这里谁尝试阅读我的长篇(^^),并需要一个真正的解决方案:)感谢SteveL建议我:)

在我的解决方案中,我有一些变化: 第一。性能:我把代码读取纹理在onSurfaceCreate。第二个是 。正如SteveL所说。我缺少gl.glEnable,我又重新设置了gl.glBindTexture

再次想到,我发现那些错误确实很愚蠢。就因为我的新手的OpenGL :(

package com.test; 

import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 

import android.app.Activity; 
import android.opengl.GLSurfaceView; 
import android.opengl.GLSurfaceView.Renderer; 
import android.os.Bundle; 

public class ColorTriangleTest extends Activity{ 

    GLSurfaceView glView; 
    ByteBuffer byteBuffer; 
    FloatBuffer vertices; 

    public void onCreate(Bundle savedInstanceState){ 

     super.onCreate(savedInstanceState); 

     int VERTEX_SIZE = (2+4)*4; 
     byteBuffer = ByteBuffer.allocateDirect(3*VERTEX_SIZE); 
     byteBuffer.order(ByteOrder.nativeOrder()); 
     vertices = byteBuffer.asFloatBuffer(); 
     vertices.put(new float[] { 0.0f, 0.0f, 1, 0, 0, 1, 
            319.0f, 0.0f, 1, 1, 0, 1, 
            160.0f, 479.0f, 1, 0, 1, 1 }); 
     vertices.flip(); 

     glView = new GLSurfaceView(this); 
     glView.setRenderer(new Render()); 
     setContentView(glView); 
    } 

    class Render implements Renderer { 

     @Override 
     public void onDrawFrame(GL10 gl) { 

      int VERTEX_SIZE = (2+4)*4; 

      gl.glViewport(0, 0, glView.getWidth(), glView.getHeight()); 
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 
      gl.glMatrixMode(GL10.GL_PROJECTION); 
      gl.glLoadIdentity(); 
      gl.glOrthof(0, 320, 0, 480, 10, -10); 

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
      gl.glEnableClientState(GL10.GL_COLOR_ARRAY); 

      vertices.position(0); 
      gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices); 
      vertices.position(2); 
      gl.glColorPointer(4, GL10.GL_FLOAT, VERTEX_SIZE, vertices); 

      gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); 

     } 

     @Override 
     public void onSurfaceChanged(GL10 gl, int width, int height) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
      // TODO Auto-generated method stub 

     } 

    } 

} 
0

哦。我已经解决了我的问题。但我无法解释为什么。 (我可以修复,因为我喜欢互联网上的一些教程)。

这是我的代码。我指出了一些我已经改变的内容。请告诉我为什么它的工作原理请:

package com.test; 

import java.io.IOException; 
import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 

import android.app.Activity; 
import android.content.res.AssetManager; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.opengl.GLSurfaceView; 
import android.opengl.GLSurfaceView.Renderer; 
import android.opengl.GLUtils; 
import android.os.Bundle; 
import android.util.Log; 

public class TextureTriangleTest extends Activity{ 

    GLSurfaceView glView; 
    ByteBuffer byteBuffer; 
    FloatBuffer vertices; 
    AssetManager assets; 

    @Override 
    public void onCreate(Bundle savedInstanceState){ 

     super.onCreate(savedInstanceState); 
     assets = getAssets(); 

     int VERTEX_SIZE = (2+2)*4; 
     byteBuffer = ByteBuffer.allocateDirect(3*VERTEX_SIZE); 
     byteBuffer.order(ByteOrder.nativeOrder()); 
     vertices = byteBuffer.asFloatBuffer(); 
     vertices.put(new float[] { 0.0f, 0.0f, 0.0f, 1.0f, 
            319.0f, 0.0f, 1.0f, 1.0f, 
            160.0f, 479.0f, 0.5f, 0.0f }); 
     vertices.flip(); 

     glView = new GLSurfaceView(this); 
     glView.setRenderer(new Render()); 
     setContentView(glView); 

    } 



    class Render implements Renderer{ 

     @Override 
     public void onDrawFrame(GL10 gl) { 

      int a = 0; 
      try { 

       Bitmap bitmap = BitmapFactory.decodeStream(assets.open("bobrgb888.png")); 
       int textureIds[] = new int[1]; 
       gl.glGenTextures(1, textureIds, 0); 
       int textureId = textureIds[0]; 
       a= textureId; 

       gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); //this line 
       GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 
       gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); 
       gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); 
       gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); //and this line 

       bitmap.recycle(); 

      } catch (IOException e) { 
       Log.d("", "FAILED LOAD FILE"); 
       throw new RuntimeException("Couldn't load asset!"); 
      } 

      gl.glViewport(0, 0, glView.getWidth(), glView.getHeight()); 
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 
      gl.glMatrixMode(GL10.GL_PROJECTION); 
      gl.glLoadIdentity(); 
      gl.glOrthof(0, 320, 0, 480, 1, -1); 

      //Here two lines that I added. Two lines I have declared above in try_catch 
      //So, WHY I NEED TO DECLARE AGAIN ??!!! 
      gl.glEnable(GL10.GL_TEXTURE_2D); 
      gl.glBindTexture(GL10.GL_TEXTURE_2D, a); 

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
      gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 

      int VERTEX_SIZE = (2+2)*4; 
      vertices.position(0); 
      gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices); 
      vertices.position(2); 
      gl.glTexCoordPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices); 

      gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); 

     } 

     @Override 
     public void onSurfaceChanged(GL10 gl, int width, int height) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
      // TODO Auto-generated method stub 

     } 

    } 

} 

这对我来说现在:)谁能解释为什么?? !!

+2

你没有使用gl.glEnable(GL10.GL_TEXTURE_2D);在TRY ... CATCH再加上你unbinded纹理(上TRY ... CATCH)与gl.glBindTexture(GL10.GL_TEXTURE_2D,0); – SteveL 2012-02-19 12:48:34

+2

为什么你要在每一帧加载纹理?将on..try部分放在onSurfaceCreated() – SteveL 2012-02-19 12:50:13