0

I am using an Ortho projection to do most of my stuff and i am happy with it, now however i need to create a simple "flip card" effect on an object similar to what View.rotateX does in Android views.

I know this is not possible in real 3D without switching to GLU perspective however i was wondering if it would be possible to "fake" this by creating a sort of trapezoidal scaling of the Quad before drawing, even an imperfect result would be fine. I DO NOT want to use a perspective projection.

This is my projection

gl.glViewport(0, 0, w, h);
gl.glMatrixMode(GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0, w, h, 0, -1f, 100f);
gl.glEnable(GL_TEXTURE_2D);

And this is my texture drawing call

gl.glTranslatef(mXOffset, mYOffset, 0f);
gl.glEnableClientState(GL_VERTEX_ARRAY);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glVertexPointer(2, GL_FLOAT, 0, sVertexBuffer);
gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
gl.glBindTexture(GL10.GL_TEXTURE_2D, id);
gl.glTexCoordPointer(2, GL_FLOAT, 0, mTextureBuffer);
gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
gl.glDisableClientState(GL_VERTEX_ARRAY);
gl.glDisableClientState(GL_TEXTURE_COORD_ARRAY);

I assume Android View implementation if using hardware acceleration is actually doing a similar thing but i cannot find the implementation details.

FrankMonza
  • 2,024
  • 16
  • 26
  • Nothing prevents you from switching between perspectives. No need to fake anything, not on OpenGL. – user1095108 Aug 10 '14 at 16:16
  • Point is that i do not want to draw my texture in a non ortho viewport, i want to draw it in the ortho perspective, i just need it to be scaled as if it was rotate in the X axis with perspective before drawing it – FrankMonza Aug 10 '14 at 16:22
  • If you want perspective, then turn perspective on. Again, you don't need to fake anything. – user1095108 Aug 11 '14 at 06:17
  • 1
    Ok this means that there is NO way to scale as a trapezoid a texture while using ortho and that android View implementation does "magic" since it does not use any perspective when implementing "rotateX" method in canvas camera. THis shounds to me like a big limitation... – FrankMonza Aug 11 '14 at 07:46
  • You usually sample a texture differently if you use a perspective projection, than when you use the orthogonal projection. – user1095108 Aug 11 '14 at 08:08

1 Answers1

1

The characteristic part of a perspective projection is the division by the distance from the eye point. This is what makes geometry closer to they eye appear bigger.

You could potentially apply an additional transformation without switching over to a full perspective matrix. But particularly when using the fixed pipeline, it's probably easier to modify the coordinates before drawing.

For a given rectangle corner with coordinates (x0, y0, 0.0f) relative to the rectangle center, a simple rotation by angle 'alpha` around the xaxis puts the corner at:

(x0, y0, 0.0f) --> (x0, y0 * cos(alpha), y0 * sin(alpha))

To apply a fake perspective to this, choose an eye distance d, which controls the amount of perspective generated, with smaller values of d resulting in a stronger perspective. Dividing by the relative distance of the rotated point then produces:

s = d / (d - y0 * sin(alpha))
(x0, y0, 0.0f) -->  s * (x0, y0 * cos(alpha), y0 * sin(alpha))

If you apply this to all 4 corners of the rectangle before rendering, you should get the perspective effect. To completely flip the rectangle, you can then increment alpha step by step from 0.0 to pi.

As long as y0 is much smaller than d, the calculation of s can also be approximated by:

s = d / (d - y0 * sin(alpha))
  = 1.0f / (1.0f - (y0 / d) * sin(alpha))
  ~ 1.0f + (y0 / d) * sin(alpha)

Substituting a control parameter c for 1.0 / d, where a larger value for c now produces a stronger perspective, the whole thing becomes:

s = 1.0f + c * y0 * sin(alpha))
(x0, y0, 0.0f) -->  s * (x0, y0 * cos(alpha), y0 * sin(alpha))

Both of these options should produce very similar results. You may want to try both, and see which one looks better.

Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • Wow, you are the man, but, sorry for the maybe newbie / stupid question, how can i do this in GLES10 given a Quad built with 2 triangles? – FrankMonza Aug 13 '14 at 07:44
  • 1
    These are calculations you can do in your own application code. Just modify the vertex coordinates accordingly. – Reto Koradi Aug 13 '14 at 07:56
  • This works but apparently i am then in this issue: http://stackoverflow.com/questions/15242507/perspective-correct-texturing-of-trapezoid-in-opengl-es-2-0 And i do not understand how to manage this in Android GLES10 since there is no glBegin or glTexCoord4f method... – FrankMonza Aug 13 '14 at 09:17
  • Ok, so i found that your answer combined with this http://stackoverflow.com/questions/5892120/texture-mapping-a-trapezoid-with-a-square-texture-in-opengl Give me what i was looking for Thanks!!!!! – FrankMonza Aug 13 '14 at 11:37