2012-02-24 29 views
0

我需要一點幫助,以實現與OpenGL ES 1.1哪種方法可以改變多邊形的紋理?

我有一個簡單的正方形多邊形(從nehe教程)與紋理。

多邊形有一個位圖,並且在創建多邊形時調用loadGLTexture(GL10 gl,Context上下文)方法一次以加載紋理。

我需要添加功能到我的應用程序來改變正方形的紋理。

哪個是改變多邊形紋理的最好方法?不能找到谷歌以正確的方式...

感謝所有

編輯:

public class Square { 
    //Buffer de vertices 
    public FloatBuffer vertexBuffer; 
    //Buffer de coordenadas de texturas 
    private FloatBuffer textureBuffer; 
    //Puntero de texturas 
    private int[] textures = new int[3]; 
    //El item a representar 
    private Bitmap bitmap; //image with POT dimensions 
    //size of the polygon: 
    public float w; 
    public float h; 
    //size of the texture 
    private float textureX; 
    private float textureY; 
    //Definición de vertices  
    public float vertices[] = new float[12]; 
    private float vertices_transformed[] = new float[12]; 
    //Coordenadas (u, v) de las texturas  
    private float texture[];  
    // Image ratio 
    float ratio; 

    public int id; 

    Context context; 

    //Inicializamos los buffers 
    public Square(Bitmap image, Context context) {  
     int bitmapW=image.getWidth(); 
     int bitmapH=image.getHeight(); 

      w=1.00f; 
      h=(float)bitmapH/bitmapW;  


     float vertices2[] = { 
      -w, -h, 0.0f, //Bottom Left 
      w, -h, 0.0f, //Bottom Right 
      -w, h, 0.0f, //Top Left 
      w, h, 0.0f  //Top Right 
     }; 
     vertices=vertices2; 

     //calculamos la siguiente potencia de 2 del lado mas largo del bitmap, alto o ancho. 
     int nextPOT; 
     if (bitmapW>bitmapH) 
      nextPOT=getNextPOT(bitmapW); 
     else 
      nextPOT=getNextPOT(bitmapH); 

     //creamos un nuevo bitmap cuadrado con dimensiones potencia de 2, y dentro de el metemos la imagen 
     bitmap = Bitmap.createBitmap(nextPOT, nextPOT, Bitmap.Config.ARGB_8888); //crea un bitmap transparente gracias al ARGB_8888 
     Canvas comboImage = new Canvas(bitmap); 
     comboImage.drawBitmap(image, 0, 0, null); 
     comboImage.save();  

     //calculamos las coordenadas de la textura dentro del bitmap que es potencia de 2 
     textureX = (float)bitmapW/nextPOT; 
     textureY = (float)bitmapH/nextPOT; 

     //creamos el array de la textura, pasándole las coordenadas ya obtenidos 
     float texture2[] ={ 
       0.0f,textureY, 
       textureX, textureY, 
       0.0f, 0.0f, 
       textureX,0.0f 
      }; 

     System.out.println("bw:"+bitmapW+" nextPOT:"+nextPOT+" texX:"+textureX); 

     texture=texture2; 


     ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4); 
     byteBuf.order(ByteOrder.nativeOrder()); 
     vertexBuffer = byteBuf.asFloatBuffer(); 
     vertexBuffer.put(vertices); 
     vertexBuffer.position(0); 

     byteBuf = ByteBuffer.allocateDirect(texture.length * 4); 
     byteBuf.order(ByteOrder.nativeOrder()); 
     textureBuffer = byteBuf.asFloatBuffer(); 
     textureBuffer.put(texture); 
     textureBuffer.position(0);  

     //setPosition(0,0); 

     ratio = (float)image.getWidth()/image.getHeight(); 

