OpenGL ES 1.1 на Android: координата текстуры Q не имеет никакого эффекта

Я разрабатываю приложение OpenGL ES 1.1 для Android (вызовы OpenGL выполняются из кода C, вызываемого через NDK).

Моя проблема в том, что я пытаюсь использовать координату текстуры Q, а также обычные координаты текстуры (S, T). Однако все, что я вкладываю в Q, не имеет заметного эффекта.

(Кроме того: причина, по которой я хочу поиграть с координатой Q, заключается в том, что я хочу сопоставить прямоугольную текстуру с трапециевидным четырехугольником в пространстве с правильным эффектом перспективы (т. Е. Не аффинным) - как описано в http://www.xyzw.us/~cass/qcoord/).

Мой метод попытки установить координату Q (отличную от значения по умолчанию 1.0f) является обычным: я предоставляю 4 координаты текстуры вместо обычных 2. Я пробовал помещать всевозможные значения в координату Q ( и даже в обычно неиспользуемые координаты R в случае их смешения) с нулевым явным эффектом на мои текстуры. Я ожидал увидеть эффекты на моих текстурах от наличия Q! = 1.0 - например, Q = 0.5 для каждой координаты текстуры должно просто удвоить каждое производное значение (S, T) - по сути, уменьшая вдвое видимые размеры текстуры. Но без изменений.

Я не могу опубликовать полный код, но вот основы:

Моя вершинная структура определяется следующим образом:

typedef struct
{
    GLfloat x, y, z;        // 3 x spacial coord - 12 bytes
    GLfloat tx, ty, tr, tq; // 4 x texture coord - 16 bytes
    GLfloat padding[1];     // make it up to 32 bytes (or 8 floats, in effect)
} VertexData;

Создание каждого объекта буфера вершин (VBO):

// alloc space for my vertex buffer
int vertexBufferSize = numVertices * sizeof(VertexData);
VertexData* vertexData = (VertexData *)malloc(vertexBufferSize);

..//for each vertex I'm creating:
    vertex.x =  (... appropriate coord)
    vertex.y =  (... appropriate coord)
    vertex.z =  (... appropriate coord)
    vertex.tx = (... appropriate coord) // AKA the 's' texture coord
    vertex.ty = (... appropriate coord) // AKA the 't' texture coord
    vertex.tr = 0.5f;   // 'R' texture coord. Usually ignored, but I set in case of mixup between Q and R
    vertex.tq = 0.5f;   // 'Q' texture coord

А вот как я даю свои вершины и указатели координат текста:

glVertexPointer(3, GL_FLOAT, stride, (GLvoid*)((char*)NULL));

// note the 4 below - we want to give 4 tex coordinates, not 2.
// 3*4 corresponds to the offset of texture coords in the VertexData struct
glTexCoordPointer(4, GL_FLOAT, 32 /*stride*/,  (GLvoid*)((char*)NULL + 3*4));

Все работает прекрасно, за исключением того, что, как я уже сказал, моя координата Q не имеет значения. Если изменить мой вызов glTextCoordPointer так, чтобы он предоставлял только 2 или 3 координаты, поведение программы не изменится:

glTexCoordPointer(2, GL_FLOAT, 32 /*stride*/,  (GLvoid*)((char*)NULL + 3*4));
// OR:
glTexCoordPointer(3, GL_FLOAT, 32 /*stride*/,  (GLvoid*)((char*)NULL + 3*4));

У меня вопрос: почему координаты текстуры Q не имеют никакого эффекта? Если это зависит от устройства или уровня API Android, могу ли я узнать, на каком устройстве или уровнях API он будет работать? Если я не могу положиться на Q-координату, делающую что-нибудь полезное, как еще я мог бы достичь того же эффекта (реалистичное, неаффинное наложение текстуры на трапецию)?

Я тестирую свой код на реальном устройстве Android: HTC Wildfire S.

Я загружаю свои текстуры с помощью библиотеки SOIL для удобства.

Обновить

Я загрузил порт NeHe для Android для Урока 6. При этом используется интерфейс Java OpenGL ES (без NDK). Я добавил к этому случайные координаты текстуры R и Q, и опять же, никакого видимого эффекта.

Обновление 2

Я отказался от попыток добиться, чтобы координата текстуры Q имела какой-либо эффект; Я предполагаю, что он поддерживается не на всех устройствах. По-прежнему интересует авторитетная информация на этот счет.

Ссылки по теме:

http://www.xyzw.us/~cass/qcoord/

http://www.gamedev.net/topic/419296-skewedsheared-texture-mapping-in-opengl

http://hacksoflife.blogspot.com/2009/11/perspective-correct-texturing-q.html

перспективная коррекция координат текстуры в 3D

http://sfml-dev.org/forum/viewtopic.php?t=2893

http://fly.cc.fer.hr/~unreal/theredbook/chapter09.html


person occulus    schedule 19.12.2011    source источник
comment
Ваш образец работает на некоторых платформах / ОС? Вы пробовали на Mac / Win / Linux использовать двоичные файлы OpenGLES?   -  person rockeye    schedule 22.12.2011
comment
Привет, рокай, еще не пробовал, но это действительно в моем списке дел (сейчас не хватает времени). Конечно, у меня есть примеры, когда другие люди делали что-то с координатой Q и получали эффекты.   -  person occulus    schedule 22.12.2011
comment
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) что-нибудь меняет?   -  person genpfault    schedule 23.12.2011
comment
Привет, genpfault, не бойтесь - это одна из вещей, которые я уже пробовал.   -  person occulus    schedule 23.12.2011


