Android OpenGL ES:帧速率和纹理

Android OpenGL ES:帧速率和纹理,android,opengl-es,frame-rate,texture-atlas,Android,Opengl Es,Frame Rate,Texture Atlas,我注意到,textureatlas的大小确实具有OpenGL ES 2应用程序的输入。atlas的尺寸为2048 X 2048,在三星Galaxy S7上使用时,其性能与每秒60帧的速度相当。即使是4096 X 4096也可以,虽然性能可能会有所损失,但不会太多 如果我现在在三星Galaxy S3上编译并运行相同的应用程序,那么如果我使用2048 X 2048的textureatlas,帧速率会非常糟糕。画一帧大约需要25毫秒。但是如果我将textureatlas减少到1024 X 1024,性

我注意到,textureatlas的大小确实具有OpenGL ES 2应用程序的输入。atlas的尺寸为2048 X 2048,在三星Galaxy S7上使用时,其性能与每秒60帧的速度相当。即使是4096 X 4096也可以,虽然性能可能会有所损失,但不会太多

如果我现在在三星Galaxy S3上编译并运行相同的应用程序,那么如果我使用2048 X 2048的textureatlas,帧速率会非常糟糕。画一帧大约需要25毫秒。但是如果我将textureatlas减少到1024 X 1024,性能将提高很多-每秒60帧

所以我的结论是,我应该根据设备使用不同尺寸的textureatlas吗?但具体来说,尺寸与设备之间的关系如何?可能是屏幕大小?例如,720x1280的屏幕大小我使用1024x1024的纹理LAS,1440x2560的是2048x2048的纹理LAS

还是我的消息来源有问题?到现在为止,我不知道如何跟踪100个共享同一帧缓冲区的精灵。相反,每个精灵都有自己的缓冲区,在onDRawFrame中,我对每个缓冲区进行单独的drawcall。但我猜bindBuffer比bindTexture快

或者我如何将位图加载到OpenGL中有问题吗?我在用国旗

Bitmap.Config.RGB_565
但是性能没有提高

渲染器源

  public MyGLRenderer(Context context) {

    this.context = context;

    nSprites = 75;

    alienUvs = new float[16][12 * nSprites];
    bgUvs = new float[12];
    vertices = new float[18 *nSprites];
    verticesBG = new float[18];

    vertexBuffer= new FloatBuffer[nSprites];
    vertexBufferBG = new FloatBuffer[1];

    // The indices for all textured quads
    indices = new short[nSprites*6];

    uvBufferAlien = new FloatBuffer[16]; // antalet frames

    uvBufferBG = new FloatBuffer[1];

    bufferId = new int[16 + nSprites + 2]; // 16 stycken för aliens, nsprites antal för punkterna

    modulo = 2;

    start = System.currentTimeMillis();

    //slumpa x o y
    xPos = new float[nSprites];
    yPos = new float[nSprites];

    for (int i = 0; i < nSprites; i++) {

        Random r = new Random();
        xPos[i] = (float)(r.nextDouble()-0.5) * 6;
        r = new Random();
        yPos[i] = (float)(r.nextDouble()-0.5) * 6;
    }
}

@Override
public void onSurfaceCreated(GL10 unused, EGLConfig config) {

    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

    vertexBuffer = GLData.createVertices(nSprites, vertices);
    vertexBufferBG[0] = GLData.createVerticesBG(verticesBG);
    GLData.createUvsData(nSprites, alienUvs, uvBufferAlien);
    uvBufferBG[0] = GLData.createUvsDataBG(bgUvs);
    GLData.createVertexBufferObject(vertexBuffer, vertexBufferBG, nSprites, uvBufferAlien, uvBufferBG, bufferId.length, bufferId);

    createCamera();

    GLES20.glEnable(GLES20.GL_CULL_FACE);

    GLES20.glEnable(GLES20.GL_BLEND);
    GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);

    // inlästa shaderprogram (källkod i strängform)
    final String vertexShader = getVertexShader();
    final String fragmentShader = getFragmentShader();

    final int vertexShaderHandle = ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, vertexShader);
    final int fragmentShaderHandle = ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShader);

    mProgramHandle = ShaderHelper.createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle,
            new String[] {"a_Position",  "a_Color", "a_Normal", "a_TexCoordinate"});

    //skapa texture
    textureHandle = TextureHelper.loadTexture(context);

    GLES20.glUseProgram(mProgramHandle);

    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix");
    mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVMatrix");
    mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_TexCoordinate");

    mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position");
}

@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {

    game_width = width;
    game_height = height;

    GLES20.glViewport(0, 0, width, height);

    final float ratio = (float) width / height;
    final float left = -ratio;
    final float right = ratio;
    final float bottom = -1.0f;
    final float top = 1.0f;
    final float near = 1f;
    final float far = 20.0f;

    Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
}


@Override
public void onDrawFrame(GL10 unused) {


    int rest = 0;
    if (modulo > 0) {
        rest = frameCntr % modulo;
    }

    if (rest == 0) {
        bitmapIndex++;

    }

    if (bitmapIndex == 16) {
        bitmapIndex = 0;
    }
    frameCntr++;


    //uvs, 16 bilder
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufferId[bitmapIndex]);
    GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
    GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mTextureCoordinateDataSize, GLES20.GL_FLOAT, false, 0, 0);


    for (int i = 0; i < nSprites; i++) {

        Matrix.setIdentityM(mModelMatrix, 0);
        Matrix.translateM(mModelMatrix, 0, xPos[i], yPos[i], -8f);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufferId[16 + i]);
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, 0, 0);

        draw();

    }


    //mease framerate
    long stop = System.currentTimeMillis();
    nbFrames++;
    if (stop - start >= 1000) {
        System.out.println("" + (float)1000 / nbFrames);
        nbFrames = 0;
        start += 1000;
    }

}

private void draw() {

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

    Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);

    GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);

    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);

    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);

}
位图解码器(代码段)


相关报道:@morrisonchange谢谢你会调查的
 public class TextureHelper {


public static int[] loadTexture(Context context) {

    int[] texturenames = new int[1];
    GLES20.glGenTextures(1, texturenames, 0);

    int resId = context.getResources().getIdentifier("aliens", "drawable", context.getPackageName());
    //Bitmap bmp = BitmapDecoder.decodeSampledBitmapFromResource(context.getResources(), resId, 960, 928);
    //Bitmap bmp = BitmapDecoder.decodeSampledBitmapFromResource(context.getResources(), resId, 780, 1280);
    Bitmap bmp = BitmapDecoder.decodeSampledBitmapFromResource(context.getResources(), resId, 2048, 2048);

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texturenames[0]);

    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);

    bmp.recycle();

    return texturenames;
 }
}
   protected static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    options.inPreferredConfig = Bitmap.Config.RGB_565;
    options.inDither = true;
    //options.inScaled = false;

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    return Bitmap.createScaledBitmap( BitmapFactory.decodeResource(res, resId, options), reqWidth, reqHeight, true);
}