Как я могу изменить шаблон iOS OpenGL ES 2.0 по умолчанию для отображения текстуры?

#ios #opengl-es #textures #opengl-es-2.0

#iOS #opengl-es #Текстуры #opengl-es-2.0

Вопрос:

Я пытаюсь изучить некоторые базовые OpenGL ES для разработки iPhone, и у меня есть задача, с которой я не могу справиться.

Кажется, я не могу изменить шаблон OpenGL ES по умолчанию для отображения текстуры на прыгающем квадрате вместо эффекта, подобного радуге по умолчанию. Я пытаюсь использовать текстуру для этого квадрата, но пока квадрат просто черный. Что я могу сделать неправильно в этом простом случае, и как я могу изменить код базового шаблона для отображения моей текстуры?

Комментарии:

1. Неужели этот вопрос преследует меня ! ?!?

2. Являются ли такие чрезмерно локализованные «измените этот образец, чтобы сделать это» -вопросы «обречены преследовать меня»? Не говоря уже о полном отсутствии какого-либо кода, что делает его идеальным вопросом для опытного экстрасенса, в любом случае.

3. @Christian — Обычно я бы с вами согласился, но в данном случае он имеет в виду базовый шаблон OpenGL ES, с которым любой может начать работать на iOS. Это урезанный пример, который обеспечивает основу для экспериментов с такими аспектами OpenGL ES, как текстурирование. У всех, у кого есть iOS SDK, есть этот простой код для начала, поэтому гораздо меньше догадок о том, что происходит. В этом случае ему просто нужно простое пошаговое руководство по добавлению текстур в квадрат, которое широко применимо.

4. @BradLarson Неизмененный образец — это не проблема. Вы можете считать это известным (как вы и рассуждали), но он не показал никакого своего кода, где он пытается адаптировать его для текстурирования, хотя он говорит, что пытался изменить его, и он «показывает черный». Таким образом, даже если вы знаете исходный образец, вы не можете сказать (и объяснить ему), что он сделал не так.

Ответ №1:

В качестве примечания, шаблон OpenGL ES по умолчанию, похоже, изменился для iOS 5.0 SDK и теперь использует GLKit для рисования вращающихся кубов, поэтому я не смог создать простой тестовый проект на основе того оригинального rainbow square, который они использовали.

Вместо этого вы можете захотеть взглянуть на пример приложения, которое я подготовил для своего урока по этой теме. Это довольно урезанное приложение, которое отображает текстуры на гранях вращающегося куба. Я подробно описываю, как это работает, в видео для этого класса в iTunes U.

В этом примере приложения используется класс PVRTexture от Apple (из одного из других примеров приложений) для загрузки в файл текстуры, сжатый PVRTC (который более экономичен по сравнению с обычными изображениями). Основной код для настройки текстуры таков:

 glGenTextures(1, amp;_name);
glBindTexture(GL_TEXTURE_2D, _name);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glCompressedTexImage2D(GL_TEXTURE_2D, i, _internalFormat, width, height, 0, [data length], [data bytes]);
 

где _name идентификатор, который вы позже будете использовать для привязки этой текстуры. Вы бы использовали glTexImage2D() вместо последней функции, если бы работали с обычной несжатой текстурой.

Затем вы можете включить использование текстур:

 glEnable(GL_TEXTURE_2D);
 

и привяжите текстуру для отображения, используя идентификатор, полученный при создании текстуры:

 glBindTexture(GL_TEXTURE_2D, pvrTexture.name);
 

По умолчанию эта текстура привязана к текстурной единице 0, но вы можете переключиться на другую единицу, используя glActiveTexture(GL_TEXTURE1) или подобное.

Затем вам нужно передать эту текстуру в вашу шейдерную программу как единое целое, причем вторым параметром является текстурная единица, к которой привязана текстура:

 glUniform1i(uniforms[UNIFORM_TEXTURE], 0);
 

Вам также нужны соответствующие позиции текстуры для ваших вершин, чтобы ваша текстура отображалась на вашей поверхности правильным образом:

 const GLfloat cubeTexCoords[] = {
    1.0, 0.0,
    0.0, 0.0,
    1.0, 1.0,
    0.0, 1.0,
    0.0, 0.0,
    1.0, 0.0,
    0.0, 1.0,
    1.0, 1.0,
    1.0, 1.0,
    0.0, 1.0,
    0.0, 0.0,
    1.0, 0.0,
    0.0, 1.0,
    1.0, 1.0,
};
 

и эти координаты будут переданы в вашу шейдерную программу в качестве атрибута:

 glVertexAttribPointer(ATTRIB_TEXTUREPOSITION, 2, GL_FLOAT, 0, 0, cubeTexCoords);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITION);
 

Ваша шейдерная программа должна иметь возможность принимать форму текстуры и ее координаты, чтобы в вашем вершинном шейдере было что-то похожее на это:

 attribute vec4 position;
attribute vec4 inputTextureCoordinate;

varying vec2 textureCoordinate;

uniform mat4 modelViewProjMatrix;

void main()
{
    gl_Position = modelViewProjMatrix * position;
    textureCoordinate = inputTextureCoordinate.xy;
}
 

и это для соответствующего фрагментного шейдера:

 varying highp vec2 textureCoordinate;

uniform sampler2D texture;

void main()
{
    gl_FragColor = texture2D(texture, textureCoordinate);
}
 

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

Вам нужно будет сопоставить атрибуты и формы при компиляции этого шейдера, но шаблон OpenGL ES 2.0 должен показать, как это сделать.

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

Комментарии:

1. Спасибо за эту информацию… Я обязательно попробую, когда смогу. Он выглядит очень полным, и это именно то, что я искал!