2014-05-17 3 views
0

나는 너무 많은 성공없이 쓴 안드로이드 게임에서 텍스처의 메모리 풋 프린트를 줄이려고 노력 해왔다. 연구를 기반으로 한 좋은 접근 방식은 ETC1을 사용하여 텍스처를 압축하는 것인데 이는 안드로이드 장치에서 주로 지원되는 형식이기 때문입니다.OpenGL ES 1.1을 사용하여 멀티 텍스처링을 구현하여 별도의 RGB 및 알파 PKM을 결합하는 방법은 무엇입니까?

말리 ARM을 사용하여 내 PNG에서 필요한 PKM을 만들 수 있습니다. 문제는 없습니다. 나는 또한 ETC1Utils를 사용하여이 PKM을 훌륭하게 렌더링 할 수 있습니다 - 지금까지 문제가 없습니다.

영문자를 처리하는 데 문제가 있습니다. 말리를 사용하여 내 PNG 용 별도의 알파 파일을 만들었습니다. 즉, "xxx.png"는 "xxx.pkm"및 "xxx_alpha.pkm"로 압축되었습니다. 한 가지 다른 접근법은 OpenGL ES 1.1에서 조각 쉐이더를 사용할 수 없기 때문에 다중 텍스처링을 사용하여이 두 텍스처를 결합하는 것입니다.

그리고 여기가 내가 붙어 있습니다. 나는이 물건에 너무 익숙하지 않고 많은 머리를 쓰지 않고있다. 기본적으로 알파 텍스처와 결합하자마자 모든 것이 흰색으로 렌더링됩니다. 여기

내 코드의 조각입니다 :

public class Texture { 

    GLGraphics glGraphics; 
    FileIO fileIO; 
    String fileName; 
    int textureId; 
    int minFilter; 
    int magFilter; 

    public int width; 
    public int height; 

    private boolean loaded = false; 

    public Texture(GLGame glGame, String fileName) { 
     this.glGraphics = glGame.getGLGraphics(); 
     this.fileIO = glGame.getFileIO(); 
     this.fileName = fileName; 
     load(); 
    } 

    public void load() { 
     GL10 gl = glGraphics.getGL(); 
     int[] textureIds = new int[2]; 
     gl.glGenTextures(2, textureIds, 0); 
     textureId = textureIds[0]; 

     InputStream inputStream = null; 

     try { 
      inputStream = fileIO.readAsset(fileName + ".pkm"); 

      int rgbTexture = textureId; 

      gl.glActiveTexture(GLES10.GL_TEXTURE0); 
      gl.glBindTexture(GLES11.GL_TEXTURE_2D, rgbTexture); 
      gl.glTexEnvf(GLES11.GL_TEXTURE_ENV, GLES11.GL_TEXTURE_ENV_MODE, GLES11.GL_MODULATE); 

      ETC1Texture etcTexture = ETC1Util.createTexture(inputStream); 
      ETC1Util.loadTexture(GLES11.GL_TEXTURE_2D, 0, 0, GLES11.GL_RGB, GLES11.GL_UNSIGNED_SHORT_5_6_5, etcTexture); 

      int alphaTexture = textureId[1]; 

      gl.glActiveTexture(GLES11.GL_TEXTURE1); 
      gl.glBindTexture(GLES11.GL_TEXTURE_2D, alphaTexture); 
      gl.glTexEnvf(GLES11.GL_TEXTURE_ENV, GLES11.GL_TEXTURE_ENV_MODE, GLES11.GL_COMBINE); 
      gl.glTexEnvf(GLES11.GL_TEXTURE_ENV, GLES11.GL_COMBINE_RGB, GLES11.GL_REPLACE); 
      gl.glTexEnvf(GLES11.GL_TEXTURE_ENV, GLES11.GL_SRC0_RGB, GLES11.GL_PREVIOUS); 
      gl.glTexEnvf(GLES11.GL_TEXTURE_ENV, GLES11.GL_OPERAND0_RGB, GLES11.GL_SRC_COLOR); 
      gl.glTexEnvf(GLES11.GL_TEXTURE_ENV, GLES11.GL_COMBINE_ALPHA, GLES11.GL_MODULATE); 
      gl.glTexEnvf(GLES11.GL_TEXTURE_ENV, GLES11.GL_SRC0_ALPHA, GLES11.GL_TEXTURE); 
      gl.glTexEnvf(GLES11.GL_TEXTURE_ENV, GLES11.GL_OPERAND0_ALPHA, GLES11.GL_SRC_ALPHA); 
      gl.glTexEnvf(GLES11.GL_TEXTURE_ENV, GLES11.GL_SRC1_ALPHA, GLES11.GL_PREVIOUS); 
      gl.glTexEnvf(GLES11.GL_TEXTURE_ENV, GLES11.GL_OPERAND1_ALPHA, GLES11.GL_SRC_ALPHA); 

      InputStream inputStreamAlpha = fileIO.readAsset(fileName + "_alpha.pkm"); 
      ETC1Texture etcAlphaTexture = ETC1Util.createTexture(inputStreamAlpha); 
      ETC1Util.loadTexture(GLES11.GL_TEXTURE_2D, 0, 0, GLES11.GL_RGB, GLES11.GL_UNSIGNED_SHORT_5_6_5, etcAlphaTexture); 

      setFilters(GL10.GL_NEAREST, GL10.GL_NEAREST); 
      gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); 

      width = etcTexture.getWidth(); 
      height = etcTexture.getHeight(); 
     } catch (IOException e) { 
      throw new RuntimeException("Couldn't load texture '" + fileName + "'", e); 
     } finally { 
      if (inputStream != null) { 
       try { 
        inputStream.close(); 
       } catch (IOException e) { 
        // do nothing 
       } 
      } 
     } 

