Original Post
Hi all,
I'm using a subdivided icosahedron as an approximation to a sphere; I'm doing it this way instead of using a quadric because I'm going to want to deform the sphere and this method gives me uniform point distribution.
The technique is described in example 2-13 of the Red Book.
The problem I'm having is texturing the thing. I want to be able to pass a function the normal of the current point and have it pass back appropriate UV coords.
Any thoughts?
Thanks in advance for any help anyone can provide!
Brgrds,
IainC
www.coldcity.com
code, pics, life
Grr I can't make the source tag keep my formatting...
[edited by - IainC on September 27, 2002 6:00:20 AM]
// ******************** DEFINES ********************
#define X_BASE 0.525731112119133606f
#define Z_BASE 0.850650808352039932f
// ******************** STRUCTS ********************
struct Vector3f {
GLfloat x, y, z;
void Set(GLfloat m_x, GLfloat m_y, GLfloat m_z) {
x = m_x; y = m_y; z = m_z;
}
};
// ******************** CLASS DEFINITION ********************
class Icosahedron {
public:
Icosahedron();
~Icosahedron();
void Init(GLfloat m_radius, int subdivisions);
void Render();
private:
void Normalize(float v[3]);
void DrawTriangle(float *v1, float *v2, float *v3);
void Subdivide(float *v1, float *v2, float *v3, long depth);
void GetTextureCoord(ASEVector3f *normal, float *targetU, float *targetV);
GLuint displayList;
GLfloat radius;
};
// ******************** CLASS IMPLEMENTATION ********************
GLfloat vdata[12][3] = {
{-X_BASE,0.0,Z_BASE},{X_BASE,0.0,Z_BASE},{-X_BASE,0.0,-Z_BASE},{X_BASE,0.0,-Z_BASE},
{0.0,Z_BASE,X_BASE},{0.0,Z_BASE,-X_BASE},{0.0,-Z_BASE,X_BASE},{0.0,-Z_BASE,-X_BASE},
{Z_BASE,X_BASE,0.0},{-Z_BASE,X_BASE,0.0},{Z_BASE,-X_BASE,0.0},{-Z_BASE,-X_BASE,0.0}};
GLuint tindices[20][3] = {
{1,4,0},{4,9,0},{4,5,9},{8,5,4},{1,8,4},
{1,10,8},{10,3,8},{8,3,5},{3,2,5},{3,7,2},
{3,10,7},{10,6,7},{6,11,7},{6,0,11},{6,1,0},
{10,1,6},{11,0,9},{2,11,9},{5,2,9},{11,2,7}};
Icosahedron::Icosahedron() {
}
Icosahedron::~Icosahedron() {
}
void Icosahedron::Init(GLfloat m_radius, int subdivisions) {
radius = m_radius;
displayList = glGenLists(1);
glNewList(displayList, GL_COMPILE);
for (int i = 0; i < 20; i++) {
Subdivide(&vdata[tindices[i][0]][0], &vdata[tindices[i][1]][0], &vdata[tindices[i][2]][0], subdivisions);
}
glEndList();
}
void Icosahedron::Render() {
glScalef(radius, radius, radius);
glCallList(displayList);
}
void Icosahedron::DrawTriangle(float *v1, float *v2, float *v3) {
Vector3f point;
GLfloat texU, texV;
glBegin(GL_TRIANGLES);
point.Set (v1[0], v1[1], v1[2]);
glNormal3f (point.x, point.y, point.z); // (Points are already normalised)
GetTextureCoord (&point, &texU, &texV);
glTexCoord2f(texU, texV);
glVertex3f (point.x, point.y, point.z);
point.Set (v2[0], v2[1], v2[2]);
glNormal3f (point.x, point.y, point.z);
GetTextureCoord (&point, &texU, &texV);
glTexCoord2f(texU, texV);
glVertex3f (point.x, point.y, point.z);
point.Set (v3[0], v3[1], v3[2]);
glNormal3f (point.x, point.y, point.z);
GetTextureCoord (&point, &texU, &texV);
glTexCoord2f(texU, texV);
glVertex3f (point.x, point.y, point.z);
glEnd();
}
void Icosahedron::GetTextureCoord(ASEVector3f *normal, float *targetU, float *targetV) {
// ****************************************
// ****************************************
// IT'S THIS FUNCTION I CAN'T GET TO WORK!!
// ****************************************
// ****************************************
}
void Icosahedron::Normalize(float v[3]) {
GLfloat d = (float)sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
if (d == 0.0) return;
v[0] /= d; v[1] /= d; v[2] /= d;
}
void Icosahedron::Subdivide(float *v1, float *v2, float *v3, long depth) {
GLfloat v12[3], v23[3], v31[3];
GLint i;
if (depth == 0) {
DrawTriangle(v1, v2, v3);
return;
}
for (i = 0; i < 3; i++) {
v12[i] = v1[i]+v2[i];
v23[i] = v2[i]+v3[i];
v31[i] = v3[i]+v1[i];
}
Normalize(v12);
Normalize(v23);
Normalize(v31);
Subdivide(v1, v12, v31, depth-1);
Subdivide(v2, v23, v12, depth-1);
Subdivide(v3, v31, v23, depth-1);
Subdivide(v12, v23, v31, depth-1);
}