     image.recycle(); 
    } 

    //Funcion de dibujado 
    public void draw(GL10 gl) { 
     gl.glFrontFace(GL10.GL_CCW); 
     //gl.glEnable(GL10.GL_BLEND); 
     //Bind our only previously generated texture in this case 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); 
     //Point to our vertex buffer 
     gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); 
     gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer); 
     //Enable vertex buffer 
     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
     //Set The Color To Blue 
     //gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f); 
     //Draw the vertices as triangle strip 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length/3); 
     //Disable the client state before leaving 
     gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
     //gl.glDisable(GL10.GL_BLEND);  
    } 

    //Carga de texturas 
    public void loadGLTexture(GL10 gl, Context context) {  
     //Generamos un puntero de texturas 
     gl.glGenTextures(1, textures, 0);  
     //y se lo asignamos a nuestro array 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); 
     //Creamos filtros de texturas 
     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_LINEAR); 
     //Diferentes parametros de textura posibles GL10.GL_CLAMP_TO_EDGE 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);  

     //Usamos Android GLUtils para espcificar una textura de 2 dimensiones para nuestro bitmap 
     GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 

     //Checkeamos si el GL context es versión 1.1 y generamos los Mipmaps por Flag. Si no, llamamos a nuestra propia implementación 
     if(gl instanceof GL11) { 
      gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE); 
      GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 
     } else { 
      buildMipmap(gl, bitmap); 
     } 
     //Limpiamos los bitmaps 
     bitmap.recycle();  
    } 

    //Nuestra implementación de MipMap. Escalamos el bitmap original hacia abajo por factor de 2 y lo asignamos como nuevo nivel de mipmap 
    private void buildMipmap(GL10 gl, Bitmap bitmap) { 
     int level = 0; 
     int height = bitmap.getHeight(); 
     int width = bitmap.getWidth(); 
     while(height >= 1 || width >= 1) { 
      GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, bitmap, 0); 
      if(height == 1 || width == 1) { 
       break; 
      } 
      level++; 
      height /= 2; 
      width /= 2; 
      Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, true); 
      bitmap.recycle(); 
      bitmap = bitmap2; 
     } 
    } 

    //returns the next POT 
    public static int getNextPOT(int n){ 
     int i = 1; 
     while(i < n) 
      i *= 2;  
     return i; 
    } 

    public void setPosition(float x , float y){ 
     vertexBuffer.put(0 , vertices[0]+x); 
     vertexBuffer.put(3 , vertices[3]+x); 
     vertexBuffer.put(6 , vertices[6]+x); 
     vertexBuffer.put(9 , vertices[9]+x); 

     vertexBuffer.put(1 , vertices[1]+y); 
     vertexBuffer.put(4 , vertices[4]+y); 
     vertexBuffer.put(7 , vertices[7]+y); 
     vertexBuffer.put(10 , vertices[10]+y);  
    } 

    public void move(float dx , float dy){ 
     vertexBuffer.put(0 , vertexBuffer.get(0)+dx); 
     vertexBuffer.put(3 , vertexBuffer.get(3)+dx); 
     vertexBuffer.put(6 , vertexBuffer.get(6)+dx); 
     vertexBuffer.put(9 , vertexBuffer.get(9)+dx); 

     vertexBuffer.put(1 , vertexBuffer.get(1)+dy); 
     vertexBuffer.put(4 , vertexBuffer.get(4)+dy); 
     vertexBuffer.put(7 , vertexBuffer.get(7)+dy); 
     vertexBuffer.put(10 , vertexBuffer.get(10)+dy);   
    } 

    //CARGA DE TEXTURAS DIFERENTES PARA EL POLÍGONO 
    static int[] mTextureNameWorkspace= new int[1]; 
    static int[] mCropWorkspace=new int[4]; 

    public int loadBitmap(Context context, GL10 gl, String imageName) { 
     BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options(); 
     sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565; 
     sBitmapOptions.inScaled=false; 

     int textureName = -1; 
     if (context != null && gl != null) { 
      gl.glGenTextures(1, mTextureNameWorkspace, 0); 
      textureName = mTextureNameWorkspace[0]; 
      gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName); 
      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_LINEAR); 

      gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); 
      gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); 

      //gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE); 
      gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE); 

      Bitmap bitmap = loadImage(imageName, context); 

      GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 

      mCropWorkspace[0] = 0; 
      mCropWorkspace[1] = bitmap.getHeight(); 
      mCropWorkspace[2] = bitmap.getWidth(); 
      mCropWorkspace[3] = -bitmap.getHeight(); 

      bitmap.recycle(); 

      ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, mCropWorkspace, 0); 
      textures[0]=textureName; 
     } 
     return textureName; 
    } 

    public static Bitmap loadImage(String imageName, Context context){ 
     if(imageName.charAt(0) == '/') { 
      imageName = imageName.substring(1); 
     } 
     imageName = imageName + ".png"; 
     Bitmap image = BitmapFactory.decodeStream(getResourceAsStream(imageName, context)); 
     return image; 
    } 
    public static InputStream getResourceAsStream(String resourceName, Context context) { 
     if(resourceName.charAt(0) == '/') { 
      resourceName = resourceName.substring(1); 
     } 

     InputStream is = null; 
     try { 
      is = context.getAssets().open(resourceName); 
     } catch (IOException e) {e.printStackTrace();} 
     return is; 
    } 


} 

