PDA

View Full Version : texture mapping a subdivision surface of a sphere

Ohmega
03-24-2011, 12:48 PM
Hey all,

I'm pretty new to OpenGL. I am taking computer graphics course, and I was asked to create a subdivision surface of a sphere and to height map + texture it.

I have created the subdivision surface successfully and implemented cubic mapping to apply the height map - which seems to work ok.

However, when using the same cubic mapping parameterization as the texture coordinates, some triangles are textured badly (screenshot attached)

As far as I was able to debug, it seems that two coordinates of the triangle get the same parameterization because of symmetry ,and therefore when openGL interpolates - those triangles are textured badly.

I am not sure if my parameterization is bad (as it is not one-to-one), or the way I applied the texture to the triangles.

Parameterization code (I am calling getParameterization with the triangle's vertices). The code chooses the correct face, and then returns the required u & v (range -1 to 1):

public static Point2f getSphereParameters(Point3f P, Point3f S) {
Vector3f OS = new Vector3f(S);
Vector3f OP = new Vector3f(P);

float angle = (float) Math.acos(OS.dot(OP) / (OS.length() * OP.length()));
float OTLength = OS.length() / (float) Math.cos(angle);

Vector3f OTVec = new Vector3f(OP);
OTVec.normalize();
OTVec.scale(OTLength);

Point3f OT = new Point3f(OTVec);

float u = 0;
float v = 0;

if (OS.getX() != 0) {
u = OT.getZ();
v = OT.getY();
} else if (OS.getY() != 0) {
u = OT.getX();
v = OT.getZ();
} else if (OS.getZ() != 0) {
u = OT.getX();
v = OT.getY();
}

return new Point2f(u / OS.length(), v / OS.length());
}

public static Point2f getParameterization(Point3f P) {
Point3f S = null;

switch (getProjectedFace(P)) {
case 1: // RIGHT
S = new Point3f(1, 0, 0);
break;
case 2: // LEFT
S = new Point3f(-1, 0, 0);
break;
case 3: // FRONT
S = new Point3f(0, 0, 1);
break;
case 4: // BACK
S = new Point3f(0, 0, -1);
break;
case 5: // TOP
S = new Point3f(0, 1, 0);
break;
case 6: // BOTTOM
S = new Point3f(0, -1, 0);
break;

}

Point2f params = getSphereParameters(P, S);

return params;
}

Applying the texture code:

gl.glBegin(GL.GL_TRIANGLES);

// TODO: decide if all vertices has the same normal (causes light problems)
// TODO: fix texture at stiches
Vector3f normal = triangle.getNormal();
gl.glNormal3f(normal.getX(), normal.getY(), normal.getZ());

Point3f vertex1 = triangle.getVertex1();
params = CubicMapping.getParameterization(vertex1);
gl.glTexCoord2f((params.x + 1) / 2, (params.y + 1) / 2);
gl.glVertex3f(vertex1.getX(), vertex1.getY(), vertex1.getZ());

Point3f vertex2 = triangle.getVertex2();
params = CubicMapping.getParameterization(vertex2);
gl.glTexCoord2f((params.x + 1) / 2, (params.y + 1) / 2);
gl.glVertex3f(vertex2.getX(), vertex2.getY(), vertex2.getZ());

Point3f vertex3 = triangle.getVertex3();
params = CubicMapping.getParameterization(vertex3);
gl.glTexCoord2f((params.x + 1) / 2, (params.y + 1) / 2);
gl.glVertex3f(vertex3.getX(), vertex3.getY(), vertex3.getZ());

gl.glEnd();

Will appreciate any help!