Texture mapping issue

Started by Elvynia, October 24, 2012, 12:33:19 PM

Previous topic - Next topic

Elvynia

Hello,

After having searching for a while where is the problem with my texture rendering, i desperately ask for a savior to my issue.

My project : An applet that allow users to draw a house (in fake 2D) and visualize it in 3D. The possibilities are very basic, only horizontal or vertical walls.

The issue : The walls are dynamically constructed to the required size and everything is fine until i try to set a texture on them. I'm using this code to build the 3D object walls :


public Object3D composeModule(final float width, final float length,
final float depth) {
final Object3D box = new Object3D(12);

final float x = width / 2;
final float y = length / 2;
final float z = depth / 2;

final SimpleVector upperLeftFront = new SimpleVector(-x, -y, -z);
final SimpleVector upperRightFront = new SimpleVector(x, -y, -z);
final SimpleVector lowerLeftFront = new SimpleVector(-x, y, -z);
final SimpleVector lowerRightFront = new SimpleVector(x, y, -z);

final SimpleVector upperLeftBack = new SimpleVector(-x, -y, z);
final SimpleVector upperRightBack = new SimpleVector(x, -y, z);
final SimpleVector lowerLeftBack = new SimpleVector(-x, y, z);
final SimpleVector lowerRightBack = new SimpleVector(x, y, z);

// Front
box.addTriangle(upperLeftFront, lowerLeftFront, upperRightFront);
box.addTriangle(upperRightFront, lowerLeftFront, lowerRightFront);
// Back
box.addTriangle(upperLeftBack, upperRightBack, lowerLeftBack);
box.addTriangle(upperRightBack, lowerRightBack, lowerLeftBack);
// Upper
                // Bad part
box.addTriangle(upperLeftBack, upperLeftFront, upperRightBack);
                // Good part
box.addTriangle(upperRightBack, upperLeftFront, upperRightFront);
// Lower
                // Good part
box.addTriangle(lowerRightBack, lowerRightFront, lowerLeftFront);
                // Bad part
box.addTriangle(lowerLeftBack, lowerRightBack, lowerLeftFront);
// Left
box.addTriangle(upperLeftFront, upperLeftBack, lowerLeftFront);
box.addTriangle(upperLeftBack, lowerLeftBack, lowerLeftFront);
// Right
box.addTriangle(upperRightFront, lowerRightFront, upperRightBack);
box.addTriangle(upperRightBack, lowerRightFront, lowerRightBack);

return box;
}



