您的位置:首页 > 移动开发 > Android开发

基于Android opengles的魔方开发总结(二)

2012-05-30 20:59 417 查看

1.1. 贴图

为了便于观察魔方扭转时各方块的所在位置,就在每个方块的面上贴了一个数字的图片。



由于手机程序在运行时经常会切换到其它的程序中运行如接电话,所以将生成数字图片的方法放到Render类的onSurfaceChanged方法中。

生成数字图片代码为:

int imgSize = 64;

int fontSize = 20;

Bitmap bitmap = Bitmap.createBitmap(imgSize, imgSize, Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(bitmap);

//设置画布背景为透明,这样我们的纹理就只显示文字,而没有颜色背景

canvas.drawColor(Color.TRANSPARENT);

Paint p = new Paint();

//设置字体、字体大小和字体颜色

String familyName = "Times New Roman";

Typeface font = Typeface.create(familyName, Typeface.NORMAL);

p.setColor(Color.WHITE);

p.setTypeface(font);

p.setTextSize(fontSize);

//在Bitmap上绘制文字

String text = cube.id;

float textWidth = p.measureText(text);

canvas.drawText(cube.id,(imgSize - textWidth)/2,imgSize - fontSize, p);

cube.loadBitmap(bitmap);

将图片生成后,在onDrawFrame运行时:

if (bInitTexture) {

bInitTexture = false;

int[] textures = new int[1];

//生成纹理编号

gl.glGenTextures(1, textures, 0);

mTextureId = textures[0];

//绑定到GL10.GL_TEXTURE_2D

gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);

/*

下一步需要给Texture填充设置参数,用来渲染的Texture可能比要渲染的区域大或者缩小,这是需要设置Texture需要放大或是缩小时OpenGL的模式:需要比较清晰的图像使用GL10.GL_NEAREST

*/

gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);

gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);

/*

如何去渲染这些不存在的Texture部分

有两种设置

GL_REPEAT 重复Texture。

GL_CLAMP_TO_EDGE 只靠边线绘制一次

*/

//水平方向靠边

gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,GL10.GL_CLAMP_TO_EDGE);

//垂直方向重复

gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);

//纹理贴图和材质混合的方式,如果选择GL10.REPLACE则只显示纹理

gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,GL10.GL_MODULATE);

//然后是将Bitmap资源和Texture绑定起来

GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0);

}

//设置面的背景色

gl.glColor4f(color.red, color.green, color.blue, color.alpha);

//如果面的背景色不为黑色则贴图,黑色面为不可见区域:

if (!color.equals(GLColor.BLACK)) {

gl.glEnable(GL10.GL_TEXTURE_2D);

//启用纹理坐标数组

gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

// 每次绘图时都需要绑定

gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);

// 获取纹理的UV坐标数组

FloatBuffer textureBuffer = getTextureBuffer();

textureBuffer.position(0);

gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

}

ShortBuffer indicesBuffer = getIndicesBuffer();

indicesBuffer.position(0);

gl.glDrawElements(GL10.GL_TRIANGLE_STRIP,4, GL10.GL_UNSIGNED_SHORT, indicesBuffer);

if (!color.equals(GLColor.BLACK)) {

gl.glDisable(GL10.GL_TEXTURE_2D);

gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

}

UV Mapping

告知OpenGL库如何将Bitmap的像素映射到Mesh上。这可以分为两步来完成:

UV Mapping指将Bitmap的像素映射到Mesh上的顶点。UV坐标定义为左上角(0,0),右下角(1,1)(因为使用的2D Texture),下图坐标显示了UV坐标,右边为我们需要染色的平面的顶点顺序:



为了能正确的匹配,需要把UV坐标中的(0,1)映射到顶点0,(1,1)映射到顶点1等等。

float textureCoordinates[] = {0,1 , 1,1 , 1,0 , 0,0};



在本项目中由于顶点全部写到mVertexList中,所以设置UV坐标时要设置8个点,在贴图时不属于该面的点设为0,0即可。

如:



设定正面为逆时针方向

bottomFace.setIndices(new short[] { 4, 0, 5, 1, });

bottomFace.setTextureCoordinates(new float[] { 0,1 , 1,1, 0,0, 0,0, 0,0, 1,0, 0,0, 0,0});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: