나는 너무 많은 성공없이 쓴 안드로이드 게임에서 텍스처의 메모리 풋 프린트를 줄이려고 노력 해왔다. 연구를 기반으로 한 좋은 접근 방식은 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를 결합하여 구현하는 방법에 대해 설명하고 있습니다. 정말 멋질 것입니다.
정말로 멀티 텍스처링을 제대로 수행하지 못했습니다. 그러나 이것을 수행하는 방법을 알아 낸 후에 OpenGL ES 1.1에서는 내가 성취하고자하는 것이 불가능하다는 것을 알았습니다. 문제는 알파 PKM이 RGB 채널에 값을 저장하기 때문에 RGB 값을 단일 알파 값으로 결합 할 수있는 멀티 텍스처링 (볼 수있는 한)이 불가능하다는 것입니다. @ClayMontgomery가 OpenGL ES 1.1에서는 이것이 가능하지 않았기 때문에이 대답을 받아 들였습니다. – brent777