Рендеринг в не-двойную текстуру на iPhone

Можно ли рендерить текстуру с помощью OpenGL ES 1.1 на iPhone (2G и старше)? Если я связываю текстуру в качестве буфера рендеринга, это должен быть размер буфера рендеринга, который не имеет размера POT. Но OpenGL ES 1.1 требует, чтобы текстуры были POT.

Может быть, это не может быть сделано на ES 1.1?

2 ответа

В то время как OpenGL ES 1.1 не поддерживает текстуры не-степени двух, новые модели устройств iOS имеют расширение GL_APPLE_texture_2D_limited_npotкоторый гласит:

Обычное текстурирование OpenGL ES 1.X ограничено изображениями с размерами степени двойки (POT). Расширение APPLE_texture_2D_limited_npot ослабляет эти ограничения по размеру для 2D текстур. Ограничения остаются в силе для кубической карты и трехмерных текстур, если они поддерживаются.

Это процедурное или перечислительное API не вводится этим расширением, за исключением того, что реализация, которая экспортирует строку расширения, позволит приложению передавать измерения 2D-текстуры, которые могут быть или не быть степенью двойки.

В отсутствие OES_texture_npot, которое снимает эти ограничения, в сочетании с 2D-текстурами NPOT не поддерживаются ни режимы mipmapping, ни wrap, кроме CLAMP_TO_EDGE. 2D-текстура NPOT с режимом обтекания, который не является CLAMP_TO_EDGE, или мин-фильтр, который не является NEAREST или LINEAR, считается неполным. Если такая текстура привязана к текстурному блоку, это как если бы отображение текстуры было отключено для этого текстурного блока.

Вы можете использовать следующий код, чтобы определить, поддерживается ли это расширение на вашем устройстве (взято из превосходной книги Филиппа Ридоа по 3D-программированию для iPhone):

const char* extensions = (char*) glGetString(GL_EXTENSIONS); 
bool npot = strstr(extensions, "GL_APPLE_texture_2D_limited_npot") != 0;

На этих устройствах вы сможете использовать текстуры, не имеющие степени двойки, до тех пор, пока вы установите правильное наложение текстуры:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

К сожалению, в этом примере моего приложения, которое рендерится с текстурой не-степени двух, используется OpenGL ES 2.0, поэтому я не уверен, что это поможет вам в этом случае.

Это может быть сделано, все, что вам нужно сделать, это получить следующую мощность на 2 больше, чем не POT.

Затем сгенерируйте кадровый буфер:

GLuint aFramebuffer;
glGenFramebuffersOES(1, &aFramebuffer);

И текстура:

GLuint aTexturebuffer;
glGenTextures(1, &aTexturebuffer);

Затем вы делаете ту же текстуру, как вещи:

glBindTexture(GL_TEXTURE_2D, aTexturebuffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glColor4ub(0, 0, 0, 255);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

int area[] = {0.0, 0.0, renderWidth, renderHeight};

glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, area);

glBindFramebufferOES(GL_FRAMEBUFFER_OES, aFramebuffer);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, aTexturebuffer, 0);

Здесь я использовал расширение draw_texture.textureWidth а также textureHeight сила 2 больше, и renderWidth а также renderHeight ширина рендера и высота. Затем, когда вы связываетесь с aFramebuffer это будет рисовать на текстуру.

Другие вопросы по тегам