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

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_2DmTextureId); 

  

/*

下一步需要给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_2DmTextureId); 

// 获取纹理的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坐标定义为左上角(00),右下角(11)(因为使用的2D Texture),下图坐标显示了UV坐标,右边为我们需要染色的平面的顶点顺序:


为了能正确的匹配,需要把UV坐标中的(01)映射到顶点0,(11)映射到顶点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});



发布了38 篇原创文章 · 获赞 4 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/tomatozq/article/details/7617787