#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. Спасибо за эту информацию… Я обязательно попробую, когда смогу. Он выглядит очень полным, и это именно то, что я искал!