android - 不同物体的不同纹理

标签 android opengl-es textures texture-mapping

我一直在关注nehe's tutorial我想补充一点。我想为不同的对象赋予不同的纹理。

这是我的立方体(Dokukup),我将在渲染器部分绘制它。它有顶点和坐标,也有我打算在运行时改变它的默认纹理。这是我的 Tus 类几乎相同的代码。

    public class DokuKup {
    private FloatBuffer koseArabellek; // Buffer for vertex-array
    private FloatBuffer dokuArabellek;

         private float[] koseler = { // koseler for a face at z=0
        -1.0f, -1.0f, 0.0f,  // 0. left-bottom-front
         1.0f, -1.0f, 0.0f,  // 1. right-bottom-front
        -1.0f,  1.0f, 0.0f,  // 2. left-top-front
         1.0f,  1.0f, 0.0f   // 3. right-top-front
   };

     float[] konac={
       0.0f, 1.0f,  //A. sol alt 
       1.0f, 1.0f,  //B. sag alt
       0.0f, 0.0f,  //C sol üst
       1.0f, 0.0f   //D sag üst
     };
     int[] dokuKunyeleri = new int[1]; //1 doku kunyeleri için katar

     public int doku=R.drawable.duvar1;
     private float[][] renkler = {  // renkler of the 6 faces
  {1.0f, 0.5f, 0.0f, 1.0f},  // 0. orange
  {1.0f, 0.0f, 1.0f, 1.0f},  // 1. violet
  {0.0f, 1.0f, 0.0f, 1.0f},  // 2. green
  {0.0f, 0.0f, 1.0f, 1.0f},  // 3. blue
  {1.0f, 0.0f, 0.0f, 1.0f},  // 4. red
  {1.0f, 1.0f, 0.0f, 1.0f}   // 5. yellow
     };

     public DokuKup() {
        ByteBuffer kka = ByteBuffer.allocateDirect(koseler.length * 4);
        kka.order(ByteOrder.nativeOrder()); //yerel sıralama kullanalım
    koseArabellek = kka.asFloatBuffer();//byte tipinden float tipine çevirelim
    koseArabellek.put(koseler);         //verilerimizi ara belleğe eşleyelim
    koseArabellek.position(0);          //rewind işlemi yapalım

    //doku konaç konumlarını katara float tipinde atalım, bir float 4 byte eder
    ByteBuffer dka= ByteBuffer.allocateDirect(konac.length*4);
    dka.order(ByteOrder.nativeOrder());
    dokuArabellek=dka.asFloatBuffer();
    dokuArabellek.put(konac);

    dokuArabellek.position(0);
     }

   //cizdirelim şekli
     public void ciz(GL10 gl) {
   gl.glFrontFace(GL10.GL_CCW); //ön yüz saat döngüsünün tersine
    gl.glEnable(GL10.GL_CULL_FACE); //yüz toplamayı aç
    gl.glCullFace(GL10.GL_BACK);    //arka yüzü topla

  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  gl.glVertexPointer(3, GL10.GL_FLOAT, 0, koseArabellek);
  gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); //doku konaç katarını seçilir kıl
  gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, dokuArabellek); //doku konaç katarını tanımla

  // front
  gl.glPushMatrix();
  gl.glTranslatef(0.0f, 0.0f, 1.0f);
  //gl.glColor4f(renkler[0][0], renkler[0][1], renkler[0][2], renkler[0][3]);
  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
  gl.glPopMatrix();

  // left
  gl.glPushMatrix();
  gl.glRotatef(270.0f, 0.0f, 1.0f, 0.0f);
  gl.glTranslatef(0.0f, 0.0f, 1.0f);
  //gl.glColor4f(renkler[1][0], renkler[1][1], renkler[1][2], renkler[1][3]);
  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
  gl.glPopMatrix();

  // back
  gl.glPushMatrix();
  gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
  gl.glTranslatef(0.0f, 0.0f, 1.0f);
  //gl.glColor4f(renkler[2][0], renkler[2][1], renkler[2][2], renkler[2][3]);
  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
  gl.glPopMatrix();

  // right
  gl.glPushMatrix();
  gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
  gl.glTranslatef(0.0f, 0.0f, 1.0f);
  //gl.glColor4f(renkler[3][0], renkler[3][1], renkler[3][2], renkler[3][3]);
  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
  gl.glPopMatrix();

  // top
  gl.glPushMatrix();
  gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f);
  gl.glTranslatef(0.0f, 0.0f, 1.0f);
  //gl.glColor4f(renkler[4][0], renkler[4][1], renkler[4][2], renkler[4][3]);
  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
  gl.glPopMatrix();

  // bottom
  gl.glPushMatrix();
  gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
  gl.glTranslatef(0.0f, 0.0f, 1.0f);
  //gl.glColor4f(renkler[5][0], renkler[5][1], renkler[5][2], renkler[5][3]);
  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
  gl.glPopMatrix();

  gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); //doku konaç akatarını devre dışı bırak
  gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
  gl.glDisable(GL10.GL_CULL_FACE);
     }

    //GL dokusuna bir görsel yükle
     public void dokuYukle(GL10 gl, Context context){
   gl.glGenTextures(1, dokuKunyeleri,0);    //doku künye katarı üret

   gl.glBindTexture(GL10.GL_TEXTURE_2D, dokuKunyeleri[0]);  //künyeyi bağla
   //doku süzgeçlerini kuralım
   //nden 3d değil?neden GL10?GL_TEXTURE_2D nedir?
   //GL_TEXTURE_MIN_FILTER: the texture minifying function is used whenever the pixel being textured maps to an area greater than one texture element.
   //GL_TEXTURE_MAG_FILTER: The texture magnification function is used when the pixel being textured maps to an area less than or equal to one texture element.
   //GL_NEAREST: Returns the value of the texture element that is nearest (in Manhattan distance) to the center of the pixel being textured.
   //GL_LINEAR: Returns the weighted average of the four texture elements that are closest to the center of the pixel being textured.
   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_REPEAT);
   gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
   //"res\drawable\alp.png" den doku görseline bir girdi akışı oluşturalım ,256x256 olmalı
   InputStream istream = context.getResources().openRawResource(doku);
   Bitmap bitmap;
   try{
       //girdiyi okuyup bitmap olarak çöz
       bitmap= BitmapFactory.decodeStream(istream);
   }finally{
       try{
           istream.close();
       }catch (Exception e) {
    }
   }

   //şu anda bağlı olan doku künyesi için , yüklü bitmapden doku oluşştur
   GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
   bitmap.recycle();

