Рендеринг в не-силу двух текстур на iPhone - PullRequest
12 голосов
/ 21 января 2011

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

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

Ответы [ 2 ]

27 голосов
/ 21 января 2011

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

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

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

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

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

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 голосов
/ 21 января 2011

Это можно сделать, все, что вам нужно сделать, это получить следующую мощность на 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, он обращается к текстуре.

...