大家好。
?
今天在学习opengl的,到了纹理贴图这里,按照“生成纹理 -> 绑定纹理 -> 画图”的步骤进行,发现几何图形可以画出来,但是纹理却死活没有出来。尝试了各种设置,都不行,不知道哪里出了问题。现在我把代码贴出来,希望有经验的朋友能给我一点指点。希望大家不吝赐教。
?
?
package com.gl;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import java.nio.ShortBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import test.opengl.R;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.opengl.GLUtils;import android.opengl.GLSurfaceView.Renderer;public class OpenGlRender implements Renderer { private float z = -1; private float[] vertices = { 0, 0, z, 1, 0, z, 1, 1, z, 0, 1, z, -1, 1, z, -1, 0, z, -1, -1, z, 0, -1, z, 1, -1, z }; private float[] colors = { 1, 0, 0, 1, //r, g, b, a 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1 }; private float[] texCoor = { 0f, 0f, 1f, 0f, 0f, 1f, 1f, 1f }; private FloatBuffer _clrBuffer; private ShortBuffer _indexBuffer; private FloatBuffer _vertexBuffer; private FloatBuffer _texBuffer; private int _nrOfVertices = 4; private int[] mTexIds = new int[2]; private Bitmap mBm; private Context mCtx; OpenGlRender(Context ctx){ mCtx = ctx; } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // TODO Auto-generated method stub gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glEnable(GL10.GL_TEXTURE_2D); mBm = BitmapFactory.decodeResource(mCtx.getResources(), R.drawable.fig01_d); updateBitmap(mBm); gl.glGenTextures(1, mTexIds, 0); gl.glBindTexture(GL10.GL_TEXTURE_2D, mTexIds[0]); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_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, mBm, 0); mBm.recycle(); initTriangle(); } private void updateBitmap(Bitmap src){ if(src == null) return; int w = pow2(src.getWidth()); int h = pow2(src.getHeight()); Bitmap b = Bitmap.createBitmap(w, h, src.hasAlpha() ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); Canvas c = new Canvas(b); c.drawBitmap(src, 0, 0, null); src = b; } private int pow2(float val){ int x = (int) (Math.log(val) / Math.log(2)); if((1 << x) >= val) return 1 << x; else return 1 << (1 + x); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); } private float angle = 0; @Override public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glClearColor(0, 0, 1.0f, 1.0f); gl.glColor4f(1f, 0f, 0f, 1f); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, _texBuffer); //size: number of coordinates per vertex; //stride: offset between 2 consecutive vertices; gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer); //gl.glColorPointer(4, GL10.GL_FLOAT, 0, _clrBuffer); //gl.glDrawElements(GL10.GL_TRIANGLE_FAN, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer); gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, _nrOfVertices); angle++; } private void initTriangle() { // float has 4 bytes ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder()); _vertexBuffer = vbb.asFloatBuffer(); _vertexBuffer.put(vertices); _vertexBuffer.position(0); // short has 4 bytes ByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2); ibb.order(ByteOrder.nativeOrder()); _indexBuffer = ibb.asShortBuffer(); for(short i = 0; i < _nrOfVertices; i++){ _indexBuffer.put(i, i); } _indexBuffer.position(0); ByteBuffer clr= ByteBuffer.allocateDirect(colors.length * 4); clr.order(ByteOrder.nativeOrder()); _clrBuffer = clr.asFloatBuffer(); _clrBuffer.put(colors); _clrBuffer.position(0); ByteBuffer tex = ByteBuffer.allocate(texCoor.length * 4); tex.order(ByteOrder.nativeOrder()); _texBuffer = tex.asFloatBuffer(); _texBuffer.put(texCoor); _texBuffer.position(0); } }?
?
?
1 楼 freedomray 2011-10-18
发现了错误所在。
原来纹理数组需要用整数,而不能用float。
应该定义为:
在应用纹理的时候,需要使用GL_FIXED类型:
原来纹理数组需要用整数,而不能用float。
应该定义为:
int one = 0x10000;private IntBuffer texIntCoor = IntBuffer.wrap(new int[]{ //0, 0, one, 0, 0, one, one, one, 0, one, one, one, 0, 0, one, 0, });
在应用纹理的时候,需要使用GL_FIXED类型:
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texIntCoor);
2 楼 freedomray 2011-10-18
进一步发现,其实并非不可使用FloatBuffer作为纹理坐标,只是在分配内存时有点隐蔽的错误:
这个地方,其实应该使用:
ByteBuffer tex = ByteBuffer.allocate(texCoor.length * 4);
这个地方,其实应该使用:
ByteBuffer tex = ByteBuffer.allocateDirect(texCoor.length * 4);
3 楼 coohcooh 2011-12-09
楼上是用哪个SDK开发这个的?2.2吗?我用2.2但是无法运行楼主的代码呢,刚学android,请指教下,谢谢啦