和我在渲染器中的代码:

        public class MyGLRenderer implements GLSurfaceView.Renderer {
Context context; //App context

//sekillerimiz
Kare dortgen1,dortgen2;
Taban taban;
private Kup kup1,kup2;
private DokuKup dokukup,dokukupSag,dokukupSol;
private DokuKup1 dokukup1;
private ArrayList<DokuKup> sagKupler,solKupler;
public Tus tusYukari,tusAsagi;



//dondurme
float xAcisi =0;
float yAcisi=0;
float xHizi =0;
float yHizi =0;
float z= -6.0f;//cisimlerin kameraya olan uzaklığı
float xKonum=0,zKonum=0;

//daha sonrasında buyutme
float xBoyutu,yBoyutu,zBoyutu;
int A,B,C,F;
int H=3;
int G=4;
int D=20;
int E1=D/H;
int E2=D/G;

//tus konumlari
//float tusX=-6,tusYukariY=3,tusAsagiY=-3;

//isiklandirma
boolean isikAc=true;
private float[] lightAmbient = {0.5f, 0.5f, 0.5f, 1.0f};
private float[] lightDiffuse = {1.0f, 1.0f, 1.0f, 1.0f};
private float[] lightPosition = {0.0f, 0.0f, 2.0f, 1.0f};

//private static float kupAcisi=0,kupHizi=-1.5f;//küp için döngü açısı ve hızı
int currentTextrueFilter=0;

public MyGLRenderer(Context context){
    this.context=context;
    dokukup1= new DokuKup1();
    dortgen1= new Kare();
    dortgen2= new Kare();
    kup1= new Kup();
    kup2= new Kup();


    dokukup=new DokuKup();
    dokukupSag=new DokuKup();
    dokukupSol  = new DokuKup();
    sagKupler= new ArrayList<DokuKup>();
    solKupler= new ArrayList<DokuKup>();
    taban= new Taban();
    dokukup.doku=R.drawable.alp;//farklı gözüksün

    //burada verelim Tuş konumlarini

    float width=256,height=256;
    tusYukari = new Tus(tusX, tusYukariY, width, height);
    tusAsagi = new Tus(tusX, tusAsagiY, width, height);
    tusAsagi.doku = R.drawable.down_button;

}




@Override
public void onDrawFrame(GL10 gl) {
    //clear color and depth buffers using clear value set earlier
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

    //isik acikmi?
    if(isikAc){
        gl.glEnable(GL10.GL_LIGHTING);
    }else{
        gl.glDisable(GL10.GL_LIGHTING);
    }
    //y asagi yukari z öne geriye, x sağa sola
    /*
    gl.glLoadIdentity();
    gl.glTranslatef(0.0f, 0.0f, z);
    gl.glRotatef(xAcisi, 1.0f, 0.0f, 0.0f);
    gl.glRotatef(yAcisi, 0.0f, 1.0f, 0.0f);
    dokukup.ciz(gl);

    gl.glLoadIdentity();
    gl.glTranslatef(0.0f, 0.0f, z);
    gl.glTranslatef(0.0f, (float)(F/2 + (int)(F-0.5)/2), -(D/2));//+1-(int)((F+0.5)/2)
    gl.glScalef(A, F, D/2 -2+1);//(float)(A/2)-1
    gl.glRotatef(xAcisi, 1.0f, 0.0f, 0.0f);
    gl.glRotatef(yAcisi, 0.0f, 1.0f, 0.0f);
    dokukup.ciz(gl);

    */




    gl.glLoadIdentity();
    gl.glScalef(0.05f, 0.05f, 0.05f);
    gl.glTranslatef(0.0f, 0.0f, z-zKonum);
    gl.glRotatef(xAcisi, 1.0f, 0.0f, 0.0f);
    gl.glRotatef(yAcisi, 0.0f, 1.0f, 0.0f);
    dokukup.ciz(gl);



    //hizini her her kare(frame) de yenilediğinde güncelliyoruz
    xAcisi+=xHizi;
    yAcisi+=yHizi;


    //tuslari bastiralim


    gl.glLoadIdentity();
    gl.glTranslatef(3.6f, -1.5f, z);
    tusYukari.ciz(gl);

    gl.glLoadIdentity();
    gl.glTranslatef(2.5f, -1.5f, z);
    tusAsagi.ciz(gl);


}

void boyutAta(int a,int b,int c,int d,int f,int g,int h){
    A=a;B=b;C=c;D=d;F=f;G=g;H=h;
    E1=D/H;
    E2=D/G;
    xBoyutu=d;
    yBoyutu=f;
    zBoyutu=a;
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    if(height == 0) height=1;   //to prevent divide by zero.
    float aspect = (float) width/height;

    //set the viewport (display area) to cover the entire window
    gl.glViewport(0, 0, width, height);

    //Setup perspective projection, with aspect ratio mathces viewport
    gl.glMatrixMode(GL10.GL_PROJECTION);    //select projection matrix
    gl.glLoadIdentity();                    //reset projection matrix

    //use perspective projection
    GLU.gluPerspective(gl, 45, aspect, 0.1f, 100.f);

    gl.glMatrixMode(GL10.GL_MODELVIEW);     //select model-view matrix
    gl.glLoadIdentity();                    //reset



}


//Call back when the surface is first or re created
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);// Set color's clear-value to black
    gl.glClearDepthf(1.0f);                 //Set Depth's clear value to farthest
    gl.glEnable(GL10.GL_DEPTH_TEST);        //enables depth-buffer for hidden surface removal
    gl.glDepthFunc(GL10.GL_LEQUAL);         //The type of depth testing to do
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); //nice perspective view
    gl.glShadeModel(GL10.GL_SMOOTH);        //enable smooth shading of color
    gl.glDisable(GL10.GL_DITHER);           //disable dithering for better performance


    //yüzey her oluşturluduğunda doku kurulmalı
    dokukup.dokuYukle(gl, context);
    gl.glEnable(GL10.GL_TEXTURE_2D);

    // ambient ve diffuse ile isiklari acalim
    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbient, 0);
    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDiffuse, 0);
    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition, 0);
    gl.glEnable(GL10.GL_LIGHT1);   // isiklandirmayi ac
    gl.glEnable(GL10.GL_LIGHT0);   // varasyilan isik ata


}

}