     loaded = true; 
    } 

    public void reload() { 
     load(); 
     bind(); 
     setFilters(minFilter, magFilter); 
     glGraphics.getGL().glBindTexture(GL10.GL_TEXTURE_2D, 0); 
    } 

    public void setFilters(int minFilter, int magFilter) { 
     this.minFilter = minFilter; 
     this.magFilter = magFilter; 

     GL10 gl = glGraphics.getGL(); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, minFilter); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, magFilter); 
    } 

    public void bind() { 
     GL10 gl = glGraphics.getGL(); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); 
    } 

    public void dispose() { 
     loaded = false; 

     GL10 gl = glGraphics.getGL(); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); 
     int[] textureIds = { textureId }; 
     gl.glDeleteTextures(1, textureIds, 0); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); 
    } 

    public boolean isLoaded() { 
     return loaded; 
    } 

    public void setLoaded(boolean loaded) { 
     this.loaded = loaded; 
    } 
} 

내 주요 관심사는 load() 메서드입니다. 이 코드는 웹에서 찾은 스 니펫을 통해 모아졌으며 일반적으로 멀티 텍스처링에 대한 이해가 부족하여 어딘가에서 분명히 잘못되었습니다. 또한 내 텍스처를 렌더링 할 때 전화 참고 :

GL10 gl = glGraphics.getGL(); 
gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 
gl.glEnable(GL10.GL_TEXTURE_2D);   

camera.setViewportAndMatrices(); 
gl.glEnable(GL10.GL_BLEND); 
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); 

// call some objects that do my rendering stuff here 

gl.glDisable(GL10.GL_BLEND); 
gl.glDisable(GL10.GL_TEXTURE_2D); 

내가 내 텍스처 클래스에 바인드() 메서드를 호출 텍스처를 렌더링

. 보시다시피, 이것은로드 할 때 RGB PKM ID로 사용 된 내 전역 textureId 변수에 바인딩됩니다. 이것이 맞는지 확실하지 않습니다. RGB의 ID 또는 알파의 ID에 바인딩해야합니까? 아니면 옳은 길에 가깝지 않은가? 내 문제는 또한 ETC1Utils를 사용하여 alphas를로드하는 방법과 관련 될 수 있습니다.이 방법이 맞는지 아닌지는 잘 모르겠습니다.

저는 정말 엉망이되어서 어디서 잘못되었는지 지적하고, 멀티 텍스처링이 ETC1 alphas와 RGBs를 결합하여 구현하는 방법에 대해 설명하고 있습니다. 정말 멋질 것입니다.

답변

0

OpenGL ES 1.1의 고정 파이프 라인에서는 이것이 가능하지 않을지 모르지만 1.1 및 2.0 here에 텍스처를 결합하는 방법에 대한 훌륭한 요약이 있습니다.

또한 PowerVR SDK에는 OGLESMultitexture.cpp라는 1.1에 대한 훌륭한 예가 있습니다.

+0

정말로 멀티 텍스처링을 제대로 수행하지 못했습니다. 그러나 이것을 수행하는 방법을 알아 낸 후에 OpenGL ES 1.1에서는 내가 성취하고자하는 것이 불가능하다는 것을 알았습니다. 문제는 알파 PKM이 RGB 채널에 값을 저장하기 때문에 RGB 값을 단일 알파 값으로 결합 할 수있는 멀티 텍스처링 (볼 수있는 한)이 불가능하다는 것입니다. @ClayMontgomery가 OpenGL ES 1.1에서는 이것이 가능하지 않았기 때문에이 대답을 받아 들였습니다. – brent777

관련 문제