public void composeWall(final Object3D drawFrom, final Object3D drawTo) {
Object3D wall = null;

                // Business stuff not touching the Object3D.

wall = composeModule(moduleLength, moduleDepth, moduleHeight);
wall.setUserObject(wallModel);

wall.setOrigin(wallPosition);
wall.setName(Globals.MODEL3D_WALL_PREFIX + wall.getID());
wall.build();
wall.setTexture("white_wall.jpg");
wall.calcTextureWrap();
wall.recreateTextureCoords();
tileTexture(wall, 100);
composer.getWorld().addObject(wall);


The result is that, on the "upper" face and "lower" face, only one of the both triangles are (almost) correctly rendered with the texture :
Upper face visible on the screen shot :


Closer image of the wall. I made the red line to show the triangle separation :


The texture used :


Thank you for your support, which has already helped me a lot of times when finding informations in the forum !

Best regards,
Elvynia.

EgonOlsen

You don't supply proper texture coordinates when creating your object. Instead, you rely on calcTextureWrap...and that's the problem. calcTextureWrap creates new texture coordinates to have at least some, but it's impossible to know for that method how you actually want them to be exactly. You have to specify them yourself in the addTriangle calls. This should help as a starting point: http://www.jpct.net/wiki/index.php/Create_a_cube

Elvynia

Hello Egon,

I understand that calcTextureWrap can't exactly set all the texture coordinates. I thought there was a mistake in my actual addTriangle (in vertex order) calls because only the half of the triangles are correct. I did a test with 4 triangles per face (with the center point) and the up and down triangles are good while left and right are totally fucked.

I've actually built my composeModule method by copying this "create_a_cube" code on the wiki. I've removed the u/v parameters because i don't understand what they represent, and it didn't change anything. I thought they was maybe built by the tileTexture call (taken from the AdvancedExample project in the wiki).

I've read the addTriangle javaDoc a hundred times but my lack of knowledge in 3D and texture stuff don't let me understand the u/v values part :  "the u component of the texture position at the first vertex".
Could you explain or direct me to understand what kind of position do i have to set for each vertex through the u/v components ?

Thank you for your quick support.
Elvynia.

EgonOlsen

u/v are the normalized texture coordinates at a vertex. 0,0 is lower left and 1,1 upper right of the texture. So the u/v-coordinates for the vertices of a plane with a scretched texture are 0,0 - 1,0 - 0,1 - 1,1...and that's what the example in the wiki applies.

Elvynia

Thanks a lot. I understand know the u/v components and it work now !

Pignic

There is the code to generate a parallelepiped with a good uv mapping :


public Object3D createBox(final float width, final float depth,
final float height, final int textureId) {
final Object3D box = new Object3D(12);

final float x = width / 2;
final float y = depth / 2;
final float z = height / 2;

final int textureFactor = 64;

final SimpleVector upperLeftFront = new SimpleVector(-x, -y, -z);
final SimpleVector upperRightFront = new SimpleVector(x, -y, -z);
final SimpleVector lowerLeftFront = new SimpleVector(-x, y, -z);
final SimpleVector lowerRightFront = new SimpleVector(x, y, -z);

final SimpleVector upperLeftBack = new SimpleVector(-x, -y, z);
final SimpleVector upperRightBack = new SimpleVector(x, -y, z);
final SimpleVector lowerLeftBack = new SimpleVector(-x, y, z);
final SimpleVector lowerRightBack = new SimpleVector(x, y, z);

// Upper
box.addTriangle(lowerLeftFront, x / textureFactor, 0, lowerRightFront,
0, 0, upperLeftFront, x / textureFactor, y / textureFactor,
textureId);
box.addTriangle(lowerRightFront, 0, 0, upperRightFront, 0, y
/ textureFactor, upperLeftFront, x / textureFactor, y
/ textureFactor, textureId);

// Lower
box.addTriangle(upperLeftBack, x / textureFactor, 0, upperRightBack, 0,
0, lowerLeftBack, x / textureFactor, z / textureFactor,
textureId);
box.addTriangle(upperRightBack, 0, 0, lowerRightBack, 0, z
/ textureFactor, lowerLeftBack, x / textureFactor, z
/ textureFactor, textureId);

// Front
box.addTriangle(upperLeftFront, x / textureFactor, z / textureFactor,
upperRightBack, 0, 0, upperLeftBack, x / textureFactor, 0,
textureId);
box.addTriangle(upperLeftFront, x / textureFactor, z / textureFactor,
upperRightFront, 0, z / textureFactor, upperRightBack, 0, 0,
textureId);

// Back
box.addTriangle(lowerLeftBack, x / textureFactor, 0, lowerRightBack, 0,
0, lowerLeftFront, x / textureFactor, z / textureFactor,
textureId);
box.addTriangle(lowerRightBack, 0, 0, lowerRightFront, 0, z
/ textureFactor, lowerLeftFront, x / textureFactor, z
/ textureFactor, textureId);

// Left
box.addTriangle(lowerRightBack, y / textureFactor, 0, upperRightBack,
0, 0, lowerRightFront, y / textureFactor, z / textureFactor,
textureId);
box.addTriangle(upperRightBack, 0, 0, upperRightFront, 0, z
/ textureFactor, lowerRightFront, y / textureFactor, z
/ textureFactor, textureId);

// Right
box.addTriangle(upperLeftBack, y / textureFactor, 0, lowerLeftBack, 0,
0, upperLeftFront, y / textureFactor, z / textureFactor,
textureId);
box.addTriangle(lowerLeftBack, 0, 0, lowerLeftFront, 0, z
/ textureFactor, upperLeftFront, y / textureFactor, z
/ textureFactor, textureId);

return box;
}