Так что в настоящее время я пытаюсь заменить мой старый текстурный атлас на массив текстур 2D, чтобы сделать жизнь проще с анизотропной фильтрацией и жадным зацеплением позже.
Я загружаю png-файлы с помощью stb и знаю, что буферы заполнены правильно, потому что, если я экспортирую каждый слой атласа, который скоро появится, прямо перед его загрузкой, это правильный файл png.
Моя установка работает так:
Я загружаю каждую текстуру в моем jar-файле с помощью stb и создаю с ним объект, в котором хранятся ширина, высота, слой и pixelData.
Когда загружается каждая текстура, я ищу самую большую текстуру и масштабирую каждую меньшую текстуру до того же размера, что и самый большой, потому что я знаю, что двухмерные текстурные массивы работают, только если каждый из слоев имеет одинаковый размер.
Затем я инициализирую массив текстур 2d следующим образом:
public void init(int layerCount, boolean supportsAlpha, int textureSize) {
this.textureId = glGenTextures();
this.maxLayer = layerCount;
int internalFormat = supportsAlpha ? GL_RGBA8 : GL_RGB8;
this.format = supportsAlpha ? GL_RGBA : GL_RGB;
glBindTexture(GL_TEXTURE_2D_ARRAY, this.textureId);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internalFormat, textureSize, textureSize, layerCount, 0, this.format, GL_UNSIGNED_BYTE, 0);
}
После этого я просматриваю карту объектов textureLayer и загружаю каждый из них следующим образом:
public void upload(ITextureLayer textureLayer) {
if (textureLayer.getLayer() >= this.maxLayer) {
LOGGER.error("Tried uploading a texture with a too big layer.");
return;
} else if (this.textureId == 0) {
LOGGER.error("Tried uploading texture layer to uninitialized texture array.");
return;
}
glBindTexture(GL_TEXTURE_2D_ARRAY, this.textureId);
// Tell openGL how to unpack the RGBA bytes
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Tell openGL to not blur the texture when it is stretched
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Upload the texture data
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, textureLayer.getLayer(), textureLayer.getWidth(), textureLayer.getHeight(), 0, this.format, GL_UNSIGNED_BYTE, textureLayer.getPixels());
int errorCode = glGetError();
if (errorCode != 0) LOGGER.error("Error while uploading texture layer {} to graphics card. {}", textureLayer.getLayer(), GLHelper.errorToString(errorCode));
}
Код ошибки для каждого из моих слоев равен 0, поэтому я предполагаю, что все прошло хорошо. Но когда я отлаживаю игру с помощью RenderDoc, я вижу, что на каждом слое каждый бит равен 0, и поэтому это просто прозрачная текстура с правильной шириной и высотой.
Я не могу понять, что я делаю неправильно, так как openGL говорит мне, что все прошло хорошо. Для меня важно, что я использую только openGL 3.3 и ниже, так как я хочу, чтобы игра также игралась на старых компьютерах, поэтому предварительное выделение памяти с помощью glTexStorage3D
не вариант.