Openglテクスチャマッピング

7208 ワード


一、テクスチャに三段階曲を使う
1、リソース:まず、OpenGL ESのテクスチャ画像のサイズが要求され、その高さと幅は2のn次方でなければなりません.例えば、32 x 32、256 x 512などです.画像はテクスチャに等しくなく、画像があれば、テクスチャとして使用するには加工が必要です.
 
public int initTexture(GL10 gl,int textureId)//textureId      ID
{
	int[] textures = new int[1]; //      ,      ID
	gl.glGenTextures(1, textures, 0); //    ID,  textures,        ID     ,        null   
	int currTextureId=textures[0];  //    ID  
	gl.glBindTexture(GL10.GL_TEXTURE_2D, currTextureId); //    ID     ,                
	gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);//  4               
        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);
        
        InputStream is = this.getResources().openRawResource(textureId);//        Bitmap,   
        Bitmap bitmapTmp; 
        try 
        {
        	bitmapTmp = BitmapFactory.decodeStream(is);
        } 
        finally 
        {
            try 
            {
                is.close();
            } 
            catch(IOException e) 
            {
                e.printStackTrace();
            }
        }
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmapTmp, 0);//                        
        bitmapTmp.recycle();//     
        
        return currTextureId;//    ID
	}


2、テクスチャ座標:これはマップの真髄であり難点でもある.テクスチャはモデルの表面に羽織られた花衣(皮が残っていない、毛が付いているという感じ)であり、OpenGL ESではモデルは最終的に多くの三角形で綴られ、各・個の三角形は3つの頂点で定義されている.テクスチャがモデルに依存する以上、テクスチャ座標もモデルの頂点座標に対応することが予想される.頂点座標は3 D座標系に対して,テクスチャ座標は左上(0,0),右上(1,0),左下(0,1),右下(1,1),中間(0.5,0.5)の順に類推される.モデル定義済みまたはモデル定義で、頂点ごとに対応するテクスチャ座標を指定します.このステップの重心です.
三角形テクスチャ座標は、次のように定義されます.
//          ================begin============================
    	final int UNIT_SIZE=30000;    	
        vCount=3;//         
        int vertices[]=new int[]//        
        {
        	2*UNIT_SIZE,0,0,
        	-2*UNIT_SIZE,0,0,
        	0,4*UNIT_SIZE,0
        };
        //          
        //vertices.length*4           
        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
        vbb.order(ByteOrder.nativeOrder());//      
        mVertexBuffer = vbb.asIntBuffer();//   int   
        mVertexBuffer.put(vertices);//             
        mVertexBuffer.position(0);//         
        //    :                          ByteBuffer
        //  ,      ByteOrder  nativeOrder(),         
        //          ================end============================
        
        //          ================begin============================
        float textureCoors[]=new float[]//    S、T     
	    {
        	0,1,
        	1,1,
        	0.5f,0
	    };        
        
        //          
        //textureCoors.length×4     float       
        ByteBuffer cbb = ByteBuffer.allocateDirect(textureCoors.length*4);
        cbb.order(ByteOrder.nativeOrder());//      
        mTextureBuffer = cbb.asFloatBuffer();//   int   
        mTextureBuffer.put(textureCoors);//             
        mTextureBuffer.position(0);//         
        //    :                          ByteBuffer
        //  ,      ByteOrder  nativeOrder(),         
        //          ================end============================

これらの頂点は直接与えられ、より多くのモデルの頂点は計算されます(例えば、円は経緯度を微分して各頂点を計算します).ここではモデリングは行われません.
3、テクスチャコール:使用も簡単なのか、それともおならが頂点座標についていればいいのか.
//    ==========begin=============================================
        //        
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		//           
        gl.glVertexPointer
        (
        		3,				//          3  xyz 
        		GL10.GL_FIXED,	//          GL_FIXED
        		0, 				//             
        		mVertexBuffer	//      
        );
        //    ==========end===============================================
        
        //  ===========begin================================================
        //    
        gl.glEnable(GL10.GL_TEXTURE_2D);   
        //        
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        //       uv    
        gl.glTexCoordPointer
        (
        		2, 					//             S、T
        		GL10.GL_FLOAT, 		//    
        		0, 					//             
        		mTextureBuffer		//      
        );
        //         ID  		
        gl.glBindTexture(GL10.GL_TEXTURE_2D,textureId);   
        //  ===========end==================================================
        
        //    
        gl.glDrawArrays
        (
        		GL10.GL_TRIANGLES, 
        		0, 
        		vCount
        );
        gl.glDisable(GL10.GL_TEXTURE_2D);//    

二、テクスチャの高級
1、テクスチャストレッチ
テクスチャサイズが常にターゲット面積と同じ大きさになるわけではありません.大きなターゲットにテクスチャを貼り付ける必要がある場合もあります.小さなターゲットに貼り付ける必要がある場合もあります.これには3つの選択肢があります.
(1)テクスチャーを伸ばすとテクスチャーがぼやけて効果が悪くなります
(2)ターゲットをテクスチャサイズと同じ小さなブロックに分割し、各ブロックにテクスチャを貼り付けることで、格納する冗長頂点が多すぎて消費が大きい
(3)テクスチャーは,伸張や圧縮されずにターゲットに繰り返し貼り付ける.
例えば、海にマップするなら、海と同じ大きさのテクスチャを用意して貼ってもいいですか.明らかに合わないし、必要もありません.1枚の水波図を探して、繰り返し貼ってOKしました.
上記の目標を達成するには、2つのことをします.
(1)テクスチャを生成する前に、いくつかの属性パラメータを定義する必要があることについて説明した.2つのパラメータが指定されている場合に注意してください.
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);

最後のパラメータはGL 10として指定する.GL_REPEAT、このようにテクスチャは繰り返しを許可して、もしGL_に設定するならばCLAMP_TO_EDGEそれはエッジストレッチです(つまり、貼り付けたテクスチャはターゲットの左上隅に貼られますが、空白のところはテクスチャのエッジをコピーして埋め続けます.図がないので、想像できないなら考えないでください)
(2)テクスチャ座標の範囲は0-1ではなく、0-n、nが繰り返したい回数です.
2、テクスチャフィルタ
テクスチャフィルタリングとは何かを理解するには、まず一つの道理を理解する必要があります.あるいは、テクスチャマップは2次元の画像を3次元空間に描くことですか.これはただ浅い認識にすぎない.テクスチャマッピングとは、テクスチャ画像から画素を一定の方法(フィルタリング)で取り出し、対応するターゲットマッピング領域に描画することを意味する.これにより、テクスチャフィルタリングの概念が明確になり、テクスチャ画像から画素を選択する方法です.
(1)最近接ポイントサンプリング
これは最も簡単な粗暴な濾過方法です.ターゲットマッピング領域のピクセルに対応するテクスチャ座標を計算し、テクスチャ座標に基づいてテクスチャ画像から対応するピクセルを選択してマッピングするのが原理です.マッピングターゲットとテクスチャ画像のサイズが同じである場合、すなわち画素が1つ1つに対応している場合、これは必然的に最も手間が省ける最良のフィルタリング方式であるが、このような状況は少なすぎて、3次元世界では近大遠小が絶えず変化し、マッピングターゲットとテクスチャ自体のサイズの差が大きいと、このような方式の効果は最も悪い.
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);

上記のように、画像の描画時にマップの元のサイズより小さい場合に使用します.
(2)リニアフィルタ
この方式は、テクスチャ座標からマッピング画素として1つの画素点を単純に選択するのではなく、その画素を中心とした画素で周囲2 x 2の画素領域を選択し、この領域の画素を重み付け平均してマッピング画素として1つの平均画素点を算出する、最近の点サンプリング方式よりもやや複雑な点である.この方法の効果は、マッピングターゲットとテクスチャピクセルのサイズの差が大きいことを負担するリスクを高め、マップをよりスムーズにすることができます.
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);   

上記のように、画像の描画時にマップの元のサイズより大きい場合に使用します.(3)mipmapマルチディテール層
mipmapはより複雑でスマートなフィルタリング方式であり、レンズと物体の距離の違いに適した一連のテクスチャを生成し、レンダリング効率とリアリティに優れています.欠点は彼がメモリを消費する代価だ.
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10_GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR_MIPMAP_NEAREST);

大きなターゲットMAGの設定は似ています.
設定が完了したら、mipmapシリーズのテクスチャを生成するコマンドも必要です.
((GL11)gl).glTexParameterf(GL10.GL_TEXTURE_2D,GL11.GL_GENERATE_MIPMAP,GL10_GL_TRUE);