回答

0

使用glTexSubImage2D

+0

你能不能給我說這個多一點的解釋......? – NullPointerException 2012-02-24 13:18:49

+0

我不再確定你在問什麼。我以爲你想知道如何更新現有的紋理,但也許你的問題比這更基本...... SteveL的答案可能是你需要的。 – 2012-02-24 14:08:10

0

事情比你想象的要複雜得多。當你使用loadGLTexture(GL10 gl,Context context)時,opengl加載你的紋理並將它的id保存到一個int中,然後在render(的多邊形)函數中使用這個id來指定這是你想要繪製的紋理。 你需要先加載你的紋理,保存id的diferents int的,然後渲染多邊形與你想要的紋理ID;

首先加載你的紋理:

int txDog=loadBitmap(context,gl,R.drawable.dog);//This generetes an opengl texture id with the given image 
int txCat=loadBitmap(context,gl,R.drawable.cat); 

下一頁把一個額外的參數,以多邊形的所謂渲染功能texid

public void Render(GL10 gl,int texid); 

然後在你的渲染功能尋找這樣一行:

gl.glBindTexture(GL10.GL_TEXTURE_2D, thetexturenameid); 

用texid替換thetexturenameid(或任何名稱)

末爲最終得出這樣的多邊形:

public void Render(gl,txDog);//if you want the dog texture 
public void Render(gl,txCat);//if you want the cat texture 




static int[] mTextureNameWorkspace= new int[1]; 
static int[] mCropWorkspace=new int[4]; 
public static int loadBitmap(Context context, GL10 gl, int resourceId) { 
    BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options(); 
    sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565; 
    sBitmapOptions.inScaled=false; 


    int textureName = -1; 
    if (context != null && gl != null) { 
     gl.glGenTextures(1, mTextureNameWorkspace, 0); 

     textureName = mTextureNameWorkspace[0]; 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName); 
     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_LINEAR); 

     gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); 

     // gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE); 
     gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,GL10.GL_MODULATE); 


     InputStream is = context.getResources().openRawResource(resourceId); 
     Bitmap bitmap; 

     bitmap = BitmapFactory.decodeStream(is, null, sBitmapOptions); 


     GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 

     mCropWorkspace[0] = 0; 
     mCropWorkspace[1] = bitmap.getHeight(); 
     mCropWorkspace[2] = bitmap.getWidth(); 
     mCropWorkspace[3] = -bitmap.getHeight(); 

     bitmap.recycle(); 

     ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, 
       GL11Ext.GL_TEXTURE_CROP_RECT_OES, mCropWorkspace, 0); 




    } 

    return textureName; 
} 

是我能解釋它的最簡單的方法

+0

我正在測試你的代碼,但是出了什麼問題,它給了我白色的空紋理:S – NullPointerException 2012-02-27 13:52:07

+0

我在我的遊戲中使用相同的代碼,並且所有的工作都很好。你的紋理大小是兩個?你在繪製之前是否綁定了正確的紋理? – SteveL 2012-02-27 14:28:18

+0

嗨,我編輯我的帖子與我的代碼,與您的代碼合併,檢查,我告訴你的函數紋理[0] =紋理名稱。這必須改變多邊形的紋理,因爲在draw方法上使用了紋理[0]。我正在改變另一個類,一個GLSurfaceView類,onDrawFrame方法,用這一行的紋理:square.loadBitmap(context,gl,「7」); (7是位圖的名稱) – NullPointerException 2012-02-28 11:16:48