1

I'm developing an OpenGL ES 1.1 app for Android (with the OpenGL calls being made from C code called via NDK).

My problem is that I'm trying to use the Q texture coordinate as well as the usual (S, T) texture coordinates. However, nothing I put into Q has any noticable effect.

(Aside: the reason for wanting to play with the Q coordinate is that I want to map a rectangular texture to a trapezoid quad in space with correct perspective effect (i.e. not affine) -- as described at http://www.xyzw.us/~cass/qcoord/).

My method for trying to set the Q coordinate (to something other than the default 1.0f) is the usual: I'm providing 4 texture coordinates instead of the usual 2. I've tried putting all sorts of values in the Q coord (and even into the typically unused R coord, in case of mixup between the two) with zero apparent effect on my textures. I would expect to see effects on my textures from having Q != 1.0 -- for example, Q = 0.5 for every texture coordinate should just double every derived (S, T) value -- in effect, halving the apparent texture sizes. But no change.

I can't really post full code, but here's the fundamentals:

My vertex struct is defined as follows:

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;

Creating each vertex buffer object (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

And here's how I give my vertex and text coord pointers:

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));

It's all working beautifully, except as I say, my Q coord makes no difference. If change my glTextCoordPointer call to only provide 2 or 3 coordinates, there is no change in the program behaviour:

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

My question is: why are my Q texture coordinates not having any effect? If it's device or Android API level specific, can I find out on what device or API levels would it work? If I can't rely on Q coordinate doing anything useful, how else could I achieve the same effect (realistic, non-affine texture mapping to a trapezoid)?

I am testing my code on an actual Android device: the HTC Wildfire S.

I am loading my textures using the SOIL library for convenience.

Update

I've downloaded the NeHe Android port for Lesson 6. This uses the Java OpenGL ES interface (no NDK). I added random R and Q texture coordinates to that, and again, no visible effect.

Update 2

I gave up on attempting to get the Q texture coordinate to have any effect; I presume it's just not supported on all devices. Still interested in authoritative info to this effect.

Related links:

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

Community
  • 1
  • 1
occulus
  • 16,959
  • 6
  • 53
  • 76
  • Does your sample works on some platforms/OS? Have you tried on Mac/Win/Linux using OpenGLES binaries? – rockeye Dec 22 '11 at 14:58
  • Hi rockeye, not tried that yet, but it is indeed on my to-do list (lack of time at this minute). I've certainly examples of other people doing things with the Q coordinate and getting effects. – occulus Dec 22 '11 at 15:52
  • Does `glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST )` change anything? – genpfault Dec 22 '11 at 22:22
  • Hi genpfault, afraid not -- it's one of the things I've tried already. – occulus Dec 22 '11 at 22:33

2 Answers2

1

I agree with you. Some android devices do not support texture q coord in OpenGL ES 1.1.

In my experience, Galaxy S, S2, S3 worked. Galaxy Note, Galaxy S2 HD doesn't. (might be GPU problem??)

But texture q coord in OpenGL ES 2.0 worked on those problematic devices.

Belows are my shader codes.

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";

So I decided using OpenGL 2.0 on 2.0 supporting device and 1.0 on the others.

I published app, about 2M downloads accomplished and didn't heard any complaint related rendering issue yet.

Hope this help.

0

This is not an exact answer to your issue, but there are few things that you might want to check :

  • Does your texture is has power-of-two height and width ?
  • The R coordinates should always be 0.f, as it used for 3d texture.
  • Why don't you pass your data inside glTexCoordPointer and glVertexPointer? eg
glTexCoordPointer(4, GL_FLOAT, 32 /* stride*/, (GLvoid*)((char*)vertexData + 3*4));

Try to run you app on other Android device or platform

rockeye
  • 2,765
  • 2
  • 30
  • 44
  • Hi rockeye. Yup, power of two height and width (512 x 512). R coordinate started as 0.0, so I've tried that -- but I ended up putting in other values there too in case my understanding or the order of R and Q was switched - just to see if I can affect what was being rendered in any way (which I couldn't). I am passing in my data using glTextCoordPointer and glVertexPointer already -- indeed, your code sample is actually a quote of the code I've posted. – occulus Dec 23 '11 at 10:10
  • No, look carefully, the last param of my code sample is vertexData, not NULL (as in your code samples). But I guess you are specifying your data in another way? – rockeye Dec 23 '11 at 10:15
  • Ah sorry, beg your pardon, yes. I'm binding the buffer already using glBindBuffer: glBindBuffer(GL_ARRAY_BUFFER, sphereVBO); glBufferData(GL_ARRAY_BUFFER, vertexBufferSize, vertexData, GL_STATIC_DRAW);. So after this call, the index given is into the specified array. So I believe it's the same effect in the end as your snippet. – occulus Dec 23 '11 at 14:27