2012-10-26 2 views
0

사용자가 화면을 터치하여 드래그하여 90 개의 2D 모양을 그릴 수있는 프로그램이 있습니다. 눈에 띄는 양의 choppiness가 있으며 DDMS는 가장 많은 CPU 시간 (~ 85 %)을 차지하는 한 가지 방법이 draw() 메소드라고합니다. 실제로는 하나의 모양 만 움직이고 다른 하나는 그렇지 않기 때문에 89 개의 모양을 FrameBuffer 객체를 사용하여 텍스처에 렌더링하고 전체 화면을 채우는 모양으로 그 질감을 그릴 수 있습니까? 그렇지 않다면 과속을 일으킬 다른 잠재적 인 방법이 있습니까?OpenGL ES2 : FrameBuffer 객체를 사용하여 더 많은 모양을 더 빨리 렌더링합니다.

private void draw() { 
    // Pass in the position information 
    mCubePositions.position(0); 
    GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, 0, mCubePositions); 
    GLES20.glEnableVertexAttribArray(mPositionHandle); 

    // Pass in the color information 
    mCubeColors.position(0); 
    GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false, 0, mCubeColors); 
    GLES20.glEnableVertexAttribArray(mColorHandle); 

    // Pass in the texture coordinate information 
    mCubeTextureCoordinates.position(0); 
    GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mTextureCoordinateDataSize, GLES20.GL_FLOAT, false, 0, mCubeTextureCoordinates); 
    GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle); 

    // 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 cube. 
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6); 
} 

미리 감사드립니다.

답변

3

쿼드 (quads)를 의미 할 때 "큐브 (cubes)"라는 질문에 혼란스러워 보였으므로이 대답은 3d 케이스를 다루기 때문에 어쨌든 더 유익 할 것입니다.

보기 및 투영 행렬을 ViewProj 행렬에 결합하십시오. 그런 다음 Vertex Shader에서 VertexPos * Model * ViewProj를 수행합니다.

또한 배치가 필요합니다. 그 안에 모든 큐브가있는 하나의 큰 배열과 각 큐브에 대한 변형이있는 다른 배열이 있어야합니다. 그런 다음 모든 큐브에 대한 단일 그리기 호출을 수행합니다. Vertex Buffer Object를 사용하도록 변환하는 것을 고려하십시오. 그리기 호출은 뒤에서 API에서 전체 논리 및 메모리 복사 등을 호출하기 때문에 CPU를 많이 사용합니다. 게임 엔진은 게임 엔진을 최소화하기 위해 노력합니다.

방법 1 무 호출이 많은 것을을 그릴 수 있도록합니다

하나의 질감 (에 "아틀라스")에 모든 다른 텍스처를 넣고 해당 부분을 찾기 위해 각 큐브의 UV를 조정하여 보상 텍스처의. 모든 모델 행렬을 인접한 배열에 배치하고 정점 셰이더에서이 배열에 인덱스를 지정합니다.

attribute vec3 a_position; 
attribute vec2 a_texCoord; 
attribute int a_modelIndex; 
attribute int a_UVlIndex; 

uniform mat4 u_model[90]; 
uniform vec2 u_UVOffset[16]; // Support 16 different textures in our atlas. 

varying vec2 v_texCoord; 
... 

void main() 
{ 
    gl_Position = u_viewProj * u_model[a_modelIndex] * vec4(a_position, 1); 
    v_texCoord = a_texCoord + u_UVOffset[a_UVlIndex]; 
    ... 
}  

당신은 하나 개의 큰 배열에 모든 정점 데이터를 팩 수 있습니다, 그래서 당신은 당신은 단지 모든 시간을 큐브 그리기 때문에, 당신은 동일한 정점을 다시 사용할 수 GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6 * 90); 그러나 더 나은 일을 끝낼 데이터를 매번 모델 행렬은 나머지 (스케일, 회전, 평행 이동)를 처리합니다. 이렇게하려면 glDrawArrays 대신 glDrawElements을 사용하고, 단순화를 위해 트라이 목록을 가정하면 정점 배열에서 정점을 만드는 36 개의 정점을 참조하는 36 개의 인덱스를 지정한 다음 36 개의 인덱스를 90 번 반복하면 인덱스 배열 정점은 (0, 0, 0)을 중심으로 한 단위 큐브 여야합니다. 이 동일한 "큐브 템플릿"은 정점 쉐이더의 모델 행렬에 의해 수정되어 각 보이는 "큐브 인스턴스"를 만듭니다. 각 프레임을 변경하는 데 필요한 것은 모델 행렬과 텍스처 UV뿐입니다.

glVertexAttribPointer()을 사용하면 원하는 모든 것을 정점 셰이더에 뿌릴 수 있으며, glVertexAttribPointer를 창의적으로 사용하여 유니폼이 아닌 특성으로 모델 행렬을 갖는 것이 더 효율적일 수 있습니다.

모바일 장치는 픽셀 바운드에 매우 민감한 경향이 있습니다. 큐브가 화면에서 꽤 큰 경우 오버로드가 많이 발생할 수 있습니다. 높은 CPU % (결국 백분율은)는 청어가 될 수 있으며 GPU에서 픽셀 바운드가 될 수 있습니다. 이것에 대한 간단한 테스트는 모든 큐브를 매우 작게 만들고 프레임 속도가 향상되는지 확인하는 것입니다.

참고로, S5570Adreno 200 GPU입니다.

+0

저는 S5570에서 실행됩니다. 대부분의 큐브는 매우 작으며 크기를 변경해도 프레임 속도에 큰 영향을 미치지 않습니다. 큐브의 개수, 크기 및 텍스처는 다른 큐브의 위치에 따라 크게 달라지며 사용자가 모양을 드래그 할 때마다 변경됩니다. ArrayList의 크기를 조절하고 매번 큐브가있는 배열로 변환 할 때마다 비효율적입니까? 어떻게 하나의 그리기 호출을 하나의 배열에서 개별 셰이프로 렌더링 할 수 있습니까? –

+0

자세한 답변을 보내 주셔서 감사합니다. 그러나 한 가지 질문 :이 방법은 아니오를 허용합니까? 그려진 큐브와 아니요. 즉시 증가하거나 감소하도록 지원되는 텍스처 –

+0

예, 최대한 많은 수의 큐브를 결정하고이 최대 값에 대한 데이터 구조를 미리 할당하여 즉시 할당하는 것을 피하는 것이 좋습니다. 예를 들어 위의 예에서 최대 16 개의 텍스처를 허용했습니다. –

관련 문제