Android opengl 立方体 多纹理
最近学习 opengl,看了一些简单的教程。发现一般都是到实现金字塔或者立方体就结束了。
纹理方面,对三维物体的多个面未做处理。参看了这些例子,做一个android 上的多纹理的立方体。
效果图:
1.
2.
以下是主要代码:
Activity负责初始化相关资源文件。重写了onTouchEvent()方法,实现鼠标翻转,方便观察。
主类:
public class Cube extends Activity {
GLRender render = new GLRender();
private float mPreviousX;
private float mPreviousY;
private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
private final float TRACKBALL_SCALE_FACTOR = 36.0f;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GLImage.load(this.getResources());
GLSurfaceView glView = new GLSurfaceView(this);
glView.setRenderer(render);
setContentView(glView);
}
public boolean onKeyUp(int keyCode, KeyEvent event)
{
render.onKeyUp(keyCode, event);
return false;
}
public boolean onTrackballEvent(MotionEvent e) {
render.xrot += e.getX() * TRACKBALL_SCALE_FACTOR;
render.yrot += e.getY() * TRACKBALL_SCALE_FACTOR;
return true;
}
public boolean onTouchEvent(MotionEvent e) {
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_MOVE:
float dx = x - mPreviousX;
float dy = y - mPreviousY;
render.xrot += dx * TOUCH_SCALE_FACTOR;
render.yrot += dy * TOUCH_SCALE_FACTOR;
}
mPreviousX = x;
mPreviousY = y;
return true;
}
}
class GLImage
{
public static Bitmap mBitmap1;
public static Bitmap mBitmap2;
public static Bitmap mBitmap3;
public static Bitmap mBitmap4;
public static Bitmap mBitmap5;
public static Bitmap mBitmap6;
public static void load(Resources resources)
{
mBitmap1 = BitmapFactory.decodeResource(resources, R.drawable.icon1);
mBitmap2 = BitmapFactory.decodeResource(resources, R.drawable.icon2);
mBitmap3 = BitmapFactory.decodeResource(resources, R.drawable.icon3);
mBitmap4 = BitmapFactory.decodeResource(resources, R.drawable.icon4);
mBitmap5 = BitmapFactory.decodeResource(resources, R.drawable.icon5);
mBitmap6 = BitmapFactory.decodeResource(resources, R.drawable.icon6);
}
}
Render实现有修改:
public class GLRender implements Renderer
{
boolean key = true;
float xrot = 0.0f;
float yrot = 0.0f;
float xspeed, yspeed;
float z = -5.0f;
int one = 0x10000;
//光线参数
FloatBuffer lightAmbient = FloatBuffer.wrap(new float[]{0.5f,0.5f,0.5f,1.0f});
FloatBuffer lightDiffuse = FloatBuffer.wrap(new float[]{1.0f,1.0f,1.0f,1.0f});
FloatBuffer lightPosition = FloatBuffer.wrap(new float[]{0.0f,0.0f,2.0f,1.0f});
int [] texture;
// 六个面,一个面4个点
int[] vertice = new int[]{
-one,-one,one,
one,-one,one,
one,one,one,
-one,one,one,
-one,-one,-one,
-one,one,-one,
one,one,-one,
one,-one,-one,
-one,one,-one,
-one,one,one,
one,one,one,
one,one,-one,
-one,-one,-one,
one,-one,-one,
one,-one,one,
-one,-one,one,
one,-one,-one,
one,one,-one,
one,one,one,
one,-one,one,
-one,-one,-one,
-one,-one,one,
-one,one,one,
-one,one,-one,
};
int[] normal = new int[]{
0,0,one,
0,0,one,
0,0,one,
0,0,one,
0,0,one,
0,0,one,
0,0,one,
0,0,one,
0,one,0,
0,one,0,
0,one,0,
0,one,0,
0,-one,0,
0,-one,0,
0,-one,0,
0,-one,0,
one,0,0,
one,0,0,
one,0,0,
one,0,0,
-one,0,0,
-one,0,0,
-one,0,0,
-one,0,0,
};
// 纹理映射数据
int[] texCoord = new int[]{
one,0,0,0,0,one,one,one,
0,0,0,one,one,one,one,0,
one,one,one,0,0,0,0,one,
0,one,one,one,one,0,0,0,
0,0,0,one,one,one,one,0,
one,0,0,0,0,one,one,one,
};
IntBuffer vertices=GLTool.getIntBu(vertice);
IntBuffer normals=GLTool.getIntBu(normal);
IntBuffer texCoords=GLTool.getIntBu(texCoord);
ByteBuffer indices1 = ByteBuffer.wrap(new byte[]{
0,1,3,2,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
});
ByteBuffer indices2 = ByteBuffer.wrap(new byte[]{
0,0,0,0,
4,5,7,6,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
});
ByteBuffer indices3 = ByteBuffer.wrap(new byte[]{
0,0,0,0,
0,0,0,0,
8,9,11,10,
0,0,0,0,
0,0,0,0,
0,0,0,0,
});
ByteBuffer indices4 = ByteBuffer.wrap(new byte[]{
0,0,0,0,
0,0,0,0,
0,0,0,0,
12,13,15,14,
0,0,0,0,
0,0,0,0,
});
ByteBuffer indices5 = ByteBuffer.wrap(new byte[]{
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
16,17,19,18,
0,0,0,0,
});
ByteBuffer indices6 = ByteBuffer.wrap(new byte[]{
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
20,21,23,22,
});
@Override
public void onDrawFrame(GL10 gl)
{
// 清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
// 重置当前的模型观察矩阵
gl.glLoadIdentity();
gl.glEnable(GL10.GL_LIGHTING);
////////////////
gl.glTranslatef(0.0f, 0.0f, z);
//设置旋转
gl.glRotatef(xrot, 0.0f, 1.0f, 0.0f);
gl.glRotatef(yrot, 1.0f, 0.0f, 0.0f);
gl.glNormalPointer(GL10.GL_FIXED, 0, normals);
gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices);
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//绘制四边形
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4, GL10.GL_UNSIGNED_BYTE, indices1);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 8, GL10.GL_UNSIGNED_BYTE, indices2);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[2]);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 12, GL10.GL_UNSIGNED_BYTE, indices3);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[3]);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 16, GL10.GL_UNSIGNED_BYTE, indices4);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[4]);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 20, GL10.GL_UNSIGNED_BYTE, indices5);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[5]);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24, GL10.GL_UNSIGNED_BYTE, indices6);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
//修改旋转角度
xrot+=0.3f;
yrot+=0.2f;
//混合开关
if (key)
{
gl.glEnable(GL10.GL_BLEND); // 打开混合
gl.glDisable(GL10.GL_DEPTH_TEST); // 关闭深度测试
}
else
{
gl.glDisable(GL10.GL_BLEND); // 关闭混合
gl.glEnable(GL10.GL_DEPTH_TEST); // 打开深度测试
}
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
float ratio = (float) width / height;
//设置OpenGL场景的大小
gl.glViewport(0, 0, width, height);
//设置投影矩阵
gl.glMatrixMode(GL10.GL_PROJECTION);
//重置投影矩阵
gl.glLoadIdentity();
// 设置视口的大小
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
// 选择模型观察矩阵
gl.glMatrixMode(GL10.GL_MODELVIEW);
// 重置模型观察矩阵
gl.glLoadIdentity();
}
@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.glEnable(GL10.GL_CULL_FACE);
// 启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
// 启用深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
//设置光线,,1.0f为全光线,a=50%
gl.glColor4f(1.0f,1.0f,1.0f,0.5f);
// 基于源象素alpha通道值的半透明混合函数
gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE);
//纹理相关
IntBuffer textureBuffer = IntBuffer.allocate(6);
gl.glGenTextures(6, textureBuffer);
texture = textureBuffer.array();
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap1, 0);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap2, 0);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[2]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap3, 0);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[3]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap4, 0);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[4]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap5, 0);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[5]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap6, 0);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
//深度测试相关
gl.glClearDepthf(1.0f);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glEnable(GL10.GL_TEXTURE_2D);
//设置环境光
gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbient);
//设置漫射光
gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDiffuse);
//设置光源位置
gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition);
//开启一号光源
gl.glEnable(GL10.GL_LIGHT1);
//开启混合
gl.glEnable(GL10.GL_BLEND);
}
public boolean onKeyUp(int keyCode, KeyEvent event)
{
key = !key;
return false;
}
}
自定义的工具类:
public class GLTool {
/*
*返回字节化的intbuffer
*/
public static IntBuffer getIntBu(int[] source){
ByteBuffer bb = ByteBuffer.allocateDirect(source.length*4);
bb.order(ByteOrder.nativeOrder());
IntBuffer vertices = bb.asIntBuffer();
vertices.put(source);
vertices.position(0);
return vertices;
}
}
转自:http://blog.****.net/one2zero/article/details/5895548