2011-04-18 3 views
10

나는 안드로이드에서 반복적으로 놀고있는 앱을 가지고 있는데, OpenGL-es를 사용합니다.안드로이드 OpenGL-es 텍스처 2 개를 로딩하지 않습니다.

현재 나는 그렇게 같은 비트 맵에서 텍스처를로드

//Load up and flip the texture - then dispose the temp 
    Bitmap temp = BitmapFactory.decodeResource(Deflecticon.getContext().getResources(), resourceID); 
    Bitmap bmp = Bitmap.createBitmap(temp, 0, 0, temp.getWidth(), temp.getHeight(), flip, true); 
    temp.recycle(); 

    //Bind the texture in memory 
    gl.glBindTexture(GL10.GL_TEXTURE_2D, id); 

    //Set the parameters of the texture. 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); 

    //On to the GPU 
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0); 

명백한 문제는 내가 사용하고 질감이 나는 사전 편집을 해요 순간 2의 거듭 제곱이어야한다는 것입니다 2의 거듭 제곱이되는 포토샵의 텍스처는 빈 테두리가 있습니다. 그러나 이것은 약간 지루한 것이고 나는 그것들을 그대로로드 할 수 있기를 원합니다. 그들은 2의 힘이 아니라는 것을 알아야합니다.

나는 비트 맵을 2 크기의 힘이되도록 확장 할 수 있고 간단히 텍스처를 늘릴 수 있지만 텍스처를 늘리 길 원치 않으며 어떤 경우에는 여러 텍스처를 하나의 "아틀라스"에 넣을 수 있습니다.

glTexSubImage2D()를 사용하여 원하는 원점에서 원하는 텍스처에 텍스처를 붙여 넣을 수 있다는 것을 알고 있습니다. 이것은 굉장합니다!

그러나 안드로이드에서 데이터가없는 텍스처를 초기화하는 방법을 모르겠습니까?

이 질문에서 previously asked은 데이터없이 glTexImage2D()를 호출 한 다음 채울 것을 제안했습니다.

그러나 "GLUtils.texImage2D (GL10.GL_TEXTURE_2D, 0, bmp, 0);"를 호출하면 안드로이드에서 " 너비/높이를 지정하지 마십시오. 그것은 내가 생각하는 비트 맵에서 이것을 읽습니다.

가장 좋은 방법은 무엇입니까? 비어 있고 데이터로 채워지지 않은 2 크기의 정확한 비트 맵을 생성하고 이것을 사용하여 텍스처를 초기화 한 다음 subImage를 사용하여 붙여 넣을 수 있습니까? 또는 새로운 비트 맵을 원하는대로 복사해야합니다 (이 작업을 쉽게 수행 할 수 있는지 확실하지 않은 경우).이 새로운 비트 맵 (경계선 제외)에 복사 한 다음 바로 사용하십시오.

편집 : 내가 opengl을 사용하고 있음을 분명히했습니다.

답변

4

2 축 크기의 힘으로 비트 맵을 만든 다음 비트 맵을 추가하면 잘 작동한다고 생각합니다. 어쩌면 ~

Bitmap.createBitmap(notPowerOf2Bitmap, offx, offy, xsize, ysize, bitmapFlag) 

그 외의 것, 나는 포토샵 프로세스를 통해 고통스러워 할 것입니다. 사진 몇 장있어?

+0

크기가 너무 많지 않으므로 나중에 변경 가능할 것으로 기대하고 있습니다. 크기를 조정하면 좋게 만듭니다. 이 방법은 nonPOTBitmap의 부분 집합을 취한다고 말합니다. 즉, 부분 집합의 비트 맵이 지정된 xSize 및 ySize보다 작 으면 빈 모서리가 생기는 것입니까? 아니면 스트레칭하겠습니까? (나는 실험하지만 슬프게도 나는 코딩 PC에 있지는 않을 것이다). – iexus

+0

비트 맵은 createScaledBitmap 메소드로 던져지기 전에는 스트레칭하지 않아야합니다. 나머지 공간은 비어 있습니다. – AedonEtLIRA

+0

지연된 응답을 드려 죄송합니다. 다른 것들과 함께 해왔습니다. 그러나 실제로이 문제를 구현하려고 왔지만이 방법으로는 작동하지 않습니다. 비트 맵을 소스보다 큰 비트 맵으로 서브 맵핑 할 수는 없습니다 ... 이제는 조금 손실이 있습니다. – iexus

2