Ответы (2)


Я согласен с тобой. Некоторые устройства Android не поддерживают текстурную координату в OpenGL ES 1.1.

По моему опыту, Galaxy S, S2, S3 работали. Galaxy Note, Galaxy S2 HD - нет. (может быть проблема с графическим процессором ??)

Но текстура q corre в OpenGL ES 2.0 работала на этих проблемных устройствах.

Ниже приведены мои шейдерные коды.

private final String mVertexShader =
    "uniform mat4 uMVPMatrix;\n" +
        "attribute vec4 aPosition;\n" +
        "attribute vec4 aTextureCoord;\n" +
        "varying vec4 vTextureCoord;\n" +
        "void main() {\n" +
        "  gl_Position = uMVPMatrix * aPosition;\n" +
        "  vTextureCoord = aTextureCoord;\n" +
        "}\n";

private final String mFragmentShader =
    "precision mediump float;\n" +
        "varying vec4 vTextureCoord;\n" +
        "uniform sampler2D sTexture;\n" +
        "void main() {\n" +
        "  gl_FragColor = texture2DProj(sTexture, vTextureCoord);\n" +
        "}\n";

Поэтому я решил использовать OpenGL 2.0 на поддерживающих устройствах 2.0 и 1.0 на остальных.

Я опубликовал приложение, было выполнено около 2 млн загрузок, и я еще не слышал никаких жалоб, связанных с рендерингом.

Надеюсь на эту помощь.

person user549769    schedule 20.08.2012

Это не точный ответ на вашу проблему, но есть несколько вещей, которые вы можете проверить:

  • У вашей текстуры есть степень двойки высоты и ширины?
  • Координаты R всегда должны быть 0.f, так как они используются для трехмерной текстуры.
  • Почему бы вам не передать свои данные внутри glTexCoordPointer и glVertexPointer? например
glTexCoordPointer(4, GL_FLOAT, 32 /* stride*/, (GLvoid*)((char*)vertexData + 3*4));

Попробуйте запустить приложение на другом устройстве или платформе Android.

person rockeye    schedule 23.12.2011
comment
Привет, рокай. Да, степень двойки высоты и ширины (512 x 512). Координата R начиналась с 0,0, поэтому я пробовал это, но в итоге я поставил и другие значения там, на случай, если мое понимание или порядок R и Q был изменен - ​​просто чтобы посмотреть, могу ли я повлиять на то, что визуализируется в в любом случае (чего я не мог). Я уже передаю свои данные, используя glTextCoordPointer и glVertexPointer - действительно, ваш образец кода на самом деле является цитатой из кода, который я опубликовал. - person occulus; 23.12.2011
comment
Нет, посмотрите внимательно, последний параметр моего примера кода - это vertexData, а не NULL (как в ваших примерах кода). Но я полагаю, вы по-другому указываете свои данные? - person rockeye; 23.12.2011
comment
Ах, извините, прошу прощения, да. Я привязываю буфер уже с помощью glBindBuffer: glBindBuffer (GL_ARRAY_BUFFER ,phereVBO); glBufferData (GL_ARRAY_BUFFER, vertexBufferSize, vertexData, GL_STATIC_DRAW) ;. Таким образом, после этого вызова данный индекс находится в указанном массиве. Итак, я считаю, что в конечном итоге это тот же эффект, что и ваш фрагмент. - person occulus; 23.12.2011