再一次,我的问题是只有 1 个纹理映射到所有不同的对象,我想在不同的对象上映射不同的纹理。

编辑:我相信这一定与此有关,但我找不到解决方案。

textureCube.textureLoad(gl, context);

最佳答案

在绘制相应的对象时,必须生成两个纹理并将它们绑定(bind)。

我看到您只创建了一个:gl.glGenTextures(1, dokuKunyeleri,0);。事实上,你应该创建两个:

int[] dokuKunyeleri = new int[2];
gl.glGenTextures(2, dokuKunyeleri, 0);

然后,在绘制对象时,应该在绘制相关对象之前绑定(bind)相关纹理:

public void ciz(GL10 gl) {
    glBindTexture(GL_TEXTURE_2D, dokuKunyeleri[0 or 1]);
    [...] // draw the object
}

顺便说一下,我认为您并不需要 DokuKup.ciz 中的所有这些东西:

gl.glFrontFace(GL10.GL_CCW); //ön yüz saat döngüsünün tersine
gl.glEnable(GL10.GL_CULL_FACE); //yüz toplamayı aç
gl.glCullFace(GL10.GL_BACK);    //arka yüzü topla

因为您随后要禁用它们。所以你应该把它们放在 MyGlRenderer.onSurfaceCreated 中。

关于android - 不同物体的不同纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21474759/

相关文章:

android - 在 Android 中使用不可编辑的电子邮件地址启动电子邮件应用程序

java - 如何使用下载的 android holo 图标、模具、字体?

java.lang.OutOfMemoryError : bitmap size exceeds VM budget & java. io.FileNotFoundException

java - Android OpenGL-ES 删除 2 个纹理之间的 Alpha channel

android opengl 纹理重叠

android - 将现有 SQLite 数据库导入 Android 应用程序

android - Android OpenGL ES 的 3D 对象中的图像纹理与颜色?

android - 没有 setZOrderOnTop(true) 的透明 SurfaceView

c++ - opengl 程序在 glBegin(GL_QUADS) 上崩溃

three.js - Threejs DataTexture 不更新