Textur
Normaler JOGL>Ball

# Football

What
Drawing a Buckyball with and without texture

The illustration to the left, the applet, is produced with the "handmade" 3D-applet described in Applet. You can click with the right mouse button or drag with the left.

The football, or buckyball, spinning in the applet is built with the same geometry as the we will use in this module.

## Geometri "Buckyball" is a known phenomena from mathematics  , nature  and the soccer field. The form of the buckyball is described by the golden ratio (1.61803399...). This number is calculated as the ratio between two adjacent numbers in the Fibonacci series. The number is used in many arguments in mathematics and it is found in many natural forms in nature  . The number often appears as a key number when forms are packed or compressed. It is also used in aesthetics as a "natural" or well-balanced ratio, for instance between the length and height of a rectangle.

Buckyball is a well known concept for chemists. It describes the position of 60 carbon atoms in the corners of the figure, as in the applet. The figure has its name from R. Buckminster Fuller  .

A buckyball has 60 corners, 20 polygons with 6 corners (hexagons) and 12 polygons with 5 corners (pentagons). The illustration is from GoldenNumber.net 

The data that is used to draw a buckyball in this module is:

_oneBall.java

When we draw a figure based on surfaces described by a set of polygons, we will have to calculate normals and we will have to determine what is in (back) and what is out(front). We must index the corners in a consistent way. In OpenGL context this means that we must describe the corners clockwise (GL_CW) or counterclockwise(GL_CW). The direction has only meaning when we decide a point of observation. One way to do this is to decide that we look at a polygon from what we decide to call the front, usually the outside.

```gl.glFrontFace(GL.GL_CW)
gl.glFrontFace(GL.GL_CCW)
```

When we hav made these decisions we can calculate normals on all polygons, (or polygon corners) by means of the cross product for vectors.

```normal6=new float;
for (int ix = 0; ix < 20; ix++)
{
float ax = p6[ix] - p6[ix];
float ay = p6[ix] - p6[ix];
float az = p6[ix] - p6[ix];
float bx = p6[ix] - p6[ix];
float by = p6[ix] - p6[ix];
float bz = p6[ix] - p6[ix];
float x = ay * bz - az * by;
float y = az * bx - ax * bz;
float z = ax * by - ay * bx;
float l=(float)Math.sqrt(x*x+y*y+z*z);
normal6[ix]=x/l;
normal6[ix]=y/l;
normal6[ix]=z/l;
}
normal5=new float;
for (int ix = 0; ix < 12; ix++)
{
float ax = p5[ix] - p5[ix];
float ay = p5[ix] - p5[ix];
float az = p5[ix] - p5[ix];
float bx = p5[ix] - p5[ix];
float by = p5[ix] - p5[ix];
float bz = p5[ix] - p5[ix];
float x = ay * bz - az * by;
float y = az * bx - ax * bz;
float z = ax * by - ay * bx;
float l=(float)Math.sqrt(x*x+y*y+z*z);
normal5[ix]=x/l;
normal5[ix]=y/l;
normal5[ix]=z/l;
}```

This makes the drawing straight forward:

```public void drawMe(GL gl)
{
int mode = GL.GL_POLYGON;//GL.GL_LINE_STRIP;
// 20 polygons with 6 edges
stdMaterials.setMaterial(gl, stdMaterials.MAT_WARM_WHITE, GL.GL_FRONT);
for (int p = 0; p < 20; p++)
{
gl.glBegin(mode);
gl.glNormal3f(normal6[p], normal6[p], normal6[p]);
for (int ix = 0; ix < 6; ix++)
gl.glVertex3f(p6[p][ix], p6[p][ix], p6[p][ix]);
gl.glEnd();
}
// 12 polygons with 5 edges
stdMaterials.setMaterial(gl, stdMaterials.MAT_RUBY, GL.GL_FRONT);
for (int p = 0; p < 12; p++)
{
gl.glBegin(mode);
gl.glNormal3f(normal5[p], normal5[p], normal5[p]);
for (int ix = 0; ix < 5; ix++)
gl.glVertex3f(p5[p][ix], p5[p][ix], p5[p][ix]);
gl.glEnd();
}
}```

## Texture

