Работают ли точечные спрайты OpenGL в Android?

Разрабатываю на Дроиде, версия 2.1-update1. Мои поддерживаемые расширения GL включают GL_OES_point_sprite и GL_OES_point_size_array.

Я не могу получить точечные спрайты для рендеринга. Приведенный ниже код генерирует исключение UnsupportedOperationException из GLWrapperBase при вызове glTexEnvi. Если я отключу текстуры и закомментирую все glTexEnvi, это вызовет то же самое исключение ниже, в glPointSizePointerOES().

Правильно ли поддерживаются точечные спрайты в Android? У кого-нибудь они заработали? Или есть проблема с моим кодом ниже?

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

Спасибо


person Ivan    schedule 09.08.2010    source источник


Ответы (3)


У меня это работает, вот моя функция рисования

Инициализировать все

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

Настройте текстурную среду для использования точечных спрайтов.

    gl.glTexEnvf(GL11.GL_POINT_SPRITE_OES, GL11.GL_COORD_REPLACE_OES, GL11.GL_TRUE);

Настройте указатели на данные (первый массив имеет вид 2d [x, y, x2, y2,...], второй — 1d [s1, s2,..])

    gl.glVertexPointer(2,GL11.GL_FLOAT,0,PosData);              
    ((GL11)(gl)).glPointSizePointerOES(GL10.GL_FLOAT, 0, SizeData);

Рисовать

    gl.glDrawArrays(GL10.GL_POINTS,0,MAX);

Отключить вещи

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

В моем инициализаторе у меня есть только мои настройки проекции и GL_BLEND для смешивания. Я думаю, вам понадобится GL_COLOR_MATERIAL, если вы хотите раскрасить свой спрайт.

person HaMMeReD    schedule 18.10.2010
comment
просто из любопытства, на каком телефоне ты это запускал? - person Ben Gotow; 13.11.2010
comment
хм - похоже, вам нужно указать размер точки, используя либо glPointSize(), либо массив размеров точек. glPointSizex() не работает на моем Nexus One с версией 2.2. вообще ничего не появляется... - person Ben Gotow; 13.11.2010
comment
Работает на 2.2 n1, попробуйте живые обои MetalRain для примера, откуда это взялось. - person HaMMeReD; 01.12.2010

Я получил точечные спрайты, работающие с ES 1.1 и 2 на нексусе. Я использую размер с фиксированной точкой, поэтому мне не нужно использовать буфер размера, но вы можете использовать мой код, чтобы сначала заставить его работать, а затем добавить буфер размера.

В моем методе рисования:

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);
person Ernir Erlingsson    schedule 29.11.2011

если вы, как и я, используете MatrixTrackingGL вам нужно использовать glTexEnvf, а не glTexEnvi (если не i в конце), и вам нужно зайти в MatrixTrackingGL и изменить glPointSizePointerOES:

public void glPointSizePointerOES(int type, int stride, Buffer pointer) {
    mgl11.glPointSizePointerOES(type, stride, pointer);
    //throw new UnsupportedOperationException();
}

Я уверен, что есть веская причина, по которой он вообще не поддерживается, но я этого не знаю, и у меня он работает на ZTE Blade под управлением Android 2.1.


Для тех, кому интересно, MatrixTrackerGL исходит из C:\Program Files\android-sdk-windows\samples\android-7\ApiDemos\src\com\example\android\apis\graphics\spritetext

Он используется при настройке вашего 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);

и означает, что вы можете использовать GLU.gluUnProject для выбора!:

        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);
person James Coote    schedule 11.10.2011