NPOT (Non-Power-of-Two) 비트 맵은 일부 GLES 플랫폼에서 지원되지만 적절한 확장자가 있는지 확인해야합니다. 그러나 PowerVR SGX에서 NPOT가 ​​지원 되더라도 다른 임의의 제한 사항이 여전히 남아 있습니다. 예를 들어 텍스처 폭은 2의 배수 여야합니다 (2의 거듭 제곱이 아닌 경우). 또한 NPOT 렌더링은 많은 GPU에서 약간 느려지는 경향이 있습니다.

당신이 할 수있는 한 가지는 단지 2의 거듭 제곱 인 래퍼 텍스처를 만든 다음 glTexSubimage2D를 사용하여 텍스처를 업로드하여 그 부분 만 커버하고 텍스처 좌표를 적절하게 조정하는 것입니다. 이 상황의 명백한 단점은 텍스처 랩핑을 사용할 수 없다는 것입니다. 랩핑을 절대적으로 지원해야한다면 glTexImage2D를 호출하기 전에 텍스쳐를 가장 가까운 2의 2의 크기로 스케일 할 수 있습니다. 이것은 일반적으로 샘플링 아티팩트를 가져오고 물건을 흐리게 만듭니다. 특히 픽셀 정밀 2D 작업.

포장을 지원할 필요가없는 경우 고려해 볼 수있는 또 다른 사항은 모든 텍스처를 몇 개의 큰 텍스처로 압축하고 단지 다각형으로 맵핑하는 "텍스처 아트라스"를 만드는 것입니다 텍스처의 일부분이 아틀라스에 배치됩니다. MIP 맵을 생성 할 때는 조심해야하지만, 패딩 된 이미지 나 스케일 된 이미지에 너무 많은 낭비가 없으므로 일반적으로 꽤 좋은 성능 이점을 제공하고 텍스처 메모리를보다 효율적으로 사용할 수 있습니다.

+0

질문으로 내 질문에 비록 당신이 샘플 안드로이드에서 래퍼 텍스처를 만들 수 있습니까? 이 작업을 수행하는 가장 좋은 방법은 무엇입니까? – iexus

+0

glTexSubimage2D에 대한 문서를보십시오. – fluffy

0

두 개의 비트 맵을 생성하지 않는 이유는 무엇입니까? 첫 번째 코드를로드 한 다음 createBitmapScaled를 사용하여 해당 비트 맵을 2의 제곱으로 바꿉니다. 성능면에서는 가능한 가장 빠른 방법인지는 모르겠지만 작동합니다.

2

저는이 문제에 대해 2 가지 해결책을 가지고 있습니다. 나는 필요한 경우보다 구체적인 될 수 있지만, 개념적으로 수행 할 수 있습니다 : -

  1. 이미지 2의 전력을 확인하고 절에서는 100 %의 알파 채널을 채우기 자르고 활성화 알파와 이미지를로드 할 수 있습니다.

  2. 텍스처 벡터/버퍼를 조정하여 해당 섹션을로드하지 않도록하십시오. 그래서 그 대신 매트릭스로 기본

    float texture[] = { 
        0.0f, 1.0f, // 
        1.0f, 1.0f, // 
        0.0f, 0.0f, // 
        1.0f, 0.0f, // 
    }; 
    

를 사용하는 예를 들어 다시 비율에 의해, 요소자를 수있는 영역, (분명이 2 triangled 광장에 이미지를로드하기위한 것입니다). 물론

float texture[] = { 
     0.0f, 0.75f, // 
     0.9f, 0.75f, // 
     0.0f, 0.0f, // 
     0.9f, 0.0f, // 
    }; 

에서 흘러 나오는 수학 또는 원치 않는 비트가 정확하거나 실제 이미지의 일부를 잘라 것입니다. 분명히이 배열은 즉시 계산되고 여기에서 설명했듯이 하드 코딩되지 않습니다.

0

GLES20.glTexImage2D()를 사용하여 지정된 너비와 높이의 빈 텍스처를 만들 수 있습니다. 예제 코드는 입니다. public static int genTexture (int texWidth, int texHeight) { int [] textureIds = new int [1]; GLES20.glGenTextures (1, textureIds, 0); assertNoError(); int textureId = textureIds [0]; texWidth = Utils.nextPowerOf2 (texWidth); texHeight = Utils.nextPowerOf2 (texHeight);

GLES20.glBindTexture(GL11.GL_TEXTURE_2D, textureId); 
    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.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.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 
      texWidth, texHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); 

    return textureId; 
} 
관련 문제