Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/185.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android OpenGL ES:一个VBO-几个精灵-分别翻译每个_Android_Opengl Es_Glsl_Opengl Es 2.0_Vbo - Fatal编程技术网

Android OpenGL ES:一个VBO-几个精灵-分别翻译每个

Android OpenGL ES:一个VBO-几个精灵-分别翻译每个,android,opengl-es,glsl,opengl-es-2.0,vbo,Android,Opengl Es,Glsl,Opengl Es 2.0,Vbo,我想知道当这些精灵的顶点存储在同一个VBO中时,如何单独访问和操纵每个精灵。出于性能原因,我对精灵使用了textureatlas,然后将其映射到vertexarray。我尝试将精灵拆分为单独的顶点数组,并将它们放在单独的VBO中。但是如果我画100个精灵,这会影响性能,因为每次调用都要进行很多单独的绘制。相反,我想使用一个相同的VBO,并从中分别翻译每个精灵。这可能吗 源代码 @Override public void onSurfaceCreated(GL10 unused, EGL

我想知道当这些精灵的顶点存储在同一个VBO中时,如何单独访问和操纵每个精灵。出于性能原因,我对精灵使用了textureatlas,然后将其映射到vertexarray。我尝试将精灵拆分为单独的顶点数组,并将它们放在单独的VBO中。但是如果我画100个精灵,这会影响性能,因为每次调用都要进行很多单独的绘制。相反,我想使用一个相同的VBO,并从中分别翻译每个精灵。这可能吗

源代码

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

    vertexBuffer = GLData.createVertices(nSprites, vertices);
    GLData.createUvsData(nSprites, alienUvs, uvBufferAlien);
    //drawListBuffer = GLData.createIndices(indices, nSprites);
    GLData.createVertexBufferObject(vertexBuffer,nSprites, uvBufferAlien, 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);

    // get shadersource
    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"});

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

    GLES20.glUseProgram(mProgramHandle);

    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix");
    mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVMatrix");
    //mColorHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Color");
    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);


    // Create a new perspective projection matrix. The height will stay the same
    // while the width will vary as per aspect ratio.
    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) {

    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.translateM(mModelMatrix, 0, 2, 0f, -7f);

    draw();

}

private void draw() {

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


    //vertices
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufferId[1]);
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, 0, 0);


    // Clear the currently bound buffer (so future OpenGL calls do not use this buffer).
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);



                         /* MATRIX */

    // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
    // (which currently contains model * view).
    Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);

    // Pass in the modelview matrix.
    GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);

    // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
    // (which now contains model * view * projection).
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);

    // Pass in the combined matrix.
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);

    // Draw the sprites

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

}
顶点着色器

 attribute vec4 a_Position;
 uniform mat4 u_MVMatrix;
 uniform mat4 u_MVPMatrix;
 void main()       {

    gl_Position = u_MVPMatrix * a_Position;

 }

您可以上载一个统一的矩阵数组,并将索引作为每个精灵的逐顶点属性上传到该数组中,以为每个精灵提供唯一的矩阵(用于骨骼动画模型蒙皮的技术,但在这里也适用)


然而,对于简单的精灵来说,上传矩阵的成本几乎与更新位置数组一样昂贵,并且您需要担心的统一数组的大小有限制。您最好只是在软件中设置它们的动画,并在批处理的每个帧中为每个顶点上载一个新位置。将位置从纹理坐标拆分为单独的缓冲区,以最小化上载每个帧的带宽。

您可以上载一个统一的矩阵数组,并将索引作为每个精灵的逐顶点属性,为每个精灵提供唯一的矩阵(该技术用于骨骼动画模型的蒙皮,但在这里也适用)


然而,对于简单的精灵来说,上传矩阵的成本几乎和更新位置数组一样昂贵,而且你需要担心的统一数组的大小也有限制。你最好只在软件中设置它们的动画,并在每一帧的批次中为每个顶点上传一个新的位置。拆分位置将图像导入一个单独的缓冲区,例如纹理坐标,以最小化上传每帧的带宽。

我对好答案投了赞成票,但问题没有解决。事实上,当我在Galaxy S3上使用我的应用程序(从S7切换)时,我简直不敢相信帧时间下降到20。我整晚都在想这个问题,但可能是1920 X 1856的te textureatlas吗?因为它不是POT还是太大了???我会试试这个-如果它不起作用,我会在堆栈上提出一个新问题并给你链接。谢谢!!!!!你是在修改纹理图集还是没有pipel的现有缓冲区对它们进行加密?可能只是触发了大量的资源拷贝。看,我投了赞成票,认为答案是好的,但问题没有解决。事实上,我无法相信,当我在Galaxy S3上使用我的应用程序时(从S7切换而来)帧时间下降到20。我整晚都在想这个问题,但可能是1920 X 1856的te textureatlas吗?因为它不是POT还是太大了???我会试试这个-如果它不起作用,我会在堆栈上提出一个新问题并给你链接。谢谢!!!!!你是在修改纹理图集还是没有pipel的现有缓冲区正在复制它们?可能只是触发了大量资源拷贝。请参阅