2011-12-19 2 views
1

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

Моя проблема в том, что я пытаюсь использовать координату текстуры 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 координаты текстуры, не имеющие никакого эффекта? Если это специфический уровень устройства или Android API, могу ли я узнать, на каком уровне устройства или API он будет работать? Если я не могу полагаться на координату Q, что-то полезное, как еще я мог бы достичь такого же эффекта (реалистичное, неаффинное отображение текстур в трапецию)?

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

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

Update

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

Update 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

perspective correction of texture coordinates in 3d

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

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

+0

Работает ли ваш образец на некоторых платформах/ОС? Вы пытались использовать Mac/Win/Linux с использованием OpenGLES-файлов? – rockeye

+0

Привет, rockeye, еще не пробовал, но это действительно в моем списке дел (нехватка времени в эту минуту). Я, конечно, примеры других людей, которые делают что-то с координатой Q и получают эффекты. – occulus

+0

Делает ли 'glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) что-нибудь? – genpfault

ответ

0

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

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

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

+0

Hi rockeye. Yup, мощность двух высот и ширины (512 x 512). Координата R начиналась как 0.0, поэтому я пробовал это - но в итоге я включил другие значения в случае, если мое понимание или порядок R и Q были переключены - просто чтобы увидеть, могу ли я повлиять на то, что отображалось в любом случае (чего я не мог). Я передаю свои данные с помощью glTextCoordPointer и glVertexPointer уже - действительно, ваш пример кода - это цитата из кода, который я опубликовал. – occulus

+0

Нет, посмотрите внимательно, последний параметр моего примера кода - vertexData, а не NULL (как в ваших образцах кода). Но, я думаю, вы указываете свои данные по-другому? – rockeye

+0

Ах, извините, прошу прощения, да. Я связываю буфер уже с помощью glBindBuffer: glBindBuffer (GL_ARRAY_BUFFER, sphereVBO); glBufferData (GL_ARRAY_BUFFER, vertexBufferSize, vertexData, GL_STATIC_DRAW) ;. Поэтому после этого вызова указанный индекс вводится в указанный массив. Поэтому я считаю, что это тот же эффект в конце, что и ваш фрагмент. – occulus

1

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

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

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

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