У меня есть очень простое приложение AR, в котором у меня есть маркер, который я обнаруживаю, затем на этом маркере я создаю плоскую поверхность openGL и применяю к ней текстуру. Я использую простой квадрат в данный момент. Код выглядит так:
#define NUM_SURFACE_OBJECT_VERTEX 12
#define NUM_SURFACE_OBJECT_INDEX 12
static const float surfaceVertices[] =
{
20, -20, 5,
20, 20, 5,
-20, 20, 5,
-20, -20, 5
};
static const float surfaceTexCoords[] =
{
1, 0,
1, 1,
0, 1,
0, 0
};
static const float surfaceNormals[] =
{
};
static const unsigned short surfaceIndices[] =
{
0, 1, 2,
2, 3, 0
};
и код для рисования выглядит следующим образом:
QCAR::Matrix44F modelViewProjection;
ShaderUtils::translatePoseMatrix(
0.0f, 0.0f, kObjectScale, &modelViewMatrix.data[0]);
ShaderUtils::scalePoseMatrix(
kObjectScale,
kObjectScale,
kObjectScale,
&modelViewMatrix.data[0]);
ShaderUtils::multiplyMatrix(
&projectionMatrix.data[0],
&modelViewMatrix.data[0],
&modelViewProjection.data[0]);
glUseProgram(shaderProgramID);
glVertexAttribPointer(
vertexHandle,
3,
GL_FLOAT,
GL_FALSE,
0,
(const GLvoid*)&surfaceVertices[0]);
glVertexAttribPointer(
textureCoordHandle,
2,
GL_FLOAT,
GL_FALSE,
0,
(const GLvoid*)&surfaceTexCoords[0]);
glEnableVertexAttribArray(vertexHandle);
glEnableVertexAttribArray(textureCoordHandle);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, [thisTexture textureID]);
glUniformMatrix4fv(
mvpMatrixHandle, 1, GL_FALSE, (const GLfloat*)&modelViewProjection.data[0]);
glDrawElements(
GL_TRIANGLES,
NUM_SURFACE_OBJECT_INDEX,
GL_UNSIGNED_SHORT,
(const GLvoid*)&surfaceIndices[0]);
ShaderUtils::checkGlError("EAGLView renderFrameQCAR");
А вот массив тестовых текстур, через которые я вращаюсь (на самом деле, все png одинаковые, я просто скопировал их несколько раз. Каждая из них имеет размер 512x512px):
const char* textureFilenames[] = {
"test.png", "test2.png", "test3.png", "test4.png", "test5.png",
"test6.png", "test7.png", "test8.png", "test8.png", "test10.png"}
Приношу свои извинения, если это не те сегменты кода, которые нужно показать, но это раздел прорисовки программы. По сути, это пример кода, над которым я пытаюсь работать, и я только что заменил модель чайника, которую они используют, на плоскую поверхность и текстуры.
Итак, отметим несколько моментов:
- Почему-то, когда я использую приведенный выше код только с 1 до 5 текстурой, все работает отлично. Я могу нормально видеть текстуру и могу двигать камеру, чтобы увидеть разные перспективы. У меня есть функция, которая меняет текстуру каждые 10 секунд, и при использовании всего нескольких текстур все по-прежнему нормально.
- При использовании более чем, например, при вращении между 10 или более различными текстурами, я начинаю странно себя вести, как плоскость, которая выступает из экрана.
- Если вы заметили мой код выше, я закомментировал все, что использует нормали. Я на самом деле не знаю, как будет выглядеть массив нормали для плоской поверхности, поэтому я просто попытался закомментировать весь код.
Я загрузил несколько фотографий для справки:
Это снимок маркера на заднем плане (несколько щепок) и текстуры, нанесенной на поверхность. Все кажется нормальным.
Это снимок, сделанный под углом. На данный момент, я вращаюсь только между 5 текстурами в коде. Здесь тоже все хорошо.
Теперь я пытаюсь вращать 10 текстур каждые 10 секунд. Даже на первой текстуре я получаю странную плоскость, которая выступает так:
Почему это может быть так? Пример кода не дает мне никаких предупреждений о загрузке текстур, и я даже пытался сделать текстуры действительно маленькими, но при этом поведение оставалось прежним. Есть ли что-то не так с тем, как я объявил вершины и индексы? Это потому что я не учел нормалей?
Спасибо!
Разъяснение
Эти снимки сделаны с моего iPad 2. На моем iPad 2 запущено приложение AR. Я использую свой MacBook Air для отображения маркера щепы. Таким образом, мой ipad распознает изображение маркера, отображаемое на моем MacBook Air, и накладывает текстуру поверх маркера.