在Renderer的实现类onSurfaceCreated(GL10 gl, EGLConfig config)方法中启动纹理贴图:gl.glEnable(GL10.GL_TEXTURE_2D),自定义装载纹理犯法:loadTexture(gl)。
放置在图片文件夹中的图片的长宽最好是2的N次方。
立方体 贴图
java代码如下:
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 glView = new GLSurfaceView(this);
MyRenderer myRender = new MyRenderer(this);
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;
//计算角度
angley += velocityX * ROTATE_FACTOR / 4000;
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 {
//立方体顶点坐标,利用3DMAX得出的数据
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个三角形,利用3DMAX得出的数据
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, };
//定义纹理贴图的坐标数据,利用3DMAX得出的数据
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;
cubeVerticesBuffer = FloatBuffer.wrap(cubeVertices);
cubeFacetsBuffer = ByteBuffer.wrap(cubeFacets);
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);
// 启用纹理贴图
gl.glEnable(GL10.GL_TEXTURE_2D);
// 装载纹理
loadTexture(gl);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
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();
// 把绘图中心移入屏幕两个单位
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);
// 绘制图形
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 {
// 加载位图,即是将Drawable转为Bitmap
bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.sand);
int[] textures = new int[1];
// 指定生成N个纹理,第一个参数指生成一个纹理,textures数组负责存储所有纹理标号
gl.glGenTextures(1, textures, 0);
// 获取第一个纹理
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();
}
}
}
}