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

2 ответа

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

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

Но текстура q координат в 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 млн. Загрузок выполнено и еще не слышал ни одной жалобы, связанной с рендерингом.

Надеюсь, это поможет.

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

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

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

Другие вопросы по тегам