绘制立方体和单个的矩阵,并映射纹理图像

绘图有很多需要注意的地方,直接提出demo,里面注释部分需要注意:

 
public class MainActivity extends AppCompatActivity {
 
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
 
private void init() {
glSurfaceView=new GLSurfaceView(this);
Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.ayx);
Bitmap bitmap2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.ayx2);
Bitmap mBitmap[] = {bitmap,bitmap2};
GLSurfaceView.Renderer renderer=new GLRender3(mBitmap);
glSurfaceView.setRenderer(renderer);
setContentView(glSurfaceView);
}
}
 
 
package com.example.zp.myapplication;
 
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
 
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.graphics.Bitmap;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;
 
public class GLRender3 implements Renderer
{
float xrot, yrot, zrot;
int textureSize = 2;
int texture[] = new int [textureSize];
int one = 0x10000;
private Bitmap mBitmap[];
//正方体的6个面,4个点确定一个面
IntBuffer vertices = BufferUtil.intToBuffer(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,
 
});
 
IntBuffer vertices2 = BufferUtil.intToBuffer(new int[]{
-one, -one, one,
one, -one, one,
one, one, one,
-one, one, one,
});
 
//图像的2维坐标与正方体每个面对应的坐标对应关系矩阵,
//存放纹理坐标的数组,指明将绘制的第i个点(i<count)分别对应着贴图的哪一个角,
// (经过实验证明纹理贴图与原来图像是上下颠倒的)四个角分别用(0,1)(左上角)、(1,1)(右上角)、(1,0)(右下角)、(0,0)(左下角)表示
IntBuffer texCoords = BufferUtil.intToBuffer(new int[]{
// one,0,0,0,0,one,one,one,
0,one,one,one,one,0,0,0,
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 texCoords2= BufferUtil.intToBuffer(new int[]{
 
 
//通过实验证明生成的纹理贴图是上下颠倒的,因此vertices里一个平面对应的点应该是上下反过来,才能在矩阵上显示为正图像
 
//按点
// 0,0,
// one,0,
// one,one,
// 0,one
 
//如:矩阵: 3 2 应该对应的是: 第 0个点:按点位置左下角 0 -> (0,0) 反过来去上 -> (0,1)
// 0 1 ----> 第 3个点:按点位置左上角 3 -> (0,1) 反过来去下 -> (0,0)
//反过来后的对应关系
0,one,
one,one,
one,0,
0,0
});
 
ByteBuffer indices = ByteBuffer.wrap(new byte[]{
0,1,3,2,
4,5,7,6,
8,9,11,10,
12,13,15,14,
16,17,19,18,
20,21,23,22,
});
 
 
public GLRender3(Bitmap mBitmap[])
{
this.mBitmap = mBitmap;
}
 
@Override
public void onDrawFrame(GL10 gl)
{
// 清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 重置当前的模型观察矩阵
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, -4.0f);
 
//设置3个方向的旋转
gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
gl.glRotatef(yrot, -1.0f, 0.0f, 0.0f);
gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);
 
 
 
 
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//启用纹理映射
 
//纹理和四边形对应的顶点
// gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices);
// gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords);
 
 
 
// //----------------绘制一个矩阵,并投影纹理---------------------------------//
// // 绑定纹理
// gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
// gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices2);
// gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords2);
// ByteBuffer indicesi = ByteBuffer.wrap(new byte[]{
//// 1,2,0,3
// 0,1,3,2
//// 2,3,1,0
//// 3,0,2,1
//
// ////实验证明,第一个是逆时针画,第二个顺时针这样循环,否则不对应的就不会画
// });
// //4指保存的点和绘图顺序就是取连续的3个点绘制三角形。
// gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4, GL10.GL_UNSIGNED_BYTE, indicesi);
 
 
// //----------------绘制一个立方体,并投影纹理---------------------------------//
//下面是一下画24个点,直接投影一种纹理和 投影2中纹理
 
// // 投影一个纹理
// gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices);
// gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords);
// gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
//             //用drawElments同时画24点会导致立方体内部有三角形,只是不透明看不到。
// gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24, GL10.GL_UNSIGNED_BYTE, indices);
 
//投影2种纹理
gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices);
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords);
for(int i = 0 ; i < 6 ; i++)
{
//当i为偶数时候投影第一个纹理,奇数时候投影第二个
if(i%2==0)
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
else
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
 
int first = i*4;
ByteBuffer indicesi = ByteBuffer.wrap(new byte[]{
(byte) first,(byte)( first+1),(byte)( first+3),(byte)( first+2)
});
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4, GL10.GL_UNSIGNED_BYTE, indicesi);
}
 
 
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
xrot+=0.5f;
yrot+=0.2f;
zrot+=0.3f;
 
}
 
@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.glClearColor(0, 0, 0, 0);
 
//启用这条时候会只在外面粘贴纹理,而内部是黑色的 
gl.glEnable(GL10.GL_CULL_FACE);
// 启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
// 启用深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
 
//启用纹理映射
gl.glClearDepthf(1.0f);
//深度测试的类型
gl.glDepthFunc(GL10.GL_LEQUAL);
//精细的透视修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
//允许2D贴图,纹理
gl.glEnable(GL10.GL_TEXTURE_2D);
getTextures(gl);
 
}
 
 
private void getTextures(GL10 gl)
{
IntBuffer intBuffer = IntBuffer.allocate(2);//申请2个纹理存储空间
// 创建纹理
gl.glGenTextures(2 , intBuffer); //创建2个纹理,绑定intuffer
texture[0] = intBuffer.get(); // 获取第一个纹理的存储指针,即纹理存储位置,位置+1
texture[1] = intBuffer.get(); //获取下一个纹理存储的位置
 
// 设置要使用的纹理
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
//生成纹理
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0 , mBitmap[0] , 0);//利用图mBitmap[0]生成纹理,存储在texture[0]
// 线形滤波
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
 
//生成第二个纹理
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0 , mBitmap[1] , 0);//利用图mBitmap[0]生成纹理,存储在texture[1]
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
 
}
 
 
}
立方体生成多个纹理图的效果图:
 
posted @ 2016-10-16 20:35  Lammy  阅读(1904)  评论(0编辑  收藏  举报