问题
I'm developing on a Droid, version 2.1-update1. My supported GL extensions include GL_OES_point_sprite and GL_OES_point_size_array.
I am unable to get point sprites to render. The code below throws UnsupportedOperationException from GLWrapperBase at the glTexEnvi call. If I disable textures and comment out the glTexEnvi all, it throws the same exception further down, at glPointSizePointerOES().
Are point sprites properly supported in Android? Has anyone gotten them working? Or is there an issue with my code below?
// Note that gl is cast to GL11
gl.glEnable(GL11.GL_TEXTURE_2D);
gl.glEnable(GL11.GL_BLEND);
gl.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
gl.glDepthMask(false);
gl.glEnable(GL11.GL_POINT_SPRITE_OES);
gl.glTexEnvi( GL11.GL_POINT_SPRITE_OES, GL11.GL_COORD_REPLACE_OES, GL11.GL_TRUE );
gl.glEnableClientState(GL11.GL_VERTEX_ARRAY);
gl.glVertexPointer(2, GL11.GL_SHORT, 0, .vertBuffer);
gl.glEnableClientState(GL11.GL_POINT_SIZE_ARRAY_OES);
gl.glPointSizePointerOES(GL11.GL_FLOAT, 0, pointSizeBuffer);
Thanks
回答1:
I got this working, here is my draw function
Initialize everything
gl.glEnable(GL10.GL_TEXTURE);
TextureManager.activateTexture(gl, R.drawable.water1); //Don't look for this, it's not public api, just looks upd texture id for android resource if loaded, and then activates it. it's the gl.glBindTexture() call replacement
gl.glEnable(GL11.GL_POINT_SPRITE_OES);
gl.glEnableClientState(GL11.GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES);
gl.glEnableClientState(GL11.GL_POINT_SIZE_ARRAY_OES);
gl.glEnableClientState(GL11.GL_POINT_SPRITE_OES);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
Set the texture environment up to use point sprites
gl.glTexEnvf(GL11.GL_POINT_SPRITE_OES, GL11.GL_COORD_REPLACE_OES, GL11.GL_TRUE);
Set up pointers to the data (First array is 2d laid out [x,y,x2,y2,...] second is 1d [s1,s2,..])
gl.glVertexPointer(2,GL11.GL_FLOAT,0,PosData);
((GL11)(gl)).glPointSizePointerOES(GL10.GL_FLOAT, 0, SizeData);
Draw
gl.glDrawArrays(GL10.GL_POINTS,0,MAX);
Disable stuff
gl.glDisableClientState(GL11.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL11.GL_POINT_SIZE_ARRAY_OES);
gl.glDisableClientState(GL11.GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES);
gl.glDisableClientState(GL11.GL_POINT_SIZE_ARRAY_OES);
gl.glDisable(GL10.GL_TEXTURE);
In my initializer I only have my projection setup and GL_BLEND enabled for blending. I think you would need GL_COLOR_MATERIAL if you wanted to color your sprite.
回答2:
I got the point sprites working with ES 1.1 & 2 on a nexus one. I use a fixed point size so I didn´t have to use a size buffer but you can use my code to first get it working and then add the size buffer.
In my draw method:
gl.glEnable(GL11.GL_POINT_SPRITE_OES);
gl.glTexEnvf(GL11.GL_POINT_SPRITE_OES, GL11.GL_COORD_REPLACE_OES, GL11.GL_TRUE);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// 2 dimensional array, (x1,y1, x2, y2, ...).
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, mVerticesBuffer);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);
gl.glPointSize(32); // Fixed point size for all points
// This only worked with GLES11 & GLES20.
GLES11.glDrawArrays(GLES11.GL_POINTS, 0, vertices.length);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_TEXTURE_2D);
gl.glDisable(GL11.GL_POINT_SPRITE_OES);
回答3:
if like me you're using MatrixTrackingGL you need to use glTexEnvf rather than glTexEnvi (f not i at the end) and you need to go into MatrixTrackingGL and change glPointSizePointerOES:
public void glPointSizePointerOES(int type, int stride, Buffer pointer) {
mgl11.glPointSizePointerOES(type, stride, pointer);
//throw new UnsupportedOperationException();
}
I'm sure there is a good reason why it is unsupported in the first place but I don't know it and it works for me on a ZTE Blade running android 2.1
For anyone wondering, MatrixTrackerGL comes from C:\Program Files\android-sdk-windows\samples\android-7\ApiDemos\src\com\example\android\apis\graphics\spritetext
It is used when setting up your GLSurface View:
// GraphicsRenderer is my implementation of Renderer
Graphics Renderer graphicsRenderer = new GraphicsRenderer(this);
GLSurfaceView mGLView = (GLSurfaceView) findViewById(R.id.graphics_glsurfaceview1);
mGLView.setGLWrapper(new GLSurfaceView.GLWrapper() {
public GL wrap(GL gl) {
return new MatrixTrackingGL(gl);
}});
mGLView.setEGLConfigChooser(true);
mGLView.setRenderer(graphicsRenderer);
and means you can use GLU.gluUnProject to do picking!:
MatrixGrabber matrixGrabber = new MatrixGrabber();
matrixGrabber.getCurrentModelView(gl);
matrixGrabber.getCurrentProjection(gl);
float[] vector = new float[4];
GLU.gluUnProject(x, y, 0f, matrixGrabber.mModelView, 0, matrixGrabber.mProjection, 0, new int[]{mGLView .getTop(),mGLView .getLeft(),mGLView .getWidth(),mGLView .getHeight()}, 0, vector, 0);
来源:https://stackoverflow.com/questions/3444429/do-opengl-point-sprites-work-in-android