初學Android OpenGL ES之使用紋理 八十三
阿新 • • 發佈:2019-01-24
mod frame ava als content detect www 大小 net
紋理的裝載則是在方法void onSurfaceCreated(GL10 gl, EGLConfig config) 中
完整代碼如下
在網上發現這些講紋理的文章,非常不錯
android 遊戲導引(4. 簡單紋理貼圖)
http://www.cnblogs.com/shengdoushi/archive/2011/01/13/1934181.html
Android OpenGL es 紋理坐標設定與貼圖規則
http://blog.csdn.net/cjkwin/article/details/6016224
Android OpenGL | ES給立方體進行紋理映射
http://www.ourunix.org/android/post/34.html
這篇的例子也是立方體的紋理,不過是用手指劃過讓立方體旋轉
使用紋理的重要代碼如下
private void loadTexture(GL10 gl)
{
Bitmap bitmap = null;
try
{
// 加載位圖
bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.sand);
int[] textures = new int[1];
// 指定生成N個紋理(第一個參數指定生成1個紋理),
// textures數組將負責存儲所有紋理的代號。
gl.glGenTextures(1, textures, 0);
// 獲取textures紋理數組中的第一個紋理
texture = textures[0];
// 通知OpenGL將texture紋理綁定到GL10.GL_TEXTURE_2D目標中
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
// 設置紋理被縮小(距離視點很遠時被縮小)時候的濾波方式
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);
// 加載位圖生成紋理
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
}
finally
{
// 生成紋理之後,回收位圖
if (bitmap != null)
bitmap.recycle();
}
}
紋理的裝載則是在方法void onSurfaceCreated(GL10 gl, EGLConfig config) 中
在Renderer的 void onDrawFrame(GL10 gl)方法中要啟用紋理的數組數據,坐標數據,執行紋理貼圖
// 啟用貼圖座標數組數據
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// 設置貼圖的的座標數據
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, cubeTexturesBuffer);
// 執行紋理貼圖
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
完整代碼如下
public class Texture3D extends Activity
implements OnGestureListener
{
// 定義旋轉角度
private float anglex = 0f;
private float angley = 0f;
static final float ROTATE_FACTOR = 60;
// 定義手勢檢測器實例
GestureDetector detector;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// 創建一個GLSurfaceView,用於顯示OpenGL繪制的圖形
GLSurfaceView glView = new GLSurfaceView(this);
// 創建GLSurfaceView的內容繪制器
MyRenderer myRender = new MyRenderer(this);
// 為GLSurfaceView設置繪制器
glView.setRenderer(myRender);
setContentView(glView);
// 創建手勢檢測器
detector = new GestureDetector(this);
}
@Override
public boolean onTouchEvent(MotionEvent me)
{
// 將該Activity上的觸碰事件交給GestureDetector處理
return detector.onTouchEvent(me);
}
@Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY)
{
velocityX = velocityX > 4000 ? 4000 : velocityX;
velocityX = velocityX < -4000 ? -4000 : velocityX;
velocityY = velocityY > 4000 ? 4000 : velocityY;
velocityY = velocityY < -4000 ? -4000 : velocityY;
// 根據橫向上的速度計算沿Y軸旋轉的角度
angley += velocityX * ROTATE_FACTOR / 4000;
// 根據縱向上的速度計算沿X軸旋轉的角度
anglex += velocityY * ROTATE_FACTOR / 4000;
return true;
}
@Override
public boolean onDown(MotionEvent arg0)
{
return false;
}
@Override
public void onLongPress(MotionEvent event)
{
}
@Override
public boolean onScroll(MotionEvent event1, MotionEvent event2,
float distanceX, float distanceY)
{
return false;
}
@Override
public void onShowPress(MotionEvent event)
{
}
@Override
public boolean onSingleTapUp(MotionEvent event)
{
return false;
}
public class MyRenderer implements Renderer
{
// 立方體的頂點座標(一共是36個頂點,組成12個三角形)
private float[] cubeVertices = { -0.6f, -0.6f, -0.6f, -0.6f, 0.6f,
-0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, -0.6f, -0.6f,
-0.6f, -0.6f, -0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f,
0.6f, 0.6f, 0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f, -0.6f,
0.6f, -0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, 0.6f,
0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, -0.6f, 0.6f,
-0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f,
0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f,
-0.6f, 0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, 0.6f,
0.6f, 0.6f, 0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, -0.6f,
-0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, 0.6f, 0.6f,
-0.6f, 0.6f, -0.6f, };
// 定義立方體所需要的6個面(一共是12個三角形所需的頂點)
private byte[] cubeFacets = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, };
// 定義紋理貼圖的座標數據
private float[] cubeTextures = { 1.0000f, 1.0000f, 1.0000f, 0.0000f,
0.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 1.0000f,
1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f,
1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f,
1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f,
0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f,
1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f,
0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f,
0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f,
0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f,
0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f };
private Context context;
private FloatBuffer cubeVerticesBuffer;
private ByteBuffer cubeFacetsBuffer;
private FloatBuffer cubeTexturesBuffer;
// 定義本程序所使用的紋理
private int texture;
public MyRenderer(Context main)
{
this.context = main;
// 將立方體的頂點位置數據數組包裝成FloatBuffer;
cubeVerticesBuffer = FloatBuffer.wrap(cubeVertices);
// 將立方體的6個面(12個三角形)的數組包裝成ByteBuffer
cubeFacetsBuffer = ByteBuffer.wrap(cubeFacets);
// 將立方體的紋理貼圖的座標數據包裝成FloatBuffer
cubeTexturesBuffer = FloatBuffer.wrap(cubeTextures);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
// 關閉抗抖動
gl.glDisable(GL10.GL_DITHER);
// 設置系統對透視進行修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glClearColor(0, 0, 0, 0);
// 設置陰影平滑模式
gl.glShadeModel(GL10.GL_SMOOTH);
// 啟用深度測試
gl.glEnable(GL10.GL_DEPTH_TEST);
// 設置深度測試的類型
gl.glDepthFunc(GL10.GL_LEQUAL);
// 啟用2D紋理貼圖
gl.glEnable(GL10.GL_TEXTURE_2D);
// 裝載紋理
loadTexture(gl);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
// 設置3D視窗的大小及位置
gl.glViewport(0, 0, width, height);
// 將當前矩陣模式設為投影矩陣
gl.glMatrixMode(GL10.GL_PROJECTION);
// 初始化單位矩陣
gl.glLoadIdentity();
// 計算透視視窗的寬度、高度比
float ratio = (float) width / height;
// 調用此方法設置透視視窗的空間大小。
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
}
public void onDrawFrame(GL10 gl)
{
// 清除屏幕緩存和深度緩存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 啟用頂點座標數據
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// 啟用貼圖座標數組數據
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// 設置當前矩陣模式為模型視圖。
gl.glMatrixMode(GL10.GL_MODELVIEW);
// --------------------繪制第一個圖形---------------------
gl.glLoadIdentity();
// 把繪圖中心移入屏幕2個單位
gl.glTranslatef(0f, 0.0f, -2.0f);
// 旋轉圖形
gl.glRotatef(angley, 0, 1, 0);
gl.glRotatef(anglex, 1, 0, 0);
// 設置頂點的位置數據
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeVerticesBuffer);
// 設置貼圖的的座標數據
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, cubeTexturesBuffer);
// 執行紋理貼圖
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
// 按cubeFacetsBuffer指定的面繪制三角形
gl.glDrawElements(GL10.GL_TRIANGLES, cubeFacetsBuffer.remaining(),
GL10.GL_UNSIGNED_BYTE, cubeFacetsBuffer);
// 繪制結束
gl.glFinish();
// 禁用頂點、紋理座標數組
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// 遞增角度值以便每次以不同角度繪制
}
private void loadTexture(GL10 gl)
{
Bitmap bitmap = null;
try
{
// 加載位圖
bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.sand);
int[] textures = new int[1];
// 指定生成N個紋理(第一個參數指定生成1個紋理),
// textures數組將負責存儲所有紋理的代號。
gl.glGenTextures(1, textures, 0);
// 獲取textures紋理數組中的第一個紋理
texture = textures[0];
// 通知OpenGL將texture紋理綁定到GL10.GL_TEXTURE_2D目標中
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
// 設置紋理被縮小(距離視點很遠時被縮小)時候的濾波方式
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);
// 加載位圖生成紋理
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
}
finally
{
// 生成紋理之後,回收位圖
if (bitmap != null)
bitmap.recycle();
}
}
}
}
再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow
初學Android OpenGL ES之使用紋理 八十三