2012-02-19 122 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