Что вы ищете, это cube map. В OpenGL вы можете сразу определить шесть текстур (представляющих стороны размера куба) и сопоставить их с помощью трехмерных текстурных координат вместо обычных 2D текстурных координат. Для простого куба координаты текстуры будут такими же, как соответствующие нормали вершин. (Если вы будете только текстурировать кубики плоскости таким образом, вы можете консолидировать нормали и текстурные координаты в своем вершинном шейдере тоже!) Карты куба намного проще, чем пытаться связать шесть разных текстур одновременно так, как вы делаете прямо сейчас.
GLuint mHandle;
glGenTextures(1, &mHandle); // create your texture normally
// Note the target being used instead of GL_TEXTURE_2D!
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_CUBE_MAP, mHandle);
// Now, load in your six distinct images. They need to be the same dimensions!
// Notice the targets being specified: the six sides of the cube map.
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, width, height, 0,
format, GL_UNSIGNED_BYTE, data1);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, width, height, 0,
format, GL_UNSIGNED_BYTE, data2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, width, height, 0,
format, GL_UNSIGNED_BYTE, data3);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, width, height, 0,
format, GL_UNSIGNED_BYTE, data4);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, width, height, 0,
format, GL_UNSIGNED_BYTE, data5);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, width, height, 0,
format, GL_UNSIGNED_BYTE, data6);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
// And of course, after you are all done using the textures...
glDeleteTextures(1, &mHandle);
Теперь, когда делать ваши шейдеры, вам нужно вершинный шейдер принимать и/или передавать 3D-координаты (Vec3) вместо 2D координат (vec2).
// old GLSL style
attribute vec3 inTextureCoordinate;
varying vec3 vTextureCoordinate;
// more recent GLSL
in vec3 inTextureCoordinate;
out vec3 vTextureCoordinate;
В этом примере, ваша вершинный шейдер просто присвоить vTextureCoordinate = inTextureCoordinate. Затем ваш шейдер фрагмента должен принять эту координату текстуры и отобразить единую карту куба.
uniform samplerCube cubeMap;
...
gl_FragColor = textureCube(cubeMap, vTextureCoordinate);
Whew! Это было много. Я что-то оставил?
Я хотел бы знать больше. – Mark
Хорошо, я публикую обновление по вашему другому вопросу, я думаю ...? Я тоже опубликую его здесь. – TheBuzzSaw
Спасибо за ответ. Теперь это уже немного больше. Тем не менее, я просто использовал пример куба для упрощения, модель, которую я пытаюсь загрузить, на самом деле имеет 30+ текстур. Не могли бы вы предложить расширение вашего решения, чтобы позволить больше текстур? –