I have to map a physical cube with the image displayed by a projector from my computer. I immediately became aware of the problem of using a 3D cube and camera projections to try to fit the virtual image on the real object, so I decided to simplify the problem and use a 2D representation of a cube and to move each vertex in 2D space until it fitted the object. The software is now complete except for a little detail: textures.
I'm using LWJGL and I've based my data structures on some of the examples on their documentation.
I used 7 vertices to represent the 3 visible faces of the real cube in 2D space, this creates 3 trapeziums (or irregular quadrilaterals) that cover each face, I mapped them with the ST (or UV) coordinates you see in this image, remember this is all in 2D:
Here's a code block where I load my vertex data into a buffer, it's all saved into a VBO with the order XYZWRGBASTPQ (note that Z is always 0, PQ are 0,1 by default):
vertices = new VertexData[7];
vertices[0] = new VertexData().setXY(0, 0).setST(0.5f, 0.5f);
vertices[1] = new VertexData().setXY(0.5f, 1f/3).setST(0.5f, 0);
vertices[2] = new VertexData().setXY(0, 2f/3).setST(0, 0);
vertices[3] = new VertexData().setXY(-0.5f, 1f/3).setST(0, 0.5f);
vertices[4] = new VertexData().setXY(-0.5f, -1f/3).setST(0, 1);
vertices[5] = new VertexData().setXY(0, -2f/3).setST(0.5f, 1);
vertices[6] = new VertexData().setXY(0.5f, -1f/3).setST(1, 1);
0 is the center of the hexagon, from there is 1-6, counter-clockwise from the top-right corner, it is drawn as a triangle fan.
Everything is fine while the trapezoid is still a parallelogram, this is another texture test:
But the problem is when the sides aren't equal, the texture is projected over triangles so when it tries to project the texture, it doesn't look as expected:
I read a lot on the subject, some of it:
Getting to know the Q texture coordinate...
Perspective correct texturing of trapezoid in OpenGL ES 2.0
Quadrilateral Interpolation, Part 1
So far nothing has gotten me close to fixing the problem, all I know is that is has something to do with the Q coordinate of the texture.
My vertex shader is the bare minimum:
#version 150 core
in vec4 in_color;
in vec4 in_position;
in vec4 in_texture;
out vec4 pass_color;
out vec4 pass_texture;
void main(void) {
pass_color = in_color;
pass_texture = in_texture;
gl_Position = in_position;
}
and my fragment shader is really simple, right now I'm using textureProj because I was trying to fiddle around with the Q coordinate.
#version 330 core
in vec4 pass_color;
in vec4 pass_texture;
out vec4 color;
uniform sampler2D texture_diffuse;
void main(void) {
color = pass_color;
color = textureProj(texture_diffuse, pass_texture);
}
I'm willing to post every piece of code in case you need it. I just need a push in the right direction.