2014-12-12 11 views
0

Hy, 저는 Android에서 앱을 개발 중이며 테스트 단계에 있으며 다른 기기에서 사용해 보겠습니다. 넥서스 7에서 앱을 개발했습니다.ARM MALI OpenGL ES 2.0 렌더링 텍스처 버그

팔 마 리 gpu 장치에서 실행할 때 렌더링 된 텍스트가 깜박 거리거나 미친 것처럼 느껴지기 시작합니다. 포인트 크기를 1로 설정하면 생성 된 텍스처에서 GLES20.GL_POINTS를 사용합니다. 깜박 거리면 아티팩트가있는 것처럼 보입니다. 포인트 크기를 10과 같이 더 큰 숫자로 설정하면 가끔은 의미가 있습니다. 초기 렌더링의 텍스처를 보여줍니다.

어떤 원인 일 수 있습니까?

private void setTexture(int texture) { 
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, 
      GLES20.GL_CLAMP_TO_EDGE); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, 
      GLES20.GL_CLAMP_TO_EDGE); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texW, texH, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); 
} 

그리고이 후

나는 그것을 그릴

public void draw(){ 
    createSmokeTexture(); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 
    setTexture(renderTex[0]); 
    drawSmokeToScreen(); 
} 

asdas :

private void createSmokeTexture() { 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[0]); 
    GLES20.glClearColor(0.48f, 0.48f, 0.48f, 0.0f); 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTex[0], 0); 
    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthRb[0]); 
    //background counts 
    renderscriptSmokeStep_involke(); 

    GLES20.glUseProgram(mProgramSmoke); 
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture); 
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramSmoke, "u_MVPMatrix"); 
    mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramSmoke, "u_Move"); 
    mTextureUniformHandle = GLES20.glGetUniformLocation(mProgramSmoke, "u_Texture"); 
    smokeParticleSizeUniformHandle = GLES20.glGetUniformLocation(mProgramSmoke, "u_PointSize"); 
    maximumDensityHandler = GLES20.glGetUniformLocation(mProgramSmoke, "u_MaximumDensity"); 

    cellDensityHandle = GLES20.glGetAttribLocation(mProgramSmoke, "a_Age"); 
    smokeStartPositionHandle = GLES20.glGetAttribLocation(mProgramSmoke, "a_Position"); 

    Matrix.setIdentityM(mMoveMatrix, 0); 
    Matrix.translateM(mMoveMatrix, 0, positionX, positionY, 0); 
    Matrix.multiplyMM(mMoveMatrix, 0, Render.mModelMatrix, 0, mMoveMatrix, 0); 

    GLES20.glUniform1f(smokeParticleSizeUniformHandle, PARTICLE_SIZE); 
    GLES20.glUniform1f(maximumDensityHandler, MAXIMUM_DENSITY); 
    GLES20.glUniform1i(mTextureUniformHandle, 0); 
    GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMoveMatrix, 0); 
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, Render.m2dProjectionMatrix, 0); 

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, particlePosBuffer); 
    GLES20.glEnableVertexAttribArray(smokeStartPositionHandle); 
    GLES20.glVertexAttribPointer(smokeStartPositionHandle, 2, GLES20.GL_FLOAT, false, 0, 0); 

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); 

    GLES20.glEnableVertexAttribArray(cellDensityHandle); 
    GLES20.glVertexAttribPointer(cellDensityHandle, 1, GLES20.GL_FLOAT, false, 0, cellDensity); 

    // Draw the point. 
    GLES20.glDrawArrays(GLES20.GL_POINTS, 0, NUM_PARTICLES); 
} 

이는 무승부에 호출됩니다 :

private void setupRenderToTexture() { 
    fb = new int[1]; 
    depthRb = new int[1]; 
    renderTex = new int[2]; 
    // generate 
    GLES20.glGenFramebuffers(1, fb, 0); 
    GLES20.glGenRenderbuffers(1, depthRb, 0); 
    GLES20.glGenTextures(1, renderTex, 0); 
    // create render buffer and bind 16-bit depth buffer 
    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthRb[0]); 
    GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, texW, texH); 
} 

이 나의 여는 textue 방법으로 렌더링 화면

private void drawSmokeToScreen() { 
    GLES20.glUseProgram(mProgramHandle); 
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix"); 
    mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_Move"); 
    positionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position"); 
    textureHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_TexCoordinate"); 

    GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, Render.mModelMatrix, 0); 
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, Render.m2dProjectionMatrix, 0); 

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, fullDrawSurfice.getPositionDataIndex()); 
    GLES20.glEnableVertexAttribArray(positionHandle); 
    GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 0, 0); 

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, fullDrawSurfice.getTextureDataIndex()); 
    GLES20.glEnableVertexAttribArray(textureHandle); 
    GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 0, 0); 

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); 

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

확인할 사항은 지원되는 포인트 크기입니다. 'glGetFloatv (GL_ALIASED_POINT_SIZE_RANGE, ...)'를 사용하십시오. 구현은 1보다 큰 포인트 크기를 지원할 필요가 없습니다. 이외에도 사람들은 문제에 대한 설명만으로는 많은 도움을 줄 수 없습니다.드라이버 버그 일 수도 있고 코드의 문제로 다른 아키텍처의 증상이 나타나지 않을 수도 있습니다. –

+0

@RetoKoradi 필요하지 않다는 것을 알아두면 좋은지,이 장치가이를 확인하고 지원합니다. 당신 말이 맞아요, 몇 분 안에 몇 가지 코드를 작성하겠습니다. 그리고 이것은 내가 다른 아키텍처에서 개발 한 경험이 없으므로 무엇을 검사해야할지 모르겠다. – FaNaT

답변

1

전화 주문에는 몇 가지 문제가있는 것으로 보입니다. 그것은 완전히 glFramebufferTexture2D()glFramebufferRenderbuffer() 호출로 렌더링 타겟을 부착하여 설치하기 전에 다음

GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[0]); 
GLES20.glClearColor(0.48f, 0.48f, 0.48f, 0.0f); 
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, 
     GLES20.GL_TEXTURE_2D, renderTex[0], 0); 
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, 
     GLES20.GL_RENDERBUFFER, depthRb[0]); 

는, 프레임 버퍼가 지워집니다 : createSmokeTexture()의 시작에서
  1. ,이 코드 시퀀스가있다. 이는 첫 번째 프레임에 대한 문제 일 가능성이 높습니다. 여기에 표시된 코드에서 렌더링 대상이 다시 연결 해제되지 않기 때문입니다. 그 후에는 전화가 중복됩니다. 설치 중에 렌더링 대상을 첨부하는 것이 훨씬 더 좋습니다. setTexture()의 끝에

  2. : draw()의 시퀀스에 기초

    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texW, texH, 0, 
         GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); 
    

    는, 이것은 완성 FBO 렌더링 후에 호출 한 메인 프레임 버퍼에 그려 얻어진 텍스처를 사용하여 이전된다. 그러나이 glTexImage2D() 호출은 기본적으로 FBO 렌더링에 의해 생성 된 텍스처의 내용을 지 웁니다.

는 이러한 문제를 모두 해결 setTexture()에서 glActiveTexture()glBindTexture() 호출하지만 glFramebufferTexture2D()과 제 1 코드 시퀀스에서 glFramebufferRenderbuffer(), 모두를 제거하십시오. 이 모든 것은 함수가되어야합니다. 그러면 다음과 같이됩니다.

GLES20.glGenTextures(1, renderTex, 0); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTex[0]); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, 
     GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, 
     GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, 
     GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, 
     GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texW, texH, 0, 
     GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); 

// create render buffer and bind 16-bit depth buffer 
GLES20.glGenRenderbuffers(1, depthRb, 0); 
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthRb[0]); 
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, 
     GLES20.GL_DEPTH_COMPONENT16, texW, texH); 

GLES20.glGenFramebuffers(1, fb, 0); 
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, 
     GLES20.GL_TEXTURE_2D, renderTex[0], 0); 
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, 
     GLES20.GL_RENDERBUFFER, depthRb[0]); 
+0

대단히 감사합니다. – FaNaT