We will add texture to all hexagons. We start out with a qudratic image and want to find which coordinates in the image we want to map to the hexagons corners. p0 d/3 , 0 p1 2d/3 , 0 p2 d-(d/3)cos(60) , (d/3)sin(60) p3 d-(2d/3)cos(60) , (2d/3)sin(60) p4 (2d/3)cos(60) , (2d/3)sin(60) p5 (d/3)cos(60) , (d/3)sin(60)

where d is the side in the triangle, and the square. When we map coordinates in a bitmap, as in the algorithm below, d always has the value 1, independant of the dimension of the bitmap measure in pixels. A texture has a logical dimension of 1 x 1. Since OpenGL (versions before 2.1) only accepts textures with format: 2n*2m, we will compose the image such that the part we want to include fits inside the triangle in question. Texture mapping can be prepared in the array tex6:

```// calculate texture points
float d=1.0f;
float cos60=(float)Math.cos(Math.PI/3.0);//60 degrees
float sin60=(float)Math.sin(Math.PI/3.0);
tex6=new float;
tex6=d/3.0f;                   tex6=0.0f;
tex6=2.0f*d/3.0f;              tex6=0.0f;
tex6=d-(d/3.0f)*cos60;         tex6=(d/3.0f)*sin60;
tex6=d-(2.0f*d/3.0f)*cos60;    tex6=(2.0f*d/3.0f)*sin60;
tex6=(2.0f*d/3.0f)*cos60;      tex6=(2.0f*d/3.0f)*sin60;
tex6=(d/3.0f)*cos60;           tex6=(d/3.0f)*sin60;
try {
}
catch (IOException ex) {
System.out.println(ex.getMessage());
}```

Rendering:

```public void drawMeTextured(GL gl,int tIx)
{
int mode = GL.GL_POLYGON;//GL.GL_LINE_STRIP;
if(tIx <0) tIx=0;
if(tIx >=textures.length) tIx=textures.length-1;
gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S,GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T,GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_NEAREST);
gl.glTexEnvi(GL.GL_TEXTURE_ENV,GL.GL_TEXTURE_ENV_MODE,GL.GL_MODULATE);
gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT,GL.GL_NICEST);
gl.glDisable(GL.GL_TEXTURE_2D);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB,
textures[tIx].getWidth(),textures[tIx].getHeight(), 0,
GL.GL_RGB, GL.GL_UNSIGNED_BYTE,
textures[tIx].getPixels());
gl.glEnable(GL.GL_TEXTURE_2D);
// 20 polygons with 6 edges
stdMaterials.setMaterial(gl, stdMaterials.MAT_WARM_WHITE, GL.GL_FRONT);
for (int p = 0; p < 20; p++)
{
gl.glBegin(mode);
gl.glNormal3f(normal6[p], normal6[p], normal6[p]);
for (int ix = 0; ix < 6; ix++)
{
gl.glTexCoord2f(tex6[ix], tex6[ix]);
gl.glVertex3f(p6[p][ix], p6[p][ix], p6[p][ix]);
}
gl.glEnd();
}
// 12 polygons with 5 edges
stdMaterials.setMaterial(gl, stdMaterials.MAT_RUBY, GL.GL_FRONT);
for (int p = 0; p < 12; p++)
{
gl.glBegin(mode);
gl.glNormal3f(normal5[p], normal5[p], normal5[p]);
for (int ix = 0; ix < 5; ix++)
gl.glVertex3f(p5[p][ix], p5[p][ix], p5[p][ix]);
gl.glEnd();
}
}```
References
1. Constructing a Buckyball with Mathematicareference.wolfram.com/legacy/v5/Demos/Notebooks/BuckyballConstruction.html24-05-2009
1. Buckyballs – a new sphere of sciencewww.science.org.au/nova/024/024key.htm24-05-2009
1. Fibonacci Numbers and the Golden Sectionwww.mcs.surrey.ac.uk/Personal/R.Knott/Fibonacci/fib.html24-05-2009
1. R. Buckminster Fullerwww.newciv.org/whole/bucky.html24-05-2009
1. Bucky BallsGOLDENNUMBER.NETwww.goldennumber.net/buckyball.htm14-10-2011
• The program project: https://svn.hiof.no/svn/psource/JOGL/bucky
Maintainance

B Stenseth, May 2009

(Welcome) JOGL>Ball